librelist archives

« back to archive

Flask-Principal - Creating multiple identity instances

Flask-Principal - Creating multiple identity instances

From:
A B
Date:
2013-01-16 @ 07:06
This is a weird question.  I've just started using Flask-Principal for role
based permissions in a multiple blueprint app.

I'm using the most recent version of  Principal (0.3.3) in conjunction with
the most current version of Flask-Login (for authentication).  When I
perform a login I make the call to:

identity_changed.send(app, identity=Identity(login.id))

I also follow the code in the documentation for connecting the
identity_loaded signal as follows:

@identity_loaded.connect_via(app)
def on_identity_loaded(sender, identity):
 identity.user = current_user
if hasattr(current_user, 'role'):
identity.provides.add(RoleNeed(current_user.role))

Disregard the fact that I'm not supporting multiple roles like the example,
shouldn't be important.

So I get everything that's going on so far.  I go through login process,
get redirected to the resource with a permission directive, and then I get
a 'flask_principal.PermissionDenied' exception.

After debugging as much as I could I discovered that there are multiple
identity objects being created in the @identity_loaded signal (not sure why
since I only call that identity_changed.send once and only once upon
successful log in), 6 instances to be exact.  The problem appears to be
that when [current_user] is an actual object it populates the 5th identity
objects [provides] property but subsequently the next identity object that
is being associated with the PrincipalPermission object has no
[identity.provides] entries and therefore I get the PermissionDenied
exception.

Based on the documentation this should work properly, so I'm not sure if
I'm in left field or in the parking lot.

Any help would be greatly appreciated.

Re: [flask] Flask-Principal - Creating multiple identity instances

From:
Patrick Landis
Date:
2013-01-16 @ 14:26
I believe by default before each request flask-principal will try to load
an identity from a session in addition to any you manually load, this might
be why you're loading multiple identities.

To disable the sessions loader when you instantiate Principal make sure one
of the arguments is use_sessions = False


On Wed, Jan 16, 2013 at 2:06 AM, A B <mi.rubbish@gmail.com> wrote:

> This is a weird question.  I've just started using Flask-Principal for
> role based permissions in a multiple blueprint app.
>
> I'm using the most recent version of  Principal (0.3.3) in conjunction
> with the most current version of Flask-Login (for authentication).  When I
> perform a login I make the call to:
>
> identity_changed.send(app, identity=Identity(login.id))
>
> I also follow the code in the documentation for connecting the
> identity_loaded signal as follows:
>
> @identity_loaded.connect_via(app)
> def on_identity_loaded(sender, identity):
>  identity.user = current_user
> if hasattr(current_user, 'role'):
> identity.provides.add(RoleNeed(current_user.role))
>
> Disregard the fact that I'm not supporting multiple roles like the
> example, shouldn't be important.
>
> So I get everything that's going on so far.  I go through login process,
> get redirected to the resource with a permission directive, and then I get
> a 'flask_principal.PermissionDenied' exception.
>
> After debugging as much as I could I discovered that there are multiple
> identity objects being created in the @identity_loaded signal (not sure why
> since I only call that identity_changed.send once and only once upon
> successful log in), 6 instances to be exact.  The problem appears to be
> that when [current_user] is an actual object it populates the 5th identity
> objects [provides] property but subsequently the next identity object that
> is being associated with the PrincipalPermission object has no
> [identity.provides] entries and therefore I get the PermissionDenied
> exception.
>
> Based on the documentation this should work properly, so I'm not sure if
> I'm in left field or in the parking lot.
>
> Any help would be greatly appreciated.
>
>
>
>

Re: [flask] Flask-Principal - Creating multiple identity instances

From:
A B
Date:
2013-01-16 @ 17:04
Patrick, thanks for the heads up on the use_sessions parameter.
 Unfortunately that didn't seem to solve the problem, instead of Identity
objects with improper provides set I received a single AnonymousIdentity
which didn't work.

I figured out what appears to be a working solution, but I'd be interested
in getting feedback as the creation of multiple Principal Identity objects
just feels wrong.

Instead of using the current_user proxy provided by Flask-Login (which
wasn't always around) I am instead making a call to load my login object
each time like this:

@identity_loaded.connect_via(app)
def on_identity_loaded(sender, identity):
login = Login.query.get(identity.name)
identity.user = login
if hasattr(login, 'role'):
identity.provides.add(RoleNeed(login.role))

Again, this seems to do the trick.  But I'm still a little leery about the
multiple identities as well as the current_user proxy.  Any further
insights would be appreciated, but I'll probably continue to test and go
with this work around.