Skip to content

Commit

Permalink
fix(auth): API token cookie match token expiration
Browse files Browse the repository at this point in the history
  • Loading branch information
rpatterson committed Dec 27, 2021
1 parent c707805 commit eeb0b5b
Showing 1 changed file with 27 additions and 3 deletions.
30 changes: 27 additions & 3 deletions src/plone/restapi/pas/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from AccessControl.SecurityInfo import ClassSecurityInfo
from BTrees.OIBTree import OIBTree
from BTrees.OOBTree import OOBTree
from DateTime import DateTime
from datetime import datetime
from datetime import timedelta
from plone.keyring.interfaces import IKeyManager
Expand Down Expand Up @@ -160,15 +161,24 @@ def updateCredentials(self, request, response, login, new_password):
if user is not None:
user_id = user.getId()
data["fullname"] = user.getProperty("fullname")
token = self.create_token(user_id, data=data)
payload, token = self.create_payload_token(user_id, data=data)
# Make available on the request for further use such as returning it in the JSON
# body of the response if the current request is for the REST API login view.
request[self.cookie_name] = token
# Make the token available to the client browser for use in UI code such as when
# the login happened through Plone Classic so that the the Volro React
# components can retrieve the token that way and use the Authorization Bearer
# header from then on.
response.setCookie(self.cookie_name, token, path="/")
cookie_kwargs = {}
if "exp" in payload:
# Match the token expiration date/time.
cookie_kwargs["expires"] = DateTime(payload["exp"]).toZone("GMT").rfc822()
response.setCookie(
self.cookie_name,
token,
path="/",
**cookie_kwargs,
)

@security.protected(ManagePortal)
@postonly
Expand Down Expand Up @@ -227,7 +237,10 @@ def delete_token(self, token):
del self._tokens[userid][token]
return True

def create_token(self, userid, timeout=None, data=None):
def create_payload_token(self, userid, timeout=None, data=None):
"""
Create and return both a JWT payload and the signed token.
"""
payload = {}
payload["sub"] = userid
if timeout is None:
Expand All @@ -244,4 +257,15 @@ def create_token(self, userid, timeout=None, data=None):
if userid not in self._tokens:
self._tokens[userid] = OIBTree()
self._tokens[userid][token] = int(time.time())
return payload, token

def create_token(self, userid, timeout=None, data=None):
"""
Create a JWT payload and the signed token, return the token.
"""
_, token = self.create_payload_token(
userid,
timeout=timeout,
data=data,
)
return token

0 comments on commit eeb0b5b

Please sign in to comment.