mirror of
https://github.com/jwinterm/modoboa.git
synced 2026-10-17 05:41:25 +02:00
Merge pull request #3561 from modoboa/FuzzyParrabellum-specialchar_pswdgenerator
Fuzzy parrabellum specialchar pswdgenerator
This commit is contained in:
@@ -24,6 +24,10 @@ const imapMigrationEnabled = computed(
|
||||
() => parametersStore.imapMigrationEnabled
|
||||
)
|
||||
|
||||
const openRspamdDashboard = () => {
|
||||
router.push(rspamdUrl.value)
|
||||
}
|
||||
|
||||
const settings = []
|
||||
const adminMenuItems = [
|
||||
{
|
||||
@@ -136,8 +140,4 @@ onMounted(() => {
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
const openRspamdDashboard = () => {
|
||||
router.push(rspamdUrl.value)
|
||||
}
|
||||
</script>
|
||||
|
||||
+25
-5
@@ -292,12 +292,32 @@ def domain_has_authorized_mx(name):
|
||||
|
||||
def make_password():
|
||||
"""Create a random password."""
|
||||
length = int(param_tools.get_global_parameter("random_password_length", app="core"))
|
||||
while True:
|
||||
password = "".join(
|
||||
random.SystemRandom().choice(string.ascii_letters + string.digits)
|
||||
for _ in range(length)
|
||||
password_length = int(
|
||||
param_tools.get_global_parameter("random_password_length", app="core")
|
||||
)
|
||||
allow_special_characters = bool(
|
||||
param_tools.get_global_parameter("allow_special_characters", app="core")
|
||||
)
|
||||
for i in range(10): # limit tries
|
||||
all_possible_chars = ""
|
||||
possible_chars_types = [string.ascii_letters, string.digits]
|
||||
certain_chars = ""
|
||||
if allow_special_characters: # add special characters in random passwd
|
||||
possible_chars_types.append(string.punctuation)
|
||||
# make it so there is always one character of each type in password
|
||||
# and then will randomize their placement
|
||||
for possible_chars in possible_chars_types:
|
||||
all_possible_chars += possible_chars
|
||||
certain_chars += random.SystemRandom().choice(possible_chars)
|
||||
password = (
|
||||
"".join(
|
||||
random.SystemRandom().choice(all_possible_chars)
|
||||
for _ in range(password_length - len(possible_chars_types))
|
||||
)
|
||||
+ certain_chars
|
||||
)
|
||||
random.shuffle(list(password))
|
||||
password = "".join(password)
|
||||
try:
|
||||
password_validation.validate_password(password)
|
||||
except ValidationError:
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
from unittest import skipIf
|
||||
import string
|
||||
|
||||
from django.test import override_settings
|
||||
from django.urls import reverse
|
||||
@@ -8,7 +9,7 @@ from modoboa.core.models import User
|
||||
from modoboa.core.tests import test_ldap
|
||||
from modoboa.lib.tests import NO_LDAP, ModoAPITestCase
|
||||
from modoboa.limits import utils as limits_utils
|
||||
from .. import factories, models
|
||||
from .. import factories, models, lib
|
||||
|
||||
|
||||
class AuthenticationTestCase(ModoAPITestCase):
|
||||
@@ -45,6 +46,32 @@ class AccountTestCase(ModoAPITestCase):
|
||||
super().setUpTestData()
|
||||
factories.populate_database()
|
||||
|
||||
def test_random_password(self):
|
||||
# Setting allow_special_characters to False
|
||||
self.localconfig.parameters.set_value("allow_special_characters", False, "core")
|
||||
random_password_length = self.localconfig.parameters.get_value(
|
||||
"random_password_length", "core"
|
||||
)
|
||||
self.localconfig.save()
|
||||
|
||||
random_password = lib.make_password()
|
||||
self.assertEqual(len(random_password), random_password_length)
|
||||
self.assertEqual(
|
||||
len([char for char in random_password if char in list(string.punctuation)]),
|
||||
0,
|
||||
)
|
||||
|
||||
# And with allow_special_characters to True
|
||||
self.localconfig.parameters.set_value("allow_special_characters", True, "core")
|
||||
self.localconfig.save()
|
||||
|
||||
random_password = lib.make_password()
|
||||
self.assertEqual(len(random_password), random_password_length)
|
||||
self.assertNotEqual(
|
||||
len([char for char in random_password if char in list(string.punctuation)]),
|
||||
0,
|
||||
)
|
||||
|
||||
def test_aliases_update_on_disable(self):
|
||||
"""Check if aliases are disabled when account is disabled."""
|
||||
account = User.objects.get(username="user@test.com")
|
||||
|
||||
@@ -75,6 +75,7 @@ class CoreGlobalParametersSerializer(serializers.Serializer):
|
||||
update_scheme = serializers.BooleanField(default=True)
|
||||
default_password = serializers.CharField(default="ChangeMe1!")
|
||||
random_password_length = serializers.IntegerField(min_value=8, default=8)
|
||||
allow_special_characters = serializers.BooleanField(default=False)
|
||||
update_password_url = serializers.URLField(required=False, allow_blank=True)
|
||||
password_recovery_msg = serializers.CharField(required=False, allow_blank=True)
|
||||
sms_password_recovery = serializers.BooleanField(default=False)
|
||||
|
||||
@@ -96,6 +96,16 @@ GLOBAL_PARAMETERS_STRUCT = collections.OrderedDict(
|
||||
),
|
||||
},
|
||||
),
|
||||
(
|
||||
"allow_special_characters",
|
||||
{
|
||||
"label": gettext_lazy("Allow special characters for random password"),
|
||||
"help_text": gettext_lazy(
|
||||
"Enable special characters in randomly generated "
|
||||
"passwords."
|
||||
),
|
||||
}
|
||||
),
|
||||
(
|
||||
"update_password_url",
|
||||
{
|
||||
|
||||
@@ -61,7 +61,7 @@ def get_dovecot_schemes():
|
||||
return [f"{{{smart_str(scheme)}}}" for scheme in schemes.split()], status
|
||||
|
||||
|
||||
def cache_available_password_hasher(bypass_cache=False):
|
||||
def cache_available_password_hasher(bypass_cache: bool = False):
|
||||
available_schemes, status = get_dovecot_schemes()
|
||||
password_scheme_choice = [
|
||||
(hasher.name, hasher.label)
|
||||
|
||||
Reference in New Issue
Block a user