fix(tokens-repo): persistent hashing

This commit is contained in:
Houkime 2023-06-21 12:15:33 +00:00 committed by Inex Code
parent 4225772573
commit c94b4d07bf

View file

@ -3,6 +3,7 @@ Token repository using Redis as backend.
""" """
from typing import Optional from typing import Optional
from datetime import datetime from datetime import datetime
from hashlib import md5
from selfprivacy_api.repositories.tokens.abstract_tokens_repository import ( from selfprivacy_api.repositories.tokens.abstract_tokens_repository import (
AbstractTokensRepository, AbstractTokensRepository,
@ -28,7 +29,10 @@ class RedisTokensRepository(AbstractTokensRepository):
@staticmethod @staticmethod
def token_key_for_device(device_name: str): def token_key_for_device(device_name: str):
return TOKENS_PREFIX + str(hash(device_name)) hash = md5()
hash.update(bytes(device_name, "utf-8"))
digest = hash.hexdigest()
return TOKENS_PREFIX + digest
def get_tokens(self) -> list[Token]: def get_tokens(self) -> list[Token]:
"""Get the tokens""" """Get the tokens"""
@ -41,11 +45,20 @@ class RedisTokensRepository(AbstractTokensRepository):
tokens.append(token) tokens.append(token)
return tokens return tokens
def _discover_token_key(self, input_token: Token) -> str:
"""brute-force searching for tokens, for robust deletion"""
redis = self.connection
token_keys = redis.keys(TOKENS_PREFIX + "*")
for key in token_keys:
token = self._token_from_hash(key)
if token == input_token:
return key
def delete_token(self, input_token: Token) -> None: def delete_token(self, input_token: Token) -> None:
"""Delete the token""" """Delete the token"""
redis = self.connection redis = self.connection
key = RedisTokensRepository._token_redis_key(input_token) key = self._discover_token_key(input_token)
if input_token not in self.get_tokens(): if key is None:
raise TokenNotFound raise TokenNotFound
redis.delete(key) redis.delete(key)
@ -138,7 +151,10 @@ class RedisTokensRepository(AbstractTokensRepository):
return None return None
def _token_from_hash(self, redis_key: str) -> Optional[Token]: def _token_from_hash(self, redis_key: str) -> Optional[Token]:
return self._hash_as_model(redis_key, Token) token = self._hash_as_model(redis_key, Token)
if token is not None:
token.created_at = token.created_at.replace(tzinfo=None)
return token
def _recovery_key_from_hash(self, redis_key: str) -> Optional[RecoveryKey]: def _recovery_key_from_hash(self, redis_key: str) -> Optional[RecoveryKey]:
return self._hash_as_model(redis_key, RecoveryKey) return self._hash_as_model(redis_key, RecoveryKey)