def send(self, from_url, to_url, xml, sync_id, content_type): to_address = to_url[len('mailto:'):] from_address = from_url[len('mailto:'):] try: getSite().sendMail(from_address, to_address, sync_id, xml) except: raise ConnectionError
def runGetAndActivate(self, subscription, tag, after_method_id=None): """ Launch the browsing of GID that will call the generation of syncml commands """ activate_kw = { 'activity' : 'SQLQueue', 'after_method_id' : after_method_id, 'tag' :tag, 'priority' :ACTIVITY_PRIORITY } pref = getSite().portal_preferences subscription.getAndActivate( callback="sendSyncCommand", activate_kw=activate_kw, packet_size=pref.getPreferredDocumentRetrievedPerActivityCount(), activity_count=pref.getPreferredRetrievalActivityCount(), ) # then send the final message of this sync part if pref.getPreferredCheckDeleteAtEnd(): subscription.activate(after_tag=tag, priority=ACTIVITY_PRIORITY+1).getDeletedSyncMLData() else: subscription.activate(after_tag=tag, priority=ACTIVITY_PRIORITY+1)._sendFinalMessage() return True
def runGetAndActivate(self, subscription, tag, after_method_id=None): """ Generate tag and method parameter and call the getAndActivate method """ activate_kw = { 'activity' : 'SQLQueue', 'after_method_id' : after_method_id, 'tag' :tag, 'priority' :ACTIVITY_PRIORITY } method_kw = { 'subscription_path' : subscription.getRelativeUrl(), } pref = getSite().portal_preferences count = subscription.getAndActivate( callback="sendSyncCommand", method_kw=method_kw, activate_kw=activate_kw, packet_size=pref.getPreferredDocumentRetrievedPerActivityCount(), activity_count=pref.getPreferredRetrievalActivityCount(), ) # Then get deleted document # this will send also the final message of this sync part subscription.activate(after_tag=tag)._getDeletedData() return True
def checkAlertCommand(syncml_request): """ This parse the alert commands received and return a dictionnary mapping database to sync mode """ database_alert_list = [] # XXX To be moved on engine search = getSite().portal_categories.syncml_alert_code.searchFolder for alert in syncml_request.alert_list: if alert["data"] == "222": # 222 is for asking next message, do not care continue # Retrieve the category # XXX Categories must be redefined, ID must be code, not title so # that we can drop the use of searchFolder alert_code_category_list = search(reference=alert['data']) if len(alert_code_category_list) == 1: alert_code_category = alert_code_category_list[0].getId() else: # Must return (405) Command not allowed raise NotImplementedError("Alert code is %s, got %s category" % (alert['data'], len(alert_code_category_list))) # Copy the whole dict & add the category id alert["code"] = alert_code_category database_alert_list.append(alert) return database_alert_list
def __call__(self, *args, **kw): portal = getSite() method_name = "SQLConnector_%s" % (self._method) method = getattr(portal, method_name, None) if method: response = method(*args, **kw) return method.absolute_url(), response else: raise ConnectionError("Method %s does not exist" % (method_name))
def resolveSyncmlAlertCode(category_id): """Return reference of syncml_alert_code category """ try: return str(int(category_id)) except ValueError: return getSite().portal_categories.getCategoryValue( category_id, base_category='syncml_alert_code').getReference()
def clear(self): super(FieldValueCacheDict, self).clear() from Products.ERP5.ERP5Site import getSite try: portal = getSite() except IndexError: pass else: portal.newCacheCookie('form_field_value_cache') self._last_sync = portal.getCacheCookie('form_field_value_cache')
def get_source(self, fullname): """ Get the source code of the given module name from the ID defined on the dynamic module (setting getTextContent() on the module directly may not work properly upon reset and there is no need for performance there as it is only used for traceback or pdb anyway) """ module = __import__(fullname, fromlist=[fullname.rsplit('.', 1)[0]], level=0) return getattr(getSite().portal_components, module.__file__[1:-1]).getTextContent(validated_only=True)
def resetDynamic(self, method_call_object, *args, **kw): """ Call resetDynamicDocuments at the end of the transaction """ from Products.ERP5.ERP5Site import getSite # method_call_object might be an unwrapped DCWorflowDefinition method, # no even belonging to a container. portal = getSite() types_tool = getattr(portal, 'portal_types', None) if types_tool is None: return types_tool.resetDynamicDocumentsOnceAtTransactionBoundary()
def get_source(self, fullname): """ Get the source code of the given module name from the ID defined on the dynamic module (setting getTextContent() on the module directly may not work properly upon reset and there is no need for performance there as it is only used for traceback or pdb anyway) """ module = __import__(fullname, fromlist=[fullname.rsplit('.', 1)[0]], level=0) return getattr( getSite().portal_components, module.__file__[1:-1]).getTextContent(validated_only=True)
def _buildAstroidModuleFromComponentModuleName(modname): from Products.ERP5.ERP5Site import getSite from Acquisition import aq_base portal = getSite() component_tool = aq_base(portal.portal_components) component_obj = None component_id = modname[len('erp5.component.'):] if '_version' in modname: try: obj = getattr(component_tool, component_id.replace('_version', '', 1)) except AttributeError: raise AstroidBuildingException() if obj.getValidationState() in ('modified', 'validated'): component_obj = obj else: raise AstroidBuildingException() else: try: package, reference = component_id.split('.', 1) except ValueError: raise AstroidBuildingException() for version in portal.getVersionPriorityNameList(): try: obj = getattr(component_tool, '%s.%s.%s' % (package, version, reference)) except AttributeError: continue if obj.getValidationState() in ('modified', 'validated'): version_modname = 'erp5.component.%s.%s_version.%s' % ( package, version, reference) module = MANAGER.astroid_cache.get( version_modname, _buildAstroidModuleFromComponentModuleName( version_modname)) MANAGER.astroid_cache[modname] = module return module if component_obj is None: raise AstroidBuildingException() # module_build() could also be used but this requires importing # the ZODB Component and also monkey-patch it to support PEP-302 # for __file__ starting with '<' module = AstroidBuilder(MANAGER).string_build( component_obj.getTextContent(validated_only=True), modname) return module
def __call__(self, *args, **kw): portal = getSite() method_name = "DocumentConnector_%s" %(self._method) method = getattr(portal, method_name, None) kw["reference"] = self._conn.reference if method: response = method(*args, **kw) return method.absolute_url(), response ## try: ## except ValueError, msg: ## raise ConnectionError(msg) ## except Exception, msg: ## raise ConnectionError(msg) else: raise ConnectionError("Method %s does not exist" %(method_name))
def __getitem__(self, cache_id): from Products.ERP5.ERP5Site import getSite try: portal = getSite() except IndexError: pass else: cookie = portal.getCacheCookie('form_field_value_cache') if cookie != self._last_sync: LOG("ERP5Form.Form", 0, "Resetting form field value cache") self._last_sync = cookie self.clear() raise KeyError('Field cache is outdated and has been reset') return super(FieldValueCacheDict, self).__getitem__(cache_id)
def _registry_dict(self): """ Create the component registry, this is very similar to Products.ERP5Type.document_class_registry and avoids checking whether a Component exists at each call at the expense of being slower when being re-generated after a reset. Moreover, it allows to handle reference easily. """ if not self.__registry_dict: portal = getSite() try: component_tool = portal.portal_components # When installing ERP5 site, erp5_core_components has not been installed # yet, thus this will obviously failed... # # XXX-arnau: Is this needed as it is now done in synchronizeDynamicModules? except AttributeError: return {} version_priority_set = set(portal.getVersionPriorityNameList()) # objectValues should not be used for a large number of objects, but # this is only done upon reset, moreover using the Catalog is too risky # as it lags behind and depends upon objects being reindexed for component in component_tool.objectValues( portal_type=self._portal_type): # Only consider modified or validated states as state transition will # be handled by component_validation_workflow which will take care of # updating the registry try: validation_state_tuple = component.getValidationState() except AttributeError: # XXX: Accessors may have not been generated yet pass else: if validation_state_tuple in ('modified', 'validated'): version = component.getVersion(validated_only=True) # The versions should have always been set on ERP5Site property # beforehand if version in version_priority_set: reference = component.getReference( validated_only=True) self.__registry_dict.setdefault( reference, {})[version] = (component.getId(), component.getUid()) return self.__registry_dict
def runApplySyncCommand(self, subscription, syncml_request, tag): """ Launch the apply sync command in activity """ send_response = subscription.getSyncmlAlertCode( ) != "refresh_from_client_only" if send_response and len(syncml_request.sync_command_list): # Generate a list of responses ID here to be scallable response_id_list = subscription.getNextMessageIdList( id_count=len(syncml_request.sync_command_list)) response_id_list.reverse() else: response_id_list = [ None for x in xrange(len(syncml_request.sync_command_list)) ] split = getSite( ).portal_preferences.getPreferredSyncActionPerActivityCount() if not split: # We do not use activities if send_response: syncml_response = subscription.generateBaseResponse() else: syncml_response = None subscription.applyActionList(syncml_request, syncml_response) if syncml_response: subscription.activate( activity="SQLQueue", priority=ACTIVITY_PRIORITY, tag=subscription.getRelativeUrl()).sendMessage( xml=str(syncml_response)) else: # XXX For now always split by one activate = subscription.activate activate_kw = { "activity": "SQLQueue", "priority": ACTIVITY_PRIORITY, "tag": tag, "group_method_id": None, "group_method_cost": 1. / float(split), } for action in syncml_request.sync_command_list: syncml_logger.info("---> launch action in activity %s" % (action, )) activate(**activate_kw).applySyncCommand( response_message_id=response_id_list.pop(), activate_kw=activate_kw, action=action, request_message_id=syncml_request.header["message_id"], simulate=False)
def __load_module(self, fullname): """ Load a module with given fullname (see PEP 302) if it's not already in sys.modules. It is assumed that imports are filtered properly in find_module(). Also, when the top-level Component module is requested (erp5.component.XXX.COMPONENT_NAME), the Component with the highest version priority will be loaded into the Version package (erp5.component.XXX.VERSION_version.COMPONENT_NAME. Therefore, the top-level Component module will just be an alias of the versioned one. As per PEP-302, raise an ImportError if the Loader could not load the module for any reason... """ site = getSite() if fullname.startswith('Products.'): module_fullname_filesystem = fullname import erp5.component fullname = erp5.component.filesystem_import_dict[ module_fullname_filesystem] else: module_fullname_filesystem = None name = fullname[len(self._namespace_prefix):] # if only Version package (erp5.component.XXX.VERSION_version) is # requested to be loaded, then create it if necessary if name.endswith('_version'): version = name[:-self.__version_suffix_len] return (version in site.getVersionPriorityNameList() and self._getVersionPackage(version) or None) module_fullname_alias = None version_package_name = name[:-self.__version_suffix_len] # If a specific version of the Component has been requested if '.' in name: try: version, name = name.split('.') version = version[:-self.__version_suffix_len] except ValueError, error: raise ImportError("%s: should be %s.VERSION.COMPONENT_REFERENCE (%s)" % \ (fullname, self._namespace, error)) component_id = "%s.%s.%s" % (self._id_prefix, version, name)
def _registry_dict(self): """ Create the component registry, this is very similar to Products.ERP5Type.document_class_registry and avoids checking whether a Component exists at each call at the expense of being slower when being re-generated after a reset. Moreover, it allows to handle reference easily. """ if not self.__registry_dict: portal = getSite() try: component_tool = portal.portal_components # When installing ERP5 site, erp5_core_components has not been installed # yet, thus this will obviously failed... # # XXX-arnau: Is this needed as it is now done in synchronizeDynamicModules? except AttributeError: return {} version_priority_set = set(portal.getVersionPriorityNameList()) # objectValues should not be used for a large number of objects, but # this is only done upon reset, moreover using the Catalog is too risky # as it lags behind and depends upon objects being reindexed for component in component_tool.objectValues(portal_type=self._portal_type): # Only consider modified or validated states as state transition will # be handled by component_validation_workflow which will take care of # updating the registry try: validation_state_tuple = component.getValidationState() except AttributeError: # XXX: Accessors may have not been generated yet pass else: if validation_state_tuple in ('modified', 'validated'): version = component.getVersion(validated_only=True) # The versions should have always been set on ERP5Site property # beforehand if version in version_priority_set: reference = component.getReference(validated_only=True) self.__registry_dict.setdefault(reference, {})[version] = ( component.getId(), component.getUid()) return self.__registry_dict
def testConstraintAfterClosingZODBConnection(self): """ Make sure that constraint works even if ZODB connection close. This test is added for the bug #20110628-ABAA76. """ # Open new connection and add a new constraint. db = self.app._p_jar.db() con = db.open() app = con.root()['Application'].__of__(self.app.aq_parent) portal = app[self.getPortalName()] from Products.ERP5.ERP5Site import getSite, setSite old_site = getSite() setSite(portal) import erp5 dummy = getattr(erp5.portal_type, 'TALES Constraint')(id='dummy') portal.portal_property_sheets.TestMigration._setObject('dummy', dummy) dummy = portal.portal_property_sheets.TestMigration.dummy dummy.edit(reference='test_dummy_constraint', expression='python: object.getTitle() == "my_tales_constraint_title"') dummy.Predicate_view() transaction.commit() # Recreate class with a newly added constraint synchronizeDynamicModules(portal, force=True) # Load test_module test_module = getattr(portal, 'Test Migration') test_module.objectValues() # Then close this new connection. transaction.abort() con.close() # This code depends on ZODB implementation. for i in db.pool.available[:]: if i[1] == con: db.pool.available.remove(i) db.pool.all.remove(con) del con # Back to the default connection. transaction.abort() self.app._p_jar._resetCache() setSite(old_site) # Call checkConsistency and make sure that ConnectionStateError does not occur. self.assert_(self.test_module.checkConsistency())
def __call__(self, *args, **kw): portal = getSite() method_name = "DocumentConnector_%s" % (self._method) method = getattr(portal, method_name, None) kw["reference"] = self._conn.reference if method: response = method(*args, **kw) return method.absolute_url(), response ## try: ## except ValueError, msg: ## raise ConnectionError(msg) ## except Exception, msg: ## raise ConnectionError(msg) else: raise ConnectionError("Method %s does not exist" % (method_name))
def runApplySyncCommand(self, subscription, syncml_request, tag): """ Launch the apply sync command in activity """ send_response = subscription.getSyncmlAlertCode() != "refresh_from_client_only" if send_response and len(syncml_request.sync_command_list): # Generate a list of responses ID here to be scallable response_id_list = subscription.getNextMessageIdList( id_count=len(syncml_request.sync_command_list)) response_id_list.reverse() else: response_id_list = [None for x in xrange(len(syncml_request.sync_command_list))] split = getSite().portal_preferences.getPreferredSyncActionPerActivityCount() if not split: if send_response: syncml_response = self._generateBaseResponse(subscription) else: syncml_response = None subscription.applyActionList(syncml_request, syncml_response) if syncml_response: subscription.activate( activity="SQLQueue", priority=ACTIVITY_PRIORITY, tag=subscription.getRelativeUrl()).sendMessage(xml=str(syncml_response)) else: # XXX For now always split by one activate = subscription.getPortalObject().portal_synchronizations.activate activate_kw = { "activity" :"SQLQueue", "priority" : ACTIVITY_PRIORITY, "tag" : tag, "group_method_id" : None, "group_method_cost" : 1./float(split), } for action in syncml_request.sync_command_list: syncml_logger.info("---> launch action in activity %s" %(action,)) activate(**activate_kw).applySyncCommand( subscription_path=subscription.getRelativeUrl(), response_message_id=response_id_list.pop(), activate_kw=activate_kw, action=action, request_message_id=syncml_request.header["message_id"], simulate=False)
def _fixPortalTypeBeforeMigration(self, portal_type): # Tools are causing problems: they used to have no type_class, or wrong # type_class, or sometimes have no type definitions at all. # Fix type definition if possible before any migration. from Products.ERP5.ERP5Site import getSite types_tool = getSite().portal_types type_definition = getattr(types_tool, portal_type, None) if type_definition is not None and \ type_definition.getTypeClass() in ('Folder', None): # wrong type_class, fix it manually: from Products.ERP5Type import document_class_registry try: type_definition.type_class = document_class_registry[ portal_type.replace(' ', '')] except KeyError: LOG('BaseTool._migratePortalType', WARNING, 'No document class could be found for portal type %r' % portal_type)
def find_module(self, fullname, path=None): """ PEP-302 Finder which determines which packages and modules will be handled by this class. It must be done carefully to avoid handling packages and modules the Loader (load_module()) will not be handled later as the latter would raise ImportError... As per PEP-302, returns None if this Finder cannot handle the given name, perhaps because the Finder of another Component Package could do it or because this is a filesystem module... """ # Ignore imports with a path which are filesystem-only and any # absolute imports which does not start with this package prefix, # None there means that "normal" sys.path will be used if path or not fullname.startswith(self._namespace_prefix): return None site = getSite() # __import__ will first try a relative import, for example # erp5.component.XXX.YYY.ZZZ where erp5.component.XXX.YYY is the current # Component where an import is done name = fullname[len(self._namespace_prefix):] if '.' in name: try: version, name = name.split('.') version = version[:-self.__version_suffix_len] except ValueError: return None try: self._registry_dict[name][version] except KeyError: return None # Skip unavailable components, otherwise Products for example could be # wrongly considered as importable and thus the actual filesystem class # ignored elif (name not in self._registry_dict and name[:-self.__version_suffix_len] not in site.getVersionPriorityNameList()): return None return self
def _fixPortalTypeBeforeMigration(self, portal_type): # Tools are causing problems: they used to have no type_class, or wrong # type_class, or sometimes have no type definitions at all. # Fix type definition if possible before any migration. from Products.ERP5.ERP5Site import getSite types_tool = getSite().portal_types type_definition = getattr(types_tool, portal_type, None) if type_definition is not None and \ type_definition.getTypeClass() in ('Folder', None): # wrong type_class, fix it manually: from Products.ERP5Type import document_class_registry try: type_definition.type_class = document_class_registry[ portal_type.replace(' ', '')] except KeyError: LOG( 'BaseTool._migratePortalType', WARNING, 'No document class could be found for portal type %r' % portal_type)
def getPortal(self): """Returns the portal object, i.e. the "fixture root". Rewrap the portal in an independant request for this test. """ if self.portal is not None: return self.portal # _module_cache_set is used to keep a reference to the code of modules # before they get reloaded. As we will use another request we need to # make sure that we still have a reference to _module_cache_set so that # it does not get garbage collected. module_cache_set = getattr(get_request(), '_module_cache_set', None) from Products.ERP5.ERP5Site import getSite site = getSite() # reconstruct the acquistion chain with an independant request. # RequestContainer -> Application -> Site from Testing.ZopeTestCase.utils import makerequest portal = getattr(makerequest(site.aq_parent), site.getId()) if module_cache_set: portal.REQUEST._module_cache_set = module_cache_set # Make the various get_request patches return this request. # This is for ERP5TypeTestCase patch from Testing.ZopeTestCase.connections import registry if registry: registry._conns[-1] = portal # This is for Localizer patch from Products.Localizer import patches request = portal.REQUEST with patches._requests_lock: patches._requests[thread.get_ident()] = request # Make live tests run under the same server URL than the host instance. if _request_server_url: request['SERVER_URL'] = _request_server_url request._resetURLS() self.portal = portal return portal
def __load_module(self, fullname): """ Load a module with given fullname (see PEP 302) if it's not already in sys.modules. It is assumed that imports are filtered properly in find_module(). Also, when the top-level Component module is requested (erp5.component.XXX.COMPONENT_NAME), the Component with the highest version priority will be loaded into the Version package (erp5.component.XXX.VERSION_version.COMPONENT_NAME. Therefore, the top-level Component module will just be an alias of the versioned one. As per PEP-302, raise an ImportError if the Loader could not load the module for any reason... """ site = getSite() name = fullname[len(self._namespace_prefix):] # if only Version package (erp5.component.XXX.VERSION_version) is # requested to be loaded, then create it if necessary if name.endswith('_version'): version = name[:-self.__version_suffix_len] return (version in site.getVersionPriorityNameList() and self._getVersionPackage(version) or None) module_fullname_alias = None version_package_name = name[:-self.__version_suffix_len] # If a specific version of the Component has been requested if '.' in name: try: version, name = name.split('.') version = version[:-self.__version_suffix_len] except ValueError, error: raise ImportError("%s: should be %s.VERSION.COMPONENT_REFERENCE (%s)" % \ (fullname, self._namespace, error)) try: component_id = self._registry_dict[name][version][0] except KeyError: raise ImportError("%s: version %s of Component %s could not be found" % \ (fullname, version, name))
def translate(self): """ Return the translated message. If the original is a string object, the return value is a string object. If it is a unicode object, the return value is a unicode object. """ message = self.message if self.domain is None: # Map the translated string with given parameters if type(self.mapping) is dict: if isinstance(message, six.text_type) : message = message.encode('utf-8') message = Template(message).substitute(self.mapping) else: from Products.ERP5.ERP5Site import getSite request = Globals.get_request() translation_service = getGlobalTranslationService() if self.mapping: unicode_mapping = {} for k, v in six.iteritems(self.mapping): if isinstance(v, str): v = v.decode('utf-8') unicode_mapping[k] = v else: unicode_mapping = self.mapping translated_message = translation_service.translate( self.domain, message, mapping=unicode_mapping, context=getSite(request), default=self.default) if translated_message is not None: message = translated_message if isinstance(self.message, str): if isinstance(message, six.text_type): message = message.encode('utf-8') elif isinstance(message, str): message = message.decode('utf-8') return message
def translate(self): """ Return the translated message. If the original is a string object, the return value is a string object. If it is a unicode object, the return value is a unicode object. """ message = self.message if self.domain is None: # Map the translated string with given parameters if type(self.mapping) is dict: if isinstance(message, unicode) : message = message.encode('utf-8') message = Template(message).substitute(self.mapping) else: from Products.ERP5.ERP5Site import getSite request = Globals.get_request() translation_service = getGlobalTranslationService() if self.mapping: unicode_mapping = {} for k, v in self.mapping.iteritems(): if isinstance(v, str): v = v.decode('utf-8') unicode_mapping[k] = v else: unicode_mapping = self.mapping translated_message = translation_service.translate( self.domain, message, mapping=unicode_mapping, context=getSite(request), default=self.default) if translated_message is not None: message = translated_message if isinstance(self.message, str): if isinstance(message, unicode): message = message.encode('utf-8') elif isinstance(message, str): message = message.decode('utf-8') return message
def formatLine(self, tb, *args, **kwargs): """ Monkey patched to add links to ZODB Components and Python Script. The regex part is a bit dirty but there is no other way besides of a copy/paste of formatLine()... """ f = tb.tb_frame filename = f.f_code.co_filename.replace('<', '').replace('>', '') lineno = tb.tb_lineno f_globals = f.f_globals line_str = HTMLExceptionFormatter_formatLine(self, tb, *args, **kwargs) from Products.ERP5.ERP5Site import getSite try: portal_absolute_url = getSite().absolute_url() import re # Use the supplement defined in the module. # This is used by Scripts (Python). if '__traceback_supplement__' in f_globals: tbs = f_globals['__traceback_supplement__'] line_str = re.sub( '^(<li>\s*)(Module script,[^<]*)(.*)$', r'\1<a href="%s/manage_main?line=%s">\2</a>\3' % (tbs[1].absolute_url(), lineno), line_str, flags=re.DOTALL) else: line_str = re.sub( '^(<li>\s*)(Module erp5\.component\.[^<]*)(.*)$', r'\1<a href="/%s/%s?line=%s">\2</a>\3' % (portal_absolute_url, filename, lineno), line_str, flags=re.DOTALL) except Exception, e: pass
def formatLine(self, tb, *args, **kwargs): """ Monkey patched to add links to ZODB Components and Python Script. The regex part is a bit dirty but there is no other way besides of a copy/paste of formatLine()... """ f = tb.tb_frame filename = f.f_code.co_filename.replace('<', '').replace('>', '') lineno = tb.tb_lineno f_globals = f.f_globals line_str = HTMLExceptionFormatter_formatLine(self, tb, *args, **kwargs) from Products.ERP5.ERP5Site import getSite try: portal_absolute_url = getSite().absolute_url() import re # Use the supplement defined in the module. # This is used by Scripts (Python). if '__traceback_supplement__' in f_globals: tbs = f_globals['__traceback_supplement__'] line_str = re.sub('^(<li>\s*)(Module script,[^<]*)(.*)$', r'\1<a href="%s/manage_main?line=%s">\2</a>\3' % (tbs[1].absolute_url(), lineno), line_str, flags=re.DOTALL) else: line_str = re.sub('^(<li>\s*)(Module erp5\.component\.[^<]*)(.*)$', r'\1<a href="/%s/%s?line=%s">\2</a>\3' % (portal_absolute_url, filename, lineno), line_str, flags=re.DOTALL) except Exception as e: pass return line_str
def unrestricted_apply(function, args=(), kw={}): # XXX-JPS: naming """Function to bypass all security checks This function is as dangerous as 'UnrestrictedMethod' decorator. Read its docstring for more information. Never use this, until you are 100% certain that you have no other way. """ security_manager = getSecurityManager() user = security_manager.getUser() anonymous = (user.getUserName() == 'Anonymous User') if user.getId() is None and not anonymous: # This is a special user, thus the user is not allowed to own objects. super_user = UnrestrictedUser(user.getUserName(), None, user.getRoles(), user.getDomains()) else: try: # XXX is it better to get roles from the parent (i.e. portal)? uf = user.aq_inner.aq_parent except AttributeError: # XXX: local imports are bad, getSite should be moved to ERP5Type. from Products.ERP5.ERP5Site import getSite uf = getSite().acl_users role_list = uf.valid_roles() if anonymous: # If the user is anonymous, use the id of the system user, # so that it would not be treated as an unauthorized user. user_id = str(system) else: user_id = user.getId() super_user = PrivilegedUser(user_id, None, role_list, user.getDomains()).__of__(uf) newSecurityManager(None, super_user) try: return apply(function, args, kw) finally: # Make sure that the original user is back. setSecurityManager(security_manager)
def super_user(): """Context manager to bypass all security checks This function is as dangerous as 'UnrestrictedMethod' decorator. Read its docstring for more information. Never use this, until you are 100% certain that you have no other way. """ security_manager = getSecurityManager() user = security_manager.getUser() anonymous = (user.getUserName() == 'Anonymous User') if user.getId() is None and not anonymous: # This is a special user, thus the user is not allowed to own objects. super_user = UnrestrictedUser(user.getUserName(), None, user.getRoles(), user.getDomains()) else: try: # XXX is it better to get roles from the parent (i.e. portal)? uf = user.aq_inner.aq_parent except AttributeError: # XXX: local imports are bad, getSite should be moved to ERP5Type. from Products.ERP5.ERP5Site import getSite uf = getSite().acl_users role_list = uf.valid_roles() if anonymous: # If the user is anonymous, use the id of the system user, # so that it would not be treated as an unauthorized user. user_id = str(system) else: user_id = user.getId() super_user = PrivilegedUser(user_id, None, role_list, user.getDomains()).__of__(uf) newSecurityManager(None, super_user) try: yield finally: # Make sure that the original user is back. setSecurityManager(security_manager)
def getPortal(self): """Returns the portal object, i.e. the "fixture root". """ from Products.ERP5.ERP5Site import getSite return getSite(get_request())
def loadClass(cls): """ - mro before load: erp5.portal_type.XXX, GhostBaseMetaClass instance, *TAIL - mro after: erp5.portal_type.XXX, *new_bases_fetched_from_ZODB """ __traceback_info__ = cls.__name__ # Do not load the class again if it has already been loaded if not cls.__isghost__: return # cls might be a subclass of a portal type class # we need to find the right class to change for klass in cls.__mro__: # XXX hardcoded, this doesnt look too good if klass.__module__ == "erp5.portal_type": break else: raise AttributeError("Could not find a portal type class in" " class hierarchy") portal_type = klass.__name__ from Products.ERP5.ERP5Site import getSite site = getSite() ERP5Base.aq_method_lock.acquire() try: try: class_definition = generatePortalTypeClass(site, portal_type) except AttributeError: LOG("ERP5Type.Dynamic", WARNING, "Could not access Portal Type Object for type %r" % portal_type, error=sys.exc_info()) base_tuple = (ERP5BaseBroken, ) portal_type_category_list = [] attribute_dict = dict(_categories=[], constraints=[]) interface_list = [] else: base_tuple, portal_type_category_list, \ interface_list, attribute_dict = class_definition klass.__isghost__ = False klass.__bases__ = base_tuple klass.resetAcquisition() for key, value in attribute_dict.iteritems(): setattr(klass, key, value) if getattr(klass.__setstate__, 'im_func', None) is \ persistent_migration.__setstate__: # optimization to reduce overhead of compatibility code klass.__setstate__ = persistent_migration.Base__setstate__ for interface in interface_list: classImplements(klass, interface) # skip this during the early Base Type / Types Tool generation # because they dont have accessors, and will mess up # workflow methods. We KNOW that we will re-load this type anyway if len(base_tuple) > 1: klass.generatePortalTypeAccessors(site, portal_type_category_list) # need to set %s__roles__ for generated methods cls.setupSecurity() except Exception: import traceback; traceback.print_exc() raise finally: ERP5Base.aq_method_lock.release()
def __load_module(self, fullname): """ Load a module with given fullname (see PEP 302) if it's not already in sys.modules. It is assumed that imports are filtered properly in find_module(). Also, when the top-level Component module is requested (erp5.component.XXX.COMPONENT_NAME), the Component with the highest version priority will be loaded into the Version package (erp5.component.XXX.VERSION_version.COMPONENT_NAME. Therefore, the top-level Component module will just be an alias of the versioned one. As per PEP-302, raise an ImportError if the Loader could not load the module for any reason... """ # In Python < 3.3, the import lock is a global lock for all modules: # http://bugs.python.org/issue9260 # # So, release the import lock acquired by import statement on all hooks to # load objects from ZODB. When an object is requested from ZEO, it sends a # RPC request and lets the asyncore thread gets the reply. This reply may # be a tuple (PICKLE, TID), sent directly to the first thread, or an # Exception, which tries to import a ZODB module and thus creates a # deadlock because of the global import lock # # Also, handle the case where find_module() may be called without import # statement as it does change anything in sys.modules import_lock_held = True try: imp.release_lock() except RuntimeError: import_lock_held = False try: site = getSite() name = fullname[len(self._namespace_prefix):] # if only Version package (erp5.component.XXX.VERSION_version) is # requested to be loaded, then create it if necessary if name.endswith('_version'): version = name[:-self.__version_suffix_len] return (version in site.getVersionPriorityNameList() and self._getVersionPackage(version) or None) module_fullname_alias = None version_package_name = name[:-self.__version_suffix_len] # If a specific version of the Component has been requested if '.' in name: try: version, name = name.split('.') version = version[:-self.__version_suffix_len] except ValueError, error: raise ImportError("%s: should be %s.VERSION.COMPONENT_REFERENCE (%s)" % \ (fullname, self._namespace, error)) try: component_id = self._registry_dict[name][version][0] except KeyError: raise ImportError("%s: version %s of Component %s could not be found" % \ (fullname, version, name)) # Otherwise, find the Component with the highest version priority else:
def find_module(self, fullname, path=None): """ PEP-302 Finder which determines which packages and modules will be handled by this class. It must be done carefully to avoid handling packages and modules the Loader (load_module()) will not be handled later as the latter would raise ImportError... As per PEP-302, returns None if this Finder cannot handle the given name, perhaps because the Finder of another Component Package could do it or because this is a filesystem module... """ # Ignore imports with a path which are filesystem-only and any # absolute imports which does not start with this package prefix, # None there means that "normal" sys.path will be used if path or not fullname.startswith(self._namespace_prefix): return None import_lock_held = True try: imp.release_lock() except RuntimeError: import_lock_held = False # The import lock has been released, but as _registry_dict may be # initialized or cleared, no other Components should access this critical # region # # TODO-arnau: Too coarse-grain? aq_method_lock.acquire() try: site = getSite() # __import__ will first try a relative import, for example # erp5.component.XXX.YYY.ZZZ where erp5.component.XXX.YYY is the current # Component where an import is done name = fullname[len(self._namespace_prefix):] if '.' in name: try: version, name = name.split('.') version = version[:-self.__version_suffix_len] except ValueError: return None try: self._registry_dict[name][version] except KeyError: return None # Skip unavailable components, otherwise Products for example could be # wrongly considered as importable and thus the actual filesystem class # ignored elif (name not in self._registry_dict and name[:-self.__version_suffix_len] not in site.getVersionPriorityNameList()): return None return self finally: aq_method_lock.release() # Internal release of import lock at the end of import machinery will # fail if the hook is not acquired if import_lock_held: imp.acquire_lock()
def find_module(self, fullname, path=None): """ PEP-302 Finder which determines which packages and modules will be handled by this class. It must be done carefully to avoid handling packages and modules the Loader (load_module()) will not be handled later as the latter would raise ImportError... As per PEP-302, returns None if this Finder cannot handle the given name, perhaps because the Finder of another Component Package could do it or because this is a filesystem module... """ # Ignore imports with a path which are filesystem-only and any # absolute imports which does not start with this package prefix, # None there means that "normal" sys.path will be used if path or not fullname.startswith(self._namespace_prefix): return None import_lock_held = True try: imp.release_lock() except RuntimeError: import_lock_held = False try: site = getSite() # __import__ will first try a relative import, for example # erp5.component.XXX.YYY.ZZZ where erp5.component.XXX.YYY is the current # Component where an import is done name = fullname[len(self._namespace_prefix):] # name=VERSION_version.REFERENCE if '.' in name: try: version, name = name.split('.') version = version[:-self.__version_suffix_len] except ValueError: return None id_ = "%s.%s.%s" % (self._id_prefix, version, name) # aq_base() because this should not go up to ERP5Site and trigger # side-effects, after all this only check for existence... try: component_tool = aq_base(site.portal_components) except AttributeError: # For old sites, just use FS Documents... return None component = getattr(component_tool, id_, None) if component is None or component.getValidationState() not in ( 'modified', 'validated'): return None # Skip unavailable components, otherwise Products for example could be # wrongly considered as importable and thus the actual filesystem class # ignored # # name=VERSION_version elif name.endswith('_version'): if name[:-self. __version_suffix_len] not in site.getVersionPriorityNameList( ): return None # name=REFERENCE else: try: component_tool = aq_base(site.portal_components) except AttributeError: # For old sites, just use FS Documents... return None for version in site.getVersionPriorityNameList(): id_ = "%s.%s.%s" % (self._id_prefix, version, name) component = getattr(component_tool, id_, None) if component is not None and component.getValidationState( ) in ('modified', 'validated'): break else: return None return self finally: # Internal release of import lock at the end of import machinery will # fail if the hook is not acquired if import_lock_held: imp.acquire_lock()
def __init__(self): """ """ from Products.ERP5.ERP5Site import getSite self.context = getSite()
def send(self, to_url, data, sync_id, content_type): getSite().portal_synchronizations.readResponse(text=data, sync_id=sync_id)
def loadClass(cls): """ - mro before load: erp5.portal_type.XXX, GhostBaseMetaClass instance, *TAIL - mro after: erp5.portal_type.XXX, *new_bases_fetched_from_ZODB """ __traceback_info__ = cls.__name__ # Do not load the class again if it has already been loaded if not cls.__isghost__: return # cls might be a subclass of a portal type class # we need to find the right class to change for klass in cls.__mro__: # XXX hardcoded, this doesnt look too good if klass.__module__ == "erp5.portal_type": break else: raise AttributeError("Could not find a portal type class in" " class hierarchy") portal_type = klass.__name__ from Products.ERP5.ERP5Site import getSite site = getSite() with aq_method_lock: try: class_definition = generatePortalTypeClass(site, portal_type) except AttributeError: LOG("ERP5Type.Dynamic", WARNING, "Could not access Portal Type Object for type %r" % portal_type, error=True) base_tuple = (ERP5BaseBroken, ) portal_type_category_list = [] attribute_dict = dict(_categories=[], constraints=[]) interface_list = [] else: base_tuple, portal_type_category_list, \ interface_list, attribute_dict = class_definition klass.__isghost__ = False klass.__bases__ = base_tuple klass.resetAcquisition() for key, value in attribute_dict.iteritems(): setattr(klass, key, value) if getattr(klass.__setstate__, 'im_func', None) is \ persistent_migration.__setstate__: # optimization to reduce overhead of compatibility code klass.__setstate__ = persistent_migration.Base__setstate__ for interface in interface_list: classImplements(klass, interface) # skip this during the early Base Type / Types Tool generation # because they dont have accessors, and will mess up # workflow methods. We KNOW that we will re-load this type anyway if len(base_tuple) > 1: klass.generatePortalTypeAccessors(site, portal_type_category_list) # need to set %s__roles__ for generated methods cls.setupSecurity()
def find_module(self, fullname, path=None): """ PEP-302 Finder which determines which packages and modules will be handled by this class. It must be done carefully to avoid handling packages and modules the Loader (load_module()) will not be handled later as the latter would raise ImportError... As per PEP-302, returns None if this Finder cannot handle the given name, perhaps because the Finder of another Component Package could do it or because this is a filesystem module... """ import erp5.component # ZODB Components if not path: if not fullname.startswith(self._namespace_prefix): return None # FS import backward compatibility else: try: fullname = erp5.component.filesystem_import_dict[fullname] except (TypeError, KeyError): return None else: if not fullname.startswith(self._namespace_prefix): return None import_lock_held = True try: imp.release_lock() except RuntimeError: import_lock_held = False try: site = getSite() if erp5.component.filesystem_import_dict is None: filesystem_import_dict = {} try: component_tool = aq_base(site.portal_components) except AttributeError: # For old sites, just use FS Documents... return None else: for component in component_tool.objectValues(): if component.getValidationState() == 'validated': component_module_name = '%s.%s' % (component._getDynamicModuleNamespace(), component.getReference()) if component.getSourceReference() is not None: filesystem_import_dict[component.getSourceReference()] = component_module_name if component.getPortalType() == 'Document Component': filesystem_import_dict[('Products.ERP5Type.Document.' + component.getReference())] = component_module_name erp5.component.filesystem_import_dict = filesystem_import_dict # __import__ will first try a relative import, for example # erp5.component.XXX.YYY.ZZZ where erp5.component.XXX.YYY is the current # Component where an import is done name = fullname[len(self._namespace_prefix):] # name=VERSION_version.REFERENCE if '.' in name: try: version, name = name.split('.') version = version[:-self.__version_suffix_len] except ValueError: return None id_ = "%s.%s.%s" % (self._id_prefix, version, name) # aq_base() because this should not go up to ERP5Site and trigger # side-effects, after all this only check for existence... component = getattr(aq_base(site.portal_components), id_, None) if component is None or component.getValidationState() not in ('modified', 'validated'): return None # Skip unavailable components, otherwise Products for example could be # wrongly considered as importable and thus the actual filesystem class # ignored # # name=VERSION_version elif name.endswith('_version'): if name[:-self.__version_suffix_len] not in site.getVersionPriorityNameList(): return None # name=REFERENCE else: component_tool = aq_base(site.portal_components) for version in site.getVersionPriorityNameList(): id_ = "%s.%s.%s" % (self._id_prefix, version, name) component = getattr(component_tool, id_, None) if component is not None and component.getValidationState() in ('modified', 'validated'): break else: return None return self finally: # Internal release of import lock at the end of import machinery will # fail if the hook is not acquired if import_lock_held: imp.acquire_lock()
def __load_module(self, fullname): """ Load a module with given fullname (see PEP 302) if it's not already in sys.modules. It is assumed that imports are filtered properly in find_module(). Also, when the top-level Component module is requested (erp5.component.XXX.COMPONENT_NAME), the Component with the highest version priority will be loaded into the Version package (erp5.component.XXX.VERSION_version.COMPONENT_NAME. Therefore, the top-level Component module will just be an alias of the versioned one. As per PEP-302, raise an ImportError if the Loader could not load the module for any reason... """ site = getSite() if fullname.startswith('Products.'): module_fullname_filesystem = fullname import erp5.component fullname = erp5.component.filesystem_import_dict[module_fullname_filesystem] else: module_fullname_filesystem = None name = fullname[len(self._namespace_prefix):] # if only Version package (erp5.component.XXX.VERSION_version) is # requested to be loaded, then create it if necessary if name.endswith('_version'): version = name[:-self.__version_suffix_len] return (version in site.getVersionPriorityNameList() and self._getVersionPackage(version) or None) module_fullname_alias = None version_package_name = name[:-self.__version_suffix_len] # If a specific version of the Component has been requested if '.' in name: try: version, name = name.split('.') version = version[:-self.__version_suffix_len] except ValueError as error: raise ImportError("%s: should be %s.VERSION.COMPONENT_REFERENCE (%s)" % \ (fullname, self._namespace, error)) component_id = "%s.%s.%s" % (self._id_prefix, version, name) # Otherwise, find the Component with the highest version priority else: component_tool = aq_base(site.portal_components) # Version priority name list is ordered in descending order for version in site.getVersionPriorityNameList(): component_id = "%s.%s.%s" % (self._id_prefix, version, name) component = getattr(component_tool, component_id, None) if component is not None and component.getValidationState() in ('modified', 'validated'): break else: raise ImportError("%s: no version of Component %s in Site priority" % \ (fullname, name)) module_fullname_alias = self._namespace + '.' + name # Check whether this module has already been loaded before for a # specific version, if so, just add it to the upper level try: module = getattr(getattr(self, version + '_version'), name) except AttributeError: pass else: setattr(self, name, module) sys.modules[module_fullname_alias] = module MNAME_MAP[module_fullname_alias] = module.__name__ if module_fullname_filesystem: sys.modules[module_fullname_filesystem] = module MNAME_MAP[module_fullname_filesystem] = module.__name__ return module component = getattr(site.portal_components, component_id) relative_url = component.getRelativeUrl() module_fullname = '%s.%s_version.%s' % (self._namespace, version, name) module = ModuleType(module_fullname, component.getDescription()) source_code_str = component.getTextContent(validated_only=True) version_package = self._getVersionPackage(version) # All the required objects have been loaded, acquire import lock to modify # sys.modules and execute PEP302 requisites imp.acquire_lock() try: # The module *must* be in sys.modules before executing the code in case # the module code imports (directly or indirectly) itself (see PEP 302) sys.modules[module_fullname] = module if module_fullname_alias: sys.modules[module_fullname_alias] = module if module_fullname_filesystem: sys.modules[module_fullname_filesystem] = module # This must be set for imports at least (see PEP 302) module.__file__ = '<' + relative_url + '>' # Only useful for get_source(), do it before exec'ing the source code # so that the source code is properly display in case of error module.__loader__ = self module.__path__ = [] module.__name__ = module_fullname self.__fullname_source_code_dict[module_fullname] = source_code_str try: # XXX: Any loading from ZODB while exec'ing the source code will result # in a deadlock source_code_obj = compile(source_code_str, module.__file__, 'exec') exec(source_code_obj, module.__dict__) except Exception as error: del sys.modules[module_fullname] if module_fullname_alias: del sys.modules[module_fullname_alias] if module_fullname_filesystem: del sys.modules[module_fullname_filesystem] reraise(ImportError, "%s: cannot load Component %s (%s)" % (fullname, name, error), sys.exc_info()[2]) # Add the newly created module to the Version package and add it as an # alias to the top-level package as well setattr(version_package, name, module) if module_fullname_alias: setattr(self, name, module) MNAME_MAP[module_fullname_alias] = module_fullname if module_fullname_filesystem: MNAME_MAP[module_fullname_filesystem] = module.__name__ import erp5.component erp5.component.ref_manager.add_module(module) finally: imp.release_lock() component._hookAfterLoad(module) return module