password expiration policy - DO NOT MERGE - #36
Conversation
9muir
left a comment
There was a problem hiding this comment.
Looks pretty good at a high level. Nice job breaking out into a much smaller PR.
|
|
||
| @app.task(bind=True) | ||
| def block_user(self): | ||
| """ Block User if User password is not updated |
There was a problem hiding this comment.
Please make the comment reflect the fact that the number of days is configured in a setting.
There was a problem hiding this comment.
comments incorporated in commit id 1703300.
| """ Block User if User password is not updated | ||
| for last 90 days | ||
| """ | ||
| six_month_ago = (django.utils.timezone.now() - |
There was a problem hiding this comment.
six_month_ago is not a good name for a variable that might not represent a date exactly six months ago.
There was a problem hiding this comment.
comments incorporated in commit id 1703300
| return JsonResponse({'permissions': list(role_permission)}) | ||
| return HttpResponseBadRequest() | ||
|
|
||
| def validate_password_strength(value): |
There was a problem hiding this comment.
Would be good to have some unit tests to validate that this rejects 'weak' passwords, especially since the regex is kinda incomprehensible. It might be clearer if the code was structured as a conjunction of three simpler regex checks: one for a number, one for a letter, and one for a special character.
There was a problem hiding this comment.
added test cases and made simpler regex checks for digit,alphabet,length and special character.
Updated in commit 1703300.
|
|
||
|
|
||
| @login_required(login_url='/login/') | ||
| def role_default_permissions(request): |
There was a problem hiding this comment.
I don't think this function is logically part of this PR
There was a problem hiding this comment.
yes, removed function.
| next_url = request.POST['next'] | ||
| if (today - user_profile.last_pwd_update).days >= \ | ||
| settings.ENDAGA['PASSSWORD_EXPIRED_LAST_SEVEN_DAYS']: | ||
| text = str(user) + ' , your account will be blocked in next '\ |
There was a problem hiding this comment.
text should include words to the effect of '... unless you change your password.'
As a style point, I'd pretty much always use string formatting operator (%) rather than concatenating a bunch of strings.
There was a problem hiding this comment.
comments incorporated in commit id 1703300.
| # For example to get a list of networks the user can view: | ||
| # >>> get_objects_for_user(user_profile.user, 'view_network', klass=Network) | ||
| network = models.ForeignKey('Network', null=True, on_delete=models.SET_NULL) | ||
| network = models.ForeignKey('Network', null=True, |
There was a problem hiding this comment.
Please revert this accidental change.
|
@aricent-ccm updated the pull request - view changes |
removed spaces.
|
@aricent-ccm updated the pull request - view changes |
…tyCellularManager into sprint2_password_expiration_feature
…com/piyush-kr/CommunityCellularManager into sprint2_password_expiration_feature
kkroo
left a comment
There was a problem hiding this comment.
Looks great! Awesome test cases. Some small changes
| @@ -153,6 +153,19 @@ def __init__(self, *args, **kwargs): | |||
|
|
|||
| class ChangePasswordForm(PasswordChangeForm): | |||
There was a problem hiding this comment.
Built in validators here: https://docs.djangoproject.com/en/dev/topics/auth/passwords/#password-validation
Do you really need to override all of these fields to show a message? The validators should print their own policy text in a ValidationError on form submission.
There was a problem hiding this comment.
Thanks,yes ,As django have four default validators and they having their own policy text.
But as per our requirement we don't need UserAttributeSimilarityValidator,CommonPasswordValidator. so only NumericPasswordValidator and MinimumLengthValidator we could use.But NumericPasswordValidator only check numeric ,it doesn't check alphanumeric and they don't have validator check for special character.For that regexValidator need to use.
For all this , made custom validator custom_password_validators, which validated min_length,alphanumeric and special character. And our custom policy provided as help text.
Removed override of all those fields , added custom validators to display our policy and validate password strength.
| </style> | ||
| <html lang="en"> | ||
| <head> | ||
| <script src="https://code.jquery.com/jquery-1.12.4.js"></script> |
There was a problem hiding this comment.
We should use the same version of jquery across the project: 1.10.2
There was a problem hiding this comment.
comments incorporated in commit id 1f9e597
| if 'next' in request.POST and request.POST['next']: | ||
| next_url = request.POST['next'] | ||
| return redirect(next_url) | ||
| if user.is_active: |
There was a problem hiding this comment.
You need to check user is not None first in the case authenticate returns None
There was a problem hiding this comment.
comments incorporated in commit id 1f9e597
| return redirect("/dashboard/profile") | ||
| return HttpResponseBadRequest() | ||
|
|
||
| def validate_password_strength(password): |
There was a problem hiding this comment.
This is already built into Django. See my previous comment
There was a problem hiding this comment.
removed and now validating fields in form itself.
| tags = 'password alert alert-danger' | ||
| messages.error(request, text, extra_tags=tags) | ||
| return redirect(redirect_url) | ||
| if request.POST['old_password'] == request.POST['new_password1']: |
There was a problem hiding this comment.
You should be doing this validation in the PasswordForm using the clean_new_password1 method. See this example: https://docs.djangoproject.com/en/1.8/_modules/django/contrib/auth/forms/#SetPasswordForm
| tags = 'password alert alert-danger' | ||
| messages.error(request, text, extra_tags=tags) | ||
| return redirect(redirect_url) | ||
| if not validate_password_strength(request.POST['new_password1']): |
There was a problem hiding this comment.
This is builtin. See my comments
There was a problem hiding this comment.
added custom validators which validate in form itself
|
@9muir has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator. |
9muir
left a comment
There was a problem hiding this comment.
Not sure what's going on with the 'for' loops in the HTML templates
| </h4> | ||
| </div> | ||
| <div class='modal-body'> | ||
| {% for message in messages %} |
There was a problem hiding this comment.
Is this really a loop? I assume we're only going to prompt a single user, the one that is logged in, to change their password.
There was a problem hiding this comment.
thanks,yes, there is one message need to prompt.But as per django message framework, message it store in FallbackStorage is the default storage.As per its definition This class first uses CookieStorage for all messages, falling back to using SessionStorage for the messages that could not fit in a single cookie. Since it is uses SessionStorage, it also requires Django's contrib.sessions application.
so it seems need to iterate in for loop for displaying message in template.If we not iterate and directly shows messages, it show like
Hi <django.contrib.messages.storage.fallback. at 0x7f1b7cb75590> Please change your password.
| <div class='modal-body'> | ||
| {% for message in messages %} | ||
| <p> | ||
| {% if message.text %} {% endif %} Hi {{ message }} |
There was a problem hiding this comment.
I don't understand what this {% if ... %} {% endif %} block is doing, it looks like nothing?
There was a problem hiding this comment.
this is not required ,removed
| {% for message in messages %} | ||
| <p> | ||
| {% if message.text %} {% endif %} Hi {{ message }} | ||
| {% endfor %} |
There was a problem hiding this comment.
This is a really weird place to put the {% endfor %}, but if you remove the 'for' construct it goes away anyway.
There was a problem hiding this comment.
require to close for loop added close
,please see above comments regarding messages.storage.fallback.
| <h4>Change Password</h4> | ||
| {% crispy change_pass_form %} | ||
|
|
||
| {% for message in messages %} |
There was a problem hiding this comment.
Another 'for' loop that I don't understand. If this really is a loop there should be a comment.
There was a problem hiding this comment.
if we not give ,it's not show message.please see above comments regarding messages.storage.fallback.
|
@aricent-ccm updated the pull request - view changes - changes since last import |
|
@aricent-ccm updated the pull request - view changes - changes since last import |
|
@aricent-ccm updated the pull request - view changes - changes since last import |

Please review password expiration policy implementation which include the below features: