core/homeassistant/components/google_assistant/auth.py

87 lines
2.8 KiB
Python

"""Google Assistant OAuth View."""
import asyncio
import logging
# Typing imports
# pylint: disable=using-constant-test,unused-import,ungrouped-imports
# if False:
from homeassistant.core import HomeAssistant # NOQA
from aiohttp.web import Request, Response # NOQA
from typing import Dict, Any # NOQA
from homeassistant.components.http import HomeAssistantView
from homeassistant.const import (
HTTP_BAD_REQUEST,
HTTP_UNAUTHORIZED,
HTTP_MOVED_PERMANENTLY,
)
from .const import (
GOOGLE_ASSISTANT_API_ENDPOINT,
CONF_PROJECT_ID, CONF_CLIENT_ID, CONF_ACCESS_TOKEN
)
BASE_OAUTH_URL = 'https://oauth-redirect.googleusercontent.com'
REDIRECT_TEMPLATE_URL = \
'{}/r/{}#access_token={}&token_type=bearer&state={}'
_LOGGER = logging.getLogger(__name__)
class GoogleAssistantAuthView(HomeAssistantView):
"""Handle Google Actions auth requests."""
url = GOOGLE_ASSISTANT_API_ENDPOINT + '/auth'
name = 'api:google_assistant:auth'
requires_auth = False
def __init__(self, hass: HomeAssistant, cfg: Dict[str, Any]) -> None:
"""Initialize instance of the view."""
super().__init__()
self.project_id = cfg.get(CONF_PROJECT_ID)
self.client_id = cfg.get(CONF_CLIENT_ID)
self.access_token = cfg.get(CONF_ACCESS_TOKEN)
@asyncio.coroutine
def get(self, request: Request) -> Response:
"""Handle oauth token request."""
query = request.query
redirect_uri = query.get('redirect_uri')
if not redirect_uri:
msg = 'missing redirect_uri field'
_LOGGER.warning(msg)
return self.json_message(msg, status_code=HTTP_BAD_REQUEST)
if self.project_id not in redirect_uri:
msg = 'missing project_id in redirect_uri'
_LOGGER.warning(msg)
return self.json_message(msg, status_code=HTTP_BAD_REQUEST)
state = query.get('state')
if not state:
msg = 'oauth request missing state'
_LOGGER.warning(msg)
return self.json_message(msg, status_code=HTTP_BAD_REQUEST)
client_id = query.get('client_id')
if self.client_id != client_id:
msg = 'invalid client id'
_LOGGER.warning(msg)
return self.json_message(msg, status_code=HTTP_UNAUTHORIZED)
generated_url = redirect_url(self.project_id, self.access_token, state)
_LOGGER.info('user login in from Google Assistant')
return self.json_message(
'redirect success',
status_code=HTTP_MOVED_PERMANENTLY,
headers={'Location': generated_url})
def redirect_url(project_id: str, access_token: str, state: str) -> str:
"""Generate the redirect format for the oauth request."""
return REDIRECT_TEMPLATE_URL.format(BASE_OAUTH_URL, project_id,
access_token, state)