Upgrade web server for OAuth connection process [add-on: google_assistant] (#1267)

* Update pages styling and better error handling

* Fix css

* Offload static folder to /usr/share/public

* Remove unnecessary os import

* Add a changelog and update the version

* Update google_assistant/config.json

* Update google_assistant/CHANGELOG.md

Co-authored-by: Pascal Vizeli <pascal.vizeli@syshack.ch>
This commit is contained in:
Eric Matte
2020-05-06 08:13:21 -04:00
committed by GitHub
parent f8a1f4d361
commit 9d83c89415
7 changed files with 164 additions and 14 deletions

View File

@@ -2,11 +2,18 @@
import json
import sys
from pathlib import Path
import threading
import time
import cherrypy
from requests_oauthlib import OAuth2Session
from google.oauth2.credentials import Credentials
HEADERS = str("""
<link rel="icon" href="/static/favicon.ico?v=1">
<link href="/static/css/style.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Roboto&display=swap" rel="stylesheet">
""")
class oauth2Site(object):
"""Website for handling oauth2."""
@@ -26,24 +33,38 @@ class oauth2Site(object):
@cherrypy.expose
def index(self):
"""Landingpage."""
"""Landing page."""
return str("""<html>
<head></head>
<head>{headers}</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>
<div class="card">
<div class="card-content">
<img src="/static/logo.png" alt="Google Assistant Logo" />
<h1>Google Assistant SDK</h1>
<p>Initial setup</p>
<ol>
<li><a href="{url}" target="_blank">Get a code from Google here</a></li>
<li><input type="text" value="" name="token" placeholder="Paste the code here" /></li>
</ol>
</div>
<div class="card-actions">
<button type="submit">CONNECT</button>
</div>
</div>
</form>
</body>
</html>""").format(url=self.auth_url)
</html>""").format(url=self.auth_url, headers=HEADERS)
@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)
try:
self.oauth2.fetch_token(self.user_data['token_uri'], client_secret=self.user_data['client_secret'], code=token)
except Exception as e:
cherrypy.log("Error with the given token: {error}".format(error=str(e)))
cherrypy.log("Restarting authentication process.")
raise cherrypy.HTTPRedirect('/')
# create credentials
credentials = Credentials(
@@ -65,8 +86,30 @@ class oauth2Site(object):
'scopes': credentials.scopes,
}))
sys.exit(0)
threading.Thread(target=self.exit_app).start()
return str("""<html>
<head>{headers}</head>
<body>
<div class="card">
<div class="card-content">
<img src="/static/logo.png" alt="Google Assistant Logo" />
<h1>Google Assistant SDK</h1>
<p>Setup completed.</p>
<p>You can now close this window.</p>
</div>
</div>
</body>
</html>""").format(url=self.auth_url, headers=HEADERS)
def exit_app(self):
time.sleep(2)
cherrypy.engine.exit()
def hide_access_logs():
"""Hide file access logging for cleaner logs"""
access_log = cherrypy.log.access_log
for handler in tuple(access_log.handlers):
access_log.removeHandler(handler)
if __name__ == '__main__':
oauth_json = Path(sys.argv[1])
@@ -75,5 +118,11 @@ if __name__ == '__main__':
with oauth_json.open('r') as data:
user_data = json.load(data)['installed']
hide_access_logs()
cherrypy.config.update({'server.socket_port': 9324, 'server.socket_host': '0.0.0.0'})
cherrypy.quickstart(oauth2Site(user_data, cred_json))
cherrypy.quickstart(oauth2Site(user_data, cred_json), config={
'/static': {
'tools.staticdir.on': True,
'tools.staticdir.dir': '/usr/share/public'
}
})

View File

@@ -0,0 +1,97 @@
body {
font-family: 'Roboto', sans-serif;
background-color: #fafafa;
display: flex;
align-items: center;
justify-content: center;
}
.card {
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12), 0 3px 1px -2px rgba(0, 0, 0, 0.2);
background-color: #ffffff;
color: #212121;
border-radius: 2px;
margin: 15px;
display: flex;
flex-direction: column;
justify-content: space-between;
width: 400px;
max-width: 90vw;
}
.card .card-content {
padding: 15px 25px;
border-bottom: 1px solid #bdbdbd;
}
.card .card-actions {
padding: 15px 25px;
}
h1 {
font-size: 24px;
}
img {
max-height: 60px;
}
ol {
margin: 28px 0 0 0;
padding: 0;
list-style-type: none;
}
ol li {
counter-increment: step-counter;
margin-bottom: 20px;
display: flex;
align-items: center;
}
ol li::before {
content: counter(step-counter);
margin-right: 5px;
padding: 3px 8px;
border-radius: 9999px;
border: 1px solid #bdbdbd;
}
input {
border: none;
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
border-bottom: 1px solid black;
font-size: 14px;
flex-grow: 1;
height: 30px;
width: 100%;
background: transparent;
outline: none;
transition: border-bottom 0.225s ease;
}
input:focus {
border-bottom: 2px solid black;
}
button {
font-size: 16px;
padding: 8px 10px;
background-color: transparent;
border: none;
color: #03a9f4;
cursor: pointer;
border-radius: 4px;
outline: none;
transition: background-color 0.225s ease;
}
button:hover {
background-color: #03a8f425;
}
button:active {
background-color: #03a8f44f;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB