-
Notifications
You must be signed in to change notification settings - Fork 156
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(recoverable): Add support for username recovery via simple login flows #1041
Conversation
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #1041 +/- ##
==========================================
+ Coverage 98.36% 98.37% +0.01%
==========================================
Files 37 37
Lines 4764 4795 +31
==========================================
+ Hits 4686 4717 +31
Misses 78 78 ☔ View full report in Codecov by Sentry. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In general - this is awesome and quite complete... thanks
A few minor things - the only larger issue is to make sure that JSON and GENERIC_RESPONSES are supported for the new endpoint.
Thanks for the review @jwag956 I'll try to address these changes tomorrow 👍🏽 |
@jwag956 Apologies this took me a bit longer to get back into. But I believe I addressed everything. Please take a look whenever you have a chance and enjoy your holidays! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wonderful! just a few more comments - only 1 substantive request...
tests/conftest.py
Outdated
@@ -127,6 +127,8 @@ def app(request: pytest.FixtureRequest) -> SecurityFixture: | |||
# Make this hex_md5 for token tests | |||
app.config["SECURITY_HASHING_SCHEMES"] = ["hex_md5"] | |||
app.config["SECURITY_DEPRECATED_HASHING_SCHEMES"] = [] | |||
# Enable username recovery for tests | |||
app.config["SECURITY_USERNAME_RECOVERY"] = True |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: do this in for loop below with all the other options
docs/api.rst
Outdated
@@ -256,6 +256,7 @@ Forms | |||
.. autoclass:: flask_security.WebAuthnVerifyForm | |||
.. autoclass:: flask_security.Form | |||
.. autoclass:: flask_security.FormInfo | |||
.. autoclass:: flask_security.UsernameRecoveryForm |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: alphabetize please!
flask_security/__init__.py
Outdated
@@ -58,6 +58,7 @@ | |||
TwoFactorSetupForm, | |||
TwoFactorVerifyCodeForm, | |||
VerifyForm, | |||
UsernameRecoveryForm, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: alphabetize
flask_security/views.py
Outdated
) | ||
|
||
if form.validate_on_submit(): | ||
user = _datastore.find_user(email=form.email.data) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You don't need to do this - UserEmailFormMixin already looks it up and sets form.user if email exists. So if validation succeeds - form.user will be set.
flask_security/views.py
Outdated
if _security._want_json(request): | ||
return base_render_json(form, include_user=False) | ||
|
||
if form.validate_on_submit(): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not comfortable calling validate_on_submit twice .... as with many other views I think that on GET or POST errors - the template should be rendered (as you do). Maybe what I am asking is - rather than this if/redirect here - do the redirect up in the validate_on_submit() part:
if validate_on_submit():
send_username_recovery_email()
if _security_want_json(request):
return base_render_json....
do_flash(xxx)
return redirect(get_url(".login")
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for sticking with this - things are looking great - few even smaller things and we'll be done!
docs/configuration.rst
Outdated
|
||
.. versionadded:: 5.6.0 | ||
|
||
.. py:data:: SECURITY_USERNAME_RECOVERY_URL |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add this to list of URLs below
docs/configuration.rst
Outdated
@@ -1155,6 +1155,38 @@ Recoverable | |||
|
|||
Default: ``_("Your password has been reset")``. | |||
|
|||
.. py:data:: SECURITY_USERNAME_RECOVERY |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given this is a separate feature - could you put this is its own 'section'
Username-Recovery
---------------------
Thanks again for the review @jwag956! I believe everything should be addressed now. Let me know what you think. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for being patient... Adding a new view has a lot of boilerplate alas..
PR adds support for requesting a forgotten username (closes #980). If the user requesting the username recovery enters an email that is valid, they will receive the associated username via the registered email, otherwise they will not.