add google auth (#147)

* add google auth

* fix parse

* Update handling

* fix spell
This commit is contained in:
Pascal Vizeli
2017-07-22 16:35:06 +02:00
committed by GitHub
parent 32f01b1acf
commit 0b8bc56642
5 changed files with 112 additions and 16 deletions

View File

@@ -5,14 +5,14 @@
RUN apt-get update \ RUN apt-get update \
&& apt-get install -y jq tzdata python3 python3-dev python3-pip \ && apt-get install -y jq tzdata python3 python3-dev python3-pip \
python3-six python3-pyasn1 libportaudio2 alsa-utils \ 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-get remove -y --purge python3-pip python3-dev \
&& apt autoremove -y \ && apt autoremove -y \
&& rm -rf /var/lib/apt/lists/* && rm -rf /var/lib/apt/lists/*
# Copy data # Copy data
COPY run.sh / COPY run.sh /
COPY hassio_gassistant.py / COPY *.py /
COPY asoundrc /root/.asoundrc COPY asoundrc /root/.asoundrc
RUN chmod a+x /run.sh RUN chmod a+x /run.sh

View File

@@ -1,6 +1,6 @@
{ {
"name": "Google Assistant", "name": "Google Assistant",
"version": "0.0.3-p1", "version": "0.0.3-p2",
"slug": "google_assistant", "slug": "google_assistant",
"description": "A virtual personal assistant developed by Google", "description": "A virtual personal assistant developed by Google",
"url": "https://home-assistant.io/addons/google_assistant/", "url": "https://home-assistant.io/addons/google_assistant/",
@@ -9,15 +9,19 @@
"arch": ["armhf", "amd64"], "arch": ["armhf", "amd64"],
"map": ["share"], "map": ["share"],
"devices": ["/dev/snd:/dev/snd:rwm"], "devices": ["/dev/snd:/dev/snd:rwm"],
"ports": {
"9324/tcp": 9324
},
"webui": "http://[HOST]:[PORT:9324]",
"options": { "options": {
"mic": "0,0", "mic": "0,0",
"speaker": "1,0", "speaker": "1,0",
"service_account": "google_assistant.json" "client_secrets": "google_assistant.json"
}, },
"schema": { "schema": {
"mic": "str", "mic": "str",
"speaker": "str", "speaker": "str",
"service_account": "str" "client_secrets": "str"
}, },
"image": "homeassistant/{arch}-addon-google_assistant" "image": "homeassistant/{arch}-addon-google_assistant"
} }

View File

@@ -1,11 +1,12 @@
"""Hass.IO Google Assistant.""" """Hass.IO Google Assistant."""
import sys import sys
from pathlib import Path
import google.oauth2.credentials
from google.assistant.library import Assistant from google.assistant.library import Assistant
from google.assistant.library.event import EventType from google.assistant.library.event import EventType
from google.oauth2 import service_account
def process_event(event): def process_event(event):
if event.type == EventType.ON_CONVERSATION_TURN_STARTED: if event.type == EventType.ON_CONVERSATION_TURN_STARTED:
@@ -18,9 +19,13 @@ def process_event(event):
if __name__ == '__main__': if __name__ == '__main__':
credentials = service_account.Credentials.from_service_account_file(sys.argv[1]) cred_json = Path(sys.argv[1])
scoped_credentials = credentials.with_scopes(['https://www.googleapis.com/auth/assistant-sdk-prototype'])
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(): for event in assistant.start():
process_event(event) process_event(event)

View File

@@ -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("""<html>
<head></head>
<body>
<p>
Get token from google: <a href="{url}" target="_blank">Authentication</a>
</p>
<form method="get" action="token">
<input type="text" value="" name="token" />
<button type="submit">Connect</button>
</form>
</body>
</html>""").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))

View File

@@ -2,9 +2,10 @@
set -e set -e
CONFIG_PATH=/data/options.json 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) SPEAKER=$(jq --raw-output '.speaker' $CONFIG_PATH)
MIC=$(jq --raw-output '.mic' $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 sed -i "s/%%MIC%%/$MIC/g" /root/.asoundrc
# check if a new assistant file exists # check if a new assistant file exists
if [ -f "/share/$SERVICE_ACCOUNT" ]; then if [ -f "/share/$CLIENT_SECRETS" ]; then
echo "[Info] Install/Update service account key file" echo "[Info] Install/Update service client_secrets file"
cp -f "/share/$SERVICE_ACCOUNT" "$OAUTH_JSON" 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 fi
exec python3 /hassio_gassistant.py "$OAUTH_JSON" < /dev/null exec python3 /hassio_gassistant.py "$CRED_JSON" < /dev/null