feat: add rate limiter

This commit is contained in:
GareArc 2025-02-27 00:49:37 -05:00
parent 89ef1f0835
commit badedc70ce
3 changed files with 31 additions and 2 deletions

View File

@ -101,3 +101,15 @@ class AccountInFreezeError(BaseHTTPException):
"This email account has been deleted within the past 30 days" "This email account has been deleted within the past 30 days"
"and is temporarily unavailable for new account registration." "and is temporarily unavailable for new account registration."
) )
class EducationVerifyLimitError(BaseHTTPException):
error_code = "education_verify_limit"
description = "Rate limit exceeded"
code = 429
class EducationActivateLimitError(BaseHTTPException):
error_code = "education_activate_limit"
description = "Rate limit exceeded"
code = 429

View File

@ -312,7 +312,7 @@ class EducationVerifyApi(Resource):
def get(self): def get(self):
account = current_user account = current_user
return BillingService.EducationIdentity.verify(account.id) return BillingService.EducationIdentity.verify(account.id, account.email)
class EducationApi(Resource): class EducationApi(Resource):

View File

@ -5,6 +5,7 @@ import httpx
from tenacity import retry, retry_if_exception_type, stop_before_delay, wait_fixed from tenacity import retry, retry_if_exception_type, stop_before_delay, wait_fixed
from extensions.ext_database import db from extensions.ext_database import db
from libs.helper import RateLimiter
from models.account import Account, TenantAccountJoin, TenantAccountRole from models.account import Account, TenantAccountJoin, TenantAccountRole
@ -93,8 +94,18 @@ class BillingService:
return cls._send_request("POST", "/account/delete-feedback", json=json) return cls._send_request("POST", "/account/delete-feedback", json=json)
class EducationIdentity: class EducationIdentity:
verification_rate_limit = RateLimiter(prefix="edu_verification_rate_limit", limit=10, period=60)
activation_rate_limit = RateLimiter(prefix="edu_activation_rate_limit", limit=10, period=60)
@classmethod @classmethod
def verify(cls, account_id: str): def verify(cls, account_id: str, account_email: str):
if cls.verification_rate_limit.is_rate_limited(account_email):
from controllers.console.error import EducationVerifyLimitError
raise EducationVerifyLimitError()
cls.verification_rate_limit.increment_rate_limit(account_email)
params = {"account_id": account_id} params = {"account_id": account_id}
return BillingService._send_request("GET", "/education/verify", params=params) return BillingService._send_request("GET", "/education/verify", params=params)
@ -105,6 +116,12 @@ class BillingService:
@classmethod @classmethod
def activate(cls, account: Account, token: str): def activate(cls, account: Account, token: str):
if cls.activation_rate_limit.is_rate_limited(account.email):
from controllers.console.error import EducationActivateLimitError
raise EducationActivateLimitError()
cls.activation_rate_limit.increment_rate_limit(account.email)
json = { json = {
"account_id": account.id, "account_id": account.id,
"email": account.email, "email": account.email,