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="В случае правильных логина и пароля access_token. " "В противном случае объект ошибки.") 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, "Телефон в формате [[+]7]1112223333 " "(в квадратных скобках необязательная часть)"), api_make_param("email", str, "Почта"), api_make_param("password", str, "Пароль пользователя"), ], returns="Аналогично методу account.auth в случае успеха") 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="JSON объект, содержащий данные формы. Структура пока не определена") 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 []