Back to index

plone3  3.1.7
Public Member Functions | Static Public Attributes | Private Member Functions
plone.app.workflow.browser.sharing.SharingView Class Reference
Inheritance diagram for plone.app.workflow.browser.sharing.SharingView:
Inheritance graph
[legend]
Collaboration diagram for plone.app.workflow.browser.sharing.SharingView:
Collaboration graph
[legend]

List of all members.

Public Member Functions

def __call__
def roles
def role_settings
def inherited
def existing_role_settings
def user_search_results
def group_search_results
def update_inherit
def update_role_settings

Static Public Attributes

tuple template = ViewPageTemplateFile('sharing.pt')

Private Member Functions

def _principal_search_results
def _inherited_roles

Detailed Description

Definition at line 41 of file sharing.py.


Member Function Documentation

Perform the update and redirect if necessary, or render the page

Definition at line 47 of file sharing.py.

00047 
00048     def __call__(self):
00049         """Perform the update and redirect if necessary, or render the page
00050         """
00051         
00052         postback = True
00053         
00054         form = self.request.form
00055         submitted = form.get('form.submitted', False)
00056     
00057         save_button = form.get('form.button.Save', None) is not None
00058         cancel_button = form.get('form.button.Cancel', None) is not None
00059     
00060         if submitted and not cancel_button:
00061 
00062             if not self.request.get('REQUEST_METHOD','GET') == 'POST':
00063                 raise Forbidden
00064 
00065             authenticator = self.context.restrictedTraverse('@@authenticator', None) 
00066             if not authenticator.verify(): 
00067                 raise Forbidden
00068 
00069             # Update the acquire-roles setting
00070             inherit = bool(form.get('inherit', False))
00071             reindex = self.update_inherit(inherit, reindex=False)
00072 
00073             # Update settings for users and groups
00074             entries = form.get('entries', [])
00075             roles = [r['id'] for r in self.roles()]
00076             settings = []
00077             for entry in entries:
00078                 settings.append(
00079                     dict(id = entry['id'],
00080                          type = entry['type'],
00081                          roles = [r for r in roles if entry.get('role_%s' % r, False)]))
00082             if settings:
00083                 reindex = self.update_role_settings(settings, reindex=False) or reindex
00084                 
00085             if reindex:
00086                 aq_inner(self.context).reindexObjectSecurity()
00087             IStatusMessage(self.request).addStatusMessage(_(u"Changes saved."), type='info')
00088             
00089         # Other buttons return to the sharing page
00090         if cancel_button:
00091             postback = False
00092         
00093         if postback:
00094             return self.template()
00095         else:
00096             context_state = self.context.restrictedTraverse("@@plone_context_state")
00097             url = context_state.view_url()
00098             self.request.response.redirect(url)
            

Here is the call graph for this function:

Here is the caller graph for this function:

Returns a tuple with the acquired local roles.

Definition at line 389 of file sharing.py.

00389 
00390     def _inherited_roles(self):
00391         """Returns a tuple with the acquired local roles."""
00392         context = aq_inner(self.context)
00393         
00394         if not self.inherited(context):
00395             return []
00396         
00397         portal = getToolByName(context, 'portal_url').getPortalObject()
00398         result = []
00399         cont = True
00400         if portal != context:
00401             parent = aq_parent(context)
00402             while cont:
00403                 if not getattr(parent, 'acl_users', False):
00404                     break
00405                 userroles = parent.acl_users._getLocalRolesForDisplay(parent)
00406                 for user, roles, role_type, name in userroles:
00407                     # Find user in result
00408                     found = 0
00409                     for user2, roles2, type2, name2 in result:
00410                         if user2 == user:
00411                             # Check which roles must be added to roles2
00412                             for role in roles:
00413                                 if not role in roles2:
00414                                     roles2.append(role)
00415                             found = 1
00416                             break
00417                     if found == 0:
00418                         # Add it to result and make sure roles is a list so
00419                         # we may append and not overwrite the loop variable
00420                         result.append([user, list(roles), role_type, name])
00421                 if parent == portal:
00422                     cont = False
00423                 elif not self.inherited(parent):
00424                     # Role acquired check here
00425                     cont = False
00426                 else:
00427                     parent = aq_parent(parent)
00428 
00429         # Tuplize all inner roles
00430         for pos in range(len(result)-1,-1,-1):
00431             result[pos][1] = tuple(result[pos][1])
00432             result[pos] = tuple(result[pos])
00433 
00434         return tuple(result)
        

Here is the call graph for this function:

Here is the caller graph for this function:

def plone.app.workflow.browser.sharing.SharingView._principal_search_results (   self,
  search_for_principal,
  get_principal_by_id,
  get_principal_title,
  principal_type,
  id_key 
) [private]
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

Definition at line 302 of file sharing.py.

00302 
00303                                   id_key):
00304         """Return search results for a query to add new users or groups.
00305         
00306         Returns a list of dicts, as per role_settings().
00307         
00308         Arguments:
00309             search_for_principal -- a function that takes an IPASSearchView and
00310                 a search string. Uses the former to search for the latter and
00311                 returns the results.
00312             get_principal_by_id -- a function that takes a user id and returns
00313                 the user of that id
00314             get_principal_title -- a function that takes a user and a default
00315                 title and returns a human-readable title for the user. If it
00316                 can't think of anything good, returns the default title.
00317             principal_type -- either 'user' or 'group', depending on what kind
00318                 of principals you want
00319             id_key -- the key under which the principal id is stored in the
00320                 dicts returned from search_for_principal
00321         """
00322         context = aq_inner(self.context)
00323         
00324         search_term = self.request.form.get('search_term', None)
00325         if not search_term:
00326             return []
00327         
00328         existing_principals = set([p['id'] for p in self.existing_role_settings() 
00329                                 if p['type'] == principal_type])
00330         empty_roles = dict([(r['id'], False) for r in self.roles()])
00331         info = []
00332         
00333         hunter = getMultiAdapter((context, self.request), name='pas_search')
00334         for principal_info in search_for_principal(hunter, search_term):
00335             principal_id = principal_info[id_key]
00336             if principal_id not in existing_principals:
00337                 principal = get_principal_by_id(principal_id)
00338                 roles = empty_roles.copy()
00339                 if principal is None:
00340                     continue
00341 
00342                 for r in principal.getRoles():
00343                     if r in roles:
00344                         roles[r] = 'global'
00345                 info.append(dict(id    = principal_id,
00346                                  title = get_principal_title(principal,
00347                                                              principal_id),
00348                                  type  = principal_type,
00349                                  roles = roles))
00350         return info
        

Here is the call graph for this function:

Here is the caller graph for this function:

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()

Definition at line 182 of file sharing.py.

00182 
00183     def existing_role_settings(self):
00184         """Get current settings for users and groups that have already got
00185         at least one of the managed local roles.
00186 
00187         Returns a list of dicts as per role_settings()
00188         """
00189         context = aq_inner(self.context)
00190         
00191         portal_membership = getToolByName(context, 'portal_membership')
00192         portal_groups = getToolByName(context, 'portal_groups')
00193         acl_users = getToolByName(context, 'acl_users')
00194         
00195         info = []
00196         
00197         # This logic is adapted from computeRoleMap.py
00198         
00199         local_roles = acl_users._getLocalRolesForDisplay(context)
00200         acquired_roles = self._inherited_roles()
00201         available_roles = [r['id'] for r in self.roles()]
00202 
00203         # first process acquired roles
00204         items = {}
00205         for name, roles, rtype, rid in acquired_roles:
00206             items[rid] = dict(id       = rid,
00207                               name     = name,
00208                               type     = rtype,
00209                               sitewide = [],
00210                               acquired = roles,
00211                               local    = [],)
00212                                 
00213         # second process local roles
00214         for name, roles, rtype, rid in local_roles:
00215             if items.has_key(rid):
00216                 items[rid]['local'] = roles
00217             else:
00218                 items[rid] = dict(id       = rid,
00219                                   name     = name,
00220                                   type     = rtype,
00221                                   sitewide = [],
00222                                   acquired = [],
00223                                   local    = roles,)
00224 
00225         # Make sure we always get the authenticated users virtual group
00226         if AUTH_GROUP not in items:
00227             items[AUTH_GROUP] = dict(id = AUTH_GROUP,
00228                                      name = _(u'Logged-in users'),
00229                                      type  = 'group',
00230                                      sitewide = [],
00231                                      acquired = [],
00232                                      local = [],)
00233 
00234         # If the current user has been given roles, remove them so that he
00235         # doesn't accidentally lock himself out.
00236         
00237         member = portal_membership.getAuthenticatedMember()
00238         if member.getId() in items:
00239             items[member.getId()]['disabled'] = True
00240 
00241         # Sort the list: first the authenticated users virtual group, then 
00242         # all other groups and then all users, alphabetically
00243 
00244         dec_users = [( a['id'] not in STICKY,
00245                        a['type'], 
00246                        a['name'],
00247                        a) for a in items.values()]
00248         dec_users.sort()
00249         
00250         # Add the items to the info dict, assigning full name if possible.
00251         # Also, recut roles in the format specified in the docstring
00252         
00253         for d in dec_users:
00254             item = d[-1]
00255             name = item['name']
00256             rid = item['id']
00257             global_roles = set()
00258             
00259             if item['type'] == 'user':
00260                 member = acl_users.getUserById(rid)
00261                 if member is not None:
00262                     name = member.getProperty('fullname') or member.getId() or name
00263                     global_roles = set(member.getRoles())
00264             elif item['type'] == 'group':
00265                 g = portal_groups.getGroupById(rid)
00266                 name = g.getGroupTitleOrName()
00267                 global_roles = set(g.getRoles())
00268                 
00269                 # This isn't a proper group, so it needs special treatment :(
00270                 if rid == AUTH_GROUP:
00271                     name = _(u'Logged-in users')
00272             
00273             info_item = dict(id    = item['id'],
00274                              type  = item['type'],
00275                              title = name,
00276                              disabled = item.get('disabled', False),
00277                              roles = {})
00278                              
00279             # Record role settings
00280             have_roles = False
00281             for r in available_roles:
00282                 if r in global_roles:
00283                     info_item['roles'][r] = 'global'
00284                 elif r in item['acquired']:
00285                     info_item['roles'][r] = 'acquired'
00286                     have_roles = True # we want to show acquired roles
00287                 elif r in item['local']:
00288                     info_item['roles'][r] = True
00289                     have_roles = True # at least one role is set
00290                 else:
00291                     info_item['roles'][r] = False
00292                     
00293             if have_roles or rid in STICKY:
00294                 info.append(info_item)
00295             
00296         return info
    

Here is the call graph for this function:

Here is the caller graph for this function:

Return search results for a query to add new groups.

Returns a list of dicts, as per role_settings().

Definition at line 371 of file sharing.py.

00371 
00372     def group_search_results(self):
00373         """Return search results for a query to add new groups.
00374         
00375         Returns a list of dicts, as per role_settings().
00376         """
00377         def search_for_principal(hunter, search_term):
00378             return hunter.searchGroups(id=search_term)
00379         
00380         def get_principal_by_id(group_id):
00381             portal_groups = getToolByName(self.context, 'portal_groups')
00382             return portal_groups.getGroupById(group_id)
00383         
00384         def get_principal_title(group, _):
00385             return group.getGroupTitleOrName()
00386             
00387         return self._principal_search_results(search_for_principal,
00388             get_principal_by_id, get_principal_title, 'group', 'groupid')
        

Here is the call graph for this function:

Here is the caller graph for this function:

def plone.app.workflow.browser.sharing.SharingView.inherited (   self,
  context = None 
)
Return True if local roles are inherited here.

Definition at line 170 of file sharing.py.

00170 
00171     def inherited(self, context=None):
00172         """Return True if local roles are inherited here.
00173         """
00174         if context is None:
00175             context = self.context
00176         if getattr(aq_base(context), '__ac_local_roles_block__', None):
00177             return False
00178         return True
        

Here is the call graph for this function:

Here is the caller graph for this function:

Get current settings for users and groups for which settings have been made.

Returns a list of dicts with keys:

 - id
 - title
 - type (one of 'group' or 'user')
 - roles
 
'roles' is a dict of settings, with keys of role ids as returned by 
roles(), and values True if the role is explicitly set, False
if the role is explicitly disabled and None if the role is inherited.

Definition at line 124 of file sharing.py.

00124 
00125     def role_settings(self):
00126         """Get current settings for users and groups for which settings have been made.
00127         
00128         Returns a list of dicts with keys:
00129         
00130          - id
00131          - title
00132          - type (one of 'group' or 'user')
00133          - roles
00134          
00135         'roles' is a dict of settings, with keys of role ids as returned by 
00136         roles(), and values True if the role is explicitly set, False
00137         if the role is explicitly disabled and None if the role is inherited.
00138         """
00139         
00140         existing_settings = self.existing_role_settings()
00141         user_results = self.user_search_results()
00142         group_results = self.group_search_results()
00143 
00144         current_settings = existing_settings + user_results + group_results
00145 
00146         # We may be called when the user does a search instead of an update.
00147         # In that case we must not loose the changes the user made and
00148         # merge those into the role settings.
00149         requested = self.request.form.get('entries', None)
00150         if requested is not None:
00151             knownroles = [r['id'] for r in self.roles()]
00152             settings = {}
00153             for entry in requested:
00154                 roles = [r for r in knownroles
00155                                 if entry.get('role_%s' % r, False)]
00156                 settings[(entry['id'], entry['type'])] = roles
00157 
00158             for entry in current_settings:
00159                 desired_roles = settings.get((entry['id'], entry['type']), None)
00160 
00161                 if desired_roles is None:
00162                     continue
00163                 for role in entry["roles"]:
00164                     if entry["roles"][role] in [True, False]:
00165                         entry["roles"][role] = role in desired_roles
00166 
00167         current_settings.sort(key=lambda x: x["type"]+str(x["title"]))
00168 
00169         return current_settings

Here is the call graph for this function:

Get a list of roles that can be managed.

Returns a list of dicts with keys:

    - id
    - title

Definition at line 102 of file sharing.py.

00102 
00103     def roles(self):
00104         """Get a list of roles that can be managed.
00105         
00106         Returns a list of dicts with keys:
00107         
00108             - id
00109             - title
00110         """
00111         context = aq_inner(self.context)
00112         portal_membership = getToolByName(context, 'portal_membership')
00113         
00114         pairs = []
00115         
00116         for name, utility in getUtilitiesFor(ISharingPageRole):
00117             permission = utility.required_permission
00118             if permission is None or portal_membership.checkPermission(permission, context):
00119                 pairs.append(dict(id = name, title = utility.title))
00120                 
00121         pairs.sort(key=lambda x: x["id"])
00122         return pairs
        

Here is the call graph for this function:

Here is the caller graph for this function:

def plone.app.workflow.browser.sharing.SharingView.update_inherit (   self,
  status = True,
  reindex = True 
)
Enable or disable local role acquisition on the context.

Returns True if changes were made, or False if the new settings
are the same as the existing settings.

Definition at line 435 of file sharing.py.

00435 
00436     def update_inherit(self, status=True, reindex=True):
00437         """Enable or disable local role acquisition on the context.
00438 
00439         Returns True if changes were made, or False if the new settings
00440         are the same as the existing settings.
00441         """
00442         context = aq_inner(self.context)
00443         portal_membership = getToolByName(context, 'portal_membership')
00444         
00445         if not portal_membership.checkPermission(permissions.ModifyPortalContent, context):
00446             raise Unauthorized
00447 
00448         block = not status 
00449         oldblock = bool(getattr(aq_base(context), '__ac_local_roles_block__', False))
00450 
00451         if block == oldblock:
00452             return False
00453 
00454         context.__ac_local_roles_block__ = block and True or None
00455         if reindex:
00456             context.reindexObjectSecurity()
00457         return True
        

Here is the call graph for this function:

Here is the caller graph for this function:

def plone.app.workflow.browser.sharing.SharingView.update_role_settings (   self,
  new_settings,
  reindex = True 
)
Update local role settings and reindex object security if necessary.

new_settings is a list of dicts with keys id, for the user/group id;
type, being either 'user' or 'group'; and roles, containing the list
of role ids that are set.

Returns True if changes were made, or False if the new settings
are the same as the existing settings.

Definition at line 459 of file sharing.py.

00459 
00460     def update_role_settings(self, new_settings, reindex=True):
00461         """Update local role settings and reindex object security if necessary.
00462         
00463         new_settings is a list of dicts with keys id, for the user/group id;
00464         type, being either 'user' or 'group'; and roles, containing the list
00465         of role ids that are set.
00466 
00467         Returns True if changes were made, or False if the new settings
00468         are the same as the existing settings.
00469         """
00470 
00471         changed = False
00472         context = aq_inner(self.context)
00473             
00474         managed_roles = frozenset([r['id'] for r in self.roles()])
00475         member_ids_to_clear = []
00476             
00477         for s in new_settings:
00478             user_id = s['id']
00479             
00480             existing_roles = frozenset(context.get_local_roles_for_userid(userid=user_id))
00481             selected_roles = frozenset(s['roles'])
00482 
00483             relevant_existing_roles = managed_roles & existing_roles
00484 
00485             # If, for the managed roles, the new set is the same as the
00486             # current set we do not need to do anything.
00487             if relevant_existing_roles == selected_roles:
00488                 continue
00489             
00490             # We will remove those roles that we are managing and which set
00491             # on the context, but which were not selected
00492             to_remove = relevant_existing_roles - selected_roles
00493 
00494             # Leaving us with the selected roles, less any roles that we
00495             # want to remove
00496             wanted_roles = (selected_roles | existing_roles) - to_remove
00497             
00498             # take away roles that we are managing, that were not selected 
00499             # and which were part of the existing roles
00500             
00501             if wanted_roles:
00502                 context.manage_setLocalRoles(user_id, list(wanted_roles))
00503                 changed = True
00504             elif existing_roles:
00505                 member_ids_to_clear.append(user_id)
00506                 
00507         if member_ids_to_clear:
00508             context.manage_delLocalRoles(userids=member_ids_to_clear)
00509             changed = True
00510         
00511         if changed and reindex:
00512             self.context.reindexObjectSecurity()
00513 
00514         return changed

Here is the call graph for this function:

Here is the caller graph for this function:

Return search results for a query to add new users.

Returns a list of dicts, as per role_settings().

Definition at line 351 of file sharing.py.

00351 
00352     def user_search_results(self):
00353         """Return search results for a query to add new users.
00354         
00355         Returns a list of dicts, as per role_settings().
00356         """
00357         def search_for_principal(hunter, search_term):
00358             return merge_search_results(chain(*[hunter.searchUsers(**{field: search_term})
00359                                  for field in ['login', 'fullname']]
00360                               ), 'userid')
00361         
00362         def get_principal_by_id(user_id):
00363             acl_users = getToolByName(self.context, 'acl_users')
00364             return acl_users.getUserById(user_id)
00365         
00366         def get_principal_title(user, default_title):
00367             return user.getProperty('fullname') or user.getId() or default_title
00368             
00369         return self._principal_search_results(search_for_principal,
00370             get_principal_by_id, get_principal_title, 'user', 'userid')
        

Here is the call graph for this function:

Here is the caller graph for this function:


Member Data Documentation

tuple plone.app.workflow.browser.sharing.SharingView.template = ViewPageTemplateFile('sharing.pt') [static]

Definition at line 45 of file sharing.py.


The documentation for this class was generated from the following file: