New fixes

This commit is contained in:
Antoine Nguyen
2025-02-18 16:15:44 +01:00
parent db0b7eb79d
commit 4458e82c25
92 changed files with 298 additions and 309 deletions
+2 -2
View File
@@ -45,7 +45,7 @@ class AccountViewSet(GetThrottleViewsetMixin, viewsets.ViewSet):
device = StaticDevice.objects.create(
user=request.user, name=f"{request.user} static device"
)
for cpt in range(10):
for _cpt in range(10):
token = StaticToken.random_token()
device.token_set.create(token=token)
django_otp.login(self.request, request.user.totpdevice_set.first())
@@ -82,7 +82,7 @@ class AccountViewSet(GetThrottleViewsetMixin, viewsets.ViewSet):
if device is None:
return response.Response({"error": _("2FA is not enabled")}, status=403)
device.token_set.all().delete()
for cpt in range(10):
for _cpt in range(10):
token = StaticToken.random_token()
device.token_set.create(token=token)
return response.Response(
+6 -6
View File
@@ -180,21 +180,21 @@ class CoreGlobalParametersSerializer(serializers.Serializer):
try:
value % {"user": "toto"}
except (KeyError, ValueError):
raise serializers.ValidationError(_("Invalid syntax"))
raise serializers.ValidationError(_("Invalid syntax")) from None
return value
def validate_ldap_sync_account_dn_template(self, value):
try:
value % {"user": "toto"}
except (KeyError, ValueError):
raise serializers.ValidationError(_("Invalid syntax"))
raise serializers.ValidationError(_("Invalid syntax")) from None
return value
def validate_ldap_search_filter(self, value):
try:
value % {"user": "toto"}
except (KeyError, ValueError, TypeError):
raise serializers.ValidationError(_("Invalid syntax"))
raise serializers.ValidationError(_("Invalid syntax")) from None
return value
def validate_rounds_number(self, value):
@@ -416,7 +416,7 @@ class PasswordRecoverySmsConfirmSerializer(serializers.Serializer):
except KeyError:
raise CustomValidationError(
{"reason": "totp secret not set in session"}, 403
)
) from None
if not oath.accept_totp(self.context["totp_secret"], data["sms_totp"])[0]:
raise CustomValidationError({"reason": "Wrong totp"}, 400)
@@ -445,7 +445,7 @@ class PasswordRecoverySmsResendSerializer(serializers.Serializer):
except KeyError:
raise CustomValidationError(
{"reason": "totp secret not set in session"}, status.HTTP_403_FORBIDDEN
)
) from None
# Attempt to get user, will raise an error if pk is not valid
self.context["user"] = User.objects.filter(
@@ -501,7 +501,7 @@ class PasswordRecoveryConfirmSerializer(serializers.Serializer):
try:
password_validation.validate_password(data["new_password1"], user)
except djangoValidationError as e:
raise PasswordRequirementsFailure(e.messages)
raise PasswordRequirementsFailure(e.messages) from None
self.context["user"] = user
return super().validate(data)
+5 -8
View File
@@ -512,7 +512,7 @@ class GeneralParametersForm(param_forms.AdminParametersForm):
}
def __init__(self, *args, **kwargs):
super(GeneralParametersForm, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)
self.fields["default_top_redirection"].choices = enabled_applications()
self._add_visibilty_rules(sms_backends.get_all_backend_visibility_rules())
self.fields["password_scheme"].choices = get_password_scheme()
@@ -532,7 +532,7 @@ class GeneralParametersForm(param_forms.AdminParametersForm):
try:
tpl % {"user": "toto"}
except (KeyError, ValueError):
raise forms.ValidationError(_("Invalid syntax"))
raise forms.ValidationError(_("Invalid syntax")) from None
return tpl
def clean_ldap_sync_account_dn_template(self):
@@ -540,7 +540,7 @@ class GeneralParametersForm(param_forms.AdminParametersForm):
try:
tpl % {"user": "toto"}
except (KeyError, ValueError):
raise forms.ValidationError(_("Invalid syntax"))
raise forms.ValidationError(_("Invalid syntax")) from None
return tpl
def clean_ldap_search_filter(self):
@@ -548,7 +548,7 @@ class GeneralParametersForm(param_forms.AdminParametersForm):
try:
ldap_filter % {"user": "toto"}
except (KeyError, ValueError, TypeError):
raise forms.ValidationError(_("Invalid syntax"))
raise forms.ValidationError(_("Invalid syntax")) from None
return ldap_filter
def clean_rounds_number(self):
@@ -613,10 +613,7 @@ class GeneralParametersForm(param_forms.AdminParametersForm):
{"first_name": "givenName", "email": "mail", "last_name": "sn"},
)
ldap_uri = "ldaps://" if values["ldap_secured"] == "ssl" else "ldap://"
ldap_uri += "%s:%s" % (
values[backend.srv_address_setting_name],
values[backend.srv_port_setting_name],
)
ldap_uri += f"{values[backend.srv_address_setting_name]}:{values[backend.srv_port_setting_name]}"
setattr(settings, backend.setting_fullname("SERVER_URI"), ldap_uri)
if values["ldap_secured"] == "starttls":
setattr(settings, backend.setting_fullname("START_TLS"), True)
+7 -6
View File
@@ -25,7 +25,7 @@ class Command:
{"BACKEND": ("django.template.backends.django.DjangoTemplates")}
]
)
self._templates_dir = "%s/templates" % os.path.dirname(__file__)
self._templates_dir = f"{os.path.dirname(__file__)}/templates"
def _render_template(self, tplfile, env):
"""Render an HTML template."""
@@ -70,7 +70,7 @@ def scan_for_commands(dirname=""):
else:
cmdclassname = cmdname.capitalize()
try:
cmdclass = getattr(cmdmod, "%sCommand" % cmdclassname)
cmdclass = getattr(cmdmod, f"{cmdclassname}Command")
except AttributeError:
continue
result[cmdname] = cmdclass
@@ -83,9 +83,10 @@ def handle_command_line():
parser = argparse.ArgumentParser(
description="A set of utilities to ease the installation of Modoboa.",
epilog="""Available commands:
%s
"""
% "\n".join(["\t%s" % c for c in sorted(commands)]),
{}
""".format(
"\n".join([f"\t{c}" for c in sorted(commands)])
),
)
parser.add_argument(
"--verbose", action="store_true", help="Activate verbose output"
@@ -94,7 +95,7 @@ def handle_command_line():
(args, remaining) = parser.parse_known_args()
if args.command not in commands:
print("Unknown command '%s'" % args.command, file=sys.stderr)
print(f"Unknown command '{args.command}'", file=sys.stderr)
sys.exit(1)
commands[args.command](commands, verbose=args.verbose).run(remaining)
+3 -3
View File
@@ -8,14 +8,14 @@ class HelpCommand(Command):
help = "Display the help message associated to a specific command" # NOQA:A003
def __init__(self, *args, **kwargs):
super(HelpCommand, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)
self._parser.add_argument("name", type=str, help="A command name")
def handle(self, parsed_args):
if parsed_args.name not in self._commands:
print("Unknown command: %s" % parsed_args.name, file=sys.stderr)
print(f"Unknown command: {parsed_args.name}", file=sys.stderr)
sys.exit(1)
cmd = self._commands[parsed_args.name](self._commands)
cmd._parser.prog = "modoboa-admin.py %s" % parsed_args.name
cmd._parser.prog = f"modoboa-admin.py {parsed_args.name}"
cmd._parser.description = cmd.help
cmd._parser.print_help()
+1 -1
View File
@@ -133,7 +133,7 @@ class APIAccessForm(forms.Form):
def __init__(self, *args, **kwargs):
"""Initialize form."""
user = kwargs.pop("user")
super(APIAccessForm, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)
self.fields["enable_api_access"].initial = hasattr(user, "auth_token")
@@ -38,7 +38,7 @@ class Command(BaseCommand):
self.verbose = options["verbose"]
log_maximum_age = param_tools.get_global_parameter("log_maximum_age")
self.__vprint("Deleting logs older than %d days..." % log_maximum_age)
self.__vprint(f"Deleting logs older than {log_maximum_age} days...")
limit = timezone.now() - datetime.timedelta(log_maximum_age)
Log.objects.filter(date_created__lt=limit).delete()
self.__vprint("Done.")
+6 -4
View File
@@ -373,15 +373,17 @@ class User(AbstractUser):
if len(row) < 8 or not row[7].strip():
raise BadRequest(
_(
"The simple user '%s' must have a valid email address"
% self.username
"The simple user '{}' must have a valid email address".format(
self.username
)
)
)
if self.username != row[7].strip():
raise BadRequest(
_(
"username and email fields must not differ for '%s'"
% self.username
"username and email fields must not differ for '{}'".format(
self.username
)
)
)
+1 -1
View File
@@ -28,7 +28,7 @@ def get_password_hasher(scheme: str) -> type[PasswordHasher]:
"""
try:
scheme = scheme.replace("-", "")
hasher = globals()["%sHasher" % scheme.upper()]
hasher = globals()[f"{scheme.upper()}Hasher"]
except KeyError:
hasher = PLAINHasher
return hasher
+1 -1
View File
@@ -148,7 +148,7 @@ if argon2_hasher is not None:
def __init__(
self,
):
super(ARGON2IDHasher, self).__init__()
super().__init__()
parameters = dict()
+1 -1
View File
@@ -80,7 +80,7 @@ class PasswordHasher(metaclass=MetaHasher):
:return: encrypted password
"""
pwhash = self._b64encode(self._encrypt(force_str(clearvalue)))
return "%s%s" % (self.scheme, force_str(pwhash))
return f"{self.scheme}{force_str(pwhash)}"
def verify(self, clearvalue, hashed_value):
"""Verify a password against a hashed value.
+6 -7
View File
@@ -181,7 +181,7 @@ def colorize_level(level):
}
if level not in classes:
return level
return "<p class='%s'>%s</p>" % (classes[level], level)
return f"<p class='{classes[level]}'>{level}</p>"
@register.filter
@@ -238,7 +238,7 @@ def connected_users(parser, token):
except ValueError:
raise template.TemplateSyntaxError(
"connected_users usage: {% connected_users as users %}"
)
) from None
return ConnectedUsers(varname)
@@ -279,14 +279,13 @@ def display_messages(msgs):
timeout = "undefined"
return mark_safe(
"""
f"""
<script type="text/javascript">
$(document).ready(function() {
$('body').notify('%s', '%s', %s);
});
$(document).ready(function() {{
$('body').notify('{level}', '{text}', {timeout});
}});
</script>
"""
% (level, text, timeout)
)
+3 -3
View File
@@ -21,7 +21,7 @@ class AuthenticationTestCase(ModoTestCase):
@classmethod
def setUpTestData(cls): # NOQA:N802
"""Create test data."""
super(AuthenticationTestCase, cls).setUpTestData()
super().setUpTestData()
cls.account = factories.UserFactory(
username="user@test.com", groups=("SimpleUsers",)
)
@@ -115,7 +115,7 @@ class ProfileTestCase(ModoTestCase):
@classmethod
def setUpTestData(cls): # NOQA:N802
"""Create test data."""
super(ProfileTestCase, cls).setUpTestData()
super().setUpTestData()
cls.account = factories.UserFactory(
username="user@test.com", groups=("SimpleUsers",)
)
@@ -231,7 +231,7 @@ class APIAccessFormTestCase(ModoTestCase):
@classmethod
def setUpTestData(cls): # NOQA:N802
"""Create test data."""
super(APIAccessFormTestCase, cls).setUpTestData()
super().setUpTestData()
cls.account = factories.UserFactory(
username="user@test.com", groups=("SimpleUsers",)
)
+2 -2
View File
@@ -84,7 +84,7 @@ class LDAPAuthenticationTestCase(LDAPTestCaseMixin, ModoTestCase):
def setUp(self):
"""Create test data."""
super(LDAPAuthenticationTestCase, self).setUp()
super().setUp()
self.activate_ldap_authentication()
def check_created_user(self, username, group="SimpleUsers", with_mb=True):
@@ -142,7 +142,7 @@ class ProfileTestCase(LDAPTestCaseMixin, ModoTestCase):
@classmethod
def setUpTestData(cls): # NOQA:N802
"""Create test data."""
super(ProfileTestCase, cls).setUpTestData()
super().setUpTestData()
cls.account = factories.UserFactory(
username="user@test.com", groups=("SimpleUsers",)
)
+3 -3
View File
@@ -148,7 +148,7 @@ class DashboardTestCase(ModoTestCase):
@classmethod
def setUpTestData(cls): # NOQA:N802
"""Create some data."""
super(DashboardTestCase, cls).setUpTestData()
super().setUpTestData()
cls.dadmin = factories.UserFactory(
username="admin@test.com", groups=("DomainAdmins",)
)
@@ -317,13 +317,13 @@ class PreferencesTestCase(ModoTestCase):
@classmethod
def setUpClass(cls):
"""Register user form."""
super(PreferencesTestCase, cls).setUpClass()
super().setUpClass()
param_tools.registry.add("user", UserSettings, "Test")
@classmethod
def tearDownClass(cls):
"""Remove user class."""
super(PreferencesTestCase, cls).tearDownClass()
super().tearDownClass()
del param_tools.registry._registry["user"]["core"]
def test_get_user_index(self):
+1 -1
View File
@@ -88,7 +88,7 @@ def get_logs_page(request, page_id=None):
if page_id is None:
return None
return get_listing_page(
Log.objects.all().order_by("%s%s" % (sort_dir, sort_order)), page_id
Log.objects.all().order_by(f"{sort_dir}{sort_order}"), page_id
)
+8 -9
View File
@@ -141,11 +141,10 @@ class LoginView(LoginViewMixin, auth_views.LoginView):
def form_invalid(self, form):
# FIXME: should we return a 401 as before ?
self.logger.warning(
"Failed connection attempt from '%(addr)s' as user '%(user)s'"
% {
"addr": self.request.META["REMOTE_ADDR"],
"user": escape(form.cleaned_data["username"]),
}
"Failed connection attempt from '{addr}' as user '{user}'".format(
addr=self.request.META["REMOTE_ADDR"],
user=escape(form.cleaned_data["username"]),
)
)
return self.render_to_response(self.get_context_data(form=form), status=401)
@@ -220,7 +219,7 @@ class VerifySMSCodeView(generic.FormView):
try:
kwargs.update({"totp_secret": self.request.session["totp_secret"]})
except KeyError:
raise Http404
raise Http404 from None
return kwargs
def form_valid(self, form):
@@ -241,11 +240,11 @@ class ResendSMSCodeView(generic.View):
"sms_password_recovery"
)
if not sms_password_recovery:
raise Http404
raise Http404 from None
try:
user = models.User._default_manager.get(pk=self.request.session["user_pk"])
except KeyError:
raise Http404
raise Http404 from None
backend = sms_backends.get_active_backend(self.request.localconfig.parameters)
secret = cryptutils.random_hex_key(20)
code = oath.totp(secret)
@@ -255,7 +254,7 @@ class ResendSMSCodeView(generic.View):
)
)
if not backend.send(text, [user.phone_number]):
raise Http404
raise Http404 from None
self.request.session["totp_secret"] = secret
return JsonResponse({"status": "ok"})