246 lines
9.7 KiB
Python
246 lines
9.7 KiB
Python
from .api_utils import *
|
||
from .models import *
|
||
from order.models import *
|
||
|
||
|
||
def _require_access_token(params):
|
||
token = api_get_param_str(params, "access_token")
|
||
return UserToken.get_user_by_token(token)
|
||
|
||
|
||
class ApiAccount:
|
||
@staticmethod
|
||
@api_method("account.auth",
|
||
doc="Аутентификация пользователя",
|
||
params=[
|
||
api_make_param("login", str, "Логин пользователя"),
|
||
api_make_param("password", str, "Пароль пользователя"),
|
||
],
|
||
returns="В случае правильных логина и пароля <code>access_token</code>. "
|
||
"В противном случае объект ошибки.")
|
||
def auth(login, password):
|
||
user = UserToken.auth(login, password)
|
||
token = UserToken.create_token(user)
|
||
|
||
return api_make_response({"access_token": token.access_token})
|
||
|
||
@staticmethod
|
||
@api_method("account.deauth",
|
||
doc="Удаление токена, дальшейшие вызовы API с этим токеном вернут ошибку невалидного токена",
|
||
params=[
|
||
API_PARAM_ACCESS_TOKEN,
|
||
], returns="В случае успеха стандартный код успеха")
|
||
def deauth(access_token):
|
||
UserToken.deauth(access_token.access_token)
|
||
return api_make_response({})
|
||
|
||
@staticmethod
|
||
@api_method("account.register",
|
||
doc="Регистрация нового пользователя",
|
||
params=[
|
||
api_make_param("name", str, "Имя пользователя"),
|
||
api_make_param("surname", str, "Фамилия пользователя"),
|
||
api_make_param("phone", str, "Телефон в формате <code>[[+]7]1112223333</code> "
|
||
"<i>(в квадратных скобках необязательная часть)</i>"),
|
||
api_make_param("email", str, "Почта"),
|
||
api_make_param("password", str, "Пароль пользователя"),
|
||
], returns="Аналогично методу <code>account.auth</code> в случае успеха")
|
||
def register(name, surname, phone, email, password):
|
||
|
||
user = SiteUser.create_user(
|
||
name=name,
|
||
surname=surname,
|
||
phone=phone,
|
||
email=email,
|
||
password=password
|
||
)
|
||
|
||
try:
|
||
user.full_clean()
|
||
user.save()
|
||
|
||
try:
|
||
token = UserToken.create_token(user)
|
||
return api_make_response({"access_token": token.access_token})
|
||
|
||
except Exception as ex:
|
||
# если вдруг токен нельзя создать
|
||
user.delete()
|
||
raise ex
|
||
|
||
except ValidationError as validation_error:
|
||
traceback.print_exc()
|
||
errors = {}
|
||
for field_name in validation_error.error_dict:
|
||
err_list = validation_error.error_dict[field_name]
|
||
print(err_list)
|
||
obj = []
|
||
for err in err_list:
|
||
obj.append({
|
||
"code": err.code
|
||
})
|
||
errors[field_name] = obj
|
||
raise Exception(API_ERROR_USER_REGISTER, errors)
|
||
|
||
@staticmethod
|
||
@api_method("account.verifyPhone",
|
||
doc="Запросить верификацию номера телефона."
|
||
"Если телефон уже верифицирован, метод вернет соответствующую ошибку",
|
||
params=[
|
||
API_PARAM_ACCESS_TOKEN,
|
||
api_make_param("code", int, "Код верификации. Если не передать, будет выполнен звонок", False),
|
||
],
|
||
returns='{"status": "success"}, если верификация пройдена. Иначе одну из стандартных ошибок')
|
||
def verify_phone(access_token, code):
|
||
user = access_token.user
|
||
|
||
if user.is_phone_verified:
|
||
raise Exception(API_ERROR_VALIDATION_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])
|
||
else:
|
||
raise Exception(API_ERROR_VALIDATION_UNKNOWN)
|
||
|
||
return api_make_response({"action": "phone_call"})
|
||
else:
|
||
res, err_code = PhoneVerificationService.check_code(user.phone, code)
|
||
|
||
if res:
|
||
user.is_phone_verified = True
|
||
user.save()
|
||
return api_make_response({})
|
||
else:
|
||
if err_code in API_ERROR_VALIDATION:
|
||
raise Exception(API_ERROR_VALIDATION[err_code])
|
||
else:
|
||
raise Exception(API_ERROR_VALIDATION_UNKNOWN)
|
||
|
||
@staticmethod
|
||
@api_method("account.get",
|
||
doc="Получение информации о пользователе",
|
||
params=[
|
||
API_PARAM_ACCESS_TOKEN,
|
||
],
|
||
returns="Поля пользователя (name, surname, email, phone, phone_verified).")
|
||
def get(access_token):
|
||
user = access_token.user
|
||
return api_make_response({
|
||
"id": user.id,
|
||
"name": user.name,
|
||
"surname": user.surname,
|
||
"email": user.email,
|
||
"phone": user.phone,
|
||
"phone_verified": user.is_phone_verified
|
||
})
|
||
|
||
|
||
class ApiOrder:
|
||
@staticmethod
|
||
@api_method("order.getForm",
|
||
doc="Получение формы создания заказа в виде полей, которые нужно показать пользователю",
|
||
params=[],
|
||
returns="<code>JSON</code> объект, содержащий данные формы. Структура пока не определена")
|
||
def get_form():
|
||
return api_make_response({
|
||
"fields": [
|
||
# name = models.CharField(max_length=200, verbose_name="Название заказа")
|
||
{
|
||
"name": "name",
|
||
"label": "Название заказа",
|
||
"widget": "text",
|
||
"attrs": {
|
||
"max_len": 200
|
||
},
|
||
"required": True
|
||
},
|
||
|
||
# square = models.DecimalField(max_digits=7, decimal_places=2, blank=False, verbose_name="Площадь в м²")
|
||
{
|
||
"name": "square",
|
||
"label": "Площадь в м²",
|
||
"widget": "decimal",
|
||
"attrs": {
|
||
"max_digits": 7,
|
||
"decimal_places": 2
|
||
},
|
||
"required": True
|
||
},
|
||
|
||
# work_time = models.CharField(max_length=100, blank=True, verbose_name="Рабочее время")
|
||
{
|
||
"name": "work_time",
|
||
"label": "Рабочее время",
|
||
"widget": "text",
|
||
"attrs": {
|
||
"max_len": 100
|
||
},
|
||
"required": False
|
||
},
|
||
|
||
# type_of_renovation = models.CharField(max_length=10, choices=TYPE_OF_RENOVATION_CHOICES,
|
||
# default=CHOICE_UNDEFINED, blank=True, verbose_name="Тип ремонта")
|
||
{
|
||
"name": "type_of_renovation",
|
||
"label": "Тип ремонта",
|
||
"widget": "choice",
|
||
"attrs": {
|
||
"default": None,
|
||
"choices": Order.TYPE_OF_RENOVATION_CHOICES
|
||
},
|
||
"required": False
|
||
},
|
||
|
||
# type_of_room = models.CharField(max_length=10, choices=TYPE_OF_ROOM_CHOICES,
|
||
# blank=True, default=CHOICE_UNDEFINED, verbose_name="Тип квартиры")
|
||
{
|
||
"name": "type_of_room",
|
||
"label": "Тип квартиры",
|
||
"widget": "radio",
|
||
"attrs": {
|
||
"default": None,
|
||
"choices": Order.TYPE_OF_ROOM_CHOICES
|
||
},
|
||
"required": False
|
||
},
|
||
|
||
# флажок
|
||
{
|
||
"name": "is_with_warranty",
|
||
"label": "С гарантией",
|
||
"widget": "checkbox",
|
||
"attrs": {
|
||
"default": True
|
||
},
|
||
"required": False
|
||
},
|
||
]
|
||
})
|
||
|
||
|
||
def api_call_method(method_name, params: dict):
|
||
try:
|
||
if method_name in api_methods_dict:
|
||
out = api_methods_dict[method_name]["func"](**params)
|
||
if out is None:
|
||
raise Exception(API_ERROR_INTERNAL_ERROR, "method returned null object")
|
||
else:
|
||
raise Exception(API_ERROR_METHOD_NOT_FOUND)
|
||
except Exception as ex:
|
||
traceback.print_exc()
|
||
out = make_error_object(ex)
|
||
return out
|
||
|
||
|
||
def api_get_documentation():
|
||
# {
|
||
# "name": p["name"],
|
||
# "type": p["type"],
|
||
# "description": p["description"],
|
||
# "required": p["required"]
|
||
# }
|
||
return [] |