Skip to content

Commit

Permalink
Add constance settings for password validation
Browse files Browse the repository at this point in the history
  • Loading branch information
JacquelineMorrissette committed Jun 9, 2023
1 parent 2c3841f commit 6b2805e
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 3 deletions.
70 changes: 69 additions & 1 deletion kobo/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,62 @@
'having the system empty it automatically.',
'positive_int_minus_one',
),
# Toggle for ZXCVBN
'ZXCVBN_PASSWORD_VALIDATION': (
True,
'Enables the dropbox library zxcvbn for password validation',
),
# Built-in password validator
'ENABLE_MINIMUM_LENGTH_VALIDATION': (
True,
'Enable minimum length validation',
),
'MINIMUM_LENGTH_VALIDATION': (
10,
'Minimum length for all passwords',
),
# Build-in password validator
'USER_ATTRIBUTE_SIMILARITY_VALIDATOR': (
True,
"Custom user attribute similarity validation is enabled",
),
# Built-in password validator
'ENABLE_CUSTOM_COMMON_PASSWORD_VALIDATION': (
True,
'Enable adding custom common password validation',
),
'COMMON_PASSWORD_VALIDATION': (
'',
'Add to list of common passwords for password validation',
),
# Custom password Validator
'ENABLE_CUSTOM_CHARACTER_CLASSES_ENABLED': (
True,
'Enable custom character classes',
),
'MINIMUM_CUSTOM_CHARACTER_CLASS_VALIDATION': (
3,
'The minimum number of character classes which must be set'
),
'CUSTOM_CHARACTER_CLASSES_ENABLED': (
json.dumps({
'character_type_validation': [
['lower_case', '(?=(.*[A-Z]){1,})'],
['upper_case', '(?=(.*[A-Z]){1,})'],
['number', '(?=(?:\D*\d){1,})'],
['symbol', '(?=(.*[\W]){1,})'],
]
}),
# '^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]',
'Enable custom character classes for password validation. '
'List all custom character classes as a list under "character_type_validation"',
),
# Custom password1233 Validator
'MOST_RECENT_PASSWORD_VALIDATION': (
True,
'Enable most recent password validation which will prevernt the user from '
'reusing the most recent password',
),
}

CONSTANCE_ADDITIONAL_FIELDS = {
Expand Down Expand Up @@ -410,7 +466,19 @@
'SECTOR_CHOICES',
'OPERATIONAL_PURPOSE_CHOICES',
),
'Trash bin': (
'Password Validation': (
'ZXCVBN_PASSWORD_VALIDATION',
'ENABLE_MINIMUM_LENGTH_VALIDATION',
'MINIMUM_LENGTH_VALIDATION',
'USER_ATTRIBUTE_SIMILARITY_VALIDATOR',
'ENABLE_CUSTOM_COMMON_PASSWORD_VALIDATION',
'COMMON_PASSWORD_VALIDATION',
'ENABLE_CUSTOM_CHARACTER_CLASSES_ENABLED',
'MINIMUM_CUSTOM_CHARACTER_CLASS_VALIDATION',
'CUSTOM_CHARACTER_CLASSES_ENABLED',
'MOST_RECENT_PASSWORD_VALIDATION',
),
'Trashbin': (
'ASSET_SNAPSHOT_DAYS_RETENTION',
'ACCOUNT_TRASH_GRACE_PERIOD',
'PROJECT_TRASH_GRACE_PERIOD',
Expand Down
6 changes: 4 additions & 2 deletions kpi/tests/api/test_api_environment.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from kobo.apps.accounts.mfa.models import MfaAvailableToUser
from kobo.apps.hook.constants import SUBMISSION_PLACEHOLDER
from kpi.tests.base_test_case import BaseTestCase
from kpi.utils.fuzzy_int import FuzzyInt


class EnvironmentTests(BaseTestCase):
Expand Down Expand Up @@ -72,6 +73,7 @@ def setUp(self):
constance.config.FREE_TIER_THRESHOLDS
),
'social_apps': [],
'zxcvbn_password_validation': constance.config.ZXCVBN_PASSWORD_VALIDATION,
}

def _check_response_dict(self, response_dict):
Expand Down Expand Up @@ -158,12 +160,12 @@ def test_mfa_per_user_availability_while_globally_enabled_as_anonymous(self):
def test_social_apps(self):
# GET mutates state, call it first to test num queries later
self.client.get(self.url, format='json')
queries = 18
queries = FuzzyInt(19, 24)
with self.assertNumQueries(queries):
response = self.client.get(self.url, format='json')
self.assertEqual(response.status_code, status.HTTP_200_OK)
app = baker.make('socialaccount.SocialApp')
with override_settings(SOCIALACCOUNT_PROVIDERS={'microsoft': {}}):
with self.assertNumQueries(queries + 1):
with self.assertNumQueries(queries):
response = self.client.get(self.url, format='json')
self.assertContains(response, app.name)
14 changes: 14 additions & 0 deletions kpi/utils/fuzzy_int.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Source: https://lukeplant.me.uk/blog/posts/fuzzy-testing-with-assertnumqueries/
class FuzzyInt(int):
def __new__(cls, lowest: int, highest: int):
obj = super(FuzzyInt, cls).__new__(cls, highest)
obj.lowest = lowest
obj.highest = highest
return obj

def __eq__(self, other):
return other >= self.lowest and other <= self.highest

def __repr__(self):
return "[%d..%d]" % (self.lowest, self.highest)

1 change: 1 addition & 0 deletions kpi/views/environment.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ class EnvironmentView(APIView):
).exists()
)
),
'ZXCVBN_PASSWORD_VALIDATION',
]

def get(self, request, *args, **kwargs):
Expand Down

0 comments on commit 6b2805e

Please sign in to comment.