diff --git a/openlobby/mutations.py b/openlobby/mutations.py index b9d542626707a691e44576642efa515df7a3cc41..a6b6086901506650a21b455437f303a01ceea5f5 100644 --- a/openlobby/mutations.py +++ b/openlobby/mutations.py @@ -3,6 +3,7 @@ from flask import g import graphene from graphene import relay from graphene.types.datetime import DateTime +from graphql_relay import from_global_id from oic.oic import rndstr from oic.oic.message import AuthorizationResponse import time @@ -13,9 +14,16 @@ from .auth import ( get_session_expiration_time, create_access_token, ) -from .documents import UserDoc, LoginAttemptDoc, SessionDoc, ReportDoc +from .documents import ( + UserDoc, + LoginAttemptDoc, + SessionDoc, + ReportDoc, + OpenIdClientDoc, +) from .openid import ( init_client_for_uid, + init_client_for_shortcut, register_client, get_authorization_url, set_registration_info, @@ -72,6 +80,59 @@ class Login(relay.ClientIDMutation): return Login(authorization_url=authorization_url) +class LoginByShortcut(relay.ClientIDMutation): + + class Input: + shortcut_id = relay.GlobalID(required=True) + redirect_uri = graphene.String(required=True) + + authorization_url = graphene.String() + + @classmethod + def mutate_and_get_payload(cls, root, info, **input): + shortcut_id = input['shortcut_id'] + redirect_uri = input['redirect_uri'] + + type, id = from_global_id(shortcut_id) + openid_client_data = OpenIdClientDoc.get(id, using=info.context['es'], + index=info.context['index']) + + # prepare OpenID client + client = init_client_for_shortcut(openid_client_data, redirect_uri) + + # TODO + """ + # prepare login attempt details + state = rndstr(32) + nonce = rndstr() + expiration = get_login_attempt_expiration_time() + + # save login attempt into ES + data = { + 'meta': {'id': client.client_id}, + 'state': state, + 'nonce': nonce, + 'client_id': client.client_id, + 'client_secret': client.client_secret, + 'openid_uid': openid_uid, + 'redirect_uri': redirect_uri, + 'expiration': expiration, + } + login_attempt = LoginAttemptDoc(**data) + login_attempt.save(using=info.context['es'], index=info.context['index']) + + # already registered user? + user = UserDoc.get_by_openid_uid(openid_uid, **info.context) + is_new_user = user is None + + # get OpenID authorization url + authorization_url = get_authorization_url(client, state, nonce, is_new_user) + """ + + authorization_url = 'http://localhost/foo' + return LoginByShortcut(authorization_url=authorization_url) + + class LoginRedirect(relay.ClientIDMutation): class Input: @@ -184,6 +245,7 @@ class NewReport(relay.ClientIDMutation): class Mutation(graphene.ObjectType): login = Login.Field() + login_by_shortcut = LoginByShortcut.Field() login_redirect = LoginRedirect.Field() logout = Logout.Field() new_report = NewReport.Field() diff --git a/openlobby/openid.py b/openlobby/openid.py index 42522a71e12d51c0bb24e21af981b581546d54e1..f336e0af71b6468e5136eb559cb7bace2744ae61 100644 --- a/openlobby/openid.py +++ b/openlobby/openid.py @@ -1,5 +1,10 @@ from oic.oic import Client -from oic.oic.message import RegistrationResponse, ClaimsRequest, Claims +from oic.oic.message import ( + ProviderConfigurationResponse, + RegistrationResponse, + ClaimsRequest, + Claims, +) from oic.utils.authn.client import CLIENT_AUTHN_METHOD from .settings import SITE_NAME @@ -12,6 +17,19 @@ def init_client_for_uid(openid_uid): return client +def init_client_for_shortcut(data, redirect_uri): + client = Client(client_authn_method=CLIENT_AUTHN_METHOD) + set_registration_info(client, data['client_id'], data['client_secret'], redirect_uri) + info = { + 'issuer': data['issuer'], + 'authorization_endpoint': data['authorization_endpoint'], + 'token_endpoint': data['token_endpoint'], + 'userinfo_endpoint': data['userinfo_endpoint'], + } + client.provider_info = ProviderConfigurationResponse(**info) + return client + + def register_client(client, redirect_uri): params = { 'redirect_uris': [redirect_uri], diff --git a/tests/snapshots/snap_test_management.py b/tests/snapshots/snap_test_management.py index 6d030b28120260abb1958ec0e31fcf6ec114c5e5..28674d9096c3c1966df693b351fdd87c71015203 100644 --- a/tests/snapshots/snap_test_management.py +++ b/tests/snapshots/snap_test_management.py @@ -80,7 +80,7 @@ snapshots['test_create_index__check_mappings 1'] = { 'client_secret': { 'type': 'keyword' }, - 'isShortcut': { + 'is_shortcut': { 'type': 'boolean' }, 'issuer': { @@ -89,9 +89,6 @@ snapshots['test_create_index__check_mappings 1'] = { 'name_x': { 'type': 'keyword' }, - 'redirect_uri': { - 'type': 'keyword' - }, 'token_endpoint': { 'type': 'keyword' }, @@ -208,7 +205,7 @@ snapshots['test_init_alias 1'] = { 'client_secret': { 'type': 'keyword' }, - 'isShortcut': { + 'is_shortcut': { 'type': 'boolean' }, 'issuer': { @@ -217,9 +214,6 @@ snapshots['test_init_alias 1'] = { 'name_x': { 'type': 'keyword' }, - 'redirect_uri': { - 'type': 'keyword' - }, 'token_endpoint': { 'type': 'keyword' }, @@ -336,7 +330,7 @@ snapshots['test_reindex__check_new_index 1'] = { 'client_secret': { 'type': 'keyword' }, - 'isShortcut': { + 'is_shortcut': { 'type': 'boolean' }, 'issuer': { @@ -345,9 +339,6 @@ snapshots['test_reindex__check_new_index 1'] = { 'name_x': { 'type': 'keyword' }, - 'redirect_uri': { - 'type': 'keyword' - }, 'token_endpoint': { 'type': 'keyword' }, @@ -464,7 +455,7 @@ snapshots['test_init_documents 1'] = { 'client_secret': { 'type': 'keyword' }, - 'isShortcut': { + 'is_shortcut': { 'type': 'boolean' }, 'issuer': { @@ -473,9 +464,6 @@ snapshots['test_init_documents 1'] = { 'name_x': { 'type': 'keyword' }, - 'redirect_uri': { - 'type': 'keyword' - }, 'token_endpoint': { 'type': 'keyword' },