Исправлен формат ошибок API, добавлена обязательная верификация номера телефона при регистрации
This commit is contained in:
parent
1a6f2d578e
commit
e164e74cde
@ -186,7 +186,7 @@ class SiteAccountManager(BaseUserManager):
|
||||
class SiteUser(AbstractBaseUser, PermissionsMixin):
|
||||
surname = models.CharField(max_length=60, verbose_name="Фамилия")
|
||||
name = models.CharField(max_length=60, verbose_name="Имя")
|
||||
email = models.EmailField(unique=True, verbose_name="Email")
|
||||
email = models.EmailField(unique=True, verbose_name="Email", null=True, blank=True, default=None)
|
||||
phone = models.CharField(unique=True, max_length=16, verbose_name="Телефон", validators=[
|
||||
RegexValidator(regex="^\\+7[0-9]{10}$"),
|
||||
])
|
||||
|
@ -7,10 +7,10 @@ from arka.settings import PHONE_VERIFICATION_RESEND_TIME_SECS
|
||||
|
||||
API_OK_OBJ = {"status": "success"}
|
||||
|
||||
API_ERROR_MULTIPLY_ERRORS = (None, 'multiply errors')
|
||||
|
||||
API_ERROR_INTERNAL_ERROR = (100, 'internal error')
|
||||
|
||||
API_ERROR_MULTIPLY_ERRORS = (101, 'multiply errors')
|
||||
|
||||
API_ERROR_METHOD_NOT_FOUND = (200, 'method not found')
|
||||
API_ERROR_MISSING_ARGUMENT = (201, 'missing argument')
|
||||
API_ERROR_UNKNOWN_ARGUMENT = (202, 'unknown argument')
|
||||
@ -24,24 +24,25 @@ API_ERROR_INVALID_TOKEN = (503, 'invalid token')
|
||||
|
||||
# времненное решение, позже нужно будет заменить на конкретные ошибки
|
||||
API_ERROR_USER_REGISTER = (510, 'user registration error')
|
||||
API_ERROR_NEED_VERIFY = (511, 'need verification code')
|
||||
|
||||
API_ERROR_VALIDATION_INVALID_CODE = (520, 'invalid code')
|
||||
API_ERROR_VALIDATION_MAX_ATTEMPTS = (521, 'max attempts')
|
||||
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_RESEND_LIMIT = (526, f'resend verification limit '
|
||||
API_ERROR_VERIFY_INVALID_CODE = (520, 'invalid code')
|
||||
API_ERROR_VERIFY_MAX_ATTEMPTS = (521, 'max attempts')
|
||||
API_ERROR_CURRENTLY_VERIFIED = (522, 'currently phone is verified')
|
||||
API_ERROR_VERIFY_FAILED = (523, 'cannot be verified')
|
||||
API_ERROR_VERIFY_NOT_READY = (524, 'verification service not ready. call this method later')
|
||||
API_ERROR_VERIFY_NOT_FOUND = (525, 'verification service did not send code. call this method without \'code\'')
|
||||
API_ERROR_VERIFY_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_VERIFY_UNKNOWN = (527, 'unknown verification error')
|
||||
|
||||
API_ERROR_VALIDATION = {
|
||||
PhoneVerificationService.CHECK_PHONE_INVALID_CODE: API_ERROR_VALIDATION_INVALID_CODE,
|
||||
PhoneVerificationService.CHECK_PHONE_MAX_ATTEMPTS: API_ERROR_VALIDATION_MAX_ATTEMPTS,
|
||||
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,
|
||||
API_ERROR_VERIFICATION = {
|
||||
PhoneVerificationService.CHECK_PHONE_INVALID_CODE: API_ERROR_VERIFY_INVALID_CODE,
|
||||
PhoneVerificationService.CHECK_PHONE_MAX_ATTEMPTS: API_ERROR_VERIFY_MAX_ATTEMPTS,
|
||||
PhoneVerificationService.CHECK_PHONE_FAILED: API_ERROR_VERIFY_FAILED,
|
||||
PhoneVerificationService.CHECK_PHONE_NOT_READY: API_ERROR_VERIFY_NOT_READY,
|
||||
PhoneVerificationService.CHECK_PHONE_NOT_FOUND: API_ERROR_VERIFY_NOT_FOUND,
|
||||
PhoneVerificationService.CHECK_PHONE_RESEND_LIMIT: API_ERROR_VERIFY_RESEND_LIMIT,
|
||||
}
|
||||
|
||||
|
||||
@ -66,9 +67,13 @@ def make_error_object(ex: Exception | list):
|
||||
"status": "error"
|
||||
}
|
||||
if type(ex) == list:
|
||||
data["error"] = [__make_error(e) for e in ex]
|
||||
data["error"] = {
|
||||
"code": API_ERROR_MULTIPLY_ERRORS[0],
|
||||
"message": API_ERROR_MULTIPLY_ERRORS[1],
|
||||
}
|
||||
data["related"] = [__make_error(e) for e in ex]
|
||||
else:
|
||||
data["error"] = [__make_error(ex)]
|
||||
data["error"] = __make_error(ex)
|
||||
|
||||
return data
|
||||
except BaseException as err:
|
||||
@ -76,9 +81,9 @@ def make_error_object(ex: Exception | list):
|
||||
|
||||
return {
|
||||
"status": "error",
|
||||
"error": [{
|
||||
"error": {
|
||||
"code": API_ERROR_INTERNAL_ERROR[0],
|
||||
"message": API_ERROR_INTERNAL_ERROR[1],
|
||||
"related": f"Exception {type(err)}: {str(err)}"
|
||||
}]
|
||||
}
|
||||
}
|
||||
|
@ -42,10 +42,12 @@ class ApiAccount:
|
||||
api_make_param("surname", str, "Фамилия пользователя"),
|
||||
api_make_param("phone", str, "Телефон в формате <code>[[+]7]1112223333</code> "
|
||||
"<i>(в квадратных скобках необязательная часть)</i>"),
|
||||
api_make_param("email", str, "Почта"),
|
||||
api_make_param("email", str, "Почта", False),
|
||||
api_make_param("password", str, "Пароль пользователя"),
|
||||
api_make_param("code", int, "Код верификации (требуется если клиенту будет отправлена "
|
||||
"одна из ошибок <i>верификации</i>)", False),
|
||||
], returns="Аналогично методу <code>account.auth</code> в случае успеха")
|
||||
def register(name, surname, phone, email, password):
|
||||
def register(name, surname, phone, email, password, code):
|
||||
|
||||
user = SiteUser.create_user(
|
||||
name=name,
|
||||
@ -57,7 +59,29 @@ class ApiAccount:
|
||||
|
||||
try:
|
||||
user.full_clean()
|
||||
|
||||
# теперь проверяем телефон
|
||||
if code is None:
|
||||
res, err_code = PhoneVerificationService.send_verify(user.phone)
|
||||
|
||||
if not res:
|
||||
if err_code in API_ERROR_VERIFICATION:
|
||||
raise Exception(API_ERROR_VERIFICATION[err_code])
|
||||
else:
|
||||
raise Exception(API_ERROR_VERIFY_UNKNOWN)
|
||||
|
||||
raise Exception(API_ERROR_NEED_VERIFY)
|
||||
else:
|
||||
res, err_code = PhoneVerificationService.check_code(user.phone, code)
|
||||
|
||||
if res:
|
||||
user.is_phone_verified = True
|
||||
user.save()
|
||||
else:
|
||||
if err_code in API_ERROR_VERIFICATION:
|
||||
raise Exception(API_ERROR_VERIFICATION[err_code])
|
||||
else:
|
||||
raise Exception(API_ERROR_VERIFY_UNKNOWN)
|
||||
|
||||
try:
|
||||
token = UserToken.create_token(user)
|
||||
@ -81,6 +105,8 @@ class ApiAccount:
|
||||
})
|
||||
errors[field_name] = obj
|
||||
raise Exception(API_ERROR_USER_REGISTER, errors)
|
||||
except BaseException as ex:
|
||||
raise ex
|
||||
|
||||
@staticmethod
|
||||
@api_method("account.verifyPhone",
|
||||
@ -95,16 +121,16 @@ class ApiAccount:
|
||||
user = access_token.user
|
||||
|
||||
if user.is_phone_verified:
|
||||
raise Exception(API_ERROR_VALIDATION_CURRENTLY_VERIFIED)
|
||||
raise Exception(API_ERROR_CURRENTLY_VERIFIED)
|
||||
|
||||
if code is None:
|
||||
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])
|
||||
if err_code in API_ERROR_VERIFICATION:
|
||||
raise Exception(API_ERROR_VERIFICATION[err_code])
|
||||
else:
|
||||
raise Exception(API_ERROR_VALIDATION_UNKNOWN)
|
||||
raise Exception(API_ERROR_VERIFY_UNKNOWN)
|
||||
|
||||
return api_make_response({"action": "phone_call"})
|
||||
else:
|
||||
@ -115,10 +141,10 @@ class ApiAccount:
|
||||
user.save()
|
||||
return api_make_response({})
|
||||
else:
|
||||
if err_code in API_ERROR_VALIDATION:
|
||||
raise Exception(API_ERROR_VALIDATION[err_code])
|
||||
if err_code in API_ERROR_VERIFICATION:
|
||||
raise Exception(API_ERROR_VERIFICATION[err_code])
|
||||
else:
|
||||
raise Exception(API_ERROR_VALIDATION_UNKNOWN)
|
||||
raise Exception(API_ERROR_VERIFY_UNKNOWN)
|
||||
|
||||
@staticmethod
|
||||
@api_method("account.get",
|
||||
|
@ -82,6 +82,9 @@ def api_method(func_name, doc="", params: list or None = None, returns=""):
|
||||
errors.append(ex)
|
||||
print(f"errors: {errors}, args: {func_args}")
|
||||
if len(errors) > 0:
|
||||
if len(errors) == 1:
|
||||
return make_error_object(errors[0])
|
||||
else:
|
||||
return make_error_object(errors)
|
||||
else:
|
||||
out = func(**func_args)
|
||||
|
@ -61,7 +61,7 @@ class UserToken(models.Model):
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
if len(self.access_token) == 0:
|
||||
source = bytearray(self.user.email + self.user.password + str(datetime.now()), 'utf-8')
|
||||
source = bytearray(str(self.user.email) + self.user.password + str(datetime.now()), 'utf-8')
|
||||
t = sha512(source).hexdigest()
|
||||
|
||||
# чекаем токен в базе
|
||||
|
Reference in New Issue
Block a user