From 9ec0044458542a9ffe2c2fe50e518b25dbc40697 Mon Sep 17 00:00:00 2001 From: Andrew Date: Wed, 29 May 2024 13:21:50 -1000 Subject: [PATCH 1/5] Use UTC for tokens_valid_from in user config --- app/classes/models/users.py | 4 +++- app/classes/shared/authentication.py | 10 +++++++++- app/classes/shared/helpers.py | 7 ++++++- app/classes/web/routes/api/auth/invalidate_tokens.py | 3 ++- app/migrations/20211120221511_api_keys.py | 3 ++- 5 files changed, 22 insertions(+), 5 deletions(-) diff --git a/app/classes/models/users.py b/app/classes/models/users.py index 3f96e651..7130bb14 100644 --- a/app/classes/models/users.py +++ b/app/classes/models/users.py @@ -38,7 +38,7 @@ class Users(BaseModel): superuser = BooleanField(default=False) lang = CharField(default="en_EN") support_logs = CharField(default="") - valid_tokens_from = DateTimeField(default=datetime.datetime.now) + valid_tokens_from = DateTimeField(default=Helpers.get_utc_now) server_order = CharField(default="") preparing = BooleanField(default=False) hints = BooleanField(default=True) @@ -261,6 +261,8 @@ class HelperUsers: @staticmethod def update_user(user_id, up_data=None): + for item in up_data: + print(item, type(item)) if up_data is None: up_data = {} if up_data: diff --git a/app/classes/shared/authentication.py b/app/classes/shared/authentication.py index fad8b730..041f3f80 100644 --- a/app/classes/shared/authentication.py +++ b/app/classes/shared/authentication.py @@ -1,5 +1,6 @@ import logging import time +from datetime import datetime from typing import Optional, Dict, Any, Tuple import jwt from jwt import PyJWTError @@ -62,7 +63,14 @@ class Authentication: user = HelperUsers.get_user(user_id) # TODO: Have a cache or something so we don't constantly # have to query the database - if int(user.get("valid_tokens_from").timestamp()) < iat: + + valid_tokens_from_str = user.get("valid_tokens_from") + + # Convert the string to a datetime object + valid_tokens_from_dt = datetime.strptime( + valid_tokens_from_str, "%Y-%m-%d %H:%M:%S.%f%z" + ) + if int(valid_tokens_from_dt.timestamp()) < iat: # Success! return key, data, user return None diff --git a/app/classes/shared/helpers.py b/app/classes/shared/helpers.py index 55a588fc..02d86899 100644 --- a/app/classes/shared/helpers.py +++ b/app/classes/shared/helpers.py @@ -19,7 +19,8 @@ import shutil import shlex import subprocess import itertools -from datetime import datetime +from datetime import datetime, timezone +import time from socket import gethostname from contextlib import redirect_stderr, suppress import libgravatar @@ -640,6 +641,10 @@ class Helpers: version = f"{major}.{minor}.{sub}" return str(version) + @staticmethod + def get_utc_now() -> datetime: + return datetime.fromtimestamp(time.time(), tz=timezone.utc) + def encode_pass(self, password): return self.passhasher.hash(password) diff --git a/app/classes/web/routes/api/auth/invalidate_tokens.py b/app/classes/web/routes/api/auth/invalidate_tokens.py index f15bf60d..62815dfd 100644 --- a/app/classes/web/routes/api/auth/invalidate_tokens.py +++ b/app/classes/web/routes/api/auth/invalidate_tokens.py @@ -1,6 +1,7 @@ import datetime import logging from app.classes.web.base_api_handler import BaseApiHandler +from app.classes.shared.helpers import Helpers logger = logging.getLogger(__name__) @@ -13,7 +14,7 @@ class ApiAuthInvalidateTokensHandler(BaseApiHandler): logger.debug(f"Invalidate tokens for user {auth_data[4]['user_id']}") self.controller.users.raw_update_user( - auth_data[4]["user_id"], {"valid_tokens_from": datetime.datetime.now()} + auth_data[4]["user_id"], {"valid_tokens_from": Helpers.get_utc_now()} ) self.finish_json(200, {"status": "ok"}) diff --git a/app/migrations/20211120221511_api_keys.py b/app/migrations/20211120221511_api_keys.py index bede2c92..f5dd1e46 100644 --- a/app/migrations/20211120221511_api_keys.py +++ b/app/migrations/20211120221511_api_keys.py @@ -1,10 +1,11 @@ import peewee import datetime +from app.classes.shared.helpers import Helpers def migrate(migrator, database, **kwargs): migrator.add_columns( - "users", valid_tokens_from=peewee.DateTimeField(default=datetime.datetime.now) + "users", valid_tokens_from=peewee.DateTimeField(default=Helpers.get_utc_now) ) migrator.drop_columns("users", ["api_token"]) From 2898917b6491f7efd44a7343cd0629bea181233c Mon Sep 17 00:00:00 2001 From: Andrew Date: Wed, 29 May 2024 19:30:07 -0400 Subject: [PATCH 2/5] Remove print statements --- app/classes/models/users.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/classes/models/users.py b/app/classes/models/users.py index 7130bb14..6f6a6bde 100644 --- a/app/classes/models/users.py +++ b/app/classes/models/users.py @@ -119,7 +119,6 @@ class HelperUsers: @staticmethod def get_user_total(): count = Users.select().where(Users.username != "system").count() - print(count) return count @staticmethod @@ -261,8 +260,6 @@ class HelperUsers: @staticmethod def update_user(user_id, up_data=None): - for item in up_data: - print(item, type(item)) if up_data is None: up_data = {} if up_data: From 251df92528ffa4412d254547296522a479024338 Mon Sep 17 00:00:00 2001 From: Andrew Date: Wed, 29 May 2024 19:32:27 -0400 Subject: [PATCH 3/5] Appease the linter --- app/classes/shared/helpers.py | 1 - app/classes/web/routes/api/auth/invalidate_tokens.py | 1 - 2 files changed, 2 deletions(-) diff --git a/app/classes/shared/helpers.py b/app/classes/shared/helpers.py index 02d86899..64d4e1d1 100644 --- a/app/classes/shared/helpers.py +++ b/app/classes/shared/helpers.py @@ -20,7 +20,6 @@ import shlex import subprocess import itertools from datetime import datetime, timezone -import time from socket import gethostname from contextlib import redirect_stderr, suppress import libgravatar diff --git a/app/classes/web/routes/api/auth/invalidate_tokens.py b/app/classes/web/routes/api/auth/invalidate_tokens.py index 62815dfd..9e38670a 100644 --- a/app/classes/web/routes/api/auth/invalidate_tokens.py +++ b/app/classes/web/routes/api/auth/invalidate_tokens.py @@ -1,4 +1,3 @@ -import datetime import logging from app.classes.web.base_api_handler import BaseApiHandler from app.classes.shared.helpers import Helpers From c3560acbd10a9086b64ad92a10ce531f8fc36c21 Mon Sep 17 00:00:00 2001 From: amcmanu3 Date: Fri, 31 May 2024 12:45:29 -0400 Subject: [PATCH 4/5] Account for str valid_tokens_from --- app/classes/shared/authentication.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/app/classes/shared/authentication.py b/app/classes/shared/authentication.py index 041f3f80..94db5532 100644 --- a/app/classes/shared/authentication.py +++ b/app/classes/shared/authentication.py @@ -63,13 +63,16 @@ class Authentication: user = HelperUsers.get_user(user_id) # TODO: Have a cache or something so we don't constantly # have to query the database - valid_tokens_from_str = user.get("valid_tokens_from") - + # It's possible this will be a string or a dt coming from the DB + # We need to account for that + try: + valid_tokens_from_dt = datetime.strptime( + valid_tokens_from_str, "%Y-%m-%d %H:%M:%S.%f%z" + ) + except TypeError: + valid_tokens_from_dt = valid_tokens_from_str # Convert the string to a datetime object - valid_tokens_from_dt = datetime.strptime( - valid_tokens_from_str, "%Y-%m-%d %H:%M:%S.%f%z" - ) if int(valid_tokens_from_dt.timestamp()) < iat: # Success! return key, data, user From ba2d3c92a6b9c765579a9da9bd0cc92e3992384d Mon Sep 17 00:00:00 2001 From: Zedifus Date: Tue, 9 Jul 2024 01:55:01 +0100 Subject: [PATCH 5/5] Update changelog !765 --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4b9f413f..767a1a4a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ TBD - Fix user creation bug where it would fail when a role was selected ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/763)) - Security improvements for general user creations on roles page ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/763)) - Security improvements for general user creations on user page ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/763)) +- Use UTC for tokens_valid_from in user config, to resolve token invalidation on instance TZ change ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/765)) ### Tweaks - Add info note to default creds file ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/760)) - Remove navigation label from sidebar ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/766))