diff --git a/areas/users/user_service.py b/areas/users/user_service.py index 772af99..ec94c44 100644 --- a/areas/users/user_service.py +++ b/areas/users/user_service.py @@ -1,3 +1,9 @@ +import ory_kratos_client +from ory_kratos_client.model.submit_self_service_recovery_flow_body \ + import SubmitSelfServiceRecoveryFlowBody +from ory_kratos_client.api import v0alpha2_api as kratos_api +from config import KRATOS_ADMIN_URL + from database import db from areas.apps import App, AppRole, AppsService from areas.roles import Role, RoleService @@ -7,6 +13,10 @@ from flask import current_app from helpers.error_handler import KratosError +kratos_admin_api_configuration = \ + ory_kratos_client.Configuration(host=KRATOS_ADMIN_URL, discard_unknown_keys=True) +KRATOS_ADMIN = \ + kratos_api.V0alpha2Api(ory_kratos_client.ApiClient(kratos_admin_api_configuration)) class UserService: @staticmethod @@ -27,7 +37,10 @@ class UserService: def post_user(data): kratos_data = { "schema_id": "default", - "traits": {"email": data["email"], "name": data["name"]}, + "traits": { + "name": data["name"], + "email": data["email"], + }, } res = KratosApi.post("/admin/identities", kratos_data).json() @@ -55,8 +68,32 @@ class UserService: db.session.add(app_role) db.session.commit() + UserService.__start_recovery_flow(data["email"]) + return UserService.get_user(res["id"]) + + @staticmethod + def __start_recovery_flow(email): + """ + Start a Kratos recovery flow for the user's email address. + + This sends out an email to the user that explains to them how they can + set their password. Make sure the user exists inside Kratos before you + use this function. + + :param email: Email to send recovery link to + :type email: str + """ + api_response = KRATOS_ADMIN.initialize_self_service_recovery_flow_without_browser() + flow = api_response['id'] + # Submit the recovery flow to send an email to the new user. + submit_self_service_recovery_flow_body = \ + SubmitSelfServiceRecoveryFlowBody(method="link", email=email) + api_response = KRATOS_ADMIN.submit_self_service_recovery_flow(flow, + submit_self_service_recovery_flow_body= + submit_self_service_recovery_flow_body) + @staticmethod def put_user(id, user_editing_id, data): kratos_data = { diff --git a/cliapp/cliapp/cli.py b/cliapp/cliapp/cli.py index 06e6fb0..6735cb2 100644 --- a/cliapp/cliapp/cli.py +++ b/cliapp/cliapp/cli.py @@ -27,11 +27,15 @@ HYDRA = hydra_client.HydraAdmin(HYDRA_ADMIN_URL) # Kratos has an admin and public end-point. We create an API for them # both. The kratos implementation has bugs, which forces us to set # the discard_unknown_keys to True. -tmp = ory_kratos_client.Configuration(host=KRATOS_ADMIN_URL, discard_unknown_keys=True) -KRATOS_ADMIN = kratos_api.V0alpha2Api(ory_kratos_client.ApiClient(tmp)) +kratos_admin_api_configuration = \ + ory_kratos_client.Configuration(host=KRATOS_ADMIN_URL, discard_unknown_keys=True) +KRATOS_ADMIN = \ + kratos_api.V0alpha2Api(ory_kratos_client.ApiClient(kratos_admin_api_configuration)) -tmp = ory_kratos_client.Configuration(host=KRATOS_PUBLIC_URL, discard_unknown_keys=True) -KRATOS_PUBLIC = kratos_api.V0alpha2Api(ory_kratos_client.ApiClient(tmp)) +kratos_public_api_configuration = \ + ory_kratos_client.Configuration(host=KRATOS_PUBLIC_URL, discard_unknown_keys=True) +KRATOS_PUBLIC = \ + kratos_api.V0alpha2Api(ory_kratos_client.ApiClient(kratos_public_api_configuration)) ############################################################################## # CLI INTERFACE # diff --git a/web/login/login.py b/web/login/login.py index 00cf3af..591acc2 100644 --- a/web/login/login.py +++ b/web/login/login.py @@ -31,11 +31,15 @@ HYDRA = hydra_client.HydraAdmin(HYDRA_ADMIN_URL) # Kratos has an admin and public end-point. We create an API for them # both. The kratos implementation has bugs, which forces us to set # the discard_unknown_keys to True. -tmp = ory_kratos_client.Configuration(host=KRATOS_ADMIN_URL, discard_unknown_keys=True) -KRATOS_ADMIN = kratos_api.V0alpha2Api(ory_kratos_client.ApiClient(tmp)) +kratos_admin_api_configuration = \ + ory_kratos_client.Configuration(host=KRATOS_ADMIN_URL, discard_unknown_keys=True) +KRATOS_ADMIN = \ + kratos_api.V0alpha2Api(ory_kratos_client.ApiClient(kratos_admin_api_configuration)) -tmp = ory_kratos_client.Configuration(host=KRATOS_PUBLIC_URL, discard_unknown_keys=True) -KRATOS_PUBLIC = kratos_api.V0alpha2Api(ory_kratos_client.ApiClient(tmp)) +kratos_public_api_configuration = \ + ory_kratos_client.Configuration(host=KRATOS_PUBLIC_URL, discard_unknown_keys=True) +KRATOS_PUBLIC = \ + kratos_api.V0alpha2Api(ory_kratos_client.ApiClient(kratos_public_api_configuration)) ADMIN_ROLE_ID = 1 NO_ACCESS_ROLE_ID = 3 diff --git a/web/static/base.js b/web/static/base.js index 6d94cea..4424760 100644 --- a/web/static/base.js +++ b/web/static/base.js @@ -1,5 +1,3 @@ - - /* base.js This is the base JS file to render the user interfaces of kratos and provide the end user with flows for login, recovery etc. @@ -433,8 +431,3 @@ $.urlParam = function(name) { } return decodeURI(results[1]) || 0; }; - - - - -