mirror of
https://github.com/home-assistant/core.git
synced 2025-07-21 12:17:07 +00:00
Provide clearer feedback in Coinbase when authentication fails (#62627)
This commit is contained in:
parent
8e8e49d3e7
commit
fa7739937d
@ -51,6 +51,15 @@ async def validate_api(hass: core.HomeAssistant, data):
|
|||||||
get_user_from_client, data[CONF_API_KEY], data[CONF_API_TOKEN]
|
get_user_from_client, data[CONF_API_KEY], data[CONF_API_TOKEN]
|
||||||
)
|
)
|
||||||
except AuthenticationError as error:
|
except AuthenticationError as error:
|
||||||
|
if "api key" in str(error):
|
||||||
|
_LOGGER.debug("Coinbase rejected API credentials due to an invalid API key")
|
||||||
|
raise InvalidKey from error
|
||||||
|
if "invalid signature" in str(error):
|
||||||
|
_LOGGER.debug(
|
||||||
|
"Coinbase rejected API credentials due to an invalid API secret"
|
||||||
|
)
|
||||||
|
raise InvalidSecret from error
|
||||||
|
_LOGGER.debug("Coinbase rejected API credentials due to an unknown error")
|
||||||
raise InvalidAuth from error
|
raise InvalidAuth from error
|
||||||
except ConnectionError as error:
|
except ConnectionError as error:
|
||||||
raise CannotConnect from error
|
raise CannotConnect from error
|
||||||
@ -110,6 +119,10 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
|||||||
info = await validate_api(self.hass, user_input)
|
info = await validate_api(self.hass, user_input)
|
||||||
except CannotConnect:
|
except CannotConnect:
|
||||||
errors["base"] = "cannot_connect"
|
errors["base"] = "cannot_connect"
|
||||||
|
except InvalidKey:
|
||||||
|
errors["base"] = "invalid_auth_key"
|
||||||
|
except InvalidSecret:
|
||||||
|
errors["base"] = "invalid_auth_secret"
|
||||||
except InvalidAuth:
|
except InvalidAuth:
|
||||||
errors["base"] = "invalid_auth"
|
errors["base"] = "invalid_auth"
|
||||||
except Exception: # pylint: disable=broad-except
|
except Exception: # pylint: disable=broad-except
|
||||||
@ -218,6 +231,14 @@ class InvalidAuth(exceptions.HomeAssistantError):
|
|||||||
"""Error to indicate there is invalid auth."""
|
"""Error to indicate there is invalid auth."""
|
||||||
|
|
||||||
|
|
||||||
|
class InvalidSecret(exceptions.HomeAssistantError):
|
||||||
|
"""Error to indicate auth failed due to invalid secret."""
|
||||||
|
|
||||||
|
|
||||||
|
class InvalidKey(exceptions.HomeAssistantError):
|
||||||
|
"""Error to indicate auth failed due to invalid key."""
|
||||||
|
|
||||||
|
|
||||||
class AlreadyConfigured(exceptions.HomeAssistantError):
|
class AlreadyConfigured(exceptions.HomeAssistantError):
|
||||||
"""Error to indicate Coinbase API Key is already configured."""
|
"""Error to indicate Coinbase API Key is already configured."""
|
||||||
|
|
||||||
|
@ -13,6 +13,8 @@
|
|||||||
"error": {
|
"error": {
|
||||||
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
|
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
|
||||||
"invalid_auth": "[%key:common::config_flow::error::invalid_auth%]",
|
"invalid_auth": "[%key:common::config_flow::error::invalid_auth%]",
|
||||||
|
"invalid_auth_key": "API credentials rejected by Coinbase due to an invalid API Key.",
|
||||||
|
"invalid_auth_secret": "API credentials rejected by Coinbase due to an invalid API Secret.",
|
||||||
"unknown": "[%key:common::config_flow::error::unknown%]"
|
"unknown": "[%key:common::config_flow::error::unknown%]"
|
||||||
},
|
},
|
||||||
"abort": {
|
"abort": {
|
||||||
|
@ -6,15 +6,15 @@
|
|||||||
"error": {
|
"error": {
|
||||||
"cannot_connect": "Failed to connect",
|
"cannot_connect": "Failed to connect",
|
||||||
"invalid_auth": "Invalid authentication",
|
"invalid_auth": "Invalid authentication",
|
||||||
|
"invalid_auth_key": "API credentials rejected by Coinbase due to an invalid API Key.",
|
||||||
|
"invalid_auth_secret": "API credentials rejected by Coinbase due to an invalid API Secret.",
|
||||||
"unknown": "Unexpected error"
|
"unknown": "Unexpected error"
|
||||||
},
|
},
|
||||||
"step": {
|
"step": {
|
||||||
"user": {
|
"user": {
|
||||||
"data": {
|
"data": {
|
||||||
"api_key": "API Key",
|
"api_key": "API Key",
|
||||||
"api_token": "API Secret",
|
"api_token": "API Secret"
|
||||||
"currencies": "Account Balance Currencies",
|
|
||||||
"exchange_rates": "Exchange Rates"
|
|
||||||
},
|
},
|
||||||
"description": "Please enter the details of your API key as provided by Coinbase.",
|
"description": "Please enter the details of your API key as provided by Coinbase.",
|
||||||
"title": "Coinbase API Key Details"
|
"title": "Coinbase API Key Details"
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
"""Test the Coinbase config flow."""
|
"""Test the Coinbase config flow."""
|
||||||
|
import logging
|
||||||
from unittest.mock import patch
|
from unittest.mock import patch
|
||||||
|
|
||||||
from coinbase.wallet.error import AuthenticationError
|
from coinbase.wallet.error import AuthenticationError
|
||||||
@ -63,23 +64,25 @@ async def test_form(hass):
|
|||||||
assert len(mock_setup_entry.mock_calls) == 1
|
assert len(mock_setup_entry.mock_calls) == 1
|
||||||
|
|
||||||
|
|
||||||
async def test_form_invalid_auth(hass):
|
async def test_form_invalid_auth(hass, caplog):
|
||||||
"""Test we handle invalid auth."""
|
"""Test we handle invalid auth."""
|
||||||
result = await hass.config_entries.flow.async_init(
|
result = await hass.config_entries.flow.async_init(
|
||||||
DOMAIN, context={"source": config_entries.SOURCE_USER}
|
DOMAIN, context={"source": config_entries.SOURCE_USER}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
caplog.set_level(logging.DEBUG)
|
||||||
|
|
||||||
response = Response()
|
response = Response()
|
||||||
response.status_code = 401
|
response.status_code = 401
|
||||||
api_auth_error = AuthenticationError(
|
api_auth_error_unknown = AuthenticationError(
|
||||||
response,
|
response,
|
||||||
"authentication_error",
|
"authentication_error",
|
||||||
"invalid signature",
|
"unknown error",
|
||||||
[{"id": "authentication_error", "message": "invalid signature"}],
|
[{"id": "authentication_error", "message": "unknown error"}],
|
||||||
)
|
)
|
||||||
with patch(
|
with patch(
|
||||||
"coinbase.wallet.client.Client.get_current_user",
|
"coinbase.wallet.client.Client.get_current_user",
|
||||||
side_effect=api_auth_error,
|
side_effect=api_auth_error_unknown,
|
||||||
):
|
):
|
||||||
result2 = await hass.config_entries.flow.async_configure(
|
result2 = await hass.config_entries.flow.async_configure(
|
||||||
result["flow_id"],
|
result["flow_id"],
|
||||||
@ -91,6 +94,53 @@ async def test_form_invalid_auth(hass):
|
|||||||
|
|
||||||
assert result2["type"] == "form"
|
assert result2["type"] == "form"
|
||||||
assert result2["errors"] == {"base": "invalid_auth"}
|
assert result2["errors"] == {"base": "invalid_auth"}
|
||||||
|
assert "Coinbase rejected API credentials due to an unknown error" in caplog.text
|
||||||
|
|
||||||
|
api_auth_error_key = AuthenticationError(
|
||||||
|
response,
|
||||||
|
"authentication_error",
|
||||||
|
"invalid api key",
|
||||||
|
[{"id": "authentication_error", "message": "invalid api key"}],
|
||||||
|
)
|
||||||
|
with patch(
|
||||||
|
"coinbase.wallet.client.Client.get_current_user",
|
||||||
|
side_effect=api_auth_error_key,
|
||||||
|
):
|
||||||
|
result2 = await hass.config_entries.flow.async_configure(
|
||||||
|
result["flow_id"],
|
||||||
|
{
|
||||||
|
CONF_API_KEY: "123456",
|
||||||
|
CONF_API_TOKEN: "AbCDeF",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
assert result2["type"] == "form"
|
||||||
|
assert result2["errors"] == {"base": "invalid_auth_key"}
|
||||||
|
assert "Coinbase rejected API credentials due to an invalid API key" in caplog.text
|
||||||
|
|
||||||
|
api_auth_error_secret = AuthenticationError(
|
||||||
|
response,
|
||||||
|
"authentication_error",
|
||||||
|
"invalid signature",
|
||||||
|
[{"id": "authentication_error", "message": "invalid signature"}],
|
||||||
|
)
|
||||||
|
with patch(
|
||||||
|
"coinbase.wallet.client.Client.get_current_user",
|
||||||
|
side_effect=api_auth_error_secret,
|
||||||
|
):
|
||||||
|
result2 = await hass.config_entries.flow.async_configure(
|
||||||
|
result["flow_id"],
|
||||||
|
{
|
||||||
|
CONF_API_KEY: "123456",
|
||||||
|
CONF_API_TOKEN: "AbCDeF",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
assert result2["type"] == "form"
|
||||||
|
assert result2["errors"] == {"base": "invalid_auth_secret"}
|
||||||
|
assert (
|
||||||
|
"Coinbase rejected API credentials due to an invalid API secret" in caplog.text
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
async def test_form_cannot_connect(hass):
|
async def test_form_cannot_connect(hass):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user