from urllib.parse import unquote import pydantic from fansifter_common.encrypter import Encrypter from fansifter_common.identifiers.exceptions import ( InvalidDoubleOptInTokenError, InvalidProfileTokenError, ) from fansifter_common.identifiers.types import ( DoubleOptInIdentifier, DoubleOptInToken, ProfileIdentifier, ProfileIdentifierValidator, ProfileToken, ) def encrypt_profile_token( encrypter: Encrypter, *, identifier: ProfileIdentifier ) -> ProfileToken: """Create a profile token by profile identifier.""" payload = ProfileIdentifierValidator.dump_json(identifier, by_alias=True) return ProfileToken(encrypter.encrypt(payload).decode()) def decrypt_profile_identifier( encrypter: Encrypter, *, token: ProfileToken ) -> ProfileIdentifier: """Get a profile identifier by profile token.""" try: data = encrypter.decrypt(unquote(token)) except Exception as exc: raise InvalidProfileTokenError from exc try: return ProfileIdentifierValidator.validate_json(data) except pydantic.ValidationError as exc: raise InvalidProfileTokenError from exc def encrypt_double_opt_in_token( encrypter: Encrypter, *, identifier: DoubleOptInIdentifier ) -> DoubleOptInToken: """Create a double opt-in token by identifier.""" payload = identifier.model_dump_json(by_alias=True) return DoubleOptInToken(encrypter.encrypt(payload.encode()).decode()) def decrypt_double_opt_in_identifier( encrypter: Encrypter, *, token: DoubleOptInToken ) -> DoubleOptInIdentifier: """Get a double opt-in identifier by token.""" try: data = encrypter.decrypt(unquote(token)) except Exception as exc: raise InvalidDoubleOptInTokenError from exc try: return DoubleOptInIdentifier.model_validate_json(data) except pydantic.ValidationError as exc: raise InvalidDoubleOptInTokenError from exc