Comments (16)
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.
I got the issue, will provide a fix soon. I simply need to figure out the best way to fix this! 😃
from adonis-guard.
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.
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.
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.
Hey @wuzi! 👋
It should work fine.
Could you please give me a repository with the reproducible example?
from adonis-guard.
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.
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.
@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.
@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.
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.
@RomainLanz Roger that! Thx for your time!
from adonis-guard.
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.
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.
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.
Happy to accept a PR @FrenchMajesty!
from adonis-guard.
Related Issues (9)
- Unable to switch between auth scheme for a policy HOT 1
- How to add active class to current page in nav bar? HOT 1
- Upgrade to v5 HOT 1
- How can I pass an additional parameter to the policy?
- Examples HOT 1
- guard.denies is always true HOT 13
- how can I test my routes to check that they have the right policy? HOT 4
- Async Gate functions issue HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from adonis-guard.