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: properties:
expires_in: expires_in:
type: number type: number
example: 3600
description: description:
lifetime (in seconds) after which the requested token lifetime (in seconds) after which the requested token
will expire. will expire. Omit, or specify null or 0 for no expiration.
note: note:
type: string type: string
description: A note attached to the token for future bookkeeping 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' user_kind = 'user' if isinstance(user, User) else 'service'
self.log.info("%s %s requested new API token", user_kind.title(), user.name) self.log.info("%s %s requested new API token", user_kind.title(), user.name)
# retrieve the model # 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 token_model['token'] = api_token
self.write(json.dumps(token_model)) self.write(json.dumps(token_model))
self.set_status(201) self.set_status(201)

View File

@@ -3,6 +3,7 @@
# Distributed under the terms of the Modified BSD License. # Distributed under the terms of the Modified BSD License.
import enum import enum
import json import json
import numbers
from base64 import decodebytes, encodebytes from base64 import decodebytes, encodebytes
from datetime import timedelta from datetime import timedelta
from functools import partial from functools import partial
@@ -813,7 +814,18 @@ class APIToken(Hashed, Base):
else: else:
assert service.id is not None assert service.id is not None
orm_token.service = service 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) orm_token.expires_at = cls.now() + timedelta(seconds=expires_in)
db.commit() db.commit()