From 167035bdf1885959e153abb4677672ab502a50cd Mon Sep 17 00:00:00 2001 From: Ali Maktabi Date: Mon, 26 Aug 2024 21:04:06 +0330 Subject: [PATCH 1/3] added is_cachable to requirements --- core/constraints/abstract.py | 1 + core/constraints/captcha.py | 1 + prizetap/validators.py | 26 ++++++++++++++------------ tokenTap/validators.py | 26 ++++++++++++++------------ 4 files changed, 30 insertions(+), 24 deletions(-) diff --git a/core/constraints/abstract.py b/core/constraints/abstract.py index 5292c94..3e967f8 100644 --- a/core/constraints/abstract.py +++ b/core/constraints/abstract.py @@ -55,6 +55,7 @@ class ConstraintVerification(ABC): _param_keys = [] app_name = ConstraintApp.GENERAL.value __response_text = "" + is_cachable = True def __init__(self, user_profile) -> None: self.user_profile = user_profile diff --git a/core/constraints/captcha.py b/core/constraints/captcha.py index 458ce4c..f2b68aa 100644 --- a/core/constraints/captcha.py +++ b/core/constraints/captcha.py @@ -13,6 +13,7 @@ class HasVerifiedCloudflareCaptcha(ConstraintVerification): _param_keys = [] app_name = ConstraintApp.GENERAL.value + is_cachable = False def is_observed(self, *args, **kwargs) -> bool: diff --git a/prizetap/validators.py b/prizetap/validators.py index e0ac8f9..22c2599 100644 --- a/prizetap/validators.py +++ b/prizetap/validators.py @@ -58,18 +58,20 @@ def check_user_constraints(self, raise_exception=True): is_verified = constraint.is_observed( **cdata, from_time=int(self.raffle.start_at.timestamp()), context={"request": self.request} ) - caching_time = 60 * 60 if is_verified else 60 - expiration_time = time.time() + caching_time - cache_data = { - "is_verified": is_verified, - "info": info, - "expiration_time": expiration_time, - } - cache.set( - cache_key, - cache_data, - caching_time, - ) + if constraint.is_cachable: + caching_time = 60 * 60 if is_verified else 60 + expiration_time = time.time() + caching_time + cache_data = { + "is_verified": is_verified, + "info": info, + "expiration_time": expiration_time, + } + cache.set( + cache_key, + cache_data, + caching_time, + ) + if not cache_data.get("is_verified"): error_messages[c.title] = constraint.response result[c.pk] = cache_data diff --git a/tokenTap/validators.py b/tokenTap/validators.py index 3ee9ae3..76a4eaa 100644 --- a/tokenTap/validators.py +++ b/tokenTap/validators.py @@ -86,18 +86,20 @@ def check_user_permissions(self, raise_exception=True): token_distribution=self.td, context={"request": self.request} ) - caching_time = 60 * 60 if is_verified else 60 - expiration_time = time.time() + caching_time - cache_data = { - "is_verified": is_verified, - "info": info, - "expiration_time": expiration_time, - } - cache.set( - cache_key, - cache_data, - caching_time, - ) + if constraint.is_cachable: + caching_time = 60 * 60 if is_verified else 60 + expiration_time = time.time() + caching_time + cache_data = { + "is_verified": is_verified, + "info": info, + "expiration_time": expiration_time, + } + + cache.set( + cache_key, + cache_data, + caching_time, + ) if not cache_data.get("is_verified"): error_messages[c.title] = constraint.response result[c.pk] = cache_data From fbef1f86c57fe84e01c330e68e1324ebe62dd4ce Mon Sep 17 00:00:00 2001 From: Ali Maktabi Date: Mon, 26 Aug 2024 21:11:37 +0330 Subject: [PATCH 2/3] fixed errors on referencing variable --- prizetap/validators.py | 20 ++++++++++++-------- tokenTap/validators.py | 17 +++++++++-------- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/prizetap/validators.py b/prizetap/validators.py index 22c2599..7764c1b 100644 --- a/prizetap/validators.py +++ b/prizetap/validators.py @@ -58,20 +58,24 @@ def check_user_constraints(self, raise_exception=True): is_verified = constraint.is_observed( **cdata, from_time=int(self.raffle.start_at.timestamp()), context={"request": self.request} ) + + caching_time = 60 * 60 if is_verified else 60 + expiration_time = time.time() + caching_time + cache_data = { + "is_verified": is_verified, + "info": info, + "expiration_time": expiration_time, + } + if constraint.is_cachable: - caching_time = 60 * 60 if is_verified else 60 - expiration_time = time.time() + caching_time - cache_data = { - "is_verified": is_verified, - "info": info, - "expiration_time": expiration_time, - } + + cache.set( cache_key, cache_data, caching_time, ) - + if not cache_data.get("is_verified"): error_messages[c.title] = constraint.response result[c.pk] = cache_data diff --git a/tokenTap/validators.py b/tokenTap/validators.py index 76a4eaa..58028b2 100644 --- a/tokenTap/validators.py +++ b/tokenTap/validators.py @@ -86,15 +86,16 @@ def check_user_permissions(self, raise_exception=True): token_distribution=self.td, context={"request": self.request} ) + + caching_time = 60 * 60 if is_verified else 60 + expiration_time = time.time() + caching_time + cache_data = { + "is_verified": is_verified, + "info": info, + "expiration_time": expiration_time, + } + if constraint.is_cachable: - caching_time = 60 * 60 if is_verified else 60 - expiration_time = time.time() + caching_time - cache_data = { - "is_verified": is_verified, - "info": info, - "expiration_time": expiration_time, - } - cache.set( cache_key, cache_data, From de89062bcaf92d771017c835142d7ea98a635238 Mon Sep 17 00:00:00 2001 From: Ali Maktabi Date: Mon, 26 Aug 2024 21:28:37 +0330 Subject: [PATCH 3/3] refactored caching constraints --- core/utils.py | 13 ++++++++++++- prizetap/validators.py | 27 ++++++++------------------- tokenTap/validators.py | 35 +++++++++++++++++------------------ 3 files changed, 37 insertions(+), 38 deletions(-) diff --git a/core/utils.py b/core/utils.py index 0375c00..873ac87 100644 --- a/core/utils.py +++ b/core/utils.py @@ -397,4 +397,15 @@ def get_client_ip(x_forwarded_for): return ip return None - \ No newline at end of file + + +def cache_constraint_result(cache_key, is_verified, info): + caching_time = 60 * 60 if is_verified else 60 + expiration_time = time.time() + caching_time + cache_data = { + "is_verified": is_verified, + "info": info, + "expiration_time": expiration_time, + } + cache.set(cache_key, cache_data, caching_time) + return cache_data \ No newline at end of file diff --git a/prizetap/validators.py b/prizetap/validators.py index 7764c1b..9dc8abe 100644 --- a/prizetap/validators.py +++ b/prizetap/validators.py @@ -6,6 +6,7 @@ from authentication.models import UserProfile from core.constraints import ConstraintVerification, get_constraint +from core.utils import cache_constraint_result from .models import Raffle, RaffleEntry @@ -39,8 +40,8 @@ def check_user_constraints(self, raise_exception=True): pass cdata = self.raffle_data.get(str(c.pk), dict()) cache_key = f"prizetap-{self.user_profile.pk}-{self.raffle.pk}-{c.pk}" - cache_data = cache.get(cache_key) - if cache_data is None: + constraint_data = cache.get(cache_key) + if constraint_data is None: """ Refactor: this is not good design beacuse info is duplicated with is_observed so we need some design change for in is_observed so @@ -59,26 +60,14 @@ def check_user_constraints(self, raise_exception=True): **cdata, from_time=int(self.raffle.start_at.timestamp()), context={"request": self.request} ) - caching_time = 60 * 60 if is_verified else 60 - expiration_time = time.time() + caching_time - cache_data = { - "is_verified": is_verified, - "info": info, - "expiration_time": expiration_time, - } - if constraint.is_cachable: + constraint_data = cache_constraint_result(cache_key, is_verified, info) + else: + constraint_data = {"is_verified": is_verified, "info": info} - - cache.set( - cache_key, - cache_data, - caching_time, - ) - - if not cache_data.get("is_verified"): + if not constraint_data.get("is_verified"): error_messages[c.title] = constraint.response - result[c.pk] = cache_data + result[c.pk] = constraint_data if len(error_messages) and raise_exception: raise PermissionDenied(error_messages) return result diff --git a/tokenTap/validators.py b/tokenTap/validators.py index 58028b2..a33698e 100644 --- a/tokenTap/validators.py +++ b/tokenTap/validators.py @@ -1,17 +1,19 @@ import json import logging -import time from django.core.cache import cache from rest_framework.exceptions import PermissionDenied from authentication.models import UserProfile from core.constraints import ConstraintVerification, get_constraint +from core.utils import cache_constraint_result from .helpers import has_credit_left from .models import ClaimReceipt, TokenDistribution + + class SetDistributionTxValidator: def __init__(self, *args, **kwargs): self.user_profile: UserProfile = kwargs["user_profile"] @@ -36,6 +38,8 @@ def is_valid(self, data): raise PermissionDenied("Tx hash is not valid") + + class TokenDistributionValidator: def __init__( self, @@ -67,10 +71,11 @@ def check_user_permissions(self, raise_exception=True): constraint.param_values = param_values[c.name] except KeyError: pass + cdata = self.td_data.get(str(c.pk), dict()) cache_key = f"tokentap-{self.user_profile.pk}-{self.td.pk}-{c.pk}" - cache_data = cache.get(cache_key) - if cache_data is None: + constraint_data = cache.get(cache_key) + if constraint_data is None: info = constraint.get_info( **cdata, token_distribution=self.td, @@ -87,26 +92,20 @@ def check_user_permissions(self, raise_exception=True): context={"request": self.request} ) - caching_time = 60 * 60 if is_verified else 60 - expiration_time = time.time() + caching_time - cache_data = { - "is_verified": is_verified, - "info": info, - "expiration_time": expiration_time, - } - if constraint.is_cachable: - cache.set( - cache_key, - cache_data, - caching_time, - ) - if not cache_data.get("is_verified"): + constraint_data = cache_constraint_result(cache_key, is_verified, info) + else: + constraint_data = {"is_verified": is_verified, "info": info} + + if not constraint_data.get("is_verified"): error_messages[c.title] = constraint.response - result[c.pk] = cache_data + result[c.pk] = constraint_data if len(error_messages) and raise_exception: raise PermissionDenied(error_messages) return result + + def cache_constraint(self): + pass def check_user_credit(self): if self.td.is_one_time_claim: