Merge pull request #4677 from minrk/expires_in_validate

Improve validation, docs for token.expires_in
This commit is contained in:
Erik Sundell
2024-01-25 00:19:33 +01:00
committed by GitHub
3 changed files with 23 additions and 3 deletions

View File

@@ -572,9 +572,10 @@ paths:
properties:
expires_in:
type: number
example: 3600
description:
lifetime (in seconds) after which the requested token
will expire.
will expire. Omit, or specify null or 0 for no expiration.
note:
type: string
description: A note attached to the token for future bookkeeping

View File

@@ -472,7 +472,14 @@ class UserTokenListAPIHandler(APIHandler):
user_kind = 'user' if isinstance(user, User) else 'service'
self.log.info("%s %s requested new API token", user_kind.title(), user.name)
# retrieve the model
token_model = self.token_model(orm.APIToken.find(self.db, api_token))
orm_token = orm.APIToken.find(self.db, api_token)
if orm_token is None:
self.log.error(
"Failed to find token after creating it: %r. Maybe it expired already?",
body,
)
raise web.HTTPError(500, "Failed to create token")
token_model = self.token_model(orm_token)
token_model['token'] = api_token
self.write(json.dumps(token_model))
self.set_status(201)

View File

@@ -3,6 +3,7 @@
# Distributed under the terms of the Modified BSD License.
import enum
import json
import numbers
from base64 import decodebytes, encodebytes
from datetime import timedelta
from functools import partial
@@ -813,7 +814,18 @@ class APIToken(Hashed, Base):
else:
assert service.id is not None
orm_token.service = service
if expires_in is not None:
if expires_in:
if not isinstance(expires_in, numbers.Real):
raise TypeError(
f"expires_in must be a positive integer or null, not {expires_in!r}"
)
expires_in = int(expires_in)
# tokens must always expire in the future
if expires_in < 1:
raise ValueError(
f"expires_in must be a positive integer or null, not {expires_in!r}"
)
orm_token.expires_at = cls.now() + timedelta(seconds=expires_in)
db.commit()