Giter Site home page Giter Site logo

async policy method about adonis-guard HOT 16 OPEN

romainlanz avatar romainlanz commented on June 18, 2024
async policy method

from adonis-guard.

Comments (16)

RomainLanz avatar RomainLanz commented on June 18, 2024 2

by looking at the code it seems you have forgotten to await the call to guard.denies().

if (await guard.denies('store', new User()))
  return response.status(403).json({ message: 'You don\'t have permission' })

from adonis-guard.

RomainLanz avatar RomainLanz commented on June 18, 2024 2

I got the issue, will provide a fix soon. I simply need to figure out the best way to fix this! 😃

from adonis-guard.

jayrchamp avatar jayrchamp commented on June 18, 2024 1

@RomainLanz

After a few tests, I realized that await guard.allows() works with async calls since it returns the promise that has been automatically resolved by the async Policy or GateName.

await guard.denies() use the logical “not” operator to return the opposite of allows which is perfectly normal, but I just noticed that this is causing the issue. await guard.denies() can't return the promise resolved by the async Policy/GateName since it tries to convert it to a boolean.

Please, correct me if I'm mistaken something.

It would be much appreciated if you could just give me your 2 cents about this below ->

Not a fan of monkey patching but as a temporary solution and since I'm not using Edge Templating, what do you think of this?

  • Use a custom GuardInit middleware
  • Overwrite denies and make it async.
  • Set default user and add guard in context
'use strict'

const { Guard } = require('@slynova/fence')

class MyCustomGuardInitMiddleware {
    async handle (ctx, next) {

        /*
        |--------------------------------------------------------------------------
        |   Monkey patching to allow async call inside `guard.denies`
        |--------------------------------------------------------------------------
        */
        Guard.prototype.denies = async function (ability, resource, user) {
            return !(await this.allows(ability, resource, user))
        }

        const guard = Guard.setDefaultUser(ctx.auth.user || null)

        /**
         * Add guard in context
         */
        ctx.guard = guard

        await next()
    }
}

module.exports = MyCustomGuardInitMiddleware
// start/kernel.js

const globalMiddleware = [
      // ...
    - 'Adonis/Middleware/GuardInit',
    + 'App/Middleware/MyCustomGuardInitMiddleware',
      // ...
]

Thx for your help! Greatly appreciated!

from adonis-guard.

woodgates avatar woodgates commented on June 18, 2024 1

Hi @jayrchamp
I was having the same issue and after reading your post I changed 'denies' for 'allows' and now it works well. thanks!

from adonis-guard.

RomainLanz avatar RomainLanz commented on June 18, 2024 1

Sorry for the late reply @jayrchamp.

Yes, this is what should be done to fix this issue.
I'm going to release a fix and add a statement in the README about denies not working with Edge.

Also, when you are monkey patching, you only want to monkey patch something once and not at every requests. Therefore, it's better to do it in a Provider or a Hook instead of using a Middleware.

from adonis-guard.

RomainLanz avatar RomainLanz commented on June 18, 2024

Hey @wuzi! 👋

It should work fine.
Could you please give me a repository with the reproducible example?

from adonis-guard.

wuzi avatar wuzi commented on June 18, 2024

Hey, sure:
https://github.com/Wuzi/testing

I've added two routes (/guard1, /guard2) one with async and one without both returning false, needs to authenticate first using POST /register sending username, email, password and password_confirmation.

from adonis-guard.

wuzi avatar wuzi commented on June 18, 2024

For a second I thought that could be it, but even with await guard.denies('store', new User()) i got the same result.

from adonis-guard.

jayrchamp avatar jayrchamp commented on June 18, 2024

@RomainLanz
Hey Romain!

I saw that async/await has been removed from Guard.denies and Guard.allows in Slynova-Org/fence on that commit here:
Slynova-Org/fence@efa3351#diff-7ea95c2e44479d89952a76cf682ac915

Any reason of why it has been changed back?

I would have also like to make async call in Policies and GateNames and to make that happen I promisified denies and allows exactly like in that commit above. But I was just wondering has why you change it back and removed async from these methods.

Cheers :)

from adonis-guard.

jayrchamp avatar jayrchamp commented on June 18, 2024

@RomainLanz
These were the changes I made in a fork to make my async calls work:

// src/guard/index.ts

  /**
   * Check the bouncer if the gate/policy allows the user.
   *
   * @param ability  Ability to test
   * @param resource Resource to test
   * @param user     Optional. User to verify
   */
  public async allows (ability: string, resource: TResource, user: Function | object | undefined): Promise<boolean> {
    const usedUser = (user !== undefined) ? user : this.$user

    try {
      if (this.$correspondsToPolicy(resource)) {
        return (new Bouncer(usedUser)).callPolicy(ability, resource)
      }

      return (new Bouncer(usedUser)).pass(ability).for(resource)
    } catch (e) {
      return false
    }
  }
// src/guard/index.ts

  /**
   * Check the bouncer if the gate/policy denies the user.
   *
   * @param ability  Ability to test
   * @param resource Resource to test
   * @param user     Optional. User to verify
   */
  public async denies (ability: string, resource: TResource, user: Function | object | undefined): Promise<boolean> {
    return !( await this.allows(ability, resource, user))
  }

I know this is more related with slynova-org/fence than adonis-guard. But since it's kind of related with this issue, I thought posting it here would make sense.

from adonis-guard.

RomainLanz avatar RomainLanz commented on June 18, 2024

Yes, that's the fix.

The issue is that it doesn't work if you are using the @cannot tag because Edge cannot be async.
@thetutlage is looking into it to maybe make Edge 2 async.

from adonis-guard.

jayrchamp avatar jayrchamp commented on June 18, 2024

@RomainLanz Roger that! Thx for your time!

from adonis-guard.

jayrchamp avatar jayrchamp commented on June 18, 2024

@RomainLanz

Also, when you are monkey patching, you only want to monkey patch something once and not at every requests. Therefore, it's better to do it in a Provider or a Hook instead of using a Middleware.

So true, didn't think of it. Thanks a lot !

from adonis-guard.

jayrchamp avatar jayrchamp commented on June 18, 2024

@woodgates

I was having the same issue and after reading your post I changed 'denies' for 'allows' and now it works well. thanks!

Glad it helped!

from adonis-guard.

FrenchMajesty avatar FrenchMajesty commented on June 18, 2024

I am also going to restructure my API to use allows instead and then simply check if it is false but this fix on async guard.denies would be greatly appreciated.

from adonis-guard.

RomainLanz avatar RomainLanz commented on June 18, 2024

Happy to accept a PR @FrenchMajesty!

from adonis-guard.

Related Issues (9)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.