Google Actions for Assistant (#9632)
* http: Add headers key to json[_message] * Add google_assistant component This component provides API endpoints for the Actions on Google Smart Home API to interact with Google Assistant. * google_assistant: Re-add fan support * google_assistant: Fix Scene handling - The way I originally wrote the MAPPING_COMPONENT and the way it's actual used changed so the comment was updated to match that. - Use const's in more places - Handle the ActivateScene command correctly * google_assistant: Fix flakey compare test Was failing on 3.4.2 and 3.5, this is more correct anyway. * google_assistant: Use volume attr for media_player
This commit is contained in:
parent
1d68777981
commit
9d20a53d63
9 changed files with 996 additions and 4 deletions
86
homeassistant/components/google_assistant/auth.py
Normal file
86
homeassistant/components/google_assistant/auth.py
Normal file
|
@ -0,0 +1,86 @@
|
|||
"""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)
|
Loading…
Add table
Add a link
Reference in a new issue