Groups keyboard shortcuts have been updated
Dismiss
See shortcuts

How to do has_permission() for a different identity?

17 views
Skip to first unread message

Sean Hammond

unread,
Nov 26, 2024, 8:48:31 AM11/26/24
to pylons-...@googlegroups.com
How can a Pyramid app do a permissions check for an identity that *isn't* the identity authenticated by the current request?

For example our app has an API that users can use to flag a post in a group as inappropriate. When this happens the app sends a notification email to every user who has permission to moderate posts in the group (all the group's moderators). So the code needs to iterate over all the group's members and ask "Does this user have permission to moderate posts in this group?"

In our app the way we've implemented this is that our security policy's `permits(request, context, permission)` method delegates to an `identity_permits(identity, context, permission)` function:

class MySecurityPolicy:
...
def permits(self, request, context, permission):
return identity_permits(request.identity, context, permission)

def identity_permits(identity, context, permission):
...

The view code that sends these email notifications can then do something like this:

context = MyContext(...)

for user in group.users:
identity = MyIdentity(user, ...)

if identity_permits(identity, context, permission="moderate"):
# Send the email.

But I'm wondering if there's a more pure Pyramid way to do this, without the custom `identity_permits()` indirection?

I think you might have to do something like this:

context = MyContext(...)
for user in group.users:
request = Request(...)
if request.has_permission(context, permission="moderate"):
# Send the email.

That is: construct a request object for each user just to make one has_permission() call on that request object.

But this requires there to be a way to construct a request object that will read as authenticated as a particular user. May need to use paster_bootstrap()?

Thanks!

Michael Merickel

unread,
Nov 26, 2024, 10:21:08 AM11/26/24
to pylons-...@googlegroups.com, pylons-...@googlegroups.com
Pyramid does supply an interface for this called principals_allowed_by_permission(context, permission) but it is often hard to implement. It was removed from the new security policy as a feature but there’s nothing stopping you from doing something similar in your own code.

Your goal should be to write an efficient database query to load the list of users with permission instead of iterating the users and testing them in memory to keep your logic scalable.

> On Nov 26, 2024, at 06:48, Sean Hammond <pylons-...@snhmnd.fastmail.com> wrote:
>
> How can a Pyramid app do a permissions check for an identity that *isn't* the identity authenticated by the current request?
> --
> You received this message because you are subscribed to the Google Groups "pylons-discuss" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to pylons-discus...@googlegroups.com.
> To view this discussion visit https://groups.google.com/d/msgid/pylons-discuss/d324d643-7682-41b3-8c8b-f574634ae7ec%40app.fastmail.com.

Sean Hammond

unread,
Nov 26, 2024, 1:07:01 PM11/26/24
to pylons-...@googlegroups.com
> Pyramid does supply an interface for this called
> principals_allowed_by_permission(context, permission) but it is often
> hard to implement. It was removed from the new security policy as a
> feature but there’s nothing stopping you from doing something similar
> in your own code.

Oh, interesting. Yes I suppose we could implement a function that accepts one of our context objects and one of our "moderate" permissions and returns a list of all a group's moderators (or their IDs). That function could be called both when checking whether an individual user is a moderator in a group, and when needing to get a list of all a group's moderators.

> Your goal should be to write an efficient database query to load the
> list of users with permission instead of iterating the users and
> testing them in memory to keep your logic scalable.

This is great advice, and actually in the example I gave we did end up implementing it with just a DB query to find all the group's moderators and not going through Pyramid permissions at all. It results in some duplicate logic between this DB query and our security policy, but it's scalable.

But I was just left wondering what Pyramid's solution was to the general problem of needing to query about a permission but not just for the current request's authenticated identity.
Reply all
Reply to author
Forward
0 new messages