EGovSecurity.py 17.4 KB
Newer Older
Mayoro Diagne's avatar
Mayoro Diagne committed
1 2 3 4
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2002-2007 Nexedi SARL and Contributors. All Rights Reserved.
Mohamadou Mbengue's avatar
Mohamadou Mbengue committed
5 6
#                  Fabien Morin <fabien@nexedi.com>
#                  Mohamadou Mbengue <mmbengue@gmail.com>
Mayoro Diagne's avatar
Mayoro Diagne committed
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
#
##############################################################################

from Products.ERP5Security.ERP5GroupManager import ConsistencyError
from Products.ERP5Type import Permissions

#############################################################
## Define permissions on EGov modules
#############################################################

def setPermissionsOnEGovModule(self, portal_type_object):
  """
  This script sets the permissions on erp5 roles
  according to a procedure settings in the request hosting form
  """
  #XXX Complete Permissions class in Products.ERP5Type 
  #include all zope permissions
  aquired_permission_list= [ 'Access Transient Objects','Access arbitrary user session data'
                           , 'Access session data',  'Add Accelerated HTTP Cache Managers'
                           , 'Add Browser Id Manager','Add CMF Action Icons Tools'
                           , 'Add CMF Setup Tools','Add CMF Unique Id Tools'
                           , 'Add Configured CMF Sites','Add ERP5 Form Printouts'
                           , 'Add Plugin Registrys', 'Add RAM Cache Managers'
                           , 'Add ReStructuredText Documents','Add Session Data Manager'
                           , 'Add Site Roots','Add Temporary Folder', 'Add Transient Object Container'
                           , 'Add Virtual Host Monsters','Add Z Gadfly Database Connections'
                           , 'Add ZODB Mount Points','Add Zope Tutorials','Change Browser Id Manager'
                           , 'Change Session Data Manager', 'Create Transient Objects'
                           , 'Edit ReStructuredText','Manage Transient Object Container'
                           ]
  zope_permission_list =  [
                          'Access contents information','Access future portal content',
                          'Access inactive portal content','Add BTreeFolder2s',
                          'Add CMF Active Processs','Add CMF Caching Policy Managers',
                          'Add CMF Calendar Tools','Add CMF Core Tools',
                          'Add CMF Default Tools', 'Add CMF Sites',
                          'Add CMFActivity Tools','Add CMFCategory Tools',
                          'Add CMFMailIn Tools', 'Add Content Type Registrys','Add Cookie Crumblers',
                          'Add Database Methods','Add Documents, Images, and Files',
                          'Add ERP5 Filesystem Formulator Forms',
                          'Add ERP5 Forms','Add ERP5 OOo Templates',
                          'Add ERP5 PDF Forms','Add ERP5 PDF Templates',
                          'Add ERP5 Publications','Add ERP5 Reports',
                          'Add ERP5 Sites','Add ERP5 Subscriptions',
                          'Add ERP5 Tools','Add ERP5Catalog Tools',
                          'Add ERP5Form Tools','Add ERP5Subversion Tools',
                          'Add ERP5SyncML Tools','Add ERP5Type Tools',
                          'Add ExtFiles','Add ExtImages',
                          'Add External Methods','Add Filesystem Directory Views',
                          'Add Folders','Add Formulator Forms',
                          'Add LocalContents','Add LocalFolders',
                          'Add Localizers','Add MailHost objects',
                          'Add MessageCatalogs','Add MimetypesRegistry Tools',
                          'Add Page Templates','Add Pluggable Index',
                          'Add PortalTransforms Tools',
                          'Add Python Scripts','Add User Folders',
                          'Add Vocabularies', 'Add Z MySQL Database Connections',
                          'Add Z MySQL Deferred Database Connections','Add ZCatalogs',
                          'Add ZMailIn Clients','Add ZMailMessages',
                          'Add portal content','Add portal events',
                          'Add portal folders','Add portal member',
                          'Add portal topics','Change DTML Documents','Change DTML Methods',
                          'Change Database Connections','Change Database Methods',
                          'Change ExtFile/ExtImage','Change External Methods',
                          'Change Formulator Fields','Change Formulator Forms',
                          'Change Images and Files','Change Lock Information',
                          'Change Page Templates','Change Python Scripts',
                          'Change Versions', 'Change ZMailIn','Change ZMailMessages',
                          'Change bindings','Change cache managers',
                          'Change cache settings','Change configuration',
                          'Change local roles','Change permissions',
                          'Change portal events','Change portal topics',
                          'Change proxy roles','Copy or Move','Create class instances',
                          'Define permissions','Delete objects',
                          'Download ExtFile/ExtImage','Edit Factories',
                          'Edit target','FTP access','Import/Export objects',
                          'Join/leave Versions','List folder contents',
                          'List portal members','List undoable changes',
                          'Log Site Errors','Log to the Event Log',
                          'Mail forgotten password','Manage Access Rules',
                          'Manage Groups','Manage Selenium test cases',
                          'Manage Vocabulary','Manage WebDAV Locks','Manage Z Classes',
                          'Manage ZCatalog Entries','Manage ZCatalogIndex Entries',
                          'Manage languages','Manage messages',
                          'Manage portal','Manage properties',
                          'Manage users','Modify Cookie Crumblers',
                          'Modify portal content','Open/Close Database Connection',
                          'Open/Close Database Connections','Post mail to ZMailIn',
                          'Query Vocabulary','Reply to item','Request review',
                          'Review portal content','Save/discard Version changes',
                          'Search ZCatalog','Search for principals',
                          'Set own password','Set own properties',
                          'Take ownership','Test Database Connections',
                          'Translate Content','Undo changes',
                          'Use Database Methods','Use Factories',
                          'Use external editor','Use mailhost services',
                          'View','View History',
                          'View ZMailMessage','View management screens',
                          'WebDAV Lock items','WebDAV Unlock items',
                          'WebDAV access',
                          ]


  role_permission_dict =  {'Anonymous':[Permissions.AccessContentsInformation, Permissions.AddPortalContent \
                                       ,Permissions.CopyOrMove, Permissions.ModifyPortalContent \
                                       ,Permissions.ListFolderContents,Permissions.View, 'View History' \
                                       ],
                           'Agent':    [Permissions.AccessContentsInformation, Permissions.AddPortalContent \
                                       ,Permissions.CopyOrMove, Permissions.ModifyPortalContent \
                                       ,Permissions.ListFolderContents,Permissions.View, 'View History' \
                                       ],
                           'Associate':[Permissions.AccessContentsInformation, Permissions.ListFolderContents \
                                       ,Permissions.View, Permissions.CopyOrMove, 'View History'  \
                                       ],
                           'Auditor':  [Permissions.AccessContentsInformation, Permissions.ListFolderContents  \
                                       ,Permissions.View, 'View History' \
                                       ],
                           'Assignee': [Permissions.AccessContentsInformation, Permissions.ListFolderContents \
                                       ,Permissions.CopyOrMove, Permissions.View, 'View History' \
                                       ],
                           'Assignor': [Permissions.AccessContentsInformation, Permissions.AddPortalContent \
                                       ,Permissions.AddPortalFolders, Permissions.CopyOrMove \
                                       ,Permissions.View, Permissions.ModifyPortalContent \
                                       ,Permissions.DeleteObjects, Permissions.ListFolderContents, 'View History' \
                                       ],
                           'Manager':  zope_permission_list
                          }

  #XXX if the procedure needs no authentification, 
  # assume anonymous role can access and add
  if portal_type_object is not None:
    step_authentication =  portal_type_object.getStepAuthentication()
Mohamadou Mbengue's avatar
Mohamadou Mbengue committed
160
    step_subscription =  portal_type_object.getStepSubscription()
Mayoro Diagne's avatar
Mayoro Diagne committed
161 162
  self.manage_acquiredPermissions(aquired_permission_list)
  for (role, permission_list) in role_permission_dict.items():
Mohamadou Mbengue's avatar
Mohamadou Mbengue committed
163
    if role == "Anonymous" and not step_authentication and not step_subscription:
Mayoro Diagne's avatar
Mayoro Diagne committed
164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325
      self.manage_role(role_to_manage=role, permissions=permission_list)
    elif role != "Anonymous":
      self.manage_role(role_to_manage=role, permissions=permission_list)
      if role == "Agent":
        portal_type_object.manage_role(role_to_manage=role, permissions=permission_list)

def getSecurityCategoryFromAssignment(self, base_category_list, user_name, 
    object, portal_type, child_category_list=[]):
  """
  This script returns a list of dictionaries which represent
  the security groups which a person is member of. It extracts
  the categories from the current user assignment.
  It is useful in the following cases:
  
  - associate a document (ex. an accounting transaction)
    to the division which the user was assigned to
    at the time it was created
  
  - calculate security membership of a user
  
  The parameters are
  
    base_category_list -- list of category values we need to retrieve
    user_name          -- string obtained from 
                                        getSecurityManager().getUser().getId()
    object             -- object which we want to assign roles to
    portal_type        -- portal type of object
  """
  category_list = []
  person_object_list = self.portal_catalog.unrestrictedSearchResults(\
                                portal_type='Person', reference=user_name)
  
  if len(person_object_list) != 1:
    if len(person_object_list) > 1:
      raise ConsistencyError, "Error: There is more than one Person with reference '%s'" % user_name
    else:
      # if a person_object was not found in the module, we do nothing more
      # this happens for example when a manager with no associated person 
      # object creates a person_object for a new user
      return []
  person_object = person_object_list[0].getObject()
  
  # We look for every valid assignments of this user
  assignment_list = person_object.contentValues(filter={'portal_type':'Assignment'})
  for assignment in assignment_list:
    if assignment.getValidationState() == 'open':
      category_dict = {}
      for base_category in base_category_list:
        category_value_list = assignment.getAcquiredValueList(base_category)
        if category_value_list:
          for category_value in category_value_list:
            if base_category in child_category_list:
              if category_value.getPortalType() not in \
                  ('Base Category', 'ERP5 Site'):
                while category_value.getPortalType() not in \
                    ('Base Category', 'ERP5 Site'):
                  category_dict.setdefault(base_category, []).append('%s*' % \
                      category_value.getRelativeUrl())
                  category_value = category_value.getParentValue()
              else:
                category_dict.setdefault(base_category, []).append(category_value.getRelativeUrl())
            else:
              category_dict.setdefault(base_category, []).append(category_value.getRelativeUrl())
      category_list.append(category_dict)
  
  return category_list


def getSecurityCategoryFromEntity(self, base_category_list, entity_name, 
    object, portal_type, child_category_list=None, portal_type_list=None):
  """
  This script returns a list of dictionaries which represent
  the security groups which a person is member of. It extracts
  the categories from the current user assignment.
  It is useful in the following cases:
  
  - associate a document (ex. an accounting transaction)
    to the division which the user was assigned to
    at the time it was created
  
  - calculate security membership of a user
  
  The parameters are
  
    base_category_list -- list of category values we need to retrieve
    entity_name          -- string obtained from 
                                        getSecurityManager().getUser().getId()
    object             -- object which we want to assign roles to
    portal_type_list   -- list of portal type to search the entity
  """
  if portal_type_list is None:
    portal_type_list = self.portal_type_list
  if child_category_list is None:
    child_category_list = []

  category_list = []
  object_list = self.portal_catalog.unrestrictedSearchResults(portal_type=portal_type_list, reference=entity_name)
  
  if len(object_list) != 1:
    if len(object_list) > 1:
      raise ConsistencyError, "Error: There is more than one Entity with reference '%s'" % entity_name
    else:
      # if a person_object was not found in the module, we do nothing more
      # this happens for example when a manager with no associated person 
      # object creates a person_object for a new user

      portal = self.getPortalObject()

      # this permit to get the module of the application. The goal is to
      # work with anonymous applications, even if they are not reindexed
      module_id = self.REQUEST.get('anonymous_module', None)
      if module_id:
        module =  getattr(portal, module_id, None)
        if module is not None:
          result = module._getOb(entity_name, None)
          if result is not None:
            object = result
          else:
            return []
      else:
        return []
  else:
    object = object_list[0].getObject()
  
  category_dict = {}
  for base_category in base_category_list:
    category_value_list = object.getAcquiredValueList(base_category)
    if category_value_list:
      for category_value in category_value_list:
        if base_category in child_category_list:
          if category_value.getPortalType() not in \
              ('Base Category', 'ERP5 Site'):
            while category_value.getPortalType() not in \
                ('Base Category', 'ERP5 Site'):
              category_dict.setdefault(base_category, []).append('%s*' % \
                  category_value.getRelativeUrl())
              category_value = category_value.getParentValue()
          else:
            category_dict.setdefault(base_category, []).append(category_value.getRelativeUrl())
        else:
          category_dict.setdefault(base_category, []).append(category_value.getRelativeUrl())
  category_list.append(category_dict)
  
  return category_list



def getSecurityCategoryFromAssignmentParent(self, base_category_list,
                                       user_name, object, portal_type):
  return getSecurityCategoryFromAssignment(self, base_category_list,
                                       user_name, object, portal_type, child_category_list=base_category_list)

def getSecurityCategoryFromAssignmentParentGroup(self, base_category_list,
                                       user_name, object, portal_type):
  return getSecurityCategoryFromAssignment(self, base_category_list,
                                       user_name, object, portal_type, child_category_list=('group',))
 
def getSecurityCategoryFromAssignmentParentFunction(self, base_category_list,
                                       user_name, object, portal_type):
  return getSecurityCategoryFromAssignment(self, base_category_list,
                                       user_name, object, portal_type, child_category_list=('function',))