Adding users to a group automatically after login using a PAS plugin

Continuing the discussion from Installing (and removing) a new PlonePAS plugin:

The idea behind my authentication plugin is to give users some power on a Plone site (but not too much). We are talking about a huge database of more than one million users.

I was thinking on creating a virtual group similar to Authenticated Users (AuthenticatedUsers) but I have no idea how to implement that.

I'm not providing any way to modify the user properties (that's out of the scope); right now I only need to give them the ability of:

  • access to forms to request some services
  • upload files on specific folders (subject to review and approval)

I also want to hide the Preferences user action.

any hints?

which problem are you trying to solve that Plone doesn't handle out of the box? Perferences can be disabled in portal_actions. A group can be created for your users and used enable access to a form in a certain folder and allow Creator access into a certain folder which has restrictions to only "File" objects.

Another alternative, depending on @hvelarde's comfort with its (security by obscurity might be good enough) implications: use CSS to "hide" some of this based on role. You can write selectors using the userrole-* class names on the body element to modify (or hide) elements on the page based on role:

body.userrole-manager #user-name {
  font-size:300%;  /* admins have big egos, adjust appropriately */
}

or a condition on the (portal) actions ?

I think I was not very clear on my question; first let me remove the issue about the Preferences link as it can be solved with a condition as @espenmn suggested: by default is set as python:member is not None and I can add a second condition to test if the users doesn't belongs to a special group; that's a little bit more clear now.

so, going back a little bit: how should I do that? according to Products.PlonePAS group interfaces there must be a way to add a user automatically to a group and specify roles for a certain group but I was not able to activate that code.

so, there should be a better way to handle this than creating a normal group and adding the user to it manually.

theoretically, every time the user logs in the site using this PAS plugin it must be added to a special group and every time the user logs out it must be removed from that group.

something similar to the way the special group Authenticated Users works.

It's still unclear Hector, why you would not simply use the Authenticated Users group. The scenario you specify ends up being algorithmically identical to that. Since you apparently don't want that, it seems you may have left out some details that may be relevant to find a solution.

because some users (staff persons) may log in using Plone standard mechanism.

the PAS plugin will give citizens registered in a special database of the municipality access to certain features and I have no way to differentiate among them and staff persons as the authentication server validates if a user is registered and returns only an identifier.

how can you manage the site otherwise?

So it appears what you want is this

  • you have multiple ways to.login, one being a new PAS plugin with a lot of users being possible
  • you want a way to give access to certsin things only to anyone of those logged in only from that PAS plugin
  • a group would probably be best

Seems you can create a new PAS plugin that only does IGroupIntrospection. Then use it to return the current logged in user as the only member of your special group if they pass some condition, eg have a user property that says they come from that pas authorisation plugin. Should be no problem.having multiple IGroupIntrospection plugins.

BTW this might make a generically useful plugin, autogroup. Consider making the condition a tal expersion so others can use this.

thank you, very much; I ended up sub-classing the AutoGroup class included in Products.PlonePAS and patched @jensens's installation method to support both plugin types.

I can see now a new virtual group in Plone's group configlet; seems to be working because it doesn't break any of the management pages.

now I need to test if my user is part of this virtual group by default.

how can I do that? can you point me to some code example?

1 Like

Not sure what that autogroup is used for but it seems to be a group you automatically have which has the same name as your username.

Just saying it would be a nice addition to Products.PlonePAS to have an AutoGroupsWithCondition Plugin that has an additional property of a list of [(groupname,tal-condition)] pairs. This could then be configured via the ZMI (or it could be in the registry).

Then anyone could go in an add a new auto group by adding ('Sena Web Users', 'python:user.getProperty('authenticated_by',None) == 'Sena') to the list in the properties of that plugin. Assuming your auth plugin set that property on its users. Then no subclassing required. The code required to interpret a tal expression is not hard to find (e.g. https://github.com/collective/collective.listingviews/blob/master/src/collective/listingviews/browser/views/base.py#L220)

@hvelarde What kind of criteria you have for those groups? Plone ships with Dynamic Groups Plugin, which allows autogrouping users on the base of TAL expression.

@djay How would that differ from the current Dynamic Groups Plugin?

sounds exactly the same. I just never heard of the Dynamic Groups plugin. Documentation looks a little thin on the ground. http://docs.plone.org/4/en/old-reference-manuals/pluggable_authentication_service/plugins/plugin-types/groups-plugins.html#id2

Might need to update the manual with something like this? http://www.uwosh.edu/ploneprojects/docs/how-tos/how-to-create-a-dynamic-group

1 Like

quite easy: any user authenticated using my plugin should be member of this new group.

that sounds awesome! how can enable that without having to create a new autogroup?

ah, wait, seems @djay already pointed the documentation… that is way too easy to be true :slight_smile:

let me test it.

In this case, I would let your plugin also implement the group interface for user->group association.

I tried but is not working; this is what I did:

  1. on the ZMI, I selected my Plone site's acl_users object
  2. I added a "Dynamic Groups Plugin" with an id and title
  3. I opened my new plugin and added a group with an id and title; I set a predicate to a TAL expression python:True for testing purposes
  4. I finally activated the plugin by checking the boxes of both "Group_Enumeration" and "Groups"

I opened a new browser and logged in using my plugin.

on my first browser I went to the Users and Groups configlet: the group is not shown; neither the user.

I can see the following message in the instance log several times:

2016-08-23 11:47:53 WARNING plone.app.controlpanel Skipped user without principal object: test

did I miss something?

what's the interface providing that? I can't find it; currently my plugin is implementing the following interfaces:

@implementer(
    ISenhaWebPlugin,
    IExtractionPlugin,
    IAuthenticationPlugin,
    IPropertiesPlugin,
    IUserFactoryPlugin,
)
class SenhaWebUsers(BasePlugin):

The important method is "getGroupsForPrincipal", defined by the interface "Products.PluggableAuthService.interfaces.plugins.IGroupsPlugin".

hvelarde: did you see this? https://pypi.python.org/pypi/Products.AutoRoleFromHostHeader
https://github.com/RedTurtle/Products.AutoRoleFromHostHeader

"Add roles or groups to anonymous or logged-in visitors based on HTTP headers" Seems quite closer to what you need. Works with Plone 4.

The plugin only assigns groups for users, but does not create group objects. So, with that plugin you need to first create the groups and then you can dynamically assign users to them.

The error message sounds like the user has been assigned group "test", but because there is no "test" group in Plone, it's ignored.

I added both, interface and method, but the code is never reached; obviously I'm doing something wrong.

unfortunately (or fortunately) the scope of the project was changed and I don't need to develop this plugin anymore.

anyway I think it would be nice to document this hidden gem (Dynamic Groups Plugin) somewhere in the documentation.

thanks for sharing! seems interesting for other use cases.

in fact test was the name of my user, not the group.