Seeking advices: user categorization

Hi everyone :smiley: I'm in charge of a massive revision in our web service's login system.
i'll try to be concise.
We want to create a login system that takes some kind of "tags" from the user and, with those in mind, decide wich object the user can see and interact with. every Object has the same tags and we use'em for searching and filtering trough the massive amount of contents in our websites. here's an exemple with some pseudocode helping you understand what i'm trying to do:

obj1
visibile if eyes=blue
hair=blond
age=18

obj2
visible if eyes=blue
hair=gray
age=all

obj3
visibile if eyes=blue
hair=blond
age=all

user1
eyes=blue
hear=blond
age=19
user2
eyes=green
hear=blond
age=19

my question is: wich approach you'd use for an hypotetic similar feature?
thanks and pardon me for my poor english :smiling_face_with_tear:
Pietro

Every Tag Combination is a Group, every Group can access Objects, but it's sounds like a lot of brainstorm to do the right way.

@p3dar You can assign dynamic roles to users depending on arbitrary attributes of the context, the request or the user using a adapter ILocalRoleProvider.

Here is a example hat checks values in fields of the context to grant local roles:

from borg.localrole.interfaces import ILocalRoleProvider
from my.package.behaviors.team import ITeam
from zope.component import adapter
from zope.interface import implementer


@implementer(ILocalRoleProvider)
@adapter(ITeam)
class LocalRoles(object):
    """Provide a local role manager for projects"""

    def __init__(self, context):
        self.context = context

    def getAllRoles(self):
        for author_id in self.context.authors:
            yield (author_id, ("Editor", "Contributor"))
        for manager_id in self.context.managers:
            yield (manager_id, ("Manager", "Editor", "Contributor"))

    def getRoles(self, principal_id):
        roles = set()
        if principal_id in (self.context.authors or []):
            roles.add("Editor")
            roles.add("Contributor")
        if principal_id in (self.context.managers or []):
            roles.add("Editor")
            roles.add("Manager")
            roles.add("Contributor")
        return roles

Registered in zcml as <adapter factory=".localroles.LocalRoles" />

1 Like

thanks for your advice, i really appreciate it but we tried this kind of approach and it ended with too many gropus :frowning: i think the best solution must be more "dynamic"!

i think this could be the best approach, i'll dig more into it! thank you very much for your advice :smiley:

Slightly off topic, but If your question is not about 'security', but just a practical way of ordering / accessing / finding content, you could make views with conditions.

So, if a typically view (now) is

  1. Find all items of type 'Person'
  2. Show image, Name and Eye color of each person

You could change this to (see also 'below')

  1. Define which criteteria to search for (depending on 'the logged in user')
  2. Find all items of types Person with these criterias
  3. Show image, Name and Eye color of each

An approach could be to make an index (and indexer) and add the users that can access (view?) (each) item to it.
(For exemple) you could then add that field to the search terms (with plone.app.querystring.operation.string.currentUser ).

A little similar to how 'Creator' -> Current logged in user works in Collections.

Not sure how fast this approach would be, but at least it should be very fast to make. You should probably be able to used the indexed field in combination with collective collectionfilter (or similar)