Ticket #934 (closed Defect: fixed)
dm4-core: privileged call to support a passwort reset mechanism
Reported by: | Malte | Owned by: | Malte |
---|---|---|---|
Priority: | Major | Milestone: | Release 4.8 |
Component: | DeepaMehta Standard Distribution | Version: | 4.7 |
Keywords: | Cc: | jri, JuergeN | |
Complexity: | 3 | Area: | Application Framework / API |
Module: | deepamehta-accesscontrol |
Description
Just needed (myDM, Kiezatlas 2 and many others).
Enable the sign-up plugin to implement a passwort reset mechanism. Access to such should be realized with the mailing feature and a token sent out. The tokenized URL then gives access to a UI where such operation can be performed by the mailbox owner.
Change History
comment:5 Changed 9 years ago by Malte
Since the "Email Address" topics are now part of the "Administration" workspace, processing the results of a "Password Reset" Dialog (asking for Username and Email) cannot investigate IF there is a specific association between the given Username and Email topic.
Thus, the password reset mail with a link is sent out if (1) the given username exists and (2) the given email address exists. By the state of the current myDM ACL/Workspace setup ("Email" topics end up in the "Collaborative" administration workspace) no further validation (e.g. if email and username do correlate) is possible.
BTW: This setup, assigning all Email Address topics to a "Collaborative" workspace also hinders the subscription plugin (see #825) to send out notifications to users mailboxes no behalf of their subscriptions.
Just to let you know: I think that the new "password reset" feature of the dm4-sign-up module should just be active/working IF the administrator has set the "Email based confirmation workflow" option (of the "Sign-up Configuration topic") to "true".
comment:7 Changed 9 years ago by Malte
I revoke my thoughts on the current password reset authentication model i just proposed in comment:5.
Such an implementation, of course, would enable other (alread registered dm4-) users to send themselves password reset links corresponding to other people user accounts (just through providing their own Email Address in the password-reset dialog (since it would be an existing E-mail Address).
Thus, i currently have no idea to implement a password-reset authentication without relating (and thus validating) the email address to a username. In this case, i think, it would be enough if we would have a call like "hasRelatedTopic("dm4.contacts.email_address", eMailAddressValue)-call just to check IF there is a relation between the provided username and emailAddressValue.
Such a solution would be enough for the envisioned password-reset feature but then, see also the request for needing access to concrete emailAddressValues directly as commented in #825comment:5.
Thanks for your help.
comment:8 Changed 9 years ago by Malte
Just to let you know how the email address and username currently are related to each other by d4m-sign-up:
Topic emailTopic = usernameTopic.getRelatedTopic("org.deepamehta.signup.user_mailbox", "dm4.core.parent", "dm4.core.child", "dm4.contacts.email_address");
That request throws a 401 since "email_address" now resides in the "Administration" workspace.
comment:9 Changed 9 years ago by Malte
The immediate solution (and only currently available answer) to this (as well as to solving issue #825) is to store "Email Address" topics in the public "System" workspace again.
comment:10 Changed 9 years ago by jri
Yes, I understand the problem.
Also in regard of the subscription module (#825).
A solution would be to add another privileged method:
String getEmailAddress(String username)
My only objection would be that the Core then virtually depends on both, the Sign-up and the Contacts modules (as it would refer to the org.deepamehta.signup.user_mailbox and dm4.contacts.email_address types) what theoretically would create a circular dependency (as all modules depend on Core). However, this would be a "soft" dependency and not a technical problem.
Should we go this way?
Would the above method be sufficient?
BTW: I would tend to keep the Email Address topics in the Administration workspace (and not move to System) to maintain the privacy aspect: a logged in user is not supposed to see the email addresses of all users.
Thank you for advancing with the Reset Password feature!
comment:11 Changed 9 years ago by jri
I like to take a step back here and think about the Reset Password mechanism in general.
If a user has forgotten her password she possibly has forgotten hers username as well, right?
I think the common Reset Password mechanism only requires the user to enter hers email address, not the username. I'm right?
To me it would make sense to design the Reset Password mechanism in this way.
The required privileged API would be look different in this case.
comment:12 follow-up: ↓ 13 Changed 9 years ago by Malte
Thanks for sharing your thoughts.
Regarding the Reset Password mechanism, OK, fine, lets' do it this way. Email Addresses will be assigned to the Administration Workspace by the sign-up plugin.
So, to send out a "Password reset link" the current API would then be sufficient ("using dm4.getAccessControl().emailAddressExists(String emailAddressValue)").
But to reset the correct password i need to fetch the full "Email Address" topic (as part of a request by anonymous) in order to be able to set the new credentials for the corresponding "username" involved (and related to the emailAddressValue as described in comment:8). So, a call like "Topic getEmailAddressTopic(String emailAddressValue)" would be needed.
And yes, from my point of view on the subscriptions case (#825), an API extension like "String getEmailAddress(String username)" would be what is needed if we want to built the support for "notifications" via mail.
comment:13 in reply to: ↑ 12 Changed 9 years ago by jri
Replying to Malte:
But to reset the correct password i need to fetch the full "Email Address" topic (as part of a request by anonymous) in order to be able to set the new credentials for the corresponding "username" involved (and related to the emailAddressValue as described in comment:8). So, a call like "Topic getEmailAddressTopic(String emailAddressValue)" would be needed.
I think you're making a mistake here.
You have an email address (String) at hand and need to query the corresponding username, right?
Even if you had the "Email Address" topic, you could not navigate to the Username topic as anonymous.
Username topics are assigned to the System workspace. Remember, despite the System workspace is public it is readable for logged in users only. (The System workspace is special in this regard.)
So, what the Reset Password mechanism requires is a privileged method:
String getUsername(String emailAddress)
And the counterpart is still needed for the subscriptions case (#825):
String getEmailAddress(String username)
If you agree I would implement these methods soon.
comment:14 Changed 9 years ago by Malte
Thanks, you're absolutely correct. So, great, let's go for that!
comment:15 Changed 9 years ago by jri
OK :-)
comment:16 Changed 9 years ago by Jörg Richter <jri@…>
comment:17 Changed 9 years ago by jri
https://github.com/jri/deepamehta/commit/6c988731
Core Access Control: revise username/email (#934).
2 Core AccessControl calls are revised:
String getUsername(String emailAddress)
In case of more than one Email Address topics exist, the one that is assigned to a Username topic is returned.
Formerly an exception was thrown.
boolean emailAddressExists(String emailAddress)
True is returned only if the email address is actually assigned to a Username topic.
See #934.
comment:18 Changed 9 years ago by Malte
- Owner changed from jri to Malte
Do you want me to extend the login dialog provided by the dm4-webclient (somehow from with the dm4-sign-up module JS) to provide a message and link, like:
Forgot your password? <link>Password reset</link>
comment:19 Changed 9 years ago by jri
Yes, very good.
Tell me if you need support at side of dm4-webclient.
comment:20 Changed 9 years ago by Malte
Ok, i got it working. I adapted the init_3 hook of my js plugin to listen to any jQuery UI Dialog opend by the webclient document. It would be nice if the login dialog had an ID but that is not required as i identify it by the existence of the #login-message element.
dm4c.add_listener("init_3", function() { .. $(document).on("dialogopen", function(event, ui) { var $login_message = $("#login-message", event.target) if ($login_message.length > 0) { $('<br/><span class="password-reset">Forgot password?<br/>' + '<a href="/sign-up/request-password">Password reset</a></span>') .insertAfter($('.ui-dialog .ui-dialog-buttonset')) } }) })
Assuming that only one jQuery Dialog should be open at once and assuming that #login-message is only contained in the dialog i want to adapt, this should be fine.
comment:21 Changed 8 years ago by jri
Nice hack using the dialogopen event :-)
comment:22 Changed 8 years ago by jri
- Status changed from accepted to closed
- Resolution set to fixed
Hey JuergeN, this ticket should cover what you were mentioning to me lately for myDM.