auth_oidc: do not use logging inside a failed transaction (#84540)
gitea/authentic/pipeline/head This commit looks good Details

This commit is contained in:
Benjamin Dauvergne 2023-12-11 13:22:50 +01:00
parent c582103077
commit 5bb21a7b63
1 changed files with 24 additions and 16 deletions

View File

@ -23,7 +23,7 @@ from django.contrib import messages
from django.contrib.auth import get_user_model
from django.contrib.auth.backends import ModelBackend
from django.db import IntegrityError
from django.db.transaction import atomic, set_rollback
from django.db.transaction import atomic
from django.utils.timezone import now
from django.utils.translation import gettext as _
from jwcrypto.jwk import JWK
@ -38,17 +38,34 @@ from authentic2.utils.template import evaluate_condition_template
from . import models, utils
logger = logging.getLogger(__name__)
class AlreadyLinked(Exception):
def __init__(self, email):
self.email = email
class OIDCBackend(ModelBackend):
# pylint: disable=arguments-renamed
def authenticate(self, request, access_token=None, id_token=None, nonce=None, provider=None):
with atomic():
return self._authenticate(
request, access_token=access_token, id_token=id_token, nonce=nonce, provider=provider
)
try:
with atomic():
return self._authenticate(
request, access_token=access_token, id_token=id_token, nonce=nonce, provider=provider
)
except AlreadyLinked as e:
logger.warning('auth_oidc: email %s is already linked to another provider.', e.email)
if request:
messages.warning(
request,
_(
'Your email is already linked to another SSO account, please contact an administrator.'
),
)
return None
def _authenticate(self, request, access_token=None, id_token=None, nonce=None, provider=None):
logger = logging.getLogger(__name__)
if None in (id_token, provider):
return
original_id_token = id_token
@ -309,16 +326,7 @@ class OIDCBackend(ModelBackend):
provider=provider, user=user, defaults={'sub': id_token.sub}
)
except IntegrityError:
set_rollback(True)
logger.warning('auth_oidc: email %s is already linked to another provider.', email)
if request:
messages.warning(
request,
_(
'Your email is already linked to another SSO account, please contact an administrator.'
),
)
return None
raise AlreadyLinked(email=email)
if not created and oidc_account.sub != id_token.sub:
logger.info(