mirror of
https://github.com/jwinterm/modoboa.git
synced 2026-10-23 06:38:40 +02:00
New fixes
This commit is contained in:
@@ -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(
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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.")
|
||||
|
||||
@@ -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
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -148,7 +148,7 @@ if argon2_hasher is not None:
|
||||
def __init__(
|
||||
self,
|
||||
):
|
||||
super(ARGON2IDHasher, self).__init__()
|
||||
super().__init__()
|
||||
|
||||
parameters = dict()
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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)
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -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",)
|
||||
)
|
||||
|
||||
@@ -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",)
|
||||
)
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -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"})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user