-
Notifications
You must be signed in to change notification settings - Fork 33
password expiration policy - DO NOT MERGE #36
base: master
Are you sure you want to change the base?
Changes from all commits
00837c8
1703300
1df4510
d807abc
bf966a7
1f9e597
094d531
a8319a1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -77,7 +77,10 @@ class UserProfile(models.Model): | |
| # because a user may have permissions on other Network instances. | ||
| # 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, | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please revert this accidental change.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. reverted. |
||
| on_delete=models.SET_NULL) | ||
| # Added for Password Expiry | ||
| last_pwd_update = models.DateTimeField(auto_now=True) | ||
|
|
||
| def __str__(self): | ||
| return "%s's profile" % self.user | ||
|
|
@@ -1466,8 +1469,7 @@ class ConfigurationKey(models.Model): | |
| Can be associated with many things. | ||
| """ | ||
| bts = models.ForeignKey(BTS, null=True, blank=True, on_delete=models.CASCADE) | ||
| network = models.ForeignKey(Network, null=True, blank=True, | ||
| on_delete=models.CASCADE) | ||
| network = models.ForeignKey(Network, null=True, blank=True, on_delete=models.CASCADE) | ||
| category = models.TextField() # "endaga", "openbts", etc.. | ||
| key = models.TextField() | ||
| value = models.TextField() | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -41,7 +41,7 @@ | |
| from endagaweb.models import Subscriber | ||
| from endagaweb.models import UsageEvent | ||
| from endagaweb.models import SystemEvent | ||
| from endagaweb.models import TimeseriesStat | ||
| from endagaweb.models import TimeseriesStat, UserProfile | ||
| from endagaweb.ic_providers.nexmo import NexmoProvider | ||
|
|
||
|
|
||
|
|
@@ -439,3 +439,17 @@ def req_bts_log(self, obj, retry_delay=60*10, max_retries=432): | |
| raise | ||
| finally: | ||
| obj.save() | ||
|
|
||
| @app.task(bind=True) | ||
| def block_user(self): | ||
| """ Block User if User password is not updated | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please make the comment reflect the fact that the number of days is configured in a setting.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. comments incorporated in commit id 1703300. |
||
| for last number of days which is configured in a settings . | ||
| """ | ||
| password_expired_duration = (django.utils.timezone.now() - | ||
| datetime.timedelta( | ||
| days=settings.ENDAGA['PASSWORD_EXPIRED_DAY'])) | ||
| user_profiles = UserProfile.objects.filter(last_pwd_update__lte=password_expired_duration) | ||
| for user_profile in user_profiles: | ||
| user_profile.user.is_active = False | ||
| print '%s user is Blocked!' % user_profile.user.username | ||
| user_profile.user.save() | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -23,6 +23,56 @@ | |
| display: none; | ||
| } | ||
| </style> | ||
| <html lang="en"> | ||
| <head> | ||
| <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script> | ||
| <script> | ||
|
|
||
| $(document).ready(function(){ | ||
| $("#dialog").modal('show'); | ||
| }); | ||
|
|
||
| </script> | ||
| </head> | ||
| <body> | ||
| {% if messages %} | ||
| <div class='modal fade' id='dialog'> | ||
| <div class='modal-dialog'> | ||
| <div class='modal-content'> | ||
| <div class='modal-header'> | ||
| <button type="button" class="close" data-dismiss="modal" aria-label="Close"> | ||
| <span aria-hidden="true">×</span> | ||
| </button> | ||
| <h4 class='modal-title'> | ||
| Password Expiry Status | ||
| </h4> | ||
| </div> | ||
| <div class='modal-body'> | ||
| {% for message in messages %} | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 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.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 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. |
||
| <p> | ||
| Hi {{ message }} | ||
| </p> | ||
| {% endfor %} | ||
| <p> | ||
| <strong> | ||
| Please change your password. | ||
| </strong> | ||
| </p> | ||
| </div> | ||
| <div class='modal-footer'> | ||
| <button type='button' class='btn btn-default' data-dismiss='modal'>Cancel</button> | ||
| <a href='/password/change' class='btn btn-primary' type='button'>Change Password</a> | ||
|
|
||
| </div> | ||
| </div> | ||
| </div> | ||
| </div> | ||
|
|
||
|
|
||
| {% endif %} | ||
| </div> | ||
| </body> | ||
|
|
||
| {% endblock %} | ||
|
|
||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| {% extends "dashboard/layout.html" %} | ||
| {% comment %} | ||
| Copyright (c) 2016-present, Facebook, Inc. | ||
| All rights reserved. | ||
|
|
||
| This source code is licensed under the BSD-style license found in the | ||
| LICENSE file in the root directory of this source tree. An additional grant | ||
| of patent rights can be found in the PATENTS file in the same directory. | ||
| {% endcomment %} | ||
| {% load apptags %} | ||
| {% load crispy_forms_tags %} | ||
|
|
||
| {% block title %} {% tmpl_const "SITENAME" %} | Monitor Usage, Pay Bills {% endblock %} | ||
|
|
||
| {% block content %} | ||
|
|
||
| <div class="row"> | ||
| <div class="col-xs-12 page-header"> | ||
| <h3>Hi {{ user_profile.display_name }}!</h3> | ||
| </div> | ||
| </div> | ||
|
|
||
| <div class="row"> | ||
|
|
||
| <div class='col-xs-12 col-sm-6 col-md-4 col-xl-2'> | ||
| <h4>Change Password</h4> | ||
| {% crispy change_pass_form %} | ||
| {% for message in messages %} | ||
| {% if 'password' in message.tags %} | ||
| <div class="{{ message.tags }} message">{{ message }}</div> | ||
| {% endif %} | ||
| {% endfor %} | ||
| </div> | ||
| </div> | ||
|
|
||
|
|
||
| {% endblock %} |
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.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
commitId:1f9e597e4ffae62e4e54c4447c02bc4e7f3a1232
