Open fuomag9 opened 1 year ago
authentik applies a DIY approach to autnetication, authorization and user management. You can enhance the user settings flow and make it do almost whatever you like.
For example, you can add an email verification stage to the user settings change flow. Similar to the enrollment flow, you should add it after the user info prompt stage but before the user write stage. Doing so will prompt the user to verify their email and if they can't no changes will be saved.
However, as far as I know it is not currently possible (as far as I know and have tested) to conditionally add the email verification stage based on whether the email property has been changed in the prompt stage before it. In my testing adding a policy binding to the email verification stage binding does not see the context generated by the previous prompt stage, thus it is not possible to skip the email stage based on the context. All of this means that your users will need to verify their email every time they change any of their user settings.
Disclaimer: I am just another user of authentik.
I'm still "new" to authentik but I guess that as a temporary fix it's still way better than nothing! (As the user can now at least change email, and I guess changing the name is probably a "rare" thing to do that won't annoy them too much if they have to verify the email as well)
Thank you btw, and I hope things can be improved (or figured out)
Another place that could need email verification "attached" is when users are manually created by admins. (in keycloak you can attach "actions" to users that they have to do such as having to reset their passwords or verify their email)
I would strongly encourage you to spend a few hours reading through the documentation. authentik can be a very flexible and powerful tool but it definitely has a steeper learning curve than some of the competition.
I would strongly encourage you to spend a few hours reading through the documentation. authentik can be a very flexible and powerful tool but it definitely has a steeper learning curve than some of the competition.
Docs are very lacking in some aspects unfortunately :(
Another place that could need email verification "attached" is when users are manually created by admins. (in keycloak you can attach "actions" to users that they have to do such as having to reset their passwords or verify their email)
If you are looking for general help and you cannot find it in the docs you should consider joining the discord channel .
But to try to answer your question:
I think you can add an email verification stage to the authentication flow and set it to activate users on successful verification. Then attach a policy binding to the stage. The policy binding should be an expression policy that checks if the user is active On second thought that won't work - your users will not be able to authenticate. BUT you can add new users to certain group (or even add some custom property to an individual user). Then check for that in the expression policy. If present, show an email verification stage and when completed remove the group/property from the user.request.user.is_active
. The policy should fail if the user is active (thus skip the email verification stage from the flow). Then your admin should create the users as inactive.
Alternatively - you can consider implementing an enrollment flow with an invitation stage. This will allow you to preset certain user properties (much like an admin creating a new user manually).
authentik applies a DIY approach to autnetication, authorization and user management. You can enhance the user settings flow and make it do almost whatever you like.
For example, you can add an email verification stage to the user settings change flow. Similar to the enrollment flow, you should add it after the user info prompt stage but before the user write stage. Doing so will prompt the user to verify their email and if they can't no changes will be saved.
However, as far as I know it is not currently possible (as far as I know and have tested) to conditionally add the email verification stage based on whether the email property has been changed in the prompt stage before it. In my testing adding a policy binding to the email verification stage binding does not see the context generated by the previous prompt stage, thus it is not possible to skip the email stage based on the context. All of this means that your users will need to verify their email every time they change any of their user settings.
Disclaimer: I am just another user of authentik.
Apologies, looks like I lied about this. I decided to try again and It IS possible to make email verification conditional. You need to use the same policy-binding-to-stage-binding technique. Just make sure that:
email = request.context.get("prompt_data", {}).get("email", "")
return request.user.email != email # True when they differ, thus present the extra stage to the user
Sadly, it appears this solution does not work (anymore?). The idea of the policy and email stage is correct, however, the email stage errors out with "No pending user" as per #6123.
Anyone have other ideas for verifying changed email addresses?
Same here. I have two policies checking the user input regarding email I have to review the policies first though because I seem to have some concepts wrong in working with prompt data
and it errors out with 'no pending user' when trying to send the email in a Settings flow
I have a not so shiny workaround that is potentially even dangerous.
I have created three policies to detect and verify a changed email address. I have a custom settings page but that doesn't matter regarding the email verification. The settings page's email field has the 'field' email and type email as well.
The reasining was: if the email stage tries to find a 'pending user' because it is probably more likely to be used for password resets or account activations (after an identification stage was run which sets a pending_user) ... then let's make one.
Email Stage is set to 'all policies must allow' - playing with the return values you could do it differently.
# detect changed email address
current = ''
new = ''
try:
current = request.user.email
except:
current = ''
prompt_data = request.context.get("prompt_data")
new = prompt_data.get('email','')
ak_message(f'{current},{new}')
if current != new:
# changed email
return True
# same email as before
return False
# if there is a request user but no pending user, copy it to the flow context (is this dangerous?)
if not request.context.get('pending_user'):
if not request.user:
ak_message('not authenticated')
return False
context['flow_plan'].context['pending_user'] = request.user
ak_message('pending user copied')
return True
ak_message('pending user alredy present')
return True
# change destination address for the email stage according to https://docs.goauthentik.io/docs/flow/stages/email/
request.context["flow_plan"].context["email"] = request.context["prompt_data"]["email"]
return True
When I submit the form without changing the email address, the settings are just saved
When I change the email address, the settings are not saved (as seen later) but I return the the 'user settings' view with the prompt stage from the user settings flow changed to a buton labeled 'User Settings'.
When I click on the button, I land on the 'resend email' page. The button for resending the email works
The Email stage uses the correct (new) email address and the old user name (when changed) for the Mail, which is as desired and expected from where I stand.
Clicking on the mail while still logged in takes me to the email verification landing page, ak_message (email address successfully verified or something)
Clicking on the mail after logging out of the user interface, the landing page is shown (and the settings are updated)
Logging out, not clicking any links and logging back in again makes the user settings interface come available again.
The former (last verified) email address is shown.
Changing the email address again (to a third address) starts the flow again sending another email to this third address (as expected)
Trying it the other way around ...
Clicking any of the links a second time just takes me to a 'detached' view of the prompt stage of the config flow (no sidebar)
I verified in the admin interface that in none of the cases, the values were applied before validating the email address by interacting with the link. Sometimes, after going to the user settings page after having clicked a validation link, the interface tells me that no flow has been configured for user settings. Logging out and in again fixes this. Reloads don't.
I am running the 2024.4 release from yesterday
Just to add: it does not work with anonymous flows (e.g. before writing a user at enrollment to check the mail address) because some part of the process expects a 'User' object and the user I am copying seems to be an 'AnonymousUser' object. I didn't expect it to, but it would have been nice to have that working.
Is your feature request related to a problem? Please describe. I need to avoid user setting a mail they don't own, bypassing the enrollment email verification check (as they can use a verified one during signup and then set an unverified later in the settings)
Describe the solution you'd like Bind a flow to email change in settings, so email can be verified.
Describe alternatives you've considered None, currently my only alternative is to disable email changes :(
Additional context None