async def get(request: Request) -> Response: try: login = await authorized_userid(request) if not login: return respond_with_json({"error": "Unauthorized"}, status=401) conn = request.app['db_pool'] Session = sessionmaker(bind=conn) session = Session() user = Users.get_user_by_login_sync(session, login=login ) if not user: return respond_with_json({"error": F"No user with login {login}"}, status=404) result = [] for basket in user.basket: if basket.order: order = {"status": basket.order.status, "date": basket.order.date.isoformat()} products = [] for product_in_basket in basket.product_in_basket: product = {"name": product_in_basket.product_shop.product.name, "quantity": product_in_basket.quantity, "price": product_in_basket.product_shop.price } products.append(product) order['products'] = products result.append(order) return respond_with_json(result) except Exception as ex: log.warning(f"Endpoint: order, Method: get. Error:{str(ex)}") return respond_with_json({"error": "Internal Server Error"}, status=500)
async def post(self, request: Request) -> Response: try: data = await request.json() if data: conn = request.app['db_pool'] Session = sessionmaker(bind=conn) session = Session() error = Users.validate_user_login(session, data['login'], data['password']) user = Users.get_user_by_login_sync(session, login=data['login']) user_id = await authorized_userid(request) if not error: response = respond_with_json({"status": "successful"}) await remember(request, response, user.login) return response else: response = respond_with_json( { "status": "unsuccessful", "error": error }, status=401) if user_id: await forget(request, response) return response else: return respond_with_json({"error": "Bad parameters"}, status=400) except Exception as ex: log.warning(f"Endpoint: login, Method: post. Error:{str(ex)}") return respond_with_json({"error": "Internal Server Error"}, status=500)
async def get(self, request: Request) -> Response: """ Получение списка данных новостей из БД. Поддерживает параметры: order = сортировка значений в определённом столбце, по умолчанию id sort = сортировка asc - возрастание/desc - убывание, по умолчанию desc limit = лимит данных, по умолчанию 5 offset = смещение, по умолчанию 0 :param * *request* (``Request``) -- запрос :rtype (``Response``) :return: список новостей """ order = request.query.get('order') sort_type = request.query.get('sort', 'desc') limit = request.query.get('limit', '5') offset = request.query.get('offset', '0') if limit.isdigit(): limit = abs(int(limit)) if offset.isdigit(): offset = abs(int(offset)) db = request.app['db'] query = db.session.query(Posts) if order: try: condition = getattr(Posts, order) except AttributeError as e: log.info(e) return respond_with_json({ 'error': f'Attribute {order} not found', 'status': 400 }) else: condition = getattr(Posts, 'id') if sort_type == 'desc': condition = condition.desc() elif sort_type == 'asc': condition = condition.asc() else: return respond_with_json({ 'error': f'Wrong parameter sort - {sort_type}', 'status': 400 }) query = query.order_by(condition).limit(limit).offset(limit * offset) data = [to_dict(x) for x in query] return respond_with_json(data)
async def post(self, request: Request) -> Response: try: user_id = await authorized_userid(request) if not user_id: return respond_with_json({"error": "Session invalid"}, status=400) response = respond_with_json({"status": "successful"}) await forget(request, response) return response except Exception as ex: log.warning(f"Endpoint: logout, Method: post. Error:{str(ex)}") return respond_with_json({"error": "Internal Server Error"}, status=500)
async def post(self, request: Request) -> Response: """ --- summary: Open or close the door security: - Bearer Authentication: [enter] - X-API-Key Authentication: [enter] - Session Authentication: [enter] tags: - door requestBody: description: JSON containing instructions to open or close the door. required: true content: application/json: schema: type: object required: - door properties: door: type: boolean example: door: true responses: "200": description: A JSON document indicating success content: application/json: schema: $ref: '#/components/schemas/Ok' "401": description: A JSON document indicating error in request (user not authenticated) content: application/json: schema: $ref: '#/components/schemas/Error' "403": description: A JSON document indicating error in request (user doesn't have permission to preform this action) content: application/json: schema: $ref: '#/components/schemas/Error' """ await check_api_permissions(request, ["enter"]) data = await request.json() await request.app["serial"].writeline( f"AUTH {int(data.get('door', 0))}") return respond_with_json({ "Ok": True, "Error": None, "status_code": 200 })
async def put(request: Request) -> Response: try: login = await authorized_userid(request) if not login: return respond_with_json({"error": "Unauthorized"}, status=401) else: conn = request.app['db_pool'] Session = sessionmaker(bind=conn) session = Session() user = Users.get_user_by_login_sync(session, login=login ) if not user: return respond_with_json({"error": F"No user with login {login}"}, status=404) basket = session.query(Basket).filter_by(users=user).filter_by(order=None).first() if not basket: return respond_with_json({"error": "Basket is empty"}, status=400) try: order = Order(basket=basket, date=datetime.now(), status="awaiting payment") basket.order = order session.add(order) session.add(basket) session.commit() except Exception as ex: session.rollback() log.warning(f"Endpoint: order, Method: put. Msg:{str(ex)}") return respond_with_json({"error": "Internal Server Error"}, status=500) return respond_with_json({"msg": "Order create successfully", "order_status": "awaiting payment"}) except Exception as ex: log.warning(f"Endpoint: order, Method: put. Msg:{str(ex)}") return respond_with_json({"error": "Internal Server Error"}, status=500)
async def logging(self, request: Request, handler) -> Response: start = time() try: response: Response = await handler(request) self.logger.info("Request finished in {:.2f}ms {} {}".format( (time() - start) * 100, response.status, response.content_type)) return response except HTTPException as exc: self.logger.exception(exc.body) return respond_with_json(data=exc, status=exc.status) except Exception as exc: self.logger.error(exc, exc_info=True) raise (exc)
async def post(self, request: Request): data = None status = 500 if request.body_exists and request.query is not None: body = await request.json() message = body['message'] recognized = await self.recognizer.recognize(message) data = {"message": dumps(recognized)} if data is not None: status = 201 else: status = 400 data = {} return respond_with_json(status=status, data=data)
async def post(self, request: Request): data = None status = 500 if request.body_exists and request.query is not None: body = await request.json() text = body['text'] predictions, raw_outputs = self.model.predict([text]) for pred in range(len(predictions)): if predictions[pred]: data = [self.raw_pred[pred]] if data is not None: status = 201 else: status = 400 data = {} return respond_with_json(status=status, data=data)
async def post(self, request: Request): data = None status = 500 if request.body_exists and request.query is not None: body = await request.json() text = body['text'] data = {"Entities": None, "Intents": None, "Topic": None} intent = await self.intent.detect(text) data["Intents"] = intent ner = await self.ner.detect(text) data["Entities"] = ner #topic = await self.topic.detect(text) #data["Topic"] = topic if data is not None: status = 201 else: status = 400 data = {} return respond_with_json(status=status, data=data)
async def put(request: Request) -> Response: try: login = await authorized_userid(request) if not login: return respond_with_json({"error": "Unauthorized"}, status=401) else: conn = request.app['db_pool'] Session = sessionmaker(bind=conn) session = Session() user = Users.get_user_by_login_sync(session, login=login) if not user: return respond_with_json( {"error": F"No user with login {login}"}, status=404) data = await request.json() if data: basket = session.query(Basket).filter_by(users=user).filter_by( order=None).first() if not basket: basket = Basket(users=user) try: for product in data["products"]: product_shop = session.query(ProductShop).filter_by( id=product['id']).first() product_in_basket = ProductInBasket( basket=basket, product_shop=product_shop, quantity=product['quantity']) session.add(product_in_basket) session.commit() except Exception as ex: session.rollback() log.warning( f"Endpoint: basket, Method: put. Msg:{str(ex)}") return respond_with_json( {"error": "Internal Server Error"}, status=500) return respond_with_json({"msg": "Products add successfully"}) else: return respond_with_json({"error": "No parameters"}, status=400) except Exception as ex: log.warning(f"Endpoint: basket, Method: put. Msg:{str(ex)}") return respond_with_json({"error": "Internal Server Error"}, status=500)
async def get(self, request: Request) -> Response: """ --- summary: Find user description: security: - Bearer Authentication: [users_read] - X-API-Key Authentication: [users_read] - Session Authentication: [users_read] tags: - users parameters: - name: username in: query description: A unique username of an user schema: type: string - name: username in: path description: A unique username of an user allowReserved: true schema: type: string - name: card in: query description: UID of a card connected with the user schema: type: string format: mifare uid pattern: '^([0-9a-fA-F]{8}|([0-9a-fA-F]{14}|[0-9a-fA-F]{20})$' - name: card in: path description: UID of a card connected with the user schema: type: string format: mifare uid pattern: '^([0-9a-fA-F]{8}|([0-9a-fA-F]{14}|[0-9a-fA-F]{20})$' - name: api_key in: query description: An API key associated with to the user schema: type: string format: Branca - name: api_key in: path description: An API key associated with to the user schema: type: string format: Branca responses: "200": description: A JSON document indicating success content: application/json: schema: $ref: '#/components/schemas/User' "401": description: A JSON document indicating error in request (user not authenticated) content: application/json: schema: $ref: '#/components/schemas/Error' "403": description: A JSON document indicating error in request (user doesn't have permission to preform this action) content: application/json: schema: $ref: '#/components/schemas/Error' "404": description: A JSON document indicating error in request (user not found) content: application/json: schema: $ref: '#/components/schemas/Error' """ await check_api_permissions(request, ["users_read"]) parameters = {**request.match_info, **request.query} search_keys, search_values = zip(*({ key: parameters[key] for key in allowed_search_parameters if parameters.get(key, None) != None }.items())) user = await find_user_by( request.app, list(search_keys), list(search_values), ["username", "cards", "permissions"], ) if user == None: raise HTTPNotFound( reason="no user with requested data exists", body=json.dumps({ "Ok": False, "Error": "no user with requested data exists", "status_code": 404, }), content_type="application/json", ) return respond_with_json({ "Ok": True, "Error": None, "status_code": 200, "user": user })
async def post(self, request: Request) -> Response: """ --- summary: Update user information description: security: - Bearer Authentication: [users_manage, self] - X-API-Key Authentication: [users_manage, self] - Session Authentication: [users_manage, self] tags: - users parameters: - name: username in: path description: The name of the user you want to modify (can also be put in request body) schema: type: string requestBody: description: JSON containing the changes to the user and/or their username to find them required: true content: application/json: schema: type: object properties: username: type: string description: username of the user you want to modify new_username: type: string description: new name for the user cards: type: array description: list of all cards that will be assigned to the user items: type: string format: mifare uid pattern: '^([0-9a-fA-F]{8}|([0-9a-fA-F]{14}|[0-9a-fA-F]{20})$' card: type: string description: a single card you want to add to the user format: mifare uid pattern: '^([0-9a-fA-F]{8}|([0-9a-fA-F]{14}|[0-9a-fA-F]{20})$' permissions: type: array description: list of all permissions that the user will have items: type: string enum: - admin - enter - logs - users_read - users_manage - cards - dashboard permission: type: string description: a single permission you want to give the user enum: - admin - enter - logs - users_read - users_manage - cards - dashboard example: username: notAdministrator new_username: Administrator card: ABABABAB permission: admin responses: "200": description: A JSON document indicating success content: application/json: schema: $ref: '#/components/schemas/User' "401": description: A JSON document indicating error in request (user not authenticated) content: application/json: schema: $ref: '#/components/schemas/Error' "403": description: A JSON document indicating error in request (user doesn't have permission to preform this action) content: application/json: schema: $ref: '#/components/schemas/Error' "404": description: A JSON document indicating error in request (user not found) content: application/json: schema: $ref: '#/components/schemas/Error' """ data = await request.json() username = request.match_info.get("username", False) or data.get( "username", False ) if not username: raise HTTPBadRequest( reason="no username provided", body=json.dumps( {"Ok": False, "Error": "no username provided", "status_code": 401} ), content_type="application/json", ) user = await find_user_by_username( request.app, username, ["_id", "permissions"] ) if user == None: raise HTTPNotFound( reason="no user with requested username exists", body=json.dumps( { "Ok": False, "Error": "no user with requested username exists", "status_code": 404, } ), content_type="application/json", ) is_self = await check_if_self(request, user.get("_id", None)) required_permissions = list(data.get("permissions", [])) if data.get("permission", False): required_permissions.append(data["permission"]) if not is_self: required_permissions.append("users_manage") await check_api_permissions(request, required_permissions) user = modify_user( request.app, user["_id"], username=data.get("new_username", None), cards=data.get("cards", None), card=data.get("card", None), permissions=data.get("permissions", None), permission=data.get("permission", None), ) return respond_with_json( {"Ok": True, "Error": None, "status_code": 200, "user": user} )
async def delete(self, request: Request) -> Response: """ --- summary: Delete card/s from user description: security: - Bearer Authentication: [cards, self] - X-API-Key Authentication: [cards, self] - Session Authentication: [cards, self] tags: - cards requestBody: description: JSON containing the changes to the user and/or their username to find them required: true content: application/json: schema: type: object properties: username: type: string description: username of the user you want to modify required: true cards: required: true oneOf: - type: array description: list of all cards that will be removed from the user items: type: string format: mifare uid pattern: '^([0-9a-fA-F]{8}|([0-9a-fA-F]{14}|[0-9a-fA-F]{20})$' - type: string description: a single card that will be removed from the user format: mifare uid pattern: '^([0-9a-fA-F]{8}|([0-9a-fA-F]{14}|[0-9a-fA-F]{20})$' example: username: example cards: - ABABABAB - 12345678 responses: "200": description: A JSON document indicating success along with some information about the user content: application/json: schema: $ref: '#/components/schemas/User' "401": description: A JSON document indicating error in request (user not authenticated) content: application/json: schema: $ref: '#/components/schemas/Error' "403": description: A JSON document indicating error in request (user doesn't have permission to preform this action) content: application/json: schema: $ref: '#/components/schemas/Error' "409": description: A JSON document indicating error in request (card already exists on user) content: application/json: schema: $ref: '#/components/schemas/Error' """ data = await request.json() username = data.get("username", False) if not username: raise HTTPBadRequest( reason="no username provided", body=json.dumps({ "Ok": False, "Error": "no username provided", "status_code": 401 }), content_type="application/json", ) user = await find_user_by_username(request.app, username, ["_id", "cards"]) if user == None: raise HTTPNotFound( reason="no user with requested username exists", body=json.dumps({ "Ok": False, "Error": "no user with requested username exists", "status_code": 404, }), content_type="application/json", ) is_self = await check_if_self(request, user.get("_id", None)) if not is_self: await check_api_permissions(request, ["cards"]) cards = data.get("cards", []) if not isinstance(cards, list): cards = [cards] user = await delete_cards_from_user(request.app, user["_id"], cards) return respond_with_json({ "Ok": True, "Error": None, "status_code": 200, "user": user })
async def get(self, request: Request) -> Response: """ --- summary: Find a user with the card/s description: security: - Bearer Authentication: [users_read] - X-API-Key Authentication: [users_read] - Session Authentication: [users_read] tags: - cards parameters: - name: card in: query description: UID of a card connected with the user schema: type: string format: mifare uid pattern: '^([0-9a-fA-F]{8}|([0-9a-fA-F]{14}|[0-9a-fA-F]{20})$' - name: card in: path description: UID of a card connected with the user schema: type: string format: mifare uid pattern: '^([0-9a-fA-F]{8}|([0-9a-fA-F]{14}|[0-9a-fA-F]{20})$' - name: cards in: query description: Array of card UIDs connected with the user (will search for user with **all** cards) schema: type: array items: type: string format: mifare uid pattern: '^([0-9a-fA-F]{8}|([0-9a-fA-F]{14}|[0-9a-fA-F]{20})$' responses: "200": description: A JSON document indicating success content: application/json: schema: $ref: '#/components/schemas/User' "401": description: A JSON document indicating error in request (user not authenticated) content: application/json: schema: $ref: '#/components/schemas/Error' "403": description: A JSON document indicating error in request (user doesn't have permission to preform this action) content: application/json: schema: $ref: '#/components/schemas/Error' "404": description: A JSON document indicating error in request (user not found) content: application/json: schema: $ref: '#/components/schemas/Error' """ await check_api_permissions(request, ["users_read"]) parameters = {**request.match_info, **request.query} if parameters.get("card", False): cards = [parameters["card"]] else: cards = list(parameters.get("cards", [])) user = await find_user_by_cards( request.app, cards, ["username", "cards", "permissions"], ) if user == None: raise HTTPNotFound( reason="no user with requested cards exists", body=json.dumps({ "Ok": False, "Error": "no user with requested cards exists", "status_code": 404, }), content_type="application/json", ) return respond_with_json({ "Ok": True, "Error": None, "status_code": 200, "user": user })
async def _swagger_def(request): """ Returns the Swagger JSON Definition """ return respond_with_json(request.app["SWAGGER_DEF_CONTENT"])
async def delete(self, request: Request) -> Response: """ --- summary: Delete a user description: security: - Bearer Authentication: [users_manage, self] - X-API-Key Authentication: [users_manage, self] - Session Authentication: [users_manage, self] tags: - users requestBody: description: JSON containing the changes to the user and/or their username to find them required: true content: application/json: schema: type: object properties: username: type: string description: username of the user you want to modify required: true example: username: example responses: "200": description: A JSON document indicating success content: application/json: schema: $ref: '#/components/schemas/Ok' "401": description: A JSON document indicating error in request (user not authenticated) content: application/json: schema: $ref: '#/components/schemas/Error' "403": description: A JSON document indicating error in request (user doesn't have permission to preform this action) content: application/json: schema: $ref: '#/components/schemas/Error' "409": description: A JSON document indicating error in request (user already exists) content: application/json: schema: $ref: '#/components/schemas/Error' """ data = await request.json() username = data.get("username", False) if not username: raise HTTPBadRequest( reason="no username provided", body=json.dumps( {"Ok": False, "Error": "no username provided", "status_code": 401} ), content_type="application/json", ) user = await find_user_by_username( request.app, username, ["_id", "permissions"] ) if user == None: raise HTTPNotFound( reason="no user with requested username exists", body=json.dumps( { "Ok": False, "Error": "no user with requested username exists", "status_code": 404, } ), content_type="application/json", ) is_self = await check_if_self(request, user.get("_id", None)) if not is_self: await check_api_permissions(request, ["users_manage"]) await delete_user(request.app, user.get("_id", None), username) return respond_with_json({"Ok": True, "Error": None, "status_code": 200})
async def get(self, request: Request) -> Response: """ --- summary: Usage statistics description: Get usage statistics between specified dates - defaults to last week - and with specified granularity - defaults to a day security: - Bearer Authentication: [logs] - X-API-Key Authentication: [logs] - Session Authentication: [logs] tags: - logs parameters: - name: start in: query required: false description: ISO Date or timestamp that will be the starting point (inclusive) of returned stats schema: oneOf: - type: string format: date-time - type: integer format: timestamp - name: end in: query required: false description: ISO Date or timestamp that will be the ending point (inclusive) of returned stats schema: oneOf: - type: string format: date-time - type: integer format: timestamp - name: granularity in: query required: false description: interval of time for each data point returned schema: type: integer default: 86400 responses: "200": description: A JSON document indicating success content: application/json: schema: $ref: '#/components/schemas/Stats' "401": description: A JSON document indicating error in request (user not authenticated) content: application/json: schema: $ref: '#/components/schemas/Error' "403": description: A JSON document indicating error in request (user doesn't have permission to preform this action) content: application/json: schema: $ref: '#/components/schemas/Error' """ await check_api_permissions(request, ["logs"]) try: datetime_from, datetime_to, granularity = ( get_datetime( request.query.get("start", ""), dt.datetime.now() - dt.timedelta(days=7), ), get_datetime(request.query.get("end", ""), dt.datetime.now()), dt.timedelta(seconds=int(request.query.get("granularity", 86400))), ) except ValueError as e: raise HTTPBadRequest( reason=str(e), body=json.dumps({"Ok": False, "Error": str(e), "status_code": 401}), content_type="application/json", ) stats = await get_grouped_logs( request.app, datetime_from, datetime_to, granularity ) return respond_with_json( {"Ok": True, "Error": None, "status_code": 200, "stats": stats} )
async def search(self, request: Request): result = [] if request.query is not None: query = request.query['q'] return respond_with_json(status=200, data=self.db_provider.search(query))
async def get(self, request: Request) -> Response: """ --- summary: Find information about an api key description: Decodes and returns token name, username of the user token is associated with, permissions that it has and the token itself security: - Bearer Authentication: [users_read] - X-API-Key Authentication: [users_read] - Session Authentication: [users_read] tags: - API - users parameters: - name: key in: query description: API token schema: type: string format: Branca - name: key in: path description: API token allowReserved: true schema: type: string format: Branca responses: "200": description: A JSON document indicating success content: application/json: schema: $ref: '#/components/schemas/APIKeyData' "401": description: A JSON document indicating error in request (user not authenticated) content: application/json: schema: $ref: '#/components/schemas/Error' "403": description: A JSON document indicating error in request (user doesn't have permission to preform this action) content: application/json: schema: $ref: '#/components/schemas/Error' "404": description: A JSON document indicating error in request (user not found) content: application/json: schema: $ref: '#/components/schemas/Error' """ await check_api_permissions(request, ["users_read"]) parameters = {**request.match_info, **request.query} if not parameters.get("key", False): raise HTTPBadRequest( reason="no key provided", body=json.dumps({ "Ok": False, "Error": "no key provided", "status_code": 401 }), content_type="application/json", ) key_data, user = await app["api_tokens"].get_token_info() if user == None: raise HTTPNotFound( reason="no user with requested key exists", body=json.dumps({ "Ok": False, "Error": "no user with requested data exists", "status_code": 404, }), content_type="application/json", ) token = { "name": key_data.get("token_name", None), "username": user.get("username", None), "permissions": key_data.get("permissions", None), "key": parameters.get("key", None), } return respond_with_json({ "Ok": True, "Error": None, "status_code": 200, "token": token })
async def post(self, request: Request) -> Response: """ --- summary: Generate a new api key security: - Bearer Authentication: [users_manage, self] - X-API-Key Authentication: [users_manage, self] - Session Authentication: [users_manage, self] tags: - API - users requestBody: description: JSON containing instructions to open or close the door. required: true content: application/json: schema: type: object properties: username: type: string description: The name of the user you want to create the token for required: true permissions: type: array description: Permission for the token - "*" means all permissions the user has (you can't give a token permissions that the user doesn't have) items: type: string enum: - admin - enter - logs - users_read - users_manage - cards - dashboard - "*" default: ["*"] token_name: type: string description: a friendly name for the token default: uuidv4() example: username: Administrator permissions: ["admin"] token_name: admin token responses: "200": description: A JSON document indicating success content: application/json: schema: $ref: '#/components/schemas/APIKeyData' "401": description: A JSON document indicating error in request (user not authenticated) content: application/json: schema: $ref: '#/components/schemas/Error' "403": description: A JSON document indicating error in request (user doesn't have permission to preform this action) content: application/json: schema: $ref: '#/components/schemas/Error' """ data = await request.json() username = data.get("username", False) if not username: raise HTTPBadRequest( reason="no username provided", body=json.dumps({ "Ok": False, "Error": "no username provided", "status_code": 401 }), content_type="application/json", ) user = await find_user_by_username(request.app, username, ["_id", "permissions"]) if user == None: raise HTTPNotFound( reason="no user with requested username exists", body=json.dumps({ "Ok": False, "Error": "no user with requested username exists", "status_code": 404, }), content_type="application/json", ) is_self = await check_if_self(request, user.get("_id", None)) required_permissions = list(data.get("permissions", [])) if data.get("permission", False): required_permissions.append(data["permission"]) if not is_self: required_permissions.append("users_manage") await check_api_permissions(request, required_permissions) key, token_name, permissions = app["api_tokens"].generate_token( username, data.get("token_name", None), data.get("permissions", ["*"]), ) token = { "name": token_name, "username": username, "permissions": permissions, "key": key, } return respond_with_json({ "Ok": True, "Error": None, "status_code": 200, "token": token })
async def put(self, request: Request) -> Response: """ --- summary: Create multiple new users description: security: - Bearer Authentication: [users_manage] - X-API-Key Authentication: [users_manage] - Session Authentication: [users_manage] tags: - users requestBody: description: JSON containing a list of new user objects required: true content: application/json: schema: type: object properties: users: type: array items: type: object properties: username: type: string description: username of the user you want to modify required: true password: type: string description: unhashed password that will be hashed before being added to the user cards: description: a single card or list of cards that will be assigned to the user oneOf: - type: array description: list of all cards that will be assigned to the user items: type: string format: mifare uid pattern: '^([0-9a-fA-F]{8}|([0-9a-fA-F]{14}|[0-9a-fA-F]{20})$' - type: string description: a single card that will be assigned to the user format: mifare uid pattern: '^([0-9a-fA-F]{8}|([0-9a-fA-F]{14}|[0-9a-fA-F]{20})$' permissions: description: a single permission or list of permissions that the user will have (you need to have a permission to assign it to others) oneOf: - type: array description: list of all permissions that the user will have items: type: string enum: - admin - enter - logs - users_read - users_manage - cards - type: string description: a single permission you want to give the user enum: - admin - enter - logs - users_read - users_manage - cards example: users: - username: example password: hunter2 cards: - ABABABAB - 12345678 permissions: enter - username: example2 password: hunter4 cards: FFFFFFFF permissions: - enter - cards - users_read responses: "200": description: A JSON document indicating success along with some information about the user content: application/json: schema: $ref: '#/components/schemas/User' "401": description: A JSON document indicating error in request (user not authenticated) content: application/json: schema: $ref: '#/components/schemas/Error' "403": description: A JSON document indicating error in request (user doesn't have permission to preform this action) content: application/json: schema: $ref: '#/components/schemas/Error' "409": description: A JSON document indicating error in request (user already exists) content: application/json: schema: $ref: '#/components/schemas/Error' """ data = await request.json() if isinstance(data.get("users", None), list): users = data["users"] elif isinstance(data.get("users", ""), str): users = [data.get("users", "")] else: raise HTTPBadRequest( reason="no users provided", body=json.dumps({ "Ok": False, "Error": "no users provided", "status_code": 401 }), content_type="application/json", ) permissions = set() for user in users: user_permissions = user.get("permissions", []) if not isinstance(user_permissions, list): user_permission = [user_permissions] permissions.update(set(user_permissions)) await check_api_permissions(request, ["users_manage", *permissions]) result_users = [] for user_data in users: username = user_data.get("username", False) if not username: raise HTTPBadRequest( reason="no username provided for at least one user", body=json.dumps({ "Ok": False, "Error": "no username provided for at least one user", "status_code": 401, }), content_type="application/json", ) user = await user_exists(request.app, username) if user: raise HTTPConflict( reason= f"User with this username ({username}) already exists", body=json.dumps({ "Ok": False, "Error": f"User with this username ({username}) already exists", "status_code": 409, }), content_type="application/json", ) cards = user_data.get("cards", []) if not isinstance(cards, list): user_data["cards"] = [cards] await register_users(request.app, users) users = [{ "username": user.get("username"), "cards": user.get("cards", []), "permissions": user.get("permissions", []), } for user in users] return respond_with_json({ "Ok": True, "Error": None, "status_code": 200, "users": users })
async def put(self, request: Request) -> Response: """ --- summary: Create a new user description: security: - Bearer Authentication: [users_manage] - X-API-Key Authentication: [users_manage] - Session Authentication: [users_manage] tags: - users requestBody: description: JSON containing the changes to the user and/or their username to find them required: true content: application/json: schema: type: object properties: username: type: string description: username of the user you want to modify required: true password: type: string description: unhashed password that will be hashed before being added to the user cards: oneOf: - type: array description: list of all cards that will be assigned to the user items: type: string format: mifare uid pattern: '^([0-9a-fA-F]{8}|([0-9a-fA-F]{14}|[0-9a-fA-F]{20})$' - type: string description: a single card that will be assigned to the user format: mifare uid pattern: '^([0-9a-fA-F]{8}|([0-9a-fA-F]{14}|[0-9a-fA-F]{20})$' permissions: oneOf: - type: array description: list of all permissions that the user will have items: type: string enum: - admin - enter - logs - users_read - users_manage - cards - type: string description: a single permission you want to give the user enum: - admin - enter - logs - users_read - users_manage - cards example: username: example password: hunter2 cards: - ABABABAB - 12345678 permissions: enter responses: "200": description: A JSON document indicating success along with some information about the user content: application/json: schema: $ref: '#/components/schemas/User' "401": description: A JSON document indicating error in request (user not authenticated) content: application/json: schema: $ref: '#/components/schemas/Error' "403": description: A JSON document indicating error in request (user doesn't have permission to preform this action) content: application/json: schema: $ref: '#/components/schemas/Error' "409": description: A JSON document indicating error in request (user already exists) content: application/json: schema: $ref: '#/components/schemas/Error' """ data = await request.json() permissions = data.get("permissions", []) if not isinstance(permissions, list): permissions = [permissions] await check_api_permissions(request, ["users_manage", *permissions]) username = data.get("username", False) if not username: raise HTTPBadRequest( reason="no username provided", body=json.dumps( {"Ok": False, "Error": "no username provided", "status_code": 401} ), content_type="application/json", ) user = await user_exists(request.app, username) if user: raise HTTPConflict( reason="User with this username already exists", body=json.dumps( { "Ok": False, "Error": "User with this username already exists", "status_code": 404, } ), content_type="application/json", ) cards = data.get("cards", []) if not isinstance(cards, list): cards = [cards] uid = register_user( request.app, username, data.get("password", None), permissions, cards ) user = find_user_by_uid(request.app, uid, ["username", "cards", "permissions"]) return respond_with_json( {"Ok": True, "Error": None, "status_code": 200, "user": user} )