"""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)