Ejemplo n.º 1
0
 def __init__(self,
              context,
              parent=None,
              groupid=u'',
              title=u'',
              description=u'',
              namespace=u'',
              roles=(),
              members=None,
              **kwargs):
     if not IWorkspaceContext.providedBy(context):
         raise ValueError('Could not adapt: context not a workspace')
     schema = interfaces.IWorkspaceGroup
     if schema.providedBy(parent):
         self.__parent__ = parent
     self.context = context
     self.adapts_project = IProjectContext.providedBy(context)
     valid_setattr(self, schema['baseid'], _decode(groupid))
     valid_setattr(self, schema['title'], _decode(title))
     valid_setattr(self, schema['description'], _decode(description))
     valid_setattr(self, schema['namespace'], _decode(namespace))
     self._keys = None
     self.portal = getSite()
     self.site_members = members or interfaces.ISiteMembers(self.portal)
     groups = Groups(self.portal)
     groupname = self.pas_group()[0]
     if groupname not in groups:
         groups.add(groupname)  # edge-case: may cause write-on-read
     self._group = GroupInfo(groupname, members=self.site_members)
Ejemplo n.º 2
0
class WorkspaceGroup(object):
    """
    Workspace group adapter: provides mapping for managing workspace
    membership in a specific group.
    """

    implements(interfaces.IWorkspaceGroup)
    adapts(IWorkspaceContext)

    # class attribute defaults (for instance attributes):
    __parent__ = None

    def __init__(self,
                 context,
                 parent=None,
                 groupid=u'',
                 title=u'',
                 description=u'',
                 namespace=u'',
                 roles=(),
                 members=None,
                 **kwargs):
        if not IWorkspaceContext.providedBy(context):
            raise ValueError('Could not adapt: context not a workspace')
        schema = interfaces.IWorkspaceGroup
        if schema.providedBy(parent):
            self.__parent__ = parent
        self.context = context
        self.adapts_project = IProjectContext.providedBy(context)
        valid_setattr(self, schema['baseid'], _decode(groupid))
        valid_setattr(self, schema['title'], _decode(title))
        valid_setattr(self, schema['description'], _decode(description))
        valid_setattr(self, schema['namespace'], _decode(namespace))
        self._keys = None
        self.portal = getSite()
        self.site_members = members or interfaces.ISiteMembers(self.portal)
        groups = Groups(self.portal)
        groupname = self.pas_group()[0]
        if groupname not in groups:
            groups.add(groupname)  # edge-case: may cause write-on-read
        self._group = GroupInfo(groupname, members=self.site_members)

    @property
    def __name__(self):
        return self.baseid or None

    def _groupname(self):
        ns = self.namespace  # usually UUID of workspace
        return '-'.join((ns, self.baseid))

    def _grouptitle(self):
        r = []  # stack of object context (LIFO)
        context = self.context
        while getattr(context, '__parent__', None) is not None:
            if ISiteRoot.providedBy(context):
                break
            r.append(context)
            context = context.__parent__
        titles = [o.Title() for o in reversed(r)]
        return u'%s - %s' % (' / '.join(titles).encode('utf-8'), self.title)

    def pas_group(self):
        return (self._groupname(), self._grouptitle())

    def _get_user(self, username):
        return self.site_members.get(username)

    def __contains__(self, username):
        return username in self.keys()

    def __getitem__(self, username):
        if username not in self.keys():
            raise KeyError('User %s not in group %s (%s)' % (
                username,
                self._groupname(),
                self._grouptitle(),
            ))
        return self._get_user(username)

    def get(self, username, default=None):
        if username not in self.keys():
            return default
        return self._get_user(username)

    # mapping enumeration -- keys/values/items:

    def keys(self):
        """
        List of login names as group members.  This may be cached,
        as it is expensive to list assigned group principals in the
        stock Plone group plugin (ZODBGroupManager).
        """
        if self._keys is None:
            self._keys = self._group.keys()
        return self._keys  # cached lookup for session

    def values(self):
        return [self._get_user(k) for k in self.keys()]

    def items(self):
        return [(k, self._get_user(k)) for k in self.keys()]

    def __len__(self):
        return len(self.keys())

    # iterable mapping methods:

    def iterkeys(self):
        return iter(self.keys())

    __iter__ = iterkeys

    def itervalues(self):
        return itertools.imap(self._get_user, self.keys())

    def iteritems(self):
        func = lambda username: (username, self._get_user(username))  # (k,v)
        return itertools.imap(func, self.keys())

    # add / delete (assign/unassign) methods:

    def add(self, username):
        if username not in self.site_members:
            raise RuntimeError('User %s unknown to site' % username)
        if username not in self.keys():
            self._group.assign(username)
        self.refresh()  # need to invalidate keys -- membership modified.

    def unassign(self, username):
        if username not in self.keys():
            raise ValueError('user %s is not group member' % username)
        self._group.unassign(username)
        self.refresh()  # need to invalidate keys -- membership modified.

    def refresh(self):
        self._keys = None  # invalidate previous cached keys
        self._group.refresh()
        if interfaces.IWorkspaceGroup.providedBy(self.__parent__):
            if self.__parent__.baseid == self.baseid:
                # group equivalence, invalidate parent group too!
                self.__parent__._keys = None