From 9c27897485a23bbcf3f53cd33dfb09653de985fc Mon Sep 17 00:00:00 2001 From: vlados31 Date: Sun, 25 Sep 2022 11:06:41 +0300 Subject: [PATCH] Small changes --- account/models.py | 16 ++++++++++------ api/api_errors.py | 7 ++++++- api/api_methods.py | 11 +++++++++-- api/api_utils.py | 2 +- arka/settings.py | 2 ++ 5 files changed, 28 insertions(+), 10 deletions(-) diff --git a/account/models.py b/account/models.py index ed95216..744447f 100644 --- a/account/models.py +++ b/account/models.py @@ -1,7 +1,8 @@ from django.db import models from django.contrib.auth.models import PermissionsMixin, AbstractBaseUser, BaseUserManager from django.core.validators import * -from arka.settings import PHONE_VERIFICATION_ENABLE, PHONE_VERIFICATION_ATTEMPTS, PHONE_VERIFICATION_APP_ID +from arka.settings import PHONE_VERIFICATION_ENABLE, PHONE_VERIFICATION_ATTEMPTS,\ + PHONE_VERIFICATION_APP_ID, PHONE_VERIFICATION_RESEND_TIME_SECS from threading import Thread, Lock, Event import random @@ -29,9 +30,6 @@ class PhoneVerificationService: def __service_run(): while True: try: - - # TODO запилить логику, которая предотвратит злоупотребление вызовами со стороны пользователей - PhoneVerificationService.__event.wait() phones = None with PhoneVerificationService.__lock: @@ -95,6 +93,7 @@ class PhoneVerificationService: CHECK_PHONE_FAILED = "failed" CHECK_PHONE_INVALID_CODE = "invalid" CHECK_PHONE_MAX_ATTEMPTS = "max-attempts" + CHECK_PHONE_RESEND_LIMIT = "resend" @staticmethod def check_code(phone: str, code: int): @@ -127,9 +126,14 @@ class PhoneVerificationService: @staticmethod def send_verify(phone: str): with PhoneVerificationService.__lock: - PhoneVerificationService.__to_verify.append(phone) + if phone in PhoneVerificationService.__codes: + c = PhoneVerificationService.__codes[phone] + if (datetime.now() - c["time"]).total_seconds() <= PHONE_VERIFICATION_RESEND_TIME_SECS: + return False, PhoneVerificationService.CHECK_PHONE_RESEND_LIMIT - PhoneVerificationService.__event.set() + PhoneVerificationService.__to_verify.append(phone) + PhoneVerificationService.__event.set() + return True, None class SiteAccountManager(BaseUserManager): diff --git a/api/api_errors.py b/api/api_errors.py index 008542b..42429b1 100644 --- a/api/api_errors.py +++ b/api/api_errors.py @@ -1,9 +1,11 @@ import traceback from account.models import PhoneVerificationService +from arka.settings import PHONE_VERIFICATION_RESEND_TIME_SECS # как создавать ошибку # raise Exception(API_ERROR_XXX, ) +API_OK_OBJ = {"status": "success"} API_ERROR_INTERNAL_ERROR = (100, 'internal error') @@ -27,7 +29,9 @@ API_ERROR_VALIDATION_CURRENTLY_VERIFIED = (522, 'currently phone is verified') API_ERROR_VALIDATION_FAILED = (523, 'cannot be verified') API_ERROR_VALIDATION_NOT_READY = (524, 'verification service not ready. call this method later') API_ERROR_VALIDATION_NOT_FOUND = (525, 'verification service did not send code. call this method without \'code\'') -API_ERROR_VALIDATION_UNKNOWN = (526, 'unknown verification error') +API_ERROR_VALIDATION_RESEND_LIMIT = (526, f'resend verification limit ' + f'(one verify for {PHONE_VERIFICATION_RESEND_TIME_SECS} secs)') +API_ERROR_VALIDATION_UNKNOWN = (527, 'unknown verification error') API_ERROR_VALIDATION = { PhoneVerificationService.CHECK_PHONE_INVALID_CODE: API_ERROR_VALIDATION_INVALID_CODE, @@ -35,6 +39,7 @@ API_ERROR_VALIDATION = { PhoneVerificationService.CHECK_PHONE_FAILED: API_ERROR_VALIDATION_FAILED, PhoneVerificationService.CHECK_PHONE_NOT_READY: API_ERROR_VALIDATION_NOT_READY, PhoneVerificationService.CHECK_PHONE_NOT_FOUND: API_ERROR_VALIDATION_NOT_FOUND, + PhoneVerificationService.CHECK_PHONE_RESEND_LIMIT: API_ERROR_VALIDATION_RESEND_LIMIT, } diff --git a/api/api_methods.py b/api/api_methods.py index 9ae2a4f..00c361c 100644 --- a/api/api_methods.py +++ b/api/api_methods.py @@ -71,7 +71,14 @@ def account_verify_phone(params): code = api_get_param_int(params, "code", False, None) if code is None: - PhoneVerificationService.send_verify(user.phone) + res, err_code = PhoneVerificationService.send_verify(user.phone) + + if not res: + if err_code in API_ERROR_VALIDATION: + raise Exception(API_ERROR_VALIDATION[err_code]) + else: + raise Exception(API_ERROR_VALIDATION_UNKNOWN) + return api_make_response({"action": "phone_call"}) else: res, err_code = PhoneVerificationService.check_code(user.phone, code) @@ -79,7 +86,7 @@ def account_verify_phone(params): if res: user.is_phone_verified = True user.save() - return api_make_response({"status": "success"}) + return api_make_response({}) else: if err_code in API_ERROR_VALIDATION: raise Exception(API_ERROR_VALIDATION[err_code]) diff --git a/api/api_utils.py b/api/api_utils.py index 3a0deb9..6a5c0d9 100644 --- a/api/api_utils.py +++ b/api/api_utils.py @@ -7,7 +7,7 @@ def __make_invalid_argument_type_error(name, value, except_type): def api_make_response(response): - return {"response": response} + return {"response": API_OK_OBJ | response} def api_get_param_int(params: dict, name: str, required=True, default=0): diff --git a/arka/settings.py b/arka/settings.py index c08528d..7e4b5ac 100644 --- a/arka/settings.py +++ b/arka/settings.py @@ -144,6 +144,8 @@ STATICFILES_DIRS = [os.path.join(BASE_DIR, "static")] DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' # LOGIN_REDIRECT_URL = '/account/' + PHONE_VERIFICATION_ENABLE = False PHONE_VERIFICATION_ATTEMPTS = 5 +PHONE_VERIFICATION_RESEND_TIME_SECS = 180 PHONE_VERIFICATION_APP_ID = "ACC90F4A-FE4A-5137-45C9-5D9E84DE9440"