From 0b8bc56642d75a039c28ae5db8cc4c4ab33aaf61 Mon Sep 17 00:00:00 2001 From: Pascal Vizeli Date: Sat, 22 Jul 2017 16:35:06 +0200 Subject: [PATCH] add google auth (#147) * add google auth * fix parse * Update handling * fix spell --- google_assistant/Dockerfile | 4 +- google_assistant/config.json | 10 +++- google_assistant/hassio_gassistant.py | 15 +++-- google_assistant/hassio_oauth.py | 79 +++++++++++++++++++++++++++ google_assistant/run.sh | 20 +++++-- 5 files changed, 112 insertions(+), 16 deletions(-) create mode 100644 google_assistant/hassio_oauth.py diff --git a/google_assistant/Dockerfile b/google_assistant/Dockerfile index 82d026f..e39aa70 100644 --- a/google_assistant/Dockerfile +++ b/google_assistant/Dockerfile @@ -5,14 +5,14 @@ RUN apt-get update \ && apt-get install -y jq tzdata python3 python3-dev python3-pip \ python3-six python3-pyasn1 libportaudio2 alsa-utils \ - && pip3 install google-assistant-library google-auth \ + && pip3 install google-assistant-library google-auth requests_oauthlib cherrypy \ && apt-get remove -y --purge python3-pip python3-dev \ && apt autoremove -y \ && rm -rf /var/lib/apt/lists/* # Copy data COPY run.sh / -COPY hassio_gassistant.py / +COPY *.py / COPY asoundrc /root/.asoundrc RUN chmod a+x /run.sh diff --git a/google_assistant/config.json b/google_assistant/config.json index aec2561..337c486 100644 --- a/google_assistant/config.json +++ b/google_assistant/config.json @@ -1,6 +1,6 @@ { "name": "Google Assistant", - "version": "0.0.3-p1", + "version": "0.0.3-p2", "slug": "google_assistant", "description": "A virtual personal assistant developed by Google", "url": "https://home-assistant.io/addons/google_assistant/", @@ -9,15 +9,19 @@ "arch": ["armhf", "amd64"], "map": ["share"], "devices": ["/dev/snd:/dev/snd:rwm"], + "ports": { + "9324/tcp": 9324 + }, + "webui": "http://[HOST]:[PORT:9324]", "options": { "mic": "0,0", "speaker": "1,0", - "service_account": "google_assistant.json" + "client_secrets": "google_assistant.json" }, "schema": { "mic": "str", "speaker": "str", - "service_account": "str" + "client_secrets": "str" }, "image": "homeassistant/{arch}-addon-google_assistant" } diff --git a/google_assistant/hassio_gassistant.py b/google_assistant/hassio_gassistant.py index fae5677..29f41d8 100644 --- a/google_assistant/hassio_gassistant.py +++ b/google_assistant/hassio_gassistant.py @@ -1,11 +1,12 @@ """Hass.IO Google Assistant.""" import sys +from pathlib import Path + +import google.oauth2.credentials from google.assistant.library import Assistant from google.assistant.library.event import EventType -from google.oauth2 import service_account - def process_event(event): if event.type == EventType.ON_CONVERSATION_TURN_STARTED: @@ -18,9 +19,13 @@ def process_event(event): if __name__ == '__main__': - credentials = service_account.Credentials.from_service_account_file(sys.argv[1]) - scoped_credentials = credentials.with_scopes(['https://www.googleapis.com/auth/assistant-sdk-prototype']) + cred_json = Path(sys.argv[1]) - with Assistant(scoped_credentials) as assistant: + # open credentials + with cred_json.open('r') as data: + credentials = google.oauth2.credentials.Credentials(token=None, **json.load(data)) + + # run assistant + with Assistant(credentials) as assistant: for event in assistant.start(): process_event(event) diff --git a/google_assistant/hassio_oauth.py b/google_assistant/hassio_oauth.py new file mode 100644 index 0000000..bbc43a3 --- /dev/null +++ b/google_assistant/hassio_oauth.py @@ -0,0 +1,79 @@ +"""Run small webservice for oath.""" +import json +import sys +from pathlib import Path + +import cherrypy +from requests_oauthlib import OAuth2Session +from google.oauth2.credentials import Credentials + + +class oauth2Site(object): + """Website for handling oauth2.""" + + def __init__(self, user_data, cred_file): + """Init webpage.""" + self.cred_file = cred_file + self.user_data = user_data + + self.oauth2 = OAuth2Session( + self.user_data['client_id'], + redirect_uri='urn:ietf:wg:oauth:2.0:oob', + scope="https://www.googleapis.com/auth/assistant-sdk-prototype" + ) + + self.auth_url, _ = self.oauth2.authorization_url(self.user_data['auth_uri'], access_type='offline', prompt='consent') + + @cherrypy.expose + def index(self): + """Landingpage.""" + return str(""" + + +

+ Get token from google: Authentication +

+
+ + +
+ + """).format(url=self.auth_url) + + @cherrypy.expose + def token(self, token): + """Read access token and process it.""" + self.oauth2.fetch_token(self.user_data['token_uri'], client_secret=self.user_data['client_secret'], code=token) + + # create credentials + credentials = Credentials( + self.oauth2.token['access_token'], + refresh_token=self.oauth2.token.get('refresh_token'), + token_uri=self.user_data['token_uri'], + client_id=self.user_data['client_id'], + client_secret=self.user_data['client_secret'], + scopes=self.oauth2.scope + ) + + # write credentials json file + with self.cred_file.open('w') as json_file: + json_file.write(json.dumps({ + 'refresh_token': credentials.refresh_token, + 'token_uri': credentials.token_uri, + 'client_id': credentials.client_id, + 'client_secret': credentials.client_secret, + 'scopes': credentials.scopes, + })) + + sys.exit(0) + + +if __name__ == '__main__': + oauth_json = Path(sys.argv[1]) + cred_json = Path(sys.argv[2]) + + with oauth_json.open('r') as data: + user_data = json.load(data)['installed'] + + cherrypy.config.update({'server.socket_port': 9324}) + cherrypy.quickstart(oauth2Site(user_data, cred_json)) diff --git a/google_assistant/run.sh b/google_assistant/run.sh index eb3ce65..1a7bda1 100644 --- a/google_assistant/run.sh +++ b/google_assistant/run.sh @@ -2,9 +2,10 @@ set -e CONFIG_PATH=/data/options.json -OAUTH_JSON=/data/auth.json +CLIENT_JSON=/data/client.json +CRED_JSON=/data/cred.json -SERVICE_ACCOUNT=$(jq --raw-output '.service_account' $CONFIG_PATH) +CLIENT_SECRETS=$(jq --raw-output '.client_secrets' $CONFIG_PATH) SPEAKER=$(jq --raw-output '.speaker' $CONFIG_PATH) MIC=$(jq --raw-output '.mic' $CONFIG_PATH) @@ -16,9 +17,16 @@ sed -i "s/%%SPEAKER%%/$SPEAKER/g" /root/.asoundrc sed -i "s/%%MIC%%/$MIC/g" /root/.asoundrc # check if a new assistant file exists -if [ -f "/share/$SERVICE_ACCOUNT" ]; then - echo "[Info] Install/Update service account key file" - cp -f "/share/$SERVICE_ACCOUNT" "$OAUTH_JSON" +if [ -f "/share/$CLIENT_SECRETS" ]; then + echo "[Info] Install/Update service client_secrets file" + cp -f "/share/$CLIENT_SECRETS" "$CLIENT_JSON" + rm -f "/share/$CLIENT_SECRETS" + + echo "[Info] Start WebUI for handling oauth2" + python3 /hassio_oauth.py "$CLIENT_JSON" "$CRED_JSON" +elif [ ! -f "$CRED_JSON" ]; then + echo "[Error] You need initialize GoogleAssistant with a client secret json!" + exit 1 fi -exec python3 /hassio_gassistant.py "$OAUTH_JSON" < /dev/null +exec python3 /hassio_gassistant.py "$CRED_JSON" < /dev/null