Files
modoboa/modoboa/core/api/v2/views.py
T

70 lines
2.6 KiB
Python

"""Core API v2 views."""
import logging
from django.utils.html import escape
from django.utils.translation import ugettext as _
from rest_framework import response, status
from rest_framework_simplejwt import views as jwt_views
from rest_framework_simplejwt.exceptions import InvalidToken, TokenError
from modoboa.core.password_hashers import get_password_hasher
from modoboa.parameters import tools as param_tools
logger = logging.getLogger("modoboa.auth")
class TokenObtainPairView(jwt_views.TokenObtainPairView):
"""We overwrite this view to deal with password scheme update."""
def post(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
try:
serializer.is_valid(raise_exception=True)
except TokenError as e:
logger.warning(
_("Failed connection attempt from '%s' as user '%s'"),
request.META["REMOTE_ADDR"],
escape(serializer.data["username"])
)
raise InvalidToken(e.args[0])
user = serializer.user
logger.info(
_("User '%s' successfully logged in"), user.username
)
if user and user.is_active:
condition = (
user.is_local and
param_tools.get_global_parameter(
"update_scheme", raise_exception=False)
)
if condition:
# check if password scheme is correct
scheme = param_tools.get_global_parameter(
"password_scheme", raise_exception=False)
# use SHA512CRYPT as default fallback
if scheme is None:
pwhash = get_password_hasher("sha512crypt")()
else:
pwhash = get_password_hasher(scheme)()
if not user.password.startswith(pwhash.scheme):
logger.info(
_("Password scheme mismatch. Updating %s password"),
user.username
)
user.set_password(request.data["password"])
user.save()
if pwhash.needs_rehash(user.password):
logger.info(
_("Password hash parameter missmatch. "
"Updating %s password"),
user.username
)
user.set_password(serializer.data["password"])
user.save()
return response.Response(
serializer.validated_data, status=status.HTTP_200_OK)