def _principal_search_results(self, search_for_principal, get_principal_by_id, get_principal_title, principal_type, id_key): """Return search results for a query to add new users or groups. Returns a list of dicts, as per role_settings(). Arguments: search_for_principal -- a function that takes an IPASSearchView and a search string. Uses the former to search for the latter and returns the results. get_principal_by_id -- a function that takes a user id and returns the user of that id get_principal_title -- a function that takes a user and a default title and returns a human-readable title for the user. If it can't think of anything good, returns the default title. principal_type -- either 'user' or 'group', depending on what kind of principals you want id_key -- the key under which the principal id is stored in the dicts returned from search_for_principal """ context = self.context translated_message = translate(_(u"Search for user or group"), context=self.request) search_term = self.request.form.get('search_term', None) if not search_term or search_term == translated_message: return [] existing_principals = set([p['id'] for p in self.existing_role_settings() if p['type'] == principal_type]) empty_roles = dict([(r['id'], False) for r in self.roles()]) info = [] hunter = getMultiAdapter((context, self.request), name='pas_search') for principal_info in search_for_principal(hunter, search_term): principal_id = principal_info[id_key] if principal_id not in existing_principals: principal = get_principal_by_id(principal_id) roles = empty_roles.copy() if principal is None: continue for r in principal.getRoles(): if r in roles: roles[r] = 'global' login = principal.getUserName() if principal_type == 'group': login = None info.append(dict(id = principal_id, title = get_principal_title(principal, principal_id), login = login, type = principal_type, roles = roles)) return info
def handle_form(self): """ We split this out so we can reuse this for ajax. Will return a boolean if it was a post or not """ postback = True form = self.request.form submitted = form.get('form.submitted', False) save_button = form.get('form.button.Save', None) is not None cancel_button = form.get('form.button.Cancel', None) is not None if submitted and save_button and not cancel_button: if not self.request.get('REQUEST_METHOD', 'GET') == 'POST': raise Forbidden authenticator = self.context.restrictedTraverse( '@@authenticator', None) if not authenticator.verify(): raise Forbidden # Update the acquire-roles setting if self.can_edit_inherit(): inherit = bool(form.get('inherit', False)) reindex = self.update_inherit(inherit, reindex=False) else: reindex = False # Update settings for users and groups entries = form.get('entries', []) roles = [r['id'] for r in self.roles()] settings = [] for entry in entries: settings.append( dict(id=entry['id'], type=entry['type'], roles=[ r for r in roles if entry.get('role_%s' % r, False) ])) if settings: reindex = self.update_role_settings(settings, reindex=False) or reindex notify(LocalrolesModifiedEvent(self.context, self.request)) if reindex: self.context.reindexObjectSecurity() notify(LocalrolesModifiedEvent(self.context, self.request)) IStatusMessage(self.request).addStatusMessage(_(u"Changes saved."), type='info') # Other buttons return to the sharing page if cancel_button: postback = False return postback
def handle_form(self): """ We split this out so we can reuse this for ajax. Will return a boolean if it was a post or not """ postback = True form = self.request.form submitted = form.get('form.submitted', False) save_button = form.get('form.button.Save', None) is not None cancel_button = form.get('form.button.Cancel', None) is not None if submitted and save_button and not cancel_button: if not self.request.get('REQUEST_METHOD', 'GET') == 'POST': raise Forbidden authenticator = self.context.restrictedTraverse('@@authenticator', None) if not authenticator.verify(): raise Forbidden # Update the acquire-roles setting if self.can_edit_inherit(): inherit = bool(form.get('inherit', False)) reindex = self.update_inherit(inherit, reindex=False) else: reindex = False # Update settings for users and groups entries = form.get('entries', []) roles = [r['id'] for r in self.roles()] settings = [] for entry in entries: settings.append( dict(id=entry['id'], type=entry['type'], roles=[r for r in roles if entry.get('role_%s' % r, False)])) if settings: reindex = self.update_role_settings(settings, reindex=False) \ or reindex if reindex: self.context.reindexObjectSecurity() notify(LocalrolesModifiedEvent(self.context, self.request)) IStatusMessage(self.request).addStatusMessage( _(u"Changes saved."), type='info') # Other buttons return to the sharing page if cancel_button: postback = False return postback
def __call__(self): """Perform the update and redirect if necessary, or render the page """ postback = True form = self.request.form submitted = form.get('form.submitted', False) cancel_button = form.get('form.button.Cancel', None) is not None if submitted and not cancel_button: if not self.request.get('REQUEST_METHOD','GET') == 'POST': raise Forbidden authenticator = self.context.restrictedTraverse('@@authenticator', None) if not authenticator.verify(): raise Forbidden # Update the acquire-roles setting inherit = bool(form.get('inherit', False)) reindex = self.update_inherit(inherit, reindex=False) # Update settings for users and groups entries = form.get('entries', []) roles = [r['id'] for r in self.roles()] settings = [] for entry in entries: settings.append( dict(id = entry['id'], type = entry['type'], roles = [r for r in roles if entry.get('role_%s' % r, False)])) if settings: reindex = self.update_role_settings(settings, reindex=False) or reindex if reindex: self.context.reindexObjectSecurity() IStatusMessage(self.request).addStatusMessage(_(u"Changes saved."), type='info') # Other buttons return to the sharing page if cancel_button: postback = False if postback: return self.index() else: context_state = self.context.restrictedTraverse("@@plone_context_state") url = context_state.view_url() self.request.response.redirect(url)
def handle_form(self): """ We split this out so we can reuse this for ajax. Will return a boolean if it was a post or not """ postback = True form = self.request.form submitted = form.get("form.submitted", False) save_button = form.get("form.button.Save", None) is not None cancel_button = form.get("form.button.Cancel", None) is not None if submitted and save_button and not cancel_button: if not self.request.get("REQUEST_METHOD", "GET") == "POST": raise Forbidden authenticator = self.context.restrictedTraverse("@@authenticator", None) if not authenticator.verify(): raise Forbidden # Update the acquire-roles setting if self.can_edit_inherit(): inherit = bool(form.get("inherit", False)) reindex = self.update_inherit(inherit, reindex=False) else: reindex = False # Update settings for users and groups entries = form.get("entries", []) roles = [r["id"] for r in self.roles()] settings = [] for entry in entries: settings.append( dict( id=entry["id"], type=entry["type"], roles=[r for r in roles if entry.get("role_%s" % r, False)] ) ) if settings: reindex = self.update_role_settings(settings, reindex=False) or reindex if reindex: self.context.reindexObjectSecurity() IStatusMessage(self.request).addStatusMessage(_(u"Changes saved."), type="info") # Other buttons return to the sharing page if cancel_button: postback = False return postback
def existing_role_settings(self): """Get current settings for users and groups that have already got at least one of the managed local roles. Returns a list of dicts as per role_settings() """ context = self.context portal_membership = getToolByName(context, 'portal_membership') portal_groups = getToolByName(context, 'portal_groups') acl_users = getToolByName(context, 'acl_users') info = [] # This logic is adapted from computeRoleMap.py local_roles = acl_users._getLocalRolesForDisplay(context) acquired_roles = self._inherited_roles() + self._borg_localroles() available_roles = [r['id'] for r in self.roles()] # first process acquired roles items = {} for name, roles, rtype, rid in acquired_roles: items[rid] = dict(id = rid, name = name, type = rtype, sitewide = [], acquired = roles, local = [], ) # second process local roles for name, roles, rtype, rid in local_roles: if rid in items: items[rid]['local'] = roles else: items[rid] = dict(id = rid, name = name, type = rtype, sitewide = [], acquired = [], local = roles, ) # Make sure we always get the authenticated users virtual group if AUTH_GROUP not in items: items[AUTH_GROUP] = dict(id = AUTH_GROUP, name = _(u'Logged-in users'), type = 'group', sitewide = [], acquired = [], local = [], ) # If the current user has been given roles, remove them so that he # doesn't accidentally lock himself out. member = portal_membership.getAuthenticatedMember() if member.getId() in items: items[member.getId()]['disabled'] = True # Sort the list: first the authenticated users virtual group, then # all other groups and then all users, alphabetically dec_users = [(a['id'] not in self.STICKY, a['type'], a['name'], a) for a in items.values()] dec_users.sort() # Add the items to the info dict, assigning full name if possible. # Also, recut roles in the format specified in the docstring for d in dec_users: item = d[-1] name = item['name'] rid = item['id'] login = rid global_roles = set() if item['type'] == 'user': member = acl_users.getUserById(rid) if member is not None: name = member.getProperty('fullname') or member.getUserName() or name global_roles = set(member.getRoles()) login = member.getUserName() elif item['type'] == 'group': g = portal_groups.getGroupById(rid) name = g.getGroupTitleOrName() login = None global_roles = set(g.getRoles()) # This isn't a proper group, so it needs special treatment :( if rid == AUTH_GROUP: name = _(u'Logged-in users') info_item = dict(id = item['id'], type = item['type'], title = name, disabled = item.get('disabled', False), roles = {}) if login != name: info_item['login'] = login # Record role settings have_roles = False for r in available_roles: if r in global_roles: info_item['roles'][r] = 'global' elif r in item['acquired']: info_item['roles'][r] = 'acquired' have_roles = True # we want to show acquired roles elif r in item['local']: info_item['roles'][r] = True have_roles = True # at least one role is set else: info_item['roles'][r] = False if have_roles or rid in self.STICKY: info.append(info_item) return info
class ManagerRole(object): implements(IRolesPageRole) title = _(u"title_can_manage", default=u"Can manage") required_permission = "Change local roles"
class ReviewerRole(object): implements(ISharingPageRole) title = _(u"title_can_review", default=u"Can review") required_permission = permissions.DelegateReviewerRole required_interface = None
class ContributorRole(object): implements(ISharingPageRole) title = _(u"title_can_add", default=u"Can add") required_permission = permissions.DelegateContributorRole required_interface = None
def sharing_handle_form(self): """ We split this out so we can reuse this for ajax. Will return a boolean if it was a post or not """ postback = True form = self.request.form submitted = form.get('form.submitted', False) save_button = form.get('form.button.Save', None) is not None cancel_button = form.get('form.button.Cancel', None) is not None if submitted and save_button and not cancel_button: if not self.request.get('REQUEST_METHOD', 'GET') == 'POST': raise Forbidden old_ac_local_roles_block = getattr( self.context, '__ac_local_roles_block__', None) authenticator = self.context.restrictedTraverse('@@authenticator', None) if not authenticator.verify(): raise Forbidden # Update the acquire-roles setting if self.can_edit_inherit(): inherit = bool(form.get('inherit', False)) reindex = self.update_inherit(inherit, reindex=False) else: reindex = False entries = form.get('entries', []) roles = [r['id'] for r in self.roles()] settings = [] for entry in entries: settings.append( dict(id=entry['id'], type=entry['type'], roles=[r for r in roles if entry.get('role_%s' % r, False)])) if settings: old_settings = self.context.get_local_roles() old_settings_dict = dict([(userid, set(roles)) for userid, roles in old_settings]) settings_dict = dict([(d['id'], set(d['roles'])) for d in settings]) old_userids = set( [tp[0] for tp in old_settings if list(tp[1]) != ['Owner']]) new_userids = set([d['id'] for d in settings if d['roles']]) all_userids = old_userids | new_userids reindex = self.update_role_settings(settings, reindex=False) \ or reindex new_ac_local_roles_block = getattr( self.context, '__ac_local_roles_block__', None) diff_context = dict() diff_context['removed_userids'] = old_userids - new_userids diff_context['added_userids'] = new_userids - old_userids diff_context['block_localroles'] = bool(new_ac_local_roles_block) diff_context['role_changes'] = dict() for userid, roles in settings_dict.items(): old_roles = old_settings_dict.get(userid, set()) if roles == old_roles: continue roles_added = roles - old_roles roles_removed = old_roles - roles user = plone.api.user.get(userid) fullname = email = None if user: fullname = user.getProperty('fullname') email = user.getProperty('email') diff_context['role_changes'][userid] = dict( fullname=fullname, email=email, added=roles_added, removed=roles_removed) if reindex: self.context.reindexObjectSecurity() event = LocalrolesModifiedEvent(self.context, self.request) event.diff_context = diff_context notify(event) IStatusMessage(self.request).addStatusMessage( _(u"Changes saved."), type='info') # Other buttons return to the sharing page if cancel_button: postback = False return postback
class AdministratorRole(grok.GlobalUtility): grok.name('Administrator') implements(ISharingPageRole) title = _(u"title_can_administrate", default=u"Can administrate") required_permission = permissions.DelegateRoles
class PublisherRole(grok.GlobalUtility): grok.name('Publisher') implements(ISharingPageRole) title = _(u"title_can_publish", default=u"Can publish") required_permission = permissions.DelegateRoles
class ReviewerRole(object): title = _(u"title_can_review", default=u"Can review") required_permission = permissions.DelegateReviewerRole required_interface = None
class ContributorRole(object): title = _(u"title_can_add", default=u"Can add") required_permission = permissions.DelegateContributorRole required_interface = None
class EditorRole(object): title = _(u"title_can_edit", default=u"Can edit") required_permission = permissions.DelegateEditorRole required_interface = None
class EditorRole(object): implements(ISharingPageRole) title = _(u"title_can_edit", default=u"Can edit") required_permission = permissions.DelegateEditorRole required_interface = None
def sharing_handle_form(self): """ We split this out so we can reuse this for ajax. Will return a boolean if it was a post or not """ postback = True form = self.request.form submitted = form.get('form.submitted', False) save_button = form.get('form.button.Save', None) is not None cancel_button = form.get('form.button.Cancel', None) is not None if submitted and save_button and not cancel_button: if not self.request.get('REQUEST_METHOD', 'GET') == 'POST': raise Forbidden old_ac_local_roles_block = getattr(self.context, '__ac_local_roles_block__', None) authenticator = self.context.restrictedTraverse( '@@authenticator', None) if not authenticator.verify(): raise Forbidden # Update the acquire-roles setting if self.can_edit_inherit(): inherit = bool(form.get('inherit', False)) reindex = self.update_inherit(inherit, reindex=False) else: reindex = False entries = form.get('entries', []) roles = [r['id'] for r in self.roles()] settings = [] for entry in entries: settings.append( dict(id=entry['id'], type=entry['type'], roles=[ r for r in roles if entry.get('role_%s' % r, False) ])) if settings: old_settings = self.context.get_local_roles() old_settings_dict = dict([(userid, set(roles)) for userid, roles in old_settings]) settings_dict = dict([(d['id'], set(d['roles'])) for d in settings]) old_userids = set( [tp[0] for tp in old_settings if list(tp[1]) != ['Owner']]) new_userids = set([d['id'] for d in settings if d['roles']]) all_userids = old_userids | new_userids reindex = self.update_role_settings(settings, reindex=False) \ or reindex new_ac_local_roles_block = getattr(self.context, '__ac_local_roles_block__', None) diff_context = dict() diff_context['removed_userids'] = old_userids - new_userids diff_context['added_userids'] = new_userids - old_userids diff_context['block_localroles'] = bool(new_ac_local_roles_block) diff_context['role_changes'] = dict() for userid, roles in settings_dict.items(): old_roles = old_settings_dict.get(userid, set()) if roles == old_roles: continue roles_added = roles - old_roles roles_removed = old_roles - roles user = plone.api.user.get(userid) fullname = email = None if user: fullname = user.getProperty('fullname') email = user.getProperty('email') diff_context['role_changes'][userid] = dict( fullname=fullname, email=email, added=roles_added, removed=roles_removed) if reindex: self.context.reindexObjectSecurity() event = LocalrolesModifiedEvent(self.context, self.request) event.diff_context = diff_context notify(event) IStatusMessage(self.request).addStatusMessage(_(u"Changes saved."), type='info') # Other buttons return to the sharing page if cancel_button: postback = False return postback