diff --git a/account/models.py b/account/models.py
index 8c6d522..478c0af 100644
--- a/account/models.py
+++ b/account/models.py
@@ -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}$"),
])
diff --git a/api/api_errors.py b/api/api_errors.py
index 40134cb..fc8226f 100644
--- a/api/api_errors.py
+++ b/api/api_errors.py
@@ -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 '
- f'(one verify for {PHONE_VERIFICATION_RESEND_TIME_SECS} secs)')
-API_ERROR_VALIDATION_UNKNOWN = (527, 'unknown verification error')
+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_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)}"
- }]
+ }
}
diff --git a/api/api_methods.py b/api/api_methods.py
index 51cc9b0..cbbaeae 100644
--- a/api/api_methods.py
+++ b/api/api_methods.py
@@ -42,10 +42,12 @@ class ApiAccount:
api_make_param("surname", str, "Фамилия пользователя"),
api_make_param("phone", str, "Телефон в формате [[+]7]1112223333
"
"(в квадратных скобках необязательная часть)"),
- api_make_param("email", str, "Почта"),
+ api_make_param("email", str, "Почта", False),
api_make_param("password", str, "Пароль пользователя"),
+ api_make_param("code", int, "Код верификации (требуется если клиенту будет отправлена "
+ "одна из ошибок верификации)", False),
], returns="Аналогично методу account.auth
в случае успеха")
- 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()
- user.save()
+
+ # теперь проверяем телефон
+ 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",
diff --git a/api/api_utils.py b/api/api_utils.py
index d27f244..61c2fbd 100644
--- a/api/api_utils.py
+++ b/api/api_utils.py
@@ -82,7 +82,10 @@ 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:
- return make_error_object(errors)
+ if len(errors) == 1:
+ return make_error_object(errors[0])
+ else:
+ return make_error_object(errors)
else:
out = func(**func_args)
if out is None:
diff --git a/api/models.py b/api/models.py
index f5c99a7..d735d07 100644
--- a/api/models.py
+++ b/api/models.py
@@ -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()
# чекаем токен в базе