160 lines
5.6 KiB
Python
160 lines
5.6 KiB
Python
import json
|
|
import os
|
|
|
|
from oauthlib.oauth2 import WebApplicationClient
|
|
from ovos_backend_manager.configuration import CONFIGURATION, DB
|
|
from pywebio.input import actions, input_group, input, TEXT
|
|
from pywebio.output import use_scope, popup, put_image, put_link, put_code, put_text, put_table, put_markdown
|
|
|
|
|
|
def get_oauth_data(app_id=None):
|
|
data = {}
|
|
if app_id:
|
|
data = DB.get_oauth_app(app_id)
|
|
data = data or {'auth_endpoint': "https://",
|
|
'token_endpoint': "https://",
|
|
'refresh_endpoint': "https://"}
|
|
if "callback_endpoint" not in data:
|
|
backend_url = f"http://0.0.0.0:{CONFIGURATION['backend_port']}/{CONFIGURATION['api_version']}"
|
|
data["callback_endpoint"] = f"{backend_url}/auth/callback/{app_id or '...'}"
|
|
|
|
with use_scope("main_view", clear=True):
|
|
return input_group('Settings', [
|
|
input("Name", value=app_id or "...",
|
|
type=TEXT, name="oauth_service"),
|
|
input("Client ID", value=data.get("client_id", ""),
|
|
type=TEXT, name='client_id'),
|
|
input("Client Secret", value=data.get("client_secret", ""),
|
|
type=TEXT, name='client_secret'),
|
|
input("Auth Endpoint", value=data.get("auth_endpoint", ""),
|
|
type=TEXT, name='auth_endpoint'),
|
|
input("Token Endpoint", value=data.get("token_endpoint", ""),
|
|
type=TEXT, name='token_endpoint'),
|
|
input("Refresh Endpoint", value=data.get("refresh_endpoint", ""),
|
|
type=TEXT, name='refresh_endpoint'),
|
|
input("Callback Endpoint", value=data["callback_endpoint"],
|
|
type=TEXT, name='callback_endpoint'),
|
|
input("Scope", value=data.get("scope", ""),
|
|
type=TEXT, name='scope')
|
|
])
|
|
|
|
|
|
def authorize_app(data):
|
|
callback_endpoint = f"http://0.0.0.0:36535/auth/callback/{data['oauth_service']}"
|
|
client = WebApplicationClient(data["client_id"])
|
|
request_uri = client.prepare_request_uri(
|
|
data["auth_endpoint"],
|
|
redirect_uri=data.get("callback_endpoint") or callback_endpoint,
|
|
show_dialog=True,
|
|
state=data['oauth_service'],
|
|
scope=data["scope"],
|
|
)
|
|
with popup(f"{data['oauth_service']}"):
|
|
put_link("Authorize", request_uri, new_window=True)
|
|
|
|
|
|
def _render_app(app_id):
|
|
with use_scope("main_view", clear=True):
|
|
data = DB.get_oauth_app(app_id)
|
|
|
|
put_markdown(f'# {app_id.title()}')
|
|
put_table([
|
|
['Client ID', data["client_id"]],
|
|
['Client Secret', data["client_secret"]],
|
|
['Scope', data["scope"]]
|
|
])
|
|
put_markdown(f'### OAuth Endpoints')
|
|
put_table([
|
|
['Auth', data["auth_endpoint"]],
|
|
['Token', data["token_endpoint"]],
|
|
['Refresh', data["refresh_endpoint"]],
|
|
['Callback', data["callback_endpoint"]],
|
|
])
|
|
|
|
|
|
def app_menu(app_id, back_handler=None):
|
|
with use_scope("logo", clear=True):
|
|
img = open(f'{os.path.dirname(__file__)}/res/oauth.png', 'rb').read()
|
|
put_image(img)
|
|
|
|
_render_app(app_id)
|
|
|
|
buttons = [
|
|
{'label': "Configure", 'value': "oauth"},
|
|
]
|
|
tok = DB.get_oauth_token(app_id)
|
|
if tok:
|
|
buttons.append({'label': "View Token", 'value': "token"})
|
|
buttons.append({'label': "Refresh Token", 'value': "refresh"})
|
|
else:
|
|
buttons.append({'label': "Authorize", 'value': "auth"})
|
|
buttons.append({'label': "Delete", 'value': "delete"})
|
|
if back_handler:
|
|
buttons.insert(0, {'label': '<- Go Back', 'value': "main"})
|
|
|
|
opt = actions(label=f"What would you like to do with {app_id}?",
|
|
buttons=buttons)
|
|
if opt == "main":
|
|
with use_scope("main_view", clear=True):
|
|
oauth_menu(back_handler=back_handler)
|
|
return
|
|
elif opt == "token":
|
|
with popup("OAuth Token"):
|
|
put_code(json.dumps(tok, indent=4), language="json")
|
|
elif opt == "auth" or opt == "refresh": # TODO special refresh handling (?)
|
|
data = DB.get_oauth_app(app_id)
|
|
authorize_app(data)
|
|
elif opt == "oauth":
|
|
data = get_oauth_data(app_id)
|
|
app_id = data.pop("oauth_service")
|
|
DB.update_oauth_app(app_id, **data)
|
|
with popup(app_id):
|
|
put_text(f"{app_id} oauth settings updated!")
|
|
|
|
elif opt == "delete":
|
|
DB.delete_oauth_app(app_id)
|
|
with popup(app_id):
|
|
put_text(f"{app_id} oauth settings deleted!")
|
|
oauth_menu(back_handler=back_handler)
|
|
return
|
|
else:
|
|
app_id = opt
|
|
|
|
app_menu(app_id, back_handler=back_handler)
|
|
|
|
|
|
def oauth_menu(back_handler=None):
|
|
with use_scope("logo", clear=True):
|
|
img = open(f'{os.path.dirname(__file__)}/res/oauth.png', 'rb').read()
|
|
put_image(img)
|
|
|
|
with use_scope("main_view", clear=True):
|
|
pass
|
|
|
|
buttons = [{'label': 'New App', 'value': "new"}]
|
|
for app in DB.list_oauth_apps():
|
|
app_id = app.pop("token_id")
|
|
data = app
|
|
buttons.append({'label': app_id, 'value': data})
|
|
if back_handler:
|
|
buttons.insert(0, {'label': '<- Go Back', 'value': "main"})
|
|
|
|
opt = actions(label="What would you like to do?",
|
|
buttons=buttons)
|
|
if opt == "new":
|
|
data = get_oauth_data()
|
|
app_id = data.pop("oauth_service")
|
|
DB.add_oauth_app(app_id, **data)
|
|
|
|
authorize_app(data)
|
|
|
|
elif opt == "main":
|
|
with use_scope("main_view", clear=True):
|
|
if back_handler:
|
|
back_handler()
|
|
return
|
|
else:
|
|
app_menu(opt, back_handler=back_handler)
|
|
return
|
|
|
|
oauth_menu(back_handler=back_handler)
|