mirror of
https://github.com/jwinterm/modoboa.git
synced 2026-10-17 05:41:25 +02:00
Fixed wrong way to check for passwords using deprecated scheme.
see #3350
This commit is contained in:
+1
-1
@@ -168,7 +168,7 @@ Update your :file:`settings.py` file with following content:
|
||||
"ckeditor.W001", # CKEditor 4.22.1 warning
|
||||
]
|
||||
|
||||
This will silence a `warning sent by django-ckeditor <https://github.com/modoboa/modoboa/issues/3316>_`.
|
||||
This will silence a `warning sent by django-ckeditor <https://github.com/modoboa/modoboa/issues/3316>`_.
|
||||
|
||||
Version 2.3.0
|
||||
=============
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
'The password scheme you are using has been deprecated and will be removed in the next minor version. The procedure to upgrade to a stronger scheme is as follows:'
|
||||
)
|
||||
}}
|
||||
<ol>
|
||||
<ol class="mt-4">
|
||||
<li
|
||||
v-html="
|
||||
$gettext(
|
||||
@@ -65,6 +65,24 @@
|
||||
"
|
||||
></li>
|
||||
</ol>
|
||||
<p
|
||||
class="mt-4"
|
||||
v-html="
|
||||
$gettext(
|
||||
'You must apply this procedure <strong>BEFORE</strong> you install a newest version of Modoboa, otherwise <strong>you will be unable to connect to the web interface anymore</strong>.',
|
||||
true
|
||||
)
|
||||
"
|
||||
></p>
|
||||
<p
|
||||
class="mt-4"
|
||||
v-html="
|
||||
$gettext(
|
||||
'Please note that you will see this message until <strong>ALL</strong> user passwords have been converted using the new scheme.',
|
||||
true
|
||||
)
|
||||
"
|
||||
></p>
|
||||
</template>
|
||||
</v-alert>
|
||||
</v-card-text>
|
||||
|
||||
@@ -2,9 +2,10 @@ from django.core.checks import register, Info, Warning
|
||||
from django.conf import settings
|
||||
from django.utils.translation import gettext as _
|
||||
|
||||
from modoboa.core.models import User
|
||||
from modoboa.core.password_hashers import get_configured_password_hasher
|
||||
from modoboa.core.utils import generate_rsa_private_key
|
||||
from modoboa.core.utils import (
|
||||
check_for_deprecated_password_schemes,
|
||||
generate_rsa_private_key,
|
||||
)
|
||||
|
||||
W001 = Warning(
|
||||
_(
|
||||
@@ -49,7 +50,7 @@ def check_rsa_private_key_exists(app_configs, **kwargs):
|
||||
@register()
|
||||
def check_password_hasher(app_configs, **kwargs):
|
||||
msgs = []
|
||||
hasher = get_configured_password_hasher()
|
||||
if hasher.deprecated or User.objects.is_password_scheme_in_use(hasher):
|
||||
hasher = check_for_deprecated_password_schemes()
|
||||
if hasher:
|
||||
msgs.append(W002)
|
||||
return msgs
|
||||
|
||||
@@ -12,7 +12,7 @@ from django.urls import reverse
|
||||
from django.utils.encoding import smart_str
|
||||
from django.utils.translation import gettext as _
|
||||
|
||||
from modoboa.core.password_hashers import get_configured_password_hasher
|
||||
from modoboa.core.utils import check_for_deprecated_password_schemes
|
||||
from modoboa.lib import exceptions, permissions
|
||||
from modoboa.lib.signals import get_request
|
||||
from . import models, signals as core_signals, utils
|
||||
@@ -132,13 +132,13 @@ def check_for_new_versions(sender, include_all: bool, **kwargs) -> list:
|
||||
]
|
||||
elif include_all:
|
||||
result += [{"id": "newversionavailable"}]
|
||||
hasher = get_configured_password_hasher()
|
||||
if hasher.deprecated or models.User.objects.is_password_scheme_in_use(hasher):
|
||||
hasher = check_for_deprecated_password_schemes()
|
||||
if hasher:
|
||||
result += [
|
||||
{
|
||||
"id": "deprecatedpasswordscheme",
|
||||
"url": reverse("core:index") + "#info/",
|
||||
"text": _("You are using a deprecated password scheme (%s)")
|
||||
"text": _("You are still using a deprecated password scheme (%s)")
|
||||
% hasher.name,
|
||||
"level": "warning",
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ def get_default_language() -> str:
|
||||
class UserManager(BaseUserManager):
|
||||
"""Custom manager for User."""
|
||||
|
||||
def is_password_scheme_in_use(self, password_hasher: PasswordHasher) -> bool:
|
||||
def is_password_scheme_in_use(self, password_hasher: type[PasswordHasher]) -> bool:
|
||||
"""Check if given password scheme is still in use."""
|
||||
return (
|
||||
self.get_queryset()
|
||||
|
||||
@@ -18,7 +18,7 @@ from modoboa.core.password_hashers.base import ( # NOQA:F401
|
||||
from modoboa.parameters import tools as param_tools
|
||||
|
||||
|
||||
def get_password_hasher(scheme: str) -> PasswordHasher:
|
||||
def get_password_hasher(scheme: str) -> type[PasswordHasher]:
|
||||
"""Retrieve the hasher corresponding to :keyword:`scheme`.
|
||||
|
||||
If no class is found, `PLAINHasher` is returned.
|
||||
@@ -35,7 +35,7 @@ def get_password_hasher(scheme: str) -> PasswordHasher:
|
||||
return hasher
|
||||
|
||||
|
||||
def get_configured_password_hasher() -> PasswordHasher:
|
||||
def get_configured_password_hasher() -> type[PasswordHasher]:
|
||||
"""Retrieve the password hasher class currently configured."""
|
||||
scheme = param_tools.get_global_parameter("password_scheme")
|
||||
return get_password_hasher(scheme)
|
||||
|
||||
@@ -104,10 +104,15 @@ class PasswordHasher(metaclass=MetaHasher):
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
def get_password_hashers(cls):
|
||||
def get_password_hashers(cls) -> list[type["PasswordHasher"]]:
|
||||
"""Return all the PasswordHasher supported by Modoboa"""
|
||||
return [hasher for hasher in cls.__subclasses__()]
|
||||
|
||||
@classmethod
|
||||
def get_deprecated_password_hashers(cls) -> list[type["PasswordHasher"]]:
|
||||
"""Return all the PasswordHasher supported by Modoboa and marked as deprecated."""
|
||||
return [hasher for hasher in cls.__subclasses__() if hasher.deprecated]
|
||||
|
||||
|
||||
class PLAINHasher(PasswordHasher):
|
||||
"""
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{% load i18n core_tags lib_tags %}
|
||||
<h2>{% trans "Information" %} <small>{% trans "Various information about Modoboa" %}</small></h2><hr>
|
||||
{% if password_hasher.deprecated or password_hasher_in_use %}
|
||||
{% if password_hasher %}
|
||||
<div class="alert alert-block alert-warning">
|
||||
<h4>{% trans "You are using a deprecated password scheme!" %}</h4>
|
||||
<p>{% blocktranslate trimmed %}
|
||||
@@ -20,6 +20,7 @@
|
||||
version of Modoboa, otherwise <strong>you will be unable to connect to
|
||||
the web interface anymore</strong>.
|
||||
{% endblocktranslate %}</p>
|
||||
<p>{% blocktranslate trimmed %}Please note that you will see this message until <strong>ALL</strong> user passwords have been converted using the new scheme.{% endblocktranslate %}</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if update_avail %}
|
||||
|
||||
+17
-2
@@ -1,15 +1,18 @@
|
||||
"""Utility functions."""
|
||||
|
||||
from pkg_resources import parse_version
|
||||
import os
|
||||
import environ
|
||||
import os
|
||||
from pkg_resources import parse_version
|
||||
from typing import Optional
|
||||
|
||||
from cryptography.hazmat.primitives import serialization
|
||||
from cryptography.hazmat.primitives.asymmetric import rsa
|
||||
|
||||
from django.utils.translation import gettext as _
|
||||
|
||||
from modoboa.core import models
|
||||
from modoboa.core.extensions import exts_pool
|
||||
from modoboa.core.password_hashers import get_configured_password_hasher, PasswordHasher
|
||||
from modoboa.lib.api_client import ModoAPIClient
|
||||
|
||||
|
||||
@@ -85,3 +88,15 @@ def generate_rsa_private_key(storage_path: str) -> bool:
|
||||
with open(env_path, "wb") as fp:
|
||||
fp.write(b'OIDC_RSA_PRIVATE_KEY="' + content + b'"\n')
|
||||
return True
|
||||
|
||||
|
||||
def check_for_deprecated_password_schemes() -> Optional[type[PasswordHasher]]:
|
||||
"""Check if deprecated password scheme is still in use."""
|
||||
hasher = get_configured_password_hasher()
|
||||
if hasher.deprecated:
|
||||
return hasher
|
||||
deprecated_hashers = PasswordHasher.get_deprecated_password_hashers()
|
||||
for dhasher in deprecated_hashers:
|
||||
if models.User.objects.is_password_scheme_in_use(dhasher):
|
||||
return dhasher
|
||||
return None
|
||||
|
||||
@@ -7,9 +7,8 @@ from django.shortcuts import render
|
||||
from django.template.loader import render_to_string
|
||||
from django.utils.translation import gettext as _
|
||||
|
||||
from modoboa.core.models import Log, User
|
||||
from modoboa.core.password_hashers import get_configured_password_hasher
|
||||
from modoboa.core.utils import check_for_updates
|
||||
from modoboa.core.models import Log
|
||||
from modoboa.core.utils import check_for_updates, check_for_deprecated_password_schemes
|
||||
from modoboa.lib.listing import get_listing_page, get_sort_order
|
||||
from modoboa.lib.web_utils import render_to_json_response
|
||||
from modoboa.parameters import tools as param_tools
|
||||
@@ -61,8 +60,7 @@ def parameters(request, tplname="core/parameters.html"):
|
||||
@user_passes_test(lambda u: u.is_superuser)
|
||||
def information(request, tplname="core/information.html"):
|
||||
status, extensions = check_for_updates()
|
||||
hasher = get_configured_password_hasher()
|
||||
password_hasher_in_use = User.objects.is_password_scheme_in_use(hasher)
|
||||
hasher = check_for_deprecated_password_schemes()
|
||||
return render_to_json_response(
|
||||
{
|
||||
"content": render_to_string(
|
||||
@@ -71,8 +69,7 @@ def information(request, tplname="core/information.html"):
|
||||
"update_avail": status,
|
||||
"extensions": extensions,
|
||||
"password_hasher": hasher,
|
||||
"password_hasher_in_use": password_hasher_in_use,
|
||||
"scheme": hasher.name,
|
||||
"scheme": hasher.name if hasher else "",
|
||||
},
|
||||
),
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user