Example #1
0
    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)
Example #2
0
 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)
Example #3
0
    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)
Example #4
0
 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)
Example #5
0
    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
        })
Example #6
0
    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)
Example #7
0
 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)
Example #10
0
 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)
Example #11
0
    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}
        )
Example #14
0
    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
        })
Example #15
0
    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
        })
Example #16
0
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})
Example #18
0
    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))
Example #20
0
    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
        })
Example #21
0
    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
        })
Example #22
0
    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}
        )