diff --git a/CHANGELOG.md b/CHANGELOG.md index 46cd2b4..be339c9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,9 @@ - Better handle values from identity data. @cekk -- Add `username_userid` User ID factory . @ericof +- Add `username_userid` User ID factory. @ericof + +- Annotate transaction in POST calls to authenticate a user. @ericof ## 1.1.2 (2023-03-15) diff --git a/src/pas/plugins/authomatic/services/authomatic.py b/src/pas/plugins/authomatic/services/authomatic.py index f3d118b..21085e2 100644 --- a/src/pas/plugins/authomatic/services/authomatic.py +++ b/src/pas/plugins/authomatic/services/authomatic.py @@ -7,11 +7,14 @@ from plone.restapi.deserializer import json_body from plone.restapi.services import Service from Products.PluggableAuthService.interfaces.plugins import IAuthenticationPlugin +from transaction.interfaces import NoTransaction from urllib.parse import parse_qsl from zope.interface import alsoProvides from zope.interface import implementer from zope.publisher.interfaces import IPublishTraverse +import transaction + @implementer(IPublishTraverse) class LoginAuthomatic(Service): @@ -189,6 +192,23 @@ def get_token(self, user) -> str: token = plugin.create_token(user.getId(), data=payload) return token + def _annotate_transaction(self, action, user): + """Add a note to the current transaction.""" + try: + # Get the current transaction + tx = transaction.get() + except NoTransaction: + return None + # Set user on the transaction + tx.setUser(user.getUser()) + user_info = user.getProperty("fullname") or user.getUserName() + msg = "" + if action == "login": + msg = f"(Logged in {user_info})" + elif action == "add_identity": + msg = f"(Added new identity to user {user_info})" + tx.note(msg) + def reply(self) -> dict: """Process OAuth callback, authenticate the user and return a JWT Token. @@ -219,12 +239,15 @@ def reply(self) -> dict: alsoProvides(self.request, IDisableCSRFProtection) if api.user.is_anonymous(): self._remember_identity(result) + action = "login" else: # Authenticated user, add an identity to it self._add_identity(result) + action = "add_identity" user = api.user.get_current() # Make sure we are not setting cookies here # as it will break the authentication mechanism with JWT tokens self.request.response.cookies = {} token = self.get_token(user) + self._annotate_transaction(action, user=user) return {"token": token}