Prefer HTTPStatus over int in HA view JSON functions (#56504)

* Prefer HTTPStatus over int in HA view JSON functions

* Update zwave tests to not expect a fixed typo
This commit is contained in:
Ville Skyttä 2021-09-22 21:59:52 +03:00 committed by GitHub
parent 39aaa383b3
commit d8d34fdd3b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
26 changed files with 191 additions and 190 deletions

View file

@ -1,5 +1,6 @@
"""Rest API for Home Assistant.""" """Rest API for Home Assistant."""
import asyncio import asyncio
from http import HTTPStatus
import json import json
import logging import logging
@ -14,10 +15,6 @@ from homeassistant.components.http import HomeAssistantView
from homeassistant.const import ( from homeassistant.const import (
EVENT_HOMEASSISTANT_STOP, EVENT_HOMEASSISTANT_STOP,
EVENT_TIME_CHANGED, EVENT_TIME_CHANGED,
HTTP_BAD_REQUEST,
HTTP_CREATED,
HTTP_NOT_FOUND,
HTTP_OK,
MATCH_ALL, MATCH_ALL,
URL_API, URL_API,
URL_API_COMPONENTS, URL_API_COMPONENTS,
@ -231,7 +228,7 @@ class APIEntityStateView(HomeAssistantView):
state = request.app["hass"].states.get(entity_id) state = request.app["hass"].states.get(entity_id)
if state: if state:
return self.json(state) return self.json(state)
return self.json_message("Entity not found.", HTTP_NOT_FOUND) return self.json_message("Entity not found.", HTTPStatus.NOT_FOUND)
async def post(self, request, entity_id): async def post(self, request, entity_id):
"""Update state of entity.""" """Update state of entity."""
@ -241,12 +238,12 @@ class APIEntityStateView(HomeAssistantView):
try: try:
data = await request.json() data = await request.json()
except ValueError: except ValueError:
return self.json_message("Invalid JSON specified.", HTTP_BAD_REQUEST) return self.json_message("Invalid JSON specified.", HTTPStatus.BAD_REQUEST)
new_state = data.get("state") new_state = data.get("state")
if new_state is None: if new_state is None:
return self.json_message("No state specified.", HTTP_BAD_REQUEST) return self.json_message("No state specified.", HTTPStatus.BAD_REQUEST)
attributes = data.get("attributes") attributes = data.get("attributes")
force_update = data.get("force_update", False) force_update = data.get("force_update", False)
@ -259,7 +256,7 @@ class APIEntityStateView(HomeAssistantView):
) )
# Read the state back for our response # Read the state back for our response
status_code = HTTP_CREATED if is_new_state else HTTP_OK status_code = HTTPStatus.CREATED if is_new_state else HTTPStatus.OK
resp = self.json(hass.states.get(entity_id), status_code) resp = self.json(hass.states.get(entity_id), status_code)
resp.headers.add("Location", f"/api/states/{entity_id}") resp.headers.add("Location", f"/api/states/{entity_id}")
@ -273,7 +270,7 @@ class APIEntityStateView(HomeAssistantView):
raise Unauthorized(entity_id=entity_id) raise Unauthorized(entity_id=entity_id)
if request.app["hass"].states.async_remove(entity_id): if request.app["hass"].states.async_remove(entity_id):
return self.json_message("Entity removed.") return self.json_message("Entity removed.")
return self.json_message("Entity not found.", HTTP_NOT_FOUND) return self.json_message("Entity not found.", HTTPStatus.NOT_FOUND)
class APIEventListenersView(HomeAssistantView): class APIEventListenersView(HomeAssistantView):
@ -303,12 +300,12 @@ class APIEventView(HomeAssistantView):
event_data = json.loads(body) if body else None event_data = json.loads(body) if body else None
except ValueError: except ValueError:
return self.json_message( return self.json_message(
"Event data should be valid JSON.", HTTP_BAD_REQUEST "Event data should be valid JSON.", HTTPStatus.BAD_REQUEST
) )
if event_data is not None and not isinstance(event_data, dict): if event_data is not None and not isinstance(event_data, dict):
return self.json_message( return self.json_message(
"Event data should be a JSON object", HTTP_BAD_REQUEST "Event data should be a JSON object", HTTPStatus.BAD_REQUEST
) )
# Special case handling for event STATE_CHANGED # Special case handling for event STATE_CHANGED
@ -355,7 +352,9 @@ class APIDomainServicesView(HomeAssistantView):
try: try:
data = json.loads(body) if body else None data = json.loads(body) if body else None
except ValueError: except ValueError:
return self.json_message("Data should be valid JSON.", HTTP_BAD_REQUEST) return self.json_message(
"Data should be valid JSON.", HTTPStatus.BAD_REQUEST
)
context = self.context(request) context = self.context(request)
@ -403,7 +402,7 @@ class APITemplateView(HomeAssistantView):
return tpl.async_render(variables=data.get("variables"), parse_result=False) return tpl.async_render(variables=data.get("variables"), parse_result=False)
except (ValueError, TemplateError) as ex: except (ValueError, TemplateError) as ex:
return self.json_message( return self.json_message(
f"Error rendering template: {ex}", HTTP_BAD_REQUEST f"Error rendering template: {ex}", HTTPStatus.BAD_REQUEST
) )

View file

@ -117,6 +117,7 @@ Result will be a long-lived access token:
from __future__ import annotations from __future__ import annotations
from datetime import timedelta from datetime import timedelta
from http import HTTPStatus
import uuid import uuid
from aiohttp import web from aiohttp import web
@ -133,7 +134,7 @@ from homeassistant.components.http.auth import async_sign_path
from homeassistant.components.http.ban import log_invalid_auth from homeassistant.components.http.ban import log_invalid_auth
from homeassistant.components.http.data_validator import RequestDataValidator from homeassistant.components.http.data_validator import RequestDataValidator
from homeassistant.components.http.view import HomeAssistantView from homeassistant.components.http.view import HomeAssistantView
from homeassistant.const import HTTP_BAD_REQUEST, HTTP_FORBIDDEN, HTTP_OK from homeassistant.const import HTTP_OK
from homeassistant.core import HomeAssistant, callback from homeassistant.core import HomeAssistant, callback
from homeassistant.loader import bind_hass from homeassistant.loader import bind_hass
from homeassistant.util import dt as dt_util from homeassistant.util import dt as dt_util
@ -259,7 +260,7 @@ class TokenView(HomeAssistantView):
return await self._async_handle_refresh_token(hass, data, request.remote) return await self._async_handle_refresh_token(hass, data, request.remote)
return self.json( return self.json(
{"error": "unsupported_grant_type"}, status_code=HTTP_BAD_REQUEST {"error": "unsupported_grant_type"}, status_code=HTTPStatus.BAD_REQUEST
) )
async def _async_handle_revoke_token(self, hass, data): async def _async_handle_revoke_token(self, hass, data):
@ -289,7 +290,7 @@ class TokenView(HomeAssistantView):
if client_id is None or not indieauth.verify_client_id(client_id): if client_id is None or not indieauth.verify_client_id(client_id):
return self.json( return self.json(
{"error": "invalid_request", "error_description": "Invalid client id"}, {"error": "invalid_request", "error_description": "Invalid client id"},
status_code=HTTP_BAD_REQUEST, status_code=HTTPStatus.BAD_REQUEST,
) )
code = data.get("code") code = data.get("code")
@ -297,7 +298,7 @@ class TokenView(HomeAssistantView):
if code is None: if code is None:
return self.json( return self.json(
{"error": "invalid_request", "error_description": "Invalid code"}, {"error": "invalid_request", "error_description": "Invalid code"},
status_code=HTTP_BAD_REQUEST, status_code=HTTPStatus.BAD_REQUEST,
) )
credential = self._retrieve_auth(client_id, RESULT_TYPE_CREDENTIALS, code) credential = self._retrieve_auth(client_id, RESULT_TYPE_CREDENTIALS, code)
@ -305,7 +306,7 @@ class TokenView(HomeAssistantView):
if credential is None or not isinstance(credential, Credentials): if credential is None or not isinstance(credential, Credentials):
return self.json( return self.json(
{"error": "invalid_request", "error_description": "Invalid code"}, {"error": "invalid_request", "error_description": "Invalid code"},
status_code=HTTP_BAD_REQUEST, status_code=HTTPStatus.BAD_REQUEST,
) )
user = await hass.auth.async_get_or_create_user(credential) user = await hass.auth.async_get_or_create_user(credential)
@ -313,7 +314,7 @@ class TokenView(HomeAssistantView):
if not user.is_active: if not user.is_active:
return self.json( return self.json(
{"error": "access_denied", "error_description": "User is not active"}, {"error": "access_denied", "error_description": "User is not active"},
status_code=HTTP_FORBIDDEN, status_code=HTTPStatus.FORBIDDEN,
) )
refresh_token = await hass.auth.async_create_refresh_token( refresh_token = await hass.auth.async_create_refresh_token(
@ -326,7 +327,7 @@ class TokenView(HomeAssistantView):
except InvalidAuthError as exc: except InvalidAuthError as exc:
return self.json( return self.json(
{"error": "access_denied", "error_description": str(exc)}, {"error": "access_denied", "error_description": str(exc)},
status_code=HTTP_FORBIDDEN, status_code=HTTPStatus.FORBIDDEN,
) )
return self.json( return self.json(
@ -346,21 +347,27 @@ class TokenView(HomeAssistantView):
if client_id is not None and not indieauth.verify_client_id(client_id): if client_id is not None and not indieauth.verify_client_id(client_id):
return self.json( return self.json(
{"error": "invalid_request", "error_description": "Invalid client id"}, {"error": "invalid_request", "error_description": "Invalid client id"},
status_code=HTTP_BAD_REQUEST, status_code=HTTPStatus.BAD_REQUEST,
) )
token = data.get("refresh_token") token = data.get("refresh_token")
if token is None: if token is None:
return self.json({"error": "invalid_request"}, status_code=HTTP_BAD_REQUEST) return self.json(
{"error": "invalid_request"}, status_code=HTTPStatus.BAD_REQUEST
)
refresh_token = await hass.auth.async_get_refresh_token_by_token(token) refresh_token = await hass.auth.async_get_refresh_token_by_token(token)
if refresh_token is None: if refresh_token is None:
return self.json({"error": "invalid_grant"}, status_code=HTTP_BAD_REQUEST) return self.json(
{"error": "invalid_grant"}, status_code=HTTPStatus.BAD_REQUEST
)
if refresh_token.client_id != client_id: if refresh_token.client_id != client_id:
return self.json({"error": "invalid_request"}, status_code=HTTP_BAD_REQUEST) return self.json(
{"error": "invalid_request"}, status_code=HTTPStatus.BAD_REQUEST
)
try: try:
access_token = hass.auth.async_create_access_token( access_token = hass.auth.async_create_access_token(
@ -369,7 +376,7 @@ class TokenView(HomeAssistantView):
except InvalidAuthError as exc: except InvalidAuthError as exc:
return self.json( return self.json(
{"error": "access_denied", "error_description": str(exc)}, {"error": "access_denied", "error_description": str(exc)},
status_code=HTTP_FORBIDDEN, status_code=HTTPStatus.FORBIDDEN,
) )
return self.json( return self.json(
@ -404,7 +411,7 @@ class LinkUserView(HomeAssistantView):
) )
if credentials is None: if credentials is None:
return self.json_message("Invalid code", status_code=HTTP_BAD_REQUEST) return self.json_message("Invalid code", status_code=HTTPStatus.BAD_REQUEST)
await hass.auth.async_link_user(user, credentials) await hass.auth.async_link_user(user, credentials)
return self.json_message("User linked") return self.json_message("User linked")

View file

@ -66,6 +66,7 @@ associate with an credential if "type" set to "link_user" in
"version": 1 "version": 1
} }
""" """
from http import HTTPStatus
from ipaddress import ip_address from ipaddress import ip_address
from aiohttp import web from aiohttp import web
@ -80,11 +81,7 @@ from homeassistant.components.http.ban import (
) )
from homeassistant.components.http.data_validator import RequestDataValidator from homeassistant.components.http.data_validator import RequestDataValidator
from homeassistant.components.http.view import HomeAssistantView from homeassistant.components.http.view import HomeAssistantView
from homeassistant.const import ( from homeassistant.const import HTTP_METHOD_NOT_ALLOWED
HTTP_BAD_REQUEST,
HTTP_METHOD_NOT_ALLOWED,
HTTP_NOT_FOUND,
)
from . import indieauth from . import indieauth
@ -109,7 +106,7 @@ class AuthProvidersView(HomeAssistantView):
if not hass.components.onboarding.async_is_user_onboarded(): if not hass.components.onboarding.async_is_user_onboarded():
return self.json_message( return self.json_message(
message="Onboarding not finished", message="Onboarding not finished",
status_code=HTTP_BAD_REQUEST, status_code=HTTPStatus.BAD_REQUEST,
message_code="onboarding_required", message_code="onboarding_required",
) )
@ -177,7 +174,7 @@ class LoginFlowIndexView(HomeAssistantView):
request.app["hass"], data["client_id"], data["redirect_uri"] request.app["hass"], data["client_id"], data["redirect_uri"]
): ):
return self.json_message( return self.json_message(
"invalid client id or redirect uri", HTTP_BAD_REQUEST "invalid client id or redirect uri", HTTPStatus.BAD_REQUEST
) )
if isinstance(data["handler"], list): if isinstance(data["handler"], list):
@ -194,9 +191,11 @@ class LoginFlowIndexView(HomeAssistantView):
}, },
) )
except data_entry_flow.UnknownHandler: except data_entry_flow.UnknownHandler:
return self.json_message("Invalid handler specified", HTTP_NOT_FOUND) return self.json_message("Invalid handler specified", HTTPStatus.NOT_FOUND)
except data_entry_flow.UnknownStep: except data_entry_flow.UnknownStep:
return self.json_message("Handler does not support init", HTTP_BAD_REQUEST) return self.json_message(
"Handler does not support init", HTTPStatus.BAD_REQUEST
)
if result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY: if result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY:
await process_success_login(request) await process_success_login(request)
@ -221,7 +220,7 @@ class LoginFlowResourceView(HomeAssistantView):
async def get(self, request): async def get(self, request):
"""Do not allow getting status of a flow in progress.""" """Do not allow getting status of a flow in progress."""
return self.json_message("Invalid flow specified", HTTP_NOT_FOUND) return self.json_message("Invalid flow specified", HTTPStatus.NOT_FOUND)
@RequestDataValidator(vol.Schema({"client_id": str}, extra=vol.ALLOW_EXTRA)) @RequestDataValidator(vol.Schema({"client_id": str}, extra=vol.ALLOW_EXTRA))
@log_invalid_auth @log_invalid_auth
@ -230,7 +229,7 @@ class LoginFlowResourceView(HomeAssistantView):
client_id = data.pop("client_id") client_id = data.pop("client_id")
if not indieauth.verify_client_id(client_id): if not indieauth.verify_client_id(client_id):
return self.json_message("Invalid client id", HTTP_BAD_REQUEST) return self.json_message("Invalid client id", HTTPStatus.BAD_REQUEST)
try: try:
# do not allow change ip during login flow # do not allow change ip during login flow
@ -238,13 +237,15 @@ class LoginFlowResourceView(HomeAssistantView):
if flow["flow_id"] == flow_id and flow["context"][ if flow["flow_id"] == flow_id and flow["context"][
"ip_address" "ip_address"
] != ip_address(request.remote): ] != ip_address(request.remote):
return self.json_message("IP address changed", HTTP_BAD_REQUEST) return self.json_message(
"IP address changed", HTTPStatus.BAD_REQUEST
)
result = await self._flow_mgr.async_configure(flow_id, data) result = await self._flow_mgr.async_configure(flow_id, data)
except data_entry_flow.UnknownFlow: except data_entry_flow.UnknownFlow:
return self.json_message("Invalid flow specified", HTTP_NOT_FOUND) return self.json_message("Invalid flow specified", HTTPStatus.NOT_FOUND)
except vol.Invalid: except vol.Invalid:
return self.json_message("User input malformed", HTTP_BAD_REQUEST) return self.json_message("User input malformed", HTTPStatus.BAD_REQUEST)
if result["type"] != data_entry_flow.RESULT_TYPE_CREATE_ENTRY: if result["type"] != data_entry_flow.RESULT_TYPE_CREATE_ENTRY:
# @log_invalid_auth does not work here since it returns HTTP 200 # @log_invalid_auth does not work here since it returns HTTP 200
@ -266,6 +267,6 @@ class LoginFlowResourceView(HomeAssistantView):
try: try:
self._flow_mgr.async_abort(flow_id) self._flow_mgr.async_abort(flow_id)
except data_entry_flow.UnknownFlow: except data_entry_flow.UnknownFlow:
return self.json_message("Invalid flow specified", HTTP_NOT_FOUND) return self.json_message("Invalid flow specified", HTTPStatus.NOT_FOUND)
return self.json_message("Flow aborted") return self.json_message("Flow aborted")

View file

@ -1,17 +1,13 @@
"""Component to configure Home Assistant via an API.""" """Component to configure Home Assistant via an API."""
import asyncio import asyncio
from http import HTTPStatus
import importlib import importlib
import os import os
import voluptuous as vol import voluptuous as vol
from homeassistant.components.http import HomeAssistantView from homeassistant.components.http import HomeAssistantView
from homeassistant.const import ( from homeassistant.const import CONF_ID, EVENT_COMPONENT_LOADED
CONF_ID,
EVENT_COMPONENT_LOADED,
HTTP_BAD_REQUEST,
HTTP_NOT_FOUND,
)
from homeassistant.core import callback from homeassistant.core import callback
from homeassistant.exceptions import HomeAssistantError from homeassistant.exceptions import HomeAssistantError
from homeassistant.setup import ATTR_COMPONENT from homeassistant.setup import ATTR_COMPONENT
@ -125,7 +121,7 @@ class BaseEditConfigView(HomeAssistantView):
value = self._get_value(hass, current, config_key) value = self._get_value(hass, current, config_key)
if value is None: if value is None:
return self.json_message("Resource not found", HTTP_NOT_FOUND) return self.json_message("Resource not found", HTTPStatus.NOT_FOUND)
return self.json(value) return self.json(value)
@ -134,12 +130,12 @@ class BaseEditConfigView(HomeAssistantView):
try: try:
data = await request.json() data = await request.json()
except ValueError: except ValueError:
return self.json_message("Invalid JSON specified", HTTP_BAD_REQUEST) return self.json_message("Invalid JSON specified", HTTPStatus.BAD_REQUEST)
try: try:
self.key_schema(config_key) self.key_schema(config_key)
except vol.Invalid as err: except vol.Invalid as err:
return self.json_message(f"Key malformed: {err}", HTTP_BAD_REQUEST) return self.json_message(f"Key malformed: {err}", HTTPStatus.BAD_REQUEST)
hass = request.app["hass"] hass = request.app["hass"]
@ -151,7 +147,9 @@ class BaseEditConfigView(HomeAssistantView):
else: else:
self.data_schema(data) self.data_schema(data)
except (vol.Invalid, HomeAssistantError) as err: except (vol.Invalid, HomeAssistantError) as err:
return self.json_message(f"Message malformed: {err}", HTTP_BAD_REQUEST) return self.json_message(
f"Message malformed: {err}", HTTPStatus.BAD_REQUEST
)
path = hass.config.path(self.path) path = hass.config.path(self.path)
@ -177,7 +175,7 @@ class BaseEditConfigView(HomeAssistantView):
path = hass.config.path(self.path) path = hass.config.path(self.path)
if value is None: if value is None:
return self.json_message("Resource not found", HTTP_NOT_FOUND) return self.json_message("Resource not found", HTTPStatus.BAD_REQUEST)
self._delete_value(hass, current, config_key) self._delete_value(hass, current, config_key)
await hass.async_add_executor_job(_write, path, current) await hass.async_add_executor_job(_write, path, current)

View file

@ -1,6 +1,8 @@
"""Http views to control the config manager.""" """Http views to control the config manager."""
from __future__ import annotations from __future__ import annotations
from http import HTTPStatus
import aiohttp.web_exceptions import aiohttp.web_exceptions
import voluptuous as vol import voluptuous as vol
@ -8,7 +10,6 @@ from homeassistant import config_entries, data_entry_flow
from homeassistant.auth.permissions.const import CAT_CONFIG_ENTRIES, POLICY_EDIT from homeassistant.auth.permissions.const import CAT_CONFIG_ENTRIES, POLICY_EDIT
from homeassistant.components import websocket_api from homeassistant.components import websocket_api
from homeassistant.components.http import HomeAssistantView from homeassistant.components.http import HomeAssistantView
from homeassistant.const import HTTP_FORBIDDEN, HTTP_NOT_FOUND
from homeassistant.core import HomeAssistant, callback from homeassistant.core import HomeAssistant, callback
from homeassistant.exceptions import Unauthorized from homeassistant.exceptions import Unauthorized
from homeassistant.helpers.data_entry_flow import ( from homeassistant.helpers.data_entry_flow import (
@ -69,7 +70,7 @@ class ConfigManagerEntryResourceView(HomeAssistantView):
try: try:
result = await hass.config_entries.async_remove(entry_id) result = await hass.config_entries.async_remove(entry_id)
except config_entries.UnknownEntry: except config_entries.UnknownEntry:
return self.json_message("Invalid entry specified", HTTP_NOT_FOUND) return self.json_message("Invalid entry specified", HTTPStatus.NOT_FOUND)
return self.json(result) return self.json(result)
@ -90,9 +91,9 @@ class ConfigManagerEntryResourceReloadView(HomeAssistantView):
try: try:
result = await hass.config_entries.async_reload(entry_id) result = await hass.config_entries.async_reload(entry_id)
except config_entries.OperationNotAllowed: except config_entries.OperationNotAllowed:
return self.json_message("Entry cannot be reloaded", HTTP_FORBIDDEN) return self.json_message("Entry cannot be reloaded", HTTPStatus.FORBIDDEN)
except config_entries.UnknownEntry: except config_entries.UnknownEntry:
return self.json_message("Invalid entry specified", HTTP_NOT_FOUND) return self.json_message("Invalid entry specified", HTTPStatus.NOT_FOUND)
return self.json({"require_restart": not result}) return self.json({"require_restart": not result})

View file

@ -1,12 +1,13 @@
"""Provide configuration end points for Z-Wave.""" """Provide configuration end points for Z-Wave."""
from collections import deque from collections import deque
from http import HTTPStatus
import logging import logging
from aiohttp.web import Response from aiohttp.web import Response
from homeassistant.components.http import HomeAssistantView from homeassistant.components.http import HomeAssistantView
from homeassistant.components.zwave import DEVICE_CONFIG_SCHEMA_ENTRY, const from homeassistant.components.zwave import DEVICE_CONFIG_SCHEMA_ENTRY, const
from homeassistant.const import HTTP_ACCEPTED, HTTP_BAD_REQUEST, HTTP_NOT_FOUND, HTTP_OK from homeassistant.const import HTTP_BAD_REQUEST
import homeassistant.core as ha import homeassistant.core as ha
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
@ -82,10 +83,12 @@ class ZWaveConfigWriteView(HomeAssistantView):
hass = request.app["hass"] hass = request.app["hass"]
network = hass.data.get(const.DATA_NETWORK) network = hass.data.get(const.DATA_NETWORK)
if network is None: if network is None:
return self.json_message("No Z-Wave network data found", HTTP_NOT_FOUND) return self.json_message(
"No Z-Wave network data found", HTTPStatus.NOT_FOUND
)
_LOGGER.info("Z-Wave configuration written to file") _LOGGER.info("Z-Wave configuration written to file")
network.write_config() network.write_config()
return self.json_message("Z-Wave configuration saved to file", HTTP_OK) return self.json_message("Z-Wave configuration saved to file")
class ZWaveNodeValueView(HomeAssistantView): class ZWaveNodeValueView(HomeAssistantView):
@ -131,7 +134,7 @@ class ZWaveNodeGroupView(HomeAssistantView):
network = hass.data.get(const.DATA_NETWORK) network = hass.data.get(const.DATA_NETWORK)
node = network.nodes.get(nodeid) node = network.nodes.get(nodeid)
if node is None: if node is None:
return self.json_message("Node not found", HTTP_NOT_FOUND) return self.json_message("Node not found", HTTPStatus.NOT_FOUND)
groupdata = node.groups groupdata = node.groups
groups = {} groups = {}
for key, value in groupdata.items(): for key, value in groupdata.items():
@ -158,7 +161,7 @@ class ZWaveNodeConfigView(HomeAssistantView):
network = hass.data.get(const.DATA_NETWORK) network = hass.data.get(const.DATA_NETWORK)
node = network.nodes.get(nodeid) node = network.nodes.get(nodeid)
if node is None: if node is None:
return self.json_message("Node not found", HTTP_NOT_FOUND) return self.json_message("Node not found", HTTPStatus.NOT_FOUND)
config = {} config = {}
for value in node.get_values( for value in node.get_values(
class_id=const.COMMAND_CLASS_CONFIGURATION class_id=const.COMMAND_CLASS_CONFIGURATION
@ -189,7 +192,7 @@ class ZWaveUserCodeView(HomeAssistantView):
network = hass.data.get(const.DATA_NETWORK) network = hass.data.get(const.DATA_NETWORK)
node = network.nodes.get(nodeid) node = network.nodes.get(nodeid)
if node is None: if node is None:
return self.json_message("Node not found", HTTP_NOT_FOUND) return self.json_message("Node not found", HTTPStatus.NOT_FOUND)
usercodes = {} usercodes = {}
if not node.has_command_class(const.COMMAND_CLASS_USER_CODE): if not node.has_command_class(const.COMMAND_CLASS_USER_CODE):
return self.json(usercodes) return self.json(usercodes)
@ -220,7 +223,7 @@ class ZWaveProtectionView(HomeAssistantView):
"""Get protection data.""" """Get protection data."""
node = network.nodes.get(nodeid) node = network.nodes.get(nodeid)
if node is None: if node is None:
return self.json_message("Node not found", HTTP_NOT_FOUND) return self.json_message("Node not found", HTTPStatus.NOT_FOUND)
protection_options = {} protection_options = {}
if not node.has_command_class(const.COMMAND_CLASS_PROTECTION): if not node.has_command_class(const.COMMAND_CLASS_PROTECTION):
return self.json(protection_options) return self.json(protection_options)
@ -247,16 +250,16 @@ class ZWaveProtectionView(HomeAssistantView):
selection = protection_data["selection"] selection = protection_data["selection"]
value_id = int(protection_data[const.ATTR_VALUE_ID]) value_id = int(protection_data[const.ATTR_VALUE_ID])
if node is None: if node is None:
return self.json_message("Node not found", HTTP_NOT_FOUND) return self.json_message("Node not found", HTTPStatus.NOT_FOUND)
if not node.has_command_class(const.COMMAND_CLASS_PROTECTION): if not node.has_command_class(const.COMMAND_CLASS_PROTECTION):
return self.json_message( return self.json_message(
"No protection commandclass on this node", HTTP_NOT_FOUND "No protection commandclass on this node", HTTPStatus.NOT_FOUND
) )
state = node.set_protection(value_id, selection) state = node.set_protection(value_id, selection)
if not state: if not state:
return self.json_message( return self.json_message(
"Protection setting did not complete", HTTP_ACCEPTED "Protection setting did not complete", HTTPStatus.ACCEPTED
) )
return self.json_message("Protection setting succsessfully set", HTTP_OK) return self.json_message("Protection setting successfully set")
return await hass.async_add_executor_job(_set_protection) return await hass.async_add_executor_job(_set_protection)

View file

@ -1,4 +1,5 @@
"""Support for functionality to have conversations with Home Assistant.""" """Support for functionality to have conversations with Home Assistant."""
from http import HTTPStatus
import logging import logging
import re import re
@ -7,7 +8,6 @@ import voluptuous as vol
from homeassistant import core from homeassistant import core
from homeassistant.components import http, websocket_api from homeassistant.components import http, websocket_api
from homeassistant.components.http.data_validator import RequestDataValidator from homeassistant.components.http.data_validator import RequestDataValidator
from homeassistant.const import HTTP_INTERNAL_SERVER_ERROR
from homeassistant.helpers import config_validation as cv, intent from homeassistant.helpers import config_validation as cv, intent
from homeassistant.loader import bind_hass from homeassistant.loader import bind_hass
@ -146,7 +146,7 @@ class ConversationProcessView(http.HomeAssistantView):
"message": str(err), "message": str(err),
}, },
}, },
status_code=HTTP_INTERNAL_SERVER_ERROR, status_code=HTTPStatus.INTERNAL_SERVER_ERROR,
) )
return self.json(intent_result) return self.json(intent_result)

View file

@ -1,6 +1,7 @@
"""Support for a Hue API to control Home Assistant.""" """Support for a Hue API to control Home Assistant."""
import asyncio import asyncio
import hashlib import hashlib
from http import HTTPStatus
from ipaddress import ip_address from ipaddress import ip_address
import logging import logging
import time import time
@ -55,9 +56,6 @@ from homeassistant.const import (
ATTR_ENTITY_ID, ATTR_ENTITY_ID,
ATTR_SUPPORTED_FEATURES, ATTR_SUPPORTED_FEATURES,
ATTR_TEMPERATURE, ATTR_TEMPERATURE,
HTTP_BAD_REQUEST,
HTTP_NOT_FOUND,
HTTP_UNAUTHORIZED,
SERVICE_CLOSE_COVER, SERVICE_CLOSE_COVER,
SERVICE_OPEN_COVER, SERVICE_OPEN_COVER,
SERVICE_TURN_OFF, SERVICE_TURN_OFF,
@ -136,15 +134,15 @@ class HueUsernameView(HomeAssistantView):
async def post(self, request): async def post(self, request):
"""Handle a POST request.""" """Handle a POST request."""
if not is_local(ip_address(request.remote)): if not is_local(ip_address(request.remote)):
return self.json_message("Only local IPs allowed", HTTP_UNAUTHORIZED) return self.json_message("Only local IPs allowed", HTTPStatus.UNAUTHORIZED)
try: try:
data = await request.json() data = await request.json()
except ValueError: except ValueError:
return self.json_message("Invalid JSON", HTTP_BAD_REQUEST) return self.json_message("Invalid JSON", HTTPStatus.BAD_REQUEST)
if "devicetype" not in data: if "devicetype" not in data:
return self.json_message("devicetype not specified", HTTP_BAD_REQUEST) return self.json_message("devicetype not specified", HTTPStatus.BAD_REQUEST)
return self.json([{"success": {"username": HUE_API_USERNAME}}]) return self.json([{"success": {"username": HUE_API_USERNAME}}])
@ -164,7 +162,7 @@ class HueAllGroupsStateView(HomeAssistantView):
def get(self, request, username): def get(self, request, username):
"""Process a request to make the Brilliant Lightpad work.""" """Process a request to make the Brilliant Lightpad work."""
if not is_local(ip_address(request.remote)): if not is_local(ip_address(request.remote)):
return self.json_message("Only local IPs allowed", HTTP_UNAUTHORIZED) return self.json_message("Only local IPs allowed", HTTPStatus.UNAUTHORIZED)
return self.json({}) return self.json({})
@ -184,7 +182,7 @@ class HueGroupView(HomeAssistantView):
def put(self, request, username): def put(self, request, username):
"""Process a request to make the Logitech Pop working.""" """Process a request to make the Logitech Pop working."""
if not is_local(ip_address(request.remote)): if not is_local(ip_address(request.remote)):
return self.json_message("Only local IPs allowed", HTTP_UNAUTHORIZED) return self.json_message("Only local IPs allowed", HTTPStatus.UNAUTHORIZED)
return self.json( return self.json(
[ [
@ -214,7 +212,7 @@ class HueAllLightsStateView(HomeAssistantView):
def get(self, request, username): def get(self, request, username):
"""Process a request to get the list of available lights.""" """Process a request to get the list of available lights."""
if not is_local(ip_address(request.remote)): if not is_local(ip_address(request.remote)):
return self.json_message("Only local IPs allowed", HTTP_UNAUTHORIZED) return self.json_message("Only local IPs allowed", HTTPStatus.UNAUTHORIZED)
return self.json(create_list_of_entities(self.config, request)) return self.json(create_list_of_entities(self.config, request))
@ -234,7 +232,7 @@ class HueFullStateView(HomeAssistantView):
def get(self, request, username): def get(self, request, username):
"""Process a request to get the list of available lights.""" """Process a request to get the list of available lights."""
if not is_local(ip_address(request.remote)): if not is_local(ip_address(request.remote)):
return self.json_message("only local IPs allowed", HTTP_UNAUTHORIZED) return self.json_message("only local IPs allowed", HTTPStatus.UNAUTHORIZED)
if username != HUE_API_USERNAME: if username != HUE_API_USERNAME:
return self.json(UNAUTHORIZED_USER) return self.json(UNAUTHORIZED_USER)
@ -262,7 +260,7 @@ class HueConfigView(HomeAssistantView):
def get(self, request, username=""): def get(self, request, username=""):
"""Process a request to get the configuration.""" """Process a request to get the configuration."""
if not is_local(ip_address(request.remote)): if not is_local(ip_address(request.remote)):
return self.json_message("only local IPs allowed", HTTP_UNAUTHORIZED) return self.json_message("only local IPs allowed", HTTPStatus.UNAUTHORIZED)
json_response = create_config_model(self.config, request) json_response = create_config_model(self.config, request)
@ -284,7 +282,7 @@ class HueOneLightStateView(HomeAssistantView):
def get(self, request, username, entity_id): def get(self, request, username, entity_id):
"""Process a request to get the state of an individual light.""" """Process a request to get the state of an individual light."""
if not is_local(ip_address(request.remote)): if not is_local(ip_address(request.remote)):
return self.json_message("Only local IPs allowed", HTTP_UNAUTHORIZED) return self.json_message("Only local IPs allowed", HTTPStatus.UNAUTHORIZED)
hass = request.app["hass"] hass = request.app["hass"]
hass_entity_id = self.config.number_to_entity_id(entity_id) hass_entity_id = self.config.number_to_entity_id(entity_id)
@ -294,17 +292,17 @@ class HueOneLightStateView(HomeAssistantView):
"Unknown entity number: %s not found in emulated_hue_ids.json", "Unknown entity number: %s not found in emulated_hue_ids.json",
entity_id, entity_id,
) )
return self.json_message("Entity not found", HTTP_NOT_FOUND) return self.json_message("Entity not found", HTTPStatus.NOT_FOUND)
entity = hass.states.get(hass_entity_id) entity = hass.states.get(hass_entity_id)
if entity is None: if entity is None:
_LOGGER.error("Entity not found: %s", hass_entity_id) _LOGGER.error("Entity not found: %s", hass_entity_id)
return self.json_message("Entity not found", HTTP_NOT_FOUND) return self.json_message("Entity not found", HTTPStatus.NOT_FOUND)
if not self.config.is_entity_exposed(entity): if not self.config.is_entity_exposed(entity):
_LOGGER.error("Entity not exposed: %s", entity_id) _LOGGER.error("Entity not exposed: %s", entity_id)
return self.json_message("Entity not exposed", HTTP_UNAUTHORIZED) return self.json_message("Entity not exposed", HTTPStatus.UNAUTHORIZED)
json_response = entity_to_json(self.config, entity) json_response = entity_to_json(self.config, entity)
@ -325,7 +323,7 @@ class HueOneLightChangeView(HomeAssistantView):
async def put(self, request, username, entity_number): # noqa: C901 async def put(self, request, username, entity_number): # noqa: C901
"""Process a request to set the state of an individual light.""" """Process a request to set the state of an individual light."""
if not is_local(ip_address(request.remote)): if not is_local(ip_address(request.remote)):
return self.json_message("Only local IPs allowed", HTTP_UNAUTHORIZED) return self.json_message("Only local IPs allowed", HTTPStatus.UNAUTHORIZED)
config = self.config config = self.config
hass = request.app["hass"] hass = request.app["hass"]
@ -333,23 +331,23 @@ class HueOneLightChangeView(HomeAssistantView):
if entity_id is None: if entity_id is None:
_LOGGER.error("Unknown entity number: %s", entity_number) _LOGGER.error("Unknown entity number: %s", entity_number)
return self.json_message("Entity not found", HTTP_NOT_FOUND) return self.json_message("Entity not found", HTTPStatus.NOT_FOUND)
entity = hass.states.get(entity_id) entity = hass.states.get(entity_id)
if entity is None: if entity is None:
_LOGGER.error("Entity not found: %s", entity_id) _LOGGER.error("Entity not found: %s", entity_id)
return self.json_message("Entity not found", HTTP_NOT_FOUND) return self.json_message("Entity not found", HTTPStatus.NOT_FOUND)
if not config.is_entity_exposed(entity): if not config.is_entity_exposed(entity):
_LOGGER.error("Entity not exposed: %s", entity_id) _LOGGER.error("Entity not exposed: %s", entity_id)
return self.json_message("Entity not exposed", HTTP_UNAUTHORIZED) return self.json_message("Entity not exposed", HTTPStatus.UNAUTHORIZED)
try: try:
request_json = await request.json() request_json = await request.json()
except ValueError: except ValueError:
_LOGGER.error("Received invalid json") _LOGGER.error("Received invalid json")
return self.json_message("Invalid JSON", HTTP_BAD_REQUEST) return self.json_message("Invalid JSON", HTTPStatus.BAD_REQUEST)
# Get the entity's supported features # Get the entity's supported features
entity_features = entity.attributes.get(ATTR_SUPPORTED_FEATURES, 0) entity_features = entity.attributes.get(ATTR_SUPPORTED_FEATURES, 0)
@ -370,7 +368,7 @@ class HueOneLightChangeView(HomeAssistantView):
if HUE_API_STATE_ON in request_json: if HUE_API_STATE_ON in request_json:
if not isinstance(request_json[HUE_API_STATE_ON], bool): if not isinstance(request_json[HUE_API_STATE_ON], bool):
_LOGGER.error("Unable to parse data: %s", request_json) _LOGGER.error("Unable to parse data: %s", request_json)
return self.json_message("Bad request", HTTP_BAD_REQUEST) return self.json_message("Bad request", HTTPStatus.BAD_REQUEST)
parsed[STATE_ON] = request_json[HUE_API_STATE_ON] parsed[STATE_ON] = request_json[HUE_API_STATE_ON]
else: else:
parsed[STATE_ON] = entity.state != STATE_OFF parsed[STATE_ON] = entity.state != STATE_OFF
@ -387,7 +385,7 @@ class HueOneLightChangeView(HomeAssistantView):
parsed[attr] = int(request_json[key]) parsed[attr] = int(request_json[key])
except ValueError: except ValueError:
_LOGGER.error("Unable to parse data (2): %s", request_json) _LOGGER.error("Unable to parse data (2): %s", request_json)
return self.json_message("Bad request", HTTP_BAD_REQUEST) return self.json_message("Bad request", HTTPStatus.BAD_REQUEST)
if HUE_API_STATE_XY in request_json: if HUE_API_STATE_XY in request_json:
try: try:
parsed[STATE_XY] = ( parsed[STATE_XY] = (
@ -396,7 +394,7 @@ class HueOneLightChangeView(HomeAssistantView):
) )
except ValueError: except ValueError:
_LOGGER.error("Unable to parse data (2): %s", request_json) _LOGGER.error("Unable to parse data (2): %s", request_json)
return self.json_message("Bad request", HTTP_BAD_REQUEST) return self.json_message("Bad request", HTTPStatus.BAD_REQUEST)
if HUE_API_STATE_BRI in request_json: if HUE_API_STATE_BRI in request_json:
if entity.domain == light.DOMAIN: if entity.domain == light.DOMAIN:

View file

@ -1,16 +1,12 @@
"""Support for the Foursquare (Swarm) API.""" """Support for the Foursquare (Swarm) API."""
from http import HTTPStatus
import logging import logging
import requests import requests
import voluptuous as vol import voluptuous as vol
from homeassistant.components.http import HomeAssistantView from homeassistant.components.http import HomeAssistantView
from homeassistant.const import ( from homeassistant.const import CONF_ACCESS_TOKEN, HTTP_CREATED, HTTP_OK
CONF_ACCESS_TOKEN,
HTTP_BAD_REQUEST,
HTTP_CREATED,
HTTP_OK,
)
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -95,7 +91,7 @@ class FoursquarePushReceiver(HomeAssistantView):
try: try:
data = await request.json() data = await request.json()
except ValueError: except ValueError:
return self.json_message("Invalid JSON", HTTP_BAD_REQUEST) return self.json_message("Invalid JSON", HTTPStatus.BAD_REQUEST)
secret = data.pop("secret", None) secret = data.pop("secret", None)
@ -105,6 +101,6 @@ class FoursquarePushReceiver(HomeAssistantView):
_LOGGER.error( _LOGGER.error(
"Received Foursquare push with invalid push secret: %s", secret "Received Foursquare push with invalid push secret: %s", secret
) )
return self.json_message("Incorrect secret", HTTP_BAD_REQUEST) return self.json_message("Incorrect secret", HTTPStatus.BAD_REQUEST)
request.app["hass"].bus.async_fire(EVENT_PUSH, data) request.app["hass"].bus.async_fire(EVENT_PUSH, data)

View file

@ -3,6 +3,7 @@ from __future__ import annotations
from collections.abc import Iterable from collections.abc import Iterable
from datetime import datetime as dt, timedelta from datetime import datetime as dt, timedelta
from http import HTTPStatus
import logging import logging
import time import time
from typing import cast from typing import cast
@ -19,13 +20,7 @@ from homeassistant.components.recorder.statistics import (
statistics_during_period, statistics_during_period,
) )
from homeassistant.components.recorder.util import session_scope from homeassistant.components.recorder.util import session_scope
from homeassistant.const import ( from homeassistant.const import CONF_DOMAINS, CONF_ENTITIES, CONF_EXCLUDE, CONF_INCLUDE
CONF_DOMAINS,
CONF_ENTITIES,
CONF_EXCLUDE,
CONF_INCLUDE,
HTTP_BAD_REQUEST,
)
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.deprecation import deprecated_class, deprecated_function from homeassistant.helpers.deprecation import deprecated_class, deprecated_function
@ -203,7 +198,7 @@ class HistoryPeriodView(HomeAssistantView):
datetime_ = dt_util.parse_datetime(datetime) datetime_ = dt_util.parse_datetime(datetime)
if datetime_ is None: if datetime_ is None:
return self.json_message("Invalid datetime", HTTP_BAD_REQUEST) return self.json_message("Invalid datetime", HTTPStatus.BAD_REQUEST)
now = dt_util.utcnow() now = dt_util.utcnow()
@ -222,7 +217,7 @@ class HistoryPeriodView(HomeAssistantView):
if end_time: if end_time:
end_time = dt_util.as_utc(end_time) end_time = dt_util.as_utc(end_time)
else: else:
return self.json_message("Invalid end_time", HTTP_BAD_REQUEST) return self.json_message("Invalid end_time", HTTPStatus.BAD_REQUEST)
else: else:
end_time = start_time + one_day end_time = start_time + one_day
entity_ids_str = request.query.get("filter_entity_id") entity_ids_str = request.query.get("filter_entity_id")

View file

@ -2,6 +2,7 @@
from contextlib import suppress from contextlib import suppress
from datetime import datetime, timedelta from datetime import datetime, timedelta
from functools import partial from functools import partial
from http import HTTPStatus
import json import json
import logging import logging
import time import time
@ -26,13 +27,7 @@ from homeassistant.components.notify import (
PLATFORM_SCHEMA, PLATFORM_SCHEMA,
BaseNotificationService, BaseNotificationService,
) )
from homeassistant.const import ( from homeassistant.const import ATTR_NAME, URL_ROOT
ATTR_NAME,
HTTP_BAD_REQUEST,
HTTP_INTERNAL_SERVER_ERROR,
HTTP_UNAUTHORIZED,
URL_ROOT,
)
from homeassistant.exceptions import HomeAssistantError from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import config_validation as cv from homeassistant.helpers import config_validation as cv
from homeassistant.util import ensure_unique_string from homeassistant.util import ensure_unique_string
@ -224,11 +219,11 @@ class HTML5PushRegistrationView(HomeAssistantView):
try: try:
data = await request.json() data = await request.json()
except ValueError: except ValueError:
return self.json_message("Invalid JSON", HTTP_BAD_REQUEST) return self.json_message("Invalid JSON", HTTPStatus.BAD_REQUEST)
try: try:
data = REGISTER_SCHEMA(data) data = REGISTER_SCHEMA(data)
except vol.Invalid as ex: except vol.Invalid as ex:
return self.json_message(humanize_error(data, ex), HTTP_BAD_REQUEST) return self.json_message(humanize_error(data, ex), HTTPStatus.BAD_REQUEST)
devname = data.get(ATTR_NAME) devname = data.get(ATTR_NAME)
data.pop(ATTR_NAME, None) data.pop(ATTR_NAME, None)
@ -252,7 +247,7 @@ class HTML5PushRegistrationView(HomeAssistantView):
self.registrations.pop(name) self.registrations.pop(name)
return self.json_message( return self.json_message(
"Error saving registration.", HTTP_INTERNAL_SERVER_ERROR "Error saving registration.", HTTPStatus.INTERNAL_SERVER_ERROR
) )
def find_registration_name(self, data, suggested=None): def find_registration_name(self, data, suggested=None):
@ -269,7 +264,7 @@ class HTML5PushRegistrationView(HomeAssistantView):
try: try:
data = await request.json() data = await request.json()
except ValueError: except ValueError:
return self.json_message("Invalid JSON", HTTP_BAD_REQUEST) return self.json_message("Invalid JSON", HTTPStatus.BAD_REQUEST)
subscription = data.get(ATTR_SUBSCRIPTION) subscription = data.get(ATTR_SUBSCRIPTION)
@ -295,7 +290,7 @@ class HTML5PushRegistrationView(HomeAssistantView):
except HomeAssistantError: except HomeAssistantError:
self.registrations[found] = reg self.registrations[found] = reg
return self.json_message( return self.json_message(
"Error saving registration.", HTTP_INTERNAL_SERVER_ERROR "Error saving registration.", HTTPStatus.INTERNAL_SERVER_ERROR
) )
return self.json_message("Push notification subscriber unregistered.") return self.json_message("Push notification subscriber unregistered.")
@ -330,7 +325,7 @@ class HTML5PushCallbackView(HomeAssistantView):
return jwt.decode(token, key, algorithms=["ES256", "HS256"]) return jwt.decode(token, key, algorithms=["ES256", "HS256"])
return self.json_message( return self.json_message(
"No target found in JWT", status_code=HTTP_UNAUTHORIZED "No target found in JWT", status_code=HTTPStatus.UNAUTHORIZED
) )
# The following is based on code from Auth0 # The following is based on code from Auth0
@ -341,7 +336,7 @@ class HTML5PushCallbackView(HomeAssistantView):
auth = request.headers.get(AUTHORIZATION) auth = request.headers.get(AUTHORIZATION)
if not auth: if not auth:
return self.json_message( return self.json_message(
"Authorization header is expected", status_code=HTTP_UNAUTHORIZED "Authorization header is expected", status_code=HTTPStatus.UNAUTHORIZED
) )
parts = auth.split() parts = auth.split()
@ -349,19 +344,21 @@ class HTML5PushCallbackView(HomeAssistantView):
if parts[0].lower() != "bearer": if parts[0].lower() != "bearer":
return self.json_message( return self.json_message(
"Authorization header must start with Bearer", "Authorization header must start with Bearer",
status_code=HTTP_UNAUTHORIZED, status_code=HTTPStatus.UNAUTHORIZED,
) )
if len(parts) != 2: if len(parts) != 2:
return self.json_message( return self.json_message(
"Authorization header must be Bearer token", "Authorization header must be Bearer token",
status_code=HTTP_UNAUTHORIZED, status_code=HTTPStatus.UNAUTHORIZED,
) )
token = parts[1] token = parts[1]
try: try:
payload = self.decode_jwt(token) payload = self.decode_jwt(token)
except jwt.exceptions.InvalidTokenError: except jwt.exceptions.InvalidTokenError:
return self.json_message("token is invalid", status_code=HTTP_UNAUTHORIZED) return self.json_message(
"token is invalid", status_code=HTTPStatus.UNAUTHORIZED
)
return payload return payload
async def post(self, request): async def post(self, request):
@ -373,7 +370,7 @@ class HTML5PushCallbackView(HomeAssistantView):
try: try:
data = await request.json() data = await request.json()
except ValueError: except ValueError:
return self.json_message("Invalid JSON", HTTP_BAD_REQUEST) return self.json_message("Invalid JSON", HTTPStatus.BAD_REQUEST)
event_payload = { event_payload = {
ATTR_TAG: data.get(ATTR_TAG), ATTR_TAG: data.get(ATTR_TAG),

View file

@ -3,14 +3,13 @@ from __future__ import annotations
from collections.abc import Awaitable from collections.abc import Awaitable
from functools import wraps from functools import wraps
from http import HTTPStatus
import logging import logging
from typing import Any, Callable from typing import Any, Callable
from aiohttp import web from aiohttp import web
import voluptuous as vol import voluptuous as vol
from homeassistant.const import HTTP_BAD_REQUEST
from .view import HomeAssistantView from .view import HomeAssistantView
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -49,7 +48,7 @@ class RequestDataValidator:
except ValueError: except ValueError:
if not self._allow_empty or (await request.content.read()) != b"": if not self._allow_empty or (await request.content.read()) != b"":
_LOGGER.error("Invalid JSON received") _LOGGER.error("Invalid JSON received")
return view.json_message("Invalid JSON.", HTTP_BAD_REQUEST) return view.json_message("Invalid JSON.", HTTPStatus.BAD_REQUEST)
data = {} data = {}
try: try:
@ -57,7 +56,7 @@ class RequestDataValidator:
except vol.Invalid as err: except vol.Invalid as err:
_LOGGER.error("Data does not match schema: %s", err) _LOGGER.error("Data does not match schema: %s", err)
return view.json_message( return view.json_message(
f"Message format incorrect: {err}", HTTP_BAD_REQUEST f"Message format incorrect: {err}", HTTPStatus.BAD_REQUEST
) )
result = await method(view, request, *args, **kwargs) result = await method(view, request, *args, **kwargs)

View file

@ -3,6 +3,7 @@ from __future__ import annotations
import asyncio import asyncio
from collections.abc import Awaitable, Callable from collections.abc import Awaitable, Callable
from http import HTTPStatus
import json import json
import logging import logging
from typing import Any from typing import Any
@ -48,7 +49,7 @@ class HomeAssistantView:
@staticmethod @staticmethod
def json( def json(
result: Any, result: Any,
status_code: int = HTTP_OK, status_code: HTTPStatus | int = HTTPStatus.OK,
headers: LooseHeaders | None = None, headers: LooseHeaders | None = None,
) -> web.Response: ) -> web.Response:
"""Return a JSON response.""" """Return a JSON response."""
@ -60,7 +61,7 @@ class HomeAssistantView:
response = web.Response( response = web.Response(
body=msg, body=msg,
content_type=CONTENT_TYPE_JSON, content_type=CONTENT_TYPE_JSON,
status=status_code, status=int(status_code),
headers=headers, headers=headers,
) )
response.enable_compression() response.enable_compression()
@ -69,7 +70,7 @@ class HomeAssistantView:
def json_message( def json_message(
self, self,
message: str, message: str,
status_code: int = HTTP_OK, status_code: HTTPStatus | int = HTTPStatus.OK,
message_code: str | None = None, message_code: str | None = None,
headers: LooseHeaders | None = None, headers: LooseHeaders | None = None,
) -> web.Response: ) -> web.Response:

View file

@ -1,11 +1,11 @@
"""Native Home Assistant iOS app component.""" """Native Home Assistant iOS app component."""
import datetime import datetime
from http import HTTPStatus
import voluptuous as vol import voluptuous as vol
from homeassistant import config_entries from homeassistant import config_entries
from homeassistant.components.http import HomeAssistantView from homeassistant.components.http import HomeAssistantView
from homeassistant.const import HTTP_BAD_REQUEST, HTTP_INTERNAL_SERVER_ERROR
from homeassistant.core import callback from homeassistant.core import callback
from homeassistant.exceptions import HomeAssistantError from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import config_validation as cv, discovery from homeassistant.helpers import config_validation as cv, discovery
@ -333,7 +333,7 @@ class iOSIdentifyDeviceView(HomeAssistantView):
try: try:
data = await request.json() data = await request.json()
except ValueError: except ValueError:
return self.json_message("Invalid JSON", HTTP_BAD_REQUEST) return self.json_message("Invalid JSON", HTTPStatus.BAD_REQUEST)
hass = request.app["hass"] hass = request.app["hass"]
@ -348,6 +348,8 @@ class iOSIdentifyDeviceView(HomeAssistantView):
try: try:
save_json(self._config_path, hass.data[DOMAIN]) save_json(self._config_path, hass.data[DOMAIN])
except HomeAssistantError: except HomeAssistantError:
return self.json_message("Error saving device.", HTTP_INTERNAL_SERVER_ERROR) return self.json_message(
"Error saving device.", HTTPStatus.INTERNAL_SERVER_ERROR
)
return self.json({"status": "registered"}) return self.json({"status": "registered"})

View file

@ -1,6 +1,7 @@
"""Support for Konnected devices.""" """Support for Konnected devices."""
import copy import copy
import hmac import hmac
from http import HTTPStatus
import json import json
import logging import logging
@ -28,9 +29,6 @@ from homeassistant.const import (
CONF_SWITCHES, CONF_SWITCHES,
CONF_TYPE, CONF_TYPE,
CONF_ZONE, CONF_ZONE,
HTTP_BAD_REQUEST,
HTTP_NOT_FOUND,
HTTP_UNAUTHORIZED,
STATE_OFF, STATE_OFF,
STATE_ON, STATE_ON,
) )
@ -325,7 +323,9 @@ class KonnectedView(HomeAssistantView):
(True for token in tokens if hmac.compare_digest(f"Bearer {token}", auth)), (True for token in tokens if hmac.compare_digest(f"Bearer {token}", auth)),
False, False,
): ):
return self.json_message("unauthorized", status_code=HTTP_UNAUTHORIZED) return self.json_message(
"unauthorized", status_code=HTTPStatus.UNAUTHORIZED
)
try: # Konnected 2.2.0 and above supports JSON payloads try: # Konnected 2.2.0 and above supports JSON payloads
payload = await request.json() payload = await request.json()
@ -339,7 +339,7 @@ class KonnectedView(HomeAssistantView):
device = data[CONF_DEVICES].get(device_id) device = data[CONF_DEVICES].get(device_id)
if device is None: if device is None:
return self.json_message( return self.json_message(
"unregistered device", status_code=HTTP_BAD_REQUEST "unregistered device", status_code=HTTPStatus.BAD_REQUEST
) )
panel = device.get("panel") panel = device.get("panel")
@ -364,7 +364,7 @@ class KonnectedView(HomeAssistantView):
if zone_data is None: if zone_data is None:
return self.json_message( return self.json_message(
"unregistered sensor/actuator", status_code=HTTP_BAD_REQUEST "unregistered sensor/actuator", status_code=HTTPStatus.BAD_REQUEST
) )
zone_data["device_id"] = device_id zone_data["device_id"] = device_id
@ -385,7 +385,7 @@ class KonnectedView(HomeAssistantView):
device = data[CONF_DEVICES].get(device_id) device = data[CONF_DEVICES].get(device_id)
if not device: if not device:
return self.json_message( return self.json_message(
f"Device {device_id} not configured", status_code=HTTP_NOT_FOUND f"Device {device_id} not configured", status_code=HTTPStatus.NOT_FOUND
) )
panel = device.get("panel") panel = device.get("panel")
@ -417,7 +417,7 @@ class KonnectedView(HomeAssistantView):
) )
return self.json_message( return self.json_message(
f"Switch on zone or pin {target} not configured", f"Switch on zone or pin {target} not configured",
status_code=HTTP_NOT_FOUND, status_code=HTTPStatus.NOT_FOUND,
) )
resp = {} resp = {}

View file

@ -1,6 +1,7 @@
"""Event parser and human readable log generator.""" """Event parser and human readable log generator."""
from contextlib import suppress from contextlib import suppress
from datetime import timedelta from datetime import timedelta
from http import HTTPStatus
from itertools import groupby from itertools import groupby
import json import json
import re import re
@ -32,7 +33,6 @@ from homeassistant.const import (
EVENT_HOMEASSISTANT_STOP, EVENT_HOMEASSISTANT_STOP,
EVENT_LOGBOOK_ENTRY, EVENT_LOGBOOK_ENTRY,
EVENT_STATE_CHANGED, EVENT_STATE_CHANGED,
HTTP_BAD_REQUEST,
) )
from homeassistant.core import DOMAIN as HA_DOMAIN, callback, split_entity_id from homeassistant.core import DOMAIN as HA_DOMAIN, callback, split_entity_id
from homeassistant.exceptions import InvalidEntityFormatError from homeassistant.exceptions import InvalidEntityFormatError
@ -198,7 +198,7 @@ class LogbookView(HomeAssistantView):
datetime = dt_util.parse_datetime(datetime) datetime = dt_util.parse_datetime(datetime)
if datetime is None: if datetime is None:
return self.json_message("Invalid datetime", HTTP_BAD_REQUEST) return self.json_message("Invalid datetime", HTTPStatus.BAD_REQUEST)
else: else:
datetime = dt_util.start_of_local_day() datetime = dt_util.start_of_local_day()
@ -226,7 +226,7 @@ class LogbookView(HomeAssistantView):
start_day = datetime start_day = datetime
end_day = dt_util.parse_datetime(end_time) end_day = dt_util.parse_datetime(end_time)
if end_day is None: if end_day is None:
return self.json_message("Invalid end_time", HTTP_BAD_REQUEST) return self.json_message("Invalid end_time", HTTPStatus.BAD_REQUEST)
hass = request.app["hass"] hass = request.app["hass"]
@ -235,7 +235,7 @@ class LogbookView(HomeAssistantView):
if entity_ids and context_id: if entity_ids and context_id:
return self.json_message( return self.json_message(
"Can't combine entity with context_id", HTTP_BAD_REQUEST "Can't combine entity with context_id", HTTPStatus.BAD_REQUEST
) )
def json_events(): def json_events():

View file

@ -1,6 +1,7 @@
"""Config flow to configure Logi Circle component.""" """Config flow to configure Logi Circle component."""
import asyncio import asyncio
from collections import OrderedDict from collections import OrderedDict
from http import HTTPStatus
import async_timeout import async_timeout
from logi_circle import LogiCircle from logi_circle import LogiCircle
@ -14,7 +15,6 @@ from homeassistant.const import (
CONF_CLIENT_ID, CONF_CLIENT_ID,
CONF_CLIENT_SECRET, CONF_CLIENT_SECRET,
CONF_SENSORS, CONF_SENSORS,
HTTP_BAD_REQUEST,
) )
from homeassistant.core import callback from homeassistant.core import callback
@ -201,5 +201,6 @@ class LogiCircleAuthCallbackView(HomeAssistantView):
) )
return self.json_message("Authorisation code saved") return self.json_message("Authorisation code saved")
return self.json_message( return self.json_message(
"Authorisation code missing from query string", status_code=HTTP_BAD_REQUEST "Authorisation code missing from query string",
status_code=HTTPStatus.BAD_REQUEST,
) )

View file

@ -1,4 +1,5 @@
"""Support for the Meraki CMX location service.""" """Support for the Meraki CMX location service."""
from http import HTTPStatus
import json import json
import logging import logging
@ -9,7 +10,6 @@ from homeassistant.components.device_tracker import (
SOURCE_TYPE_ROUTER, SOURCE_TYPE_ROUTER,
) )
from homeassistant.components.http import HomeAssistantView from homeassistant.components.http import HomeAssistantView
from homeassistant.const import HTTP_BAD_REQUEST, HTTP_UNPROCESSABLE_ENTITY
from homeassistant.core import callback from homeassistant.core import callback
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
@ -56,21 +56,23 @@ class MerakiView(HomeAssistantView):
try: try:
data = await request.json() data = await request.json()
except ValueError: except ValueError:
return self.json_message("Invalid JSON", HTTP_BAD_REQUEST) return self.json_message("Invalid JSON", HTTPStatus.BAD_REQUEST)
_LOGGER.debug("Meraki Data from Post: %s", json.dumps(data)) _LOGGER.debug("Meraki Data from Post: %s", json.dumps(data))
if not data.get("secret", False): if not data.get("secret", False):
_LOGGER.error("The secret is invalid") _LOGGER.error("The secret is invalid")
return self.json_message("No secret", HTTP_UNPROCESSABLE_ENTITY) return self.json_message("No secret", HTTPStatus.UNPROCESSABLE_ENTITY)
if data["secret"] != self.secret: if data["secret"] != self.secret:
_LOGGER.error("Invalid Secret received from Meraki") _LOGGER.error("Invalid Secret received from Meraki")
return self.json_message("Invalid secret", HTTP_UNPROCESSABLE_ENTITY) return self.json_message("Invalid secret", HTTPStatus.UNPROCESSABLE_ENTITY)
if data["version"] != VERSION: if data["version"] != VERSION:
_LOGGER.error("Invalid API version: %s", data["version"]) _LOGGER.error("Invalid API version: %s", data["version"])
return self.json_message("Invalid version", HTTP_UNPROCESSABLE_ENTITY) return self.json_message("Invalid version", HTTPStatus.UNPROCESSABLE_ENTITY)
_LOGGER.debug("Valid Secret") _LOGGER.debug("Valid Secret")
if data["type"] not in ("DevicesSeen", "BluetoothDevicesSeen"): if data["type"] not in ("DevicesSeen", "BluetoothDevicesSeen"):
_LOGGER.error("Unknown Device %s", data["type"]) _LOGGER.error("Unknown Device %s", data["type"])
return self.json_message("Invalid device type", HTTP_UNPROCESSABLE_ENTITY) return self.json_message(
"Invalid device type", HTTPStatus.UNPROCESSABLE_ENTITY
)
_LOGGER.debug("Processing %s", data["type"]) _LOGGER.debug("Processing %s", data["type"])
if not data["data"]["observations"]: if not data["data"]["observations"]:
_LOGGER.debug("No observations found") _LOGGER.debug("No observations found")

View file

@ -2,6 +2,7 @@
from __future__ import annotations from __future__ import annotations
from contextlib import suppress from contextlib import suppress
from http import HTTPStatus
import secrets import secrets
from aiohttp.web import Request, Response from aiohttp.web import Request, Response
@ -11,7 +12,7 @@ import voluptuous as vol
from homeassistant.components.http import HomeAssistantView from homeassistant.components.http import HomeAssistantView
from homeassistant.components.http.data_validator import RequestDataValidator from homeassistant.components.http.data_validator import RequestDataValidator
from homeassistant.const import ATTR_DEVICE_ID, CONF_WEBHOOK_ID, HTTP_CREATED from homeassistant.const import ATTR_DEVICE_ID, CONF_WEBHOOK_ID
from homeassistant.helpers import config_validation as cv from homeassistant.helpers import config_validation as cv
from homeassistant.util import slugify from homeassistant.util import slugify
@ -109,5 +110,5 @@ class RegistrationsView(HomeAssistantView):
CONF_SECRET: data.get(CONF_SECRET), CONF_SECRET: data.get(CONF_SECRET),
CONF_WEBHOOK_ID: data[CONF_WEBHOOK_ID], CONF_WEBHOOK_ID: data[CONF_WEBHOOK_ID],
}, },
status_code=HTTP_CREATED, status_code=HTTPStatus.CREATED,
) )

View file

@ -1,5 +1,6 @@
"""Onboarding views.""" """Onboarding views."""
import asyncio import asyncio
from http import HTTPStatus
from aiohttp.web_exceptions import HTTPUnauthorized from aiohttp.web_exceptions import HTTPUnauthorized
import voluptuous as vol import voluptuous as vol
@ -9,7 +10,6 @@ from homeassistant.components.auth import indieauth
from homeassistant.components.http.const import KEY_HASS_REFRESH_TOKEN_ID from homeassistant.components.http.const import KEY_HASS_REFRESH_TOKEN_ID
from homeassistant.components.http.data_validator import RequestDataValidator from homeassistant.components.http.data_validator import RequestDataValidator
from homeassistant.components.http.view import HomeAssistantView from homeassistant.components.http.view import HomeAssistantView
from homeassistant.const import HTTP_BAD_REQUEST, HTTP_FORBIDDEN
from homeassistant.core import callback from homeassistant.core import callback
from homeassistant.helpers.system_info import async_get_system_info from homeassistant.helpers.system_info import async_get_system_info
@ -124,7 +124,7 @@ class UserOnboardingView(_BaseOnboardingView):
async with self._lock: async with self._lock:
if self._async_is_done(): if self._async_is_done():
return self.json_message("User step already done", HTTP_FORBIDDEN) return self.json_message("User step already done", HTTPStatus.FORBIDDEN)
provider = _async_get_hass_provider(hass) provider = _async_get_hass_provider(hass)
await provider.async_initialize() await provider.async_initialize()
@ -179,7 +179,7 @@ class CoreConfigOnboardingView(_BaseOnboardingView):
async with self._lock: async with self._lock:
if self._async_is_done(): if self._async_is_done():
return self.json_message( return self.json_message(
"Core config step already done", HTTP_FORBIDDEN "Core config step already done", HTTPStatus.FORBIDDEN
) )
await self._async_mark_done(hass) await self._async_mark_done(hass)
@ -217,7 +217,7 @@ class IntegrationOnboardingView(_BaseOnboardingView):
async with self._lock: async with self._lock:
if self._async_is_done(): if self._async_is_done():
return self.json_message( return self.json_message(
"Integration step already done", HTTP_FORBIDDEN "Integration step already done", HTTPStatus.FORBIDDEN
) )
await self._async_mark_done(hass) await self._async_mark_done(hass)
@ -227,13 +227,13 @@ class IntegrationOnboardingView(_BaseOnboardingView):
request.app["hass"], data["client_id"], data["redirect_uri"] request.app["hass"], data["client_id"], data["redirect_uri"]
): ):
return self.json_message( return self.json_message(
"invalid client id or redirect uri", HTTP_BAD_REQUEST "invalid client id or redirect uri", HTTPStatus.BAD_REQUEST
) )
refresh_token = await hass.auth.async_get_refresh_token(refresh_token_id) refresh_token = await hass.auth.async_get_refresh_token(refresh_token_id)
if refresh_token is None or refresh_token.credential is None: if refresh_token is None or refresh_token.credential is None:
return self.json_message( return self.json_message(
"Credentials for user not available", HTTP_FORBIDDEN "Credentials for user not available", HTTPStatus.FORBIDDEN
) )
# Return authorization code so we can redirect user and log them in # Return authorization code so we can redirect user and log them in
@ -257,7 +257,7 @@ class AnalyticsOnboardingView(_BaseOnboardingView):
async with self._lock: async with self._lock:
if self._async_is_done(): if self._async_is_done():
return self.json_message( return self.json_message(
"Analytics config step already done", HTTP_FORBIDDEN "Analytics config step already done", HTTPStatus.FORBIDDEN
) )
await self._async_mark_done(hass) await self._async_mark_done(hass)

View file

@ -1,4 +1,5 @@
"""Support to manage a shopping list.""" """Support to manage a shopping list."""
from http import HTTPStatus
import logging import logging
import uuid import uuid
@ -7,7 +8,7 @@ import voluptuous as vol
from homeassistant import config_entries from homeassistant import config_entries
from homeassistant.components import http, websocket_api from homeassistant.components import http, websocket_api
from homeassistant.components.http.data_validator import RequestDataValidator from homeassistant.components.http.data_validator import RequestDataValidator
from homeassistant.const import ATTR_NAME, HTTP_BAD_REQUEST, HTTP_NOT_FOUND from homeassistant.const import ATTR_NAME
from homeassistant.core import callback from homeassistant.core import callback
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
from homeassistant.util.json import load_json, save_json from homeassistant.util.json import load_json, save_json
@ -293,9 +294,9 @@ class UpdateShoppingListItemView(http.HomeAssistantView):
request.app["hass"].bus.async_fire(EVENT) request.app["hass"].bus.async_fire(EVENT)
return self.json(item) return self.json(item)
except KeyError: except KeyError:
return self.json_message("Item not found", HTTP_NOT_FOUND) return self.json_message("Item not found", HTTPStatus.NOT_FOUND)
except vol.Invalid: except vol.Invalid:
return self.json_message("Item not found", HTTP_BAD_REQUEST) return self.json_message("Item not found", HTTPStatus.BAD_REQUEST)
class CreateShoppingListItemView(http.HomeAssistantView): class CreateShoppingListItemView(http.HomeAssistantView):

View file

@ -1,16 +1,13 @@
"""Support for Telegram bots using webhooks.""" """Support for Telegram bots using webhooks."""
import datetime as dt import datetime as dt
from http import HTTPStatus
from ipaddress import ip_address from ipaddress import ip_address
import logging import logging
from telegram.error import TimedOut from telegram.error import TimedOut
from homeassistant.components.http import HomeAssistantView from homeassistant.components.http import HomeAssistantView
from homeassistant.const import ( from homeassistant.const import EVENT_HOMEASSISTANT_STOP
EVENT_HOMEASSISTANT_STOP,
HTTP_BAD_REQUEST,
HTTP_UNAUTHORIZED,
)
from homeassistant.helpers.network import get_url from homeassistant.helpers.network import get_url
from . import ( from . import (
@ -98,13 +95,13 @@ class BotPushReceiver(HomeAssistantView, BaseTelegramBotEntity):
real_ip = ip_address(request.remote) real_ip = ip_address(request.remote)
if not any(real_ip in net for net in self.trusted_networks): if not any(real_ip in net for net in self.trusted_networks):
_LOGGER.warning("Access denied from %s", real_ip) _LOGGER.warning("Access denied from %s", real_ip)
return self.json_message("Access denied", HTTP_UNAUTHORIZED) return self.json_message("Access denied", HTTPStatus.UNAUTHORIZED)
try: try:
data = await request.json() data = await request.json()
except ValueError: except ValueError:
return self.json_message("Invalid JSON", HTTP_BAD_REQUEST) return self.json_message("Invalid JSON", HTTPStatus.BAD_REQUEST)
if not self.process_message(data): if not self.process_message(data):
return self.json_message("Invalid message", HTTP_BAD_REQUEST) return self.json_message("Invalid message", HTTPStatus.BAD_REQUEST)
return None return None

View file

@ -4,6 +4,7 @@ from __future__ import annotations
import asyncio import asyncio
import functools as ft import functools as ft
import hashlib import hashlib
from http import HTTPStatus
import io import io
import logging import logging
import mimetypes import mimetypes
@ -29,7 +30,6 @@ from homeassistant.const import (
CONF_DESCRIPTION, CONF_DESCRIPTION,
CONF_NAME, CONF_NAME,
CONF_PLATFORM, CONF_PLATFORM,
HTTP_BAD_REQUEST,
HTTP_NOT_FOUND, HTTP_NOT_FOUND,
PLATFORM_FORMAT, PLATFORM_FORMAT,
) )
@ -598,10 +598,10 @@ class TextToSpeechUrlView(HomeAssistantView):
try: try:
data = await request.json() data = await request.json()
except ValueError: except ValueError:
return self.json_message("Invalid JSON specified", HTTP_BAD_REQUEST) return self.json_message("Invalid JSON specified", HTTPStatus.BAD_REQUEST)
if not data.get(ATTR_PLATFORM) and data.get(ATTR_MESSAGE): if not data.get(ATTR_PLATFORM) and data.get(ATTR_MESSAGE):
return self.json_message( return self.json_message(
"Must specify platform and message", HTTP_BAD_REQUEST "Must specify platform and message", HTTPStatus.BAD_REQUEST
) )
p_type = data[ATTR_PLATFORM] p_type = data[ATTR_PLATFORM]
@ -616,7 +616,7 @@ class TextToSpeechUrlView(HomeAssistantView):
) )
except HomeAssistantError as err: except HomeAssistantError as err:
_LOGGER.error("Error on init tts: %s", err) _LOGGER.error("Error on init tts: %s", err)
return self.json({"error": err}, HTTP_BAD_REQUEST) return self.json({"error": err}, HTTPStatus.BAD_REQUEST)
base = self.tts.base_url or get_url(self.tts.hass) base = self.tts.base_url or get_url(self.tts.hass)
url = base + path url = base + path

View file

@ -507,7 +507,7 @@ class ConfigEntryWithingsApi(AbstractWithingsApi):
def json_message_response(message: str, message_code: int) -> Response: def json_message_response(message: str, message_code: int) -> Response:
"""Produce common json output.""" """Produce common json output."""
return HomeAssistantView.json({"message": message, "code": message_code}, 200) return HomeAssistantView.json({"message": message, "code": message_code})
class WebhookAvailability(IntEnum): class WebhookAvailability(IntEnum):

View file

@ -1,6 +1,7 @@
"""Helpers for the data entry flow.""" """Helpers for the data entry flow."""
from __future__ import annotations from __future__ import annotations
from http import HTTPStatus
from typing import Any from typing import Any
from aiohttp import web from aiohttp import web
@ -9,7 +10,6 @@ import voluptuous as vol
from homeassistant import config_entries, data_entry_flow from homeassistant import config_entries, data_entry_flow
from homeassistant.components.http import HomeAssistantView from homeassistant.components.http import HomeAssistantView
from homeassistant.components.http.data_validator import RequestDataValidator from homeassistant.components.http.data_validator import RequestDataValidator
from homeassistant.const import HTTP_BAD_REQUEST, HTTP_NOT_FOUND
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
@ -77,9 +77,11 @@ class FlowManagerIndexView(_BaseFlowManagerView):
}, },
) )
except data_entry_flow.UnknownHandler: except data_entry_flow.UnknownHandler:
return self.json_message("Invalid handler specified", HTTP_NOT_FOUND) return self.json_message("Invalid handler specified", HTTPStatus.NOT_FOUND)
except data_entry_flow.UnknownStep: except data_entry_flow.UnknownStep:
return self.json_message("Handler does not support user", HTTP_BAD_REQUEST) return self.json_message(
"Handler does not support user", HTTPStatus.BAD_REQUEST
)
result = self._prepare_result_json(result) result = self._prepare_result_json(result)
@ -94,7 +96,7 @@ class FlowManagerResourceView(_BaseFlowManagerView):
try: try:
result = await self._flow_mgr.async_configure(flow_id) result = await self._flow_mgr.async_configure(flow_id)
except data_entry_flow.UnknownFlow: except data_entry_flow.UnknownFlow:
return self.json_message("Invalid flow specified", HTTP_NOT_FOUND) return self.json_message("Invalid flow specified", HTTPStatus.NOT_FOUND)
result = self._prepare_result_json(result) result = self._prepare_result_json(result)
@ -108,9 +110,9 @@ class FlowManagerResourceView(_BaseFlowManagerView):
try: try:
result = await self._flow_mgr.async_configure(flow_id, data) result = await self._flow_mgr.async_configure(flow_id, data)
except data_entry_flow.UnknownFlow: except data_entry_flow.UnknownFlow:
return self.json_message("Invalid flow specified", HTTP_NOT_FOUND) return self.json_message("Invalid flow specified", HTTPStatus.NOT_FOUND)
except vol.Invalid: except vol.Invalid:
return self.json_message("User input malformed", HTTP_BAD_REQUEST) return self.json_message("User input malformed", HTTPStatus.BAD_REQUEST)
result = self._prepare_result_json(result) result = self._prepare_result_json(result)
@ -121,6 +123,6 @@ class FlowManagerResourceView(_BaseFlowManagerView):
try: try:
self._flow_mgr.async_abort(flow_id) self._flow_mgr.async_abort(flow_id)
except data_entry_flow.UnknownFlow: except data_entry_flow.UnknownFlow:
return self.json_message("Invalid flow specified", HTTP_NOT_FOUND) return self.json_message("Invalid flow specified", HTTPStatus.NOT_FOUND)
return self.json_message("Flow aborted") return self.json_message("Flow aborted")

View file

@ -455,7 +455,7 @@ async def test_set_protection_value(hass, client):
assert resp.status == 200 assert resp.status == 200
result = await resp.json() result = await resp.json()
assert node.set_protection.called assert node.set_protection.called
assert result == {"message": "Protection setting succsessfully set"} assert result == {"message": "Protection setting successfully set"}
async def test_set_protection_value_failed(hass, client): async def test_set_protection_value_failed(hass, client):