librelist archives

« back to archive

Flask-Principal: ItemNeed example

Flask-Principal: ItemNeed example

From:
Luca Lesinigo
Date:
2011-12-11 @ 15:02
I'm evaluating Flask-Principal because I need some security / identity / 
permissions system in the app I'm developing. The most common use case 
I'll have is if a user can 'see' a particular instance of an object and if
the user can also 'edit' the same instance. In other words, if the User 
has no access, readonly access, readwrite access to a specific instance of
an object.

I started by studying the examples on Flask documentation and they seem to
compute and store each and every specific Permission, at every request 
start up, for the logged in user: 
http://packages.python.org/Flask-Principal/#authentication-providers

I'll be dealing with many objects, thousands of them, and such approach is
totally out of question. What I'd like to do is write a function that'll 
compute if/what access the user has to the given resource, and call that 
function for the specific resource.

As an example, if the logged in user Foo tries to GET /resource/123 I want
to add to the relevant method a decorator that would end up calling 
something like check_read_access(Foo, 123) and act upon the result.

Is that something I can implement using Flask-Principal, or would it be 
better to implement independently (maybe leveraging Flask-Login for user 
id and adding just the permissions part)?

thanks,
--
Luca Lesinigo

Re: [flask] Flask-Principal: ItemNeed example

From:
Amirouche Boubekki
Date:
2011-12-11 @ 19:30
2011/12/11 Luca Lesinigo <luca@lesinigo.it>

> As an example, if the logged in user Foo tries to GET /resource/123 I want
> to add to the relevant method a decorator that would end up calling
> something like check_read_access(Foo, 123) and act upon the result.
>

I was looking for something like that too, so I started an extension for
that [0]. I never got to the point of permissions management. My plan was
to require a ``can`` [1] method to User objects which would have been
implemented by the developer.

Planned API was:

@app.route('/post/<int:identifier>')
def read(identifier):
    # do something with this object

It should be possible to decorate it with:

@door.need(Post, 'read', 'identifier')
@app.route('/post/<int:identifier>')
def read(identifier):
    # do something useful

The permission decorator will compute the Permission object and pass it to
the ``current_user.can`` method which would finally do the math and answer
True/False.

``can`` method can be rather complex that why it's left to the developer to
write [2]

Whatever this just my rambling about this subject.

Flask-Login maintainer did not explain why he is using it's own
implementation of secured cookie, and the API wasn't cool enough. That why
I started Flask-Door in the first place.

If Flask-Door looks nice enough, go fork it and implement the missing
``need`` decorator. There is bunch of tests that should run and help you
integrate Door in your application.

HTH,



[0] https://bitbucket.org/abki/flask-door/src
[1]
http://packages.python.org/Flask-Principal/#flaskext.principal.Identity.can
[2] My understanding is that general permission problem is a graph problem
which is not possible to solve efficently in a RDBMS