Beispiel #1
0
    async def remover(self, request: Request, path: str = None):
        path_ = f"/{path or ''}"
        try:
            paper = await self.get_path(path_, self._models, 0)
            paper._table = request.app._table
        except NotFound as e:
            return ErrorMessage(message=e.args[0], code=404)

        perm = await self._models.Permission.get(self._table,
                                                 context=paper.type,
                                                 name="remove")
        token = AuthToken.get(request.headers)
        actor = await token.get_actor(self._table, self.config["JWT_SECRET"],
                                      self._models.User)
        # actor = await self._models.User.get(self._table, slug = "garito")
        if not await perm.allows(actor, paper):
            return ErrorMessage(message="Unauthorized", code=401)

        member = getattr(paper, "remove")
        if member is None:
            member = self._generic_remover
            args = [request, paper, actor]
        else:
            args = [request, actor]

        try:
            result = await member(*args)
            return OkListResult(result=result)
        except Exception as e:
            message = format_exception(*exc_info()) if request.app.config.get(
                "DEBUG", False) else str(e)
            for line in message:
                logger.error(line)
            return ErrorMessage(message=message, code=500)
Beispiel #2
0
 async def updater(self, request, path: str = None):
     try:
         data = SetupModeRequest(**request.json)
         await request.app._root_model.setup(request, data)
         return response.json(Ok())
     except TypeError as e:
         return response.json(ErrorMessage(message=e.args[0], code=400),
                              400)
     except Unauthorized as e:
         return response.json(ErrorMessage(message=e.args[0], code=401),
                              401)
Beispiel #3
0
    async def updater(self, request: Request, path: str = None):
        if request.json is None:
            return ErrorMessage(message=f"Data must be provided", code=400)

        path_ = f"/{path or ''}"
        try:
            paper = await self.get_path(path_, self._models, 1)
            paper._table = request.app._table
        except NotFound as e:
            return ErrorMessage(message=e.args[0], code=404)

        url = paper.get_url()
        member = path_.replace(url, "")[1:] if url > "/" else path_[1:]
        if not member:
            member = "update"

        perm = await self._models.Permission.get(self._table,
                                                 context=paper.type,
                                                 name=member)
        token = AuthToken.get(request.headers)
        actor = await token.get_actor(self._table, self.config["JWT_SECRET"],
                                      self._models.User)
        # actor = await self._models.User.get(self._table, slug = "garito")
        if not perm or not await perm.allows(actor, paper):
            return ErrorMessage(message="Unauthorized", code=401)

        args = [request]
        _introspection = self._introspection[paper.type]["call" if member ==
                                                         "index" else member]
        if "actor" in _introspection:
            args.append(actor)

        consumes = _introspection.get("consumes", None)
        try:
            model = consumes(**request.json)
            args.append(model)
        except TypeError as e:
            return ErrorMessage(message=f"Validation error: {e}", code=400)

        try:
            result = await getattr(paper, member)(*args)
            if isinstance(result, Tree):
                result = result.to_plain_dict()
            return OkListResult(result=result, code=200) if isinstance(
                result, list) else OkResult(result=result, code=200)
        except Exception as e:
            message = format_exception(*exc_info()) if request.app.config.get(
                "DEBUG", False) else str(e)
            for line in message:
                logger.error(line)
            return ErrorMessage(message=message, code=400)
Beispiel #4
0
    async def factory(self, request, model, path: str = None):
        path_ = f"/{path or ''}"
        try:
            paper = await self.get_path(path_, self._models, 0)
            paper._table = request.app._table
        except NotFound as e:
            return ErrorMessage(message=e.args[0], code=404)

        if f"create_{model}" in self._introspection[paper.__class__.__name__]:
            theModel = self._introspection[
                paper.__class__.__name__][f"create_{model}"]["consumes"]
        else:
            theModel = getattr(self._models, model.capitalize())

        try:
            consume = theModel.from_dict(request.json)
        except TypeError as e:
            return ErrorMessage(message=e.args, code=400)

        perm = await self._models.Permission.get(self._table,
                                                 context=paper.type,
                                                 name=f"create_{model}")
        token = AuthToken.get(request.headers)
        actor = await token.get_actor(self._table, self.config["JWT_SECRET"],
                                      self._models.User)
        # actor = await self._models.User.get(self._table, slug = "garito")
        if not await perm.allows(actor, paper):
            return ErrorMessage(message="Unauthorized", code=401)

        member = getattr(paper, f"create_{model}", None)
        if member is None:
            member = self._generic_factory
            args = [request, paper, actor, consume]
        else:
            known = {"request": request, "actor": actor, "consume": consume}
            args = [
                known[param] for param in signature(member).parameters
                if param in known.keys()
            ]

        try:
            result = await member(*args)
            if isinstance(result, Tree):
                result = result.to_plain_dict()
            return OkResult(result=result, code=201)
        except DuplicateKeyError:
            return ErrorMessage(
                message=f"{consume.name} already exists @ {paper.name}",
                code=409)
Beispiel #5
0
    async def change_password(self, request: Request,
                              consume: ChangePasswordRequest) -> Ok:
        """Allows to change the actor's password"""
        if not check_password_hash(self.password, consume.old):
            return ErrorMessage("Bad old password", 401)

        await self.update(request.app._models, password=consume.new)
Beispiel #6
0
    async def auth(self, request: Request):
        if request.json is None:
            return ErrorMessage(message=f"Data must be provided", code=400)

        root = await self._root_model.get(self._table, path="")
        auth = self._models.Auth(**request.json)
        return await root.auth(request, auth)
Beispiel #7
0
 async def auth(self, request: Request, consume: Auth) -> AuthToken:
     """Authorizes email and password"""
     token = await consume.authorize(self._table,
                                     request.app.config["JWT_SECRET"],
                                     request.app._models.User)
     return token if token else ErrorMessage("The autentication has failed",
                                             401)
Beispiel #8
0
    async def forgot_password(self, request: Request,
                              consume: ForgotPasswordRequest) -> Ok:
        """Sends a password recovery mail to the specified mail"""
        from sanic.log import logger

        user = await request.app._models.User.get(self._table,
                                                  email=consume.email)
        if not user:
            return ErrorMessage("Unregistered email", 404)

        prevToken = await PasswordResetToken.get(self._table,
                                                 email=consume.email)
        if prevToken:
            return ErrorMessage("Already requested", 429)

        token = PasswordResetToken(consume.email, path="/")
        token._table = self._table
        await token.create()

        await request.app.notify(request,
                                 'forgot_password',
                                 actor=user,
                                 token=token)