-
Notifications
You must be signed in to change notification settings - Fork 136
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feat/endpoint authorization #849
Conversation
I think the structure is not quite there.
|
I would follow a slightly different structure:
Wdyt? |
You mean to use a basic structure like this in
I was thinking about using a structure like the one used for entities for endpoints as well, but it seems reasonable to have different forms for both cases. I'd like to hear your thoughts about how to be specific for a route (considering that a route is made of both HTTP Method and Path). This way only the Path is being considered. More general questions are:
|
I don't really get your previous comment. The first step I recommended is to add a single |
Alright! I've just pushed with what I imagine that is the first step using the approach that you seem to be talking about. I followed the approach suggested by @ivan-tymoshenko to provide a method to be called inside the handler, but in terms of developer experience I think it would be better to do it before that and make it invisible for developers. It might be a bit more difficult to implement because of the way that we deal with request hooks and plugins at fastify core (I don't know much, it's my first time using it). I still have a doubt about using on |
packages/db-authorization/index.js
Outdated
@@ -61,6 +61,37 @@ async function auth (app, opts) { | |||
} | |||
} | |||
|
|||
app.addHook('onRoute', function () { | |||
app.addHook('onRequest', function (request, reply, done) { | |||
request.authorize = async () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this could be implemented as
app.decorateRequest('authorize', authorizeFn)
Instead of using the hooks.
Signed-off-by: Luiz Ribeiro <ltrindaderibeiro@gmail.com>
wdyt @ivan-tymoshenko ? |
await request.extractUser() | ||
|
||
const authorizationMatch = endpointRules.find(rule => { | ||
if (rule.role === request.user['X-PLATFORMATIC-ROLE'] && rule[restMapper[request.method]]) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (rule.role === request.user['X-PLATFORMATIC-ROLE'] && rule[restMapper[request.method]]) { | |
if (rule.role === request.user[rokeKey] && rule[restMapper[request.method]]) { |
return !!request.raw.url.match(endPointRegEx) | ||
} | ||
return false | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The whole point of adding a decorator is to support not doing this in here. We want to provide a generic utility folks could use manually.
Then we use the data in rule.endpoint
to automatically add a preHandler
that call this endpoint with the given rule.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't get the part about using it manually. Do you mean something like passing the rules to req.authorize()
like @ivan-tymoshenko said?
It looks a bit confusing to me to be honest. I like the idea of using preHandler
to prevent calling req.authorize()
inside the plugin, but I'm not sure if it is possible if it's not using all the authorization rules from a configuration files
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I find this idea confusing too... @mcollina ..😉🙂
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see the idea of defining all rules in one file, but I don't like the idea of mapping custom routes to the rules/entities manually. It would be impossible to maintain it with a real application. I would prefer an explicit request.authorize(rules)
call.
const endpointRules = opts.rules.filter(rule => { | ||
if (rule?.endpoint) { | ||
const endPointRegEx = new RegExp(rule.endpoint) | ||
return !!request.raw.url.match(endPointRegEx) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would not work for all possible fastify routes. It should work for parametric and regexp routes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The idea behind this was to use a root/base endpoint to cover the parametric routes. I agree that it is not ideal though. A rule using the endpoint /pages
would also cover /pages/pageId
.
I did not think about how to cover regexp rules.
return false | ||
}) | ||
|
||
const restMapper = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why only these methods?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still wip, there is still a lot to be done on this
roleKey: 'X-PLATFORMATIC-ROLE', | ||
anonymousRole: 'anonymous', | ||
rules: [{ | ||
role: 'user', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand what this rule means. find, save, and delete should be related to some entity.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not a big fan of this either. It was implemented like that to look like the rules provided for entities
Co-authored-by: Matteo Collina <matteo.collina@gmail.com>
Hey folks! I was still working on this but it was nice to have a review from both of you. If the spec becomes to big it might be worth to split it in a few features to have it fully covered. My main concerns at this point are:
|
closing for no updates |
Hey @mcollina, @ivan-tymoshenko.
Have a look on the initial draft for endpoint based access control.
Let me know if I'm missing out something.