mirror of
https://github.com/aljazceru/addons.git
synced 2025-12-17 21:24:20 +01:00
add google auth (#147)
* add google auth * fix parse * Update handling * fix spell
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
79
google_assistant/hassio_oauth.py
Normal file
79
google_assistant/hassio_oauth.py
Normal 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))
|
||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user