def mailPassword(self, forgotten_userid, REQUEST): """ Email a forgotten password to a member. o Raise an exception if user ID is not found. """ mtool = getUtility(IMembershipTool) member = mtool.getMemberById(forgotten_userid) if member is None: raise ValueError(_(u'The username you entered could not be ' u'found.')) email = self._getValidEmailAddress(member) # Rather than have the template try to use the mailhost, we will # render the message ourselves and send it from here (where we # don't need to worry about 'UseMailHost' permissions). if getattr(self, 'REQUEST', None) is None: context = RequestContainer(REQUEST=REQUEST) for item in reversed(aq_chain(self)): context = aq_base(item).__of__(context) else: context = self method = context.password_email kw = {'member': member, 'password': member.getPassword()} if getattr(aq_base(method), 'isDocTemp', 0): mail_text = method(self, REQUEST, **kw) else: mail_text = method(**kw) host = getUtility(IMailHost) host.send(mail_text) return context.mail_password_response(self, REQUEST)
def _unrestrictedGetObject(self): parent = aq_parent(self) if (aq_get(parent, 'REQUEST', None) is None and _GLOBALREQUEST_INSTALLED and _REQUESTCONTAINER_EXISTS): request = getRequest() if request is not None: # path should be absolute, starting at the physical root parent = self.getPhysicalRoot() request_container = RequestContainer(REQUEST=request) parent = aq_base(parent).__of__(request_container) try: return parent.unrestrictedTraverse(self.getPath()) except: connection = queryUtility(ISQLConnectionsUtility, name=self.portal_type, default=None) if connection == None and self.portal_type: fti = queryUtility(IDexterityFTI, name=self.portal_type, default=None) if not fti: return None updateConnectionsForFti(fti) connection = queryUtility(ISQLConnectionsUtility, name=self.portal_type, default=None) return connection.getVirtualItem(self.sql_id, context=parent)
def getObject(self, REQUEST=None): """Return the object for this record Will return None if the object cannot be found via its cataloged path (i.e., it was deleted or moved without recataloging), or if the user is not authorized to access the object. This method mimicks a subset of what publisher's traversal does, so it allows access if the final object can be accessed even if intermediate objects cannot. """ path = self.getPath().split('/') if not path: return None parent = aq_parent(self) if (aq_get(parent, 'REQUEST', None) is None): request = getRequest() if request is not None: # path should be absolute, starting at the physical root parent = self.getPhysicalRoot() request_container = RequestContainer(REQUEST=request) parent = aq_base(parent).__of__(request_container) if len(path) > 1: parent = parent.unrestrictedTraverse(path[:-1]) return parent.restrictedTraverse(path[-1])
def render_object(obj, path, where, append_html=True, output_root='', raise_errors=False): path = path.strip('/') assert '..' not in path outputfile = os.path.join(where, path) outputdir = os.path.dirname(outputfile) environ = {'SERVER_NAME': 'localhost', 'SERVER_PORT': '80'} stdin = StringIO() response = Response(stdout=sys.stdout, stderr=sys.stderr) request = Request(stdin, environ, response) if output_root: request['SERVER_URL'] = relpath(output_root, outputdir) setDefaultSkin(request) app = Application().__of__(RequestContainer(REQUEST=request)) obj = obj.__of__(app) request.other['VirtualRootPhysicalPath'] = obj.getPhysicalPath() obj = obj.unrestrictedTraverse(path) if getattr(obj, 'index_html', None) is not None: obj = obj.index_html try: result = mapply(obj, request.args, request) except Exception, e: print >> sys.stderr, "cannot render %s: %s: %s" % ( path, e.__class__.__name__, e) if raise_errors: raise
def _getContext(app): request = HTTPRequest(None, { 'SERVER_NAME': 'localhost', 'SERVER_PORT': '8080', 'REQUEST_METHOD': 'GET' }, HTTPResponse(stdout=None)) return app.__of__(RequestContainer(REQUEST=request))
def mailPassword(self, forgotten_userid, REQUEST): """ Email a forgotten password to a member. o Raise an exception if user ID is not found. """ mtool = getUtility(IMembershipTool) member = mtool.getMemberById(forgotten_userid) if member is None: raise ValueError( _(u'The username you entered could not be ' u'found.')) email = self._getValidEmailAddress(member) # Rather than have the template try to use the mailhost, we will # render the message ourselves and send it from here (where we # don't need to worry about 'UseMailHost' permissions). if getattr(self, 'REQUEST', None) is None: context = RequestContainer(REQUEST=REQUEST) for item in reversed(aq_chain(self)): context = aq_base(item).__of__(context) else: context = self method = context.unrestrictedTraverse('password_email') kw = {'member': member, 'password': member.getPassword()} if getattr(aq_base(method), 'isDocTemp', 0): mail_text = method(self, REQUEST, **kw) else: mail_text = method(**kw) host = getUtility(IMailHost) try: host.send(mail_text, immediate=True) except (TypeError, socket.error): # fallback for mail hosts that don't implement the new signature # fallback to queue if immediate fails host.send(mail_text) try: # BBB: for CMF 2.2's mail_password script return context.mail_password_response(self, REQUEST) except AttributeError: pass
def _getContext(app): resp = HTTPResponse(stdout=None) env = { "SERVER_NAME": "localhost", "SERVER_PORT": "8080", "REQUEST_METHOD": "GET", } req = HTTPRequest(None, env, resp) return app.__of__(RequestContainer(REQUEST=req))
def getPortalObject(self): """ Get the portal object itself. """ request_container = RequestContainer(REQUEST=getRequest()) portal_obj = queryUtility(ISiteRoot) if portal_obj is None: # fallback for bootstrap portal_obj = aq_parent(aq_inner(self)) return portal_obj.__of__(request_container)
def getMembersFolder(self): """ Get the members folder object. """ parent = aq_parent(aq_inner(self)) members_folder = getattr(parent, 'Members', None) if members_folder is None: return None request_container = RequestContainer(REQUEST=getRequest()) return members_folder.__of__(request_container)
def mailPassword(self, forgotten_userid, REQUEST): """ Email a forgotten password to a member. o Raise an exception if user ID is not found. """ mtool = getUtility(IMembershipTool) member = mtool.getMemberById(forgotten_userid) if member is None: raise ValueError(_(u'The username you entered could not be ' u'found.')) email = self._getValidEmailAddress(member) # Rather than have the template try to use the mailhost, we will # render the message ourselves and send it from here (where we # don't need to worry about 'UseMailHost' permissions). if getattr(self, 'REQUEST', None) is None: context = RequestContainer(REQUEST=REQUEST) for item in reversed(aq_chain(self)): context = aq_base(item).__of__(context) else: context = self method = context.unrestrictedTraverse('password_email') kw = {'member': member, 'password': member.getPassword()} if getattr(aq_base(method), 'isDocTemp', 0): mail_text = method(self, REQUEST, **kw) else: mail_text = method(**kw) host = getUtility(IMailHost) try: host.send(mail_text, immediate=True) except (TypeError, socket.error): # fallback for mail hosts that don't implement the new signature # fallback to queue if immediate fails host.send(mail_text) try: # BBB: for CMF 2.2's mail_password script return context.mail_password_response(self, REQUEST) except AttributeError: pass
def registeredNotify(self, new_member_id, password=None, REQUEST=None): """ Handle mailing the registration / welcome message. """ if REQUEST is None: raise ValueError(u"'REQUEST' argument is missing.") mtool = getUtility(IMembershipTool) member = mtool.getMemberById(new_member_id) if member is None: raise ValueError( _(u'The username you entered could not be ' u'found.')) if password is None: password = member.getPassword() email = self._getValidEmailAddress(member) # Rather than have the template try to use the mailhost, we will # render the message ourselves and send it from here (where we # don't need to worry about 'UseMailHost' permissions). if getattr(self, 'REQUEST', None) is None: context = RequestContainer(REQUEST=REQUEST) for item in reversed(aq_chain(self)): context = aq_base(item).__of__(context) else: context = self method = context.unrestrictedTraverse('registered_email') kw = {'member': member, 'password': password, 'email': email} if getattr(aq_base(method), 'isDocTemp', 0): mail_text = method(self, REQUEST, **kw) else: mail_text = method(**kw) host = getUtility(IMailHost) try: host.send(mail_text, immediate=True) except (TypeError, socket.error): # fallback for mail hosts that don't implement the new signature # fallback to queue if immediate fails host.send(mail_text)
def _getContext(self, app): resp = HTTPResponse(stdout=None) env = { 'SERVER_NAME': 'localhost', 'SERVER_PORT': '8080', 'REQUEST_METHOD': 'GET' } req = HTTPRequest(None, env, resp) app.__of__(RequestContainer(REQUEST=req)) return app
def getMembersFolder(self): """ Get the members folder object. """ parent = aq_parent(aq_inner(self)) try: members_folder = parent.restrictedTraverse(self.membersfolder_id) except (AttributeError, KeyError): return None request_container = RequestContainer(REQUEST=getRequest()) return members_folder.__of__(request_container)
def addRequestContainer(app, environ=None): """Add the request container with a fake request to the app object's acquisition context and return the wrapped app object. Additional request environment values can be passed as a dict ``environ``. """ from ZPublisher.BaseRequest import RequestContainer req = makeTestRequest(environ) requestcontainer = RequestContainer(REQUEST=req) return app.__of__(requestcontainer)
def registeredNotify(self, new_member_id, password=None, REQUEST=None): """ Handle mailing the registration / welcome message. """ if REQUEST is None: raise ValueError(u"'REQUEST' argument is missing.") mtool = getUtility(IMembershipTool) member = mtool.getMemberById(new_member_id) if member is None: raise ValueError(_(u'The username you entered could not be ' u'found.')) if password is None: password = member.getPassword() email = self._getValidEmailAddress(member) # Rather than have the template try to use the mailhost, we will # render the message ourselves and send it from here (where we # don't need to worry about 'UseMailHost' permissions). if getattr(self, 'REQUEST', None) is None: context = RequestContainer(REQUEST=REQUEST) for item in reversed(aq_chain(self)): context = aq_base(item).__of__(context) else: context = self method = context.unrestrictedTraverse('registered_email') kw = {'member': member, 'password': password, 'email': email} if getattr(aq_base(method), 'isDocTemp', 0): mail_text = method(self, REQUEST, **kw) else: mail_text = method(**kw) host = getUtility(IMailHost) try: host.send(mail_text, immediate=True) except (TypeError, socket.error): # fallback for mail hosts that don't implement the new signature # fallback to queue if immediate fails host.send(mail_text)
def makerequest(app, user, password): """Like Testing.makerequest but add authentication info.""" resp = HTTPResponse(stdout=stdout) environ['SERVER_NAME'] = 'foo' environ['SERVER_PORT'] = '80' environ['REQUEST_METHOD'] = 'GET' environ['AUTHENTICATED_USER'] = user environ['__ac_name'] = user environ['__ac_password'] = password req = HTTPRequest(stdin, environ, resp) return app.__of__(RequestContainer(REQUEST=req))
def install(): from ZPublisher.BaseRequest import RequestContainer from Products.ERP5Type.Globals import get_request portal = self.getPortalObject() # BusinessTemplate.install needs a request template_tool = portal.aq_base.__of__(portal.aq_parent.__of__( RequestContainer(REQUEST=get_request()))).portal_templates if template_tool.getInstalledBusinessTemplate(bt_name) is None: from Products.ERP5.ERP5Site import getBootstrapBusinessTemplateUrl url = getBootstrapBusinessTemplateUrl(bt_name) template_tool.download(url).install()
def wrap_app_in_request(app): """ Wrap an app in request suitable for execution of templates, and such that Traversable.absolute_url() works in a controlled way. Sets request['SERVER_URL'] and returns tuple of correctly wrapped app and corresponding request object. """ request = test_request() request.setServerURL(protocol='http', hostname=BASE_HOST) app = app.__of__(RequestContainer(REQUEST=request)) app.REQUEST = request return app, request
def getContext(self, app): from ZPublisher.HTTPRequest import HTTPRequest from ZPublisher.HTTPResponse import HTTPResponse from ZPublisher.BaseRequest import RequestContainer resp = HTTPResponse(stdout=None) env = { 'SERVER_NAME':'localhost', 'SERVER_PORT':'8080', 'REQUEST_METHOD':'GET' } req = HTTPRequest(None, env, resp) return app.__of__(RequestContainer(REQUEST = req))
def getApplication(self, request): # Open the database. conn = self.db.open() cleanup = Cleanup(conn.close) request.hold(cleanup) # Close the connection on request.close() # Get the application object. root = conn.root() app = root.get(self.root_name, None) app = app.__of__(RequestContainer(REQUEST=request)) request['PARENTS'].append(app) return app
def _unrestrictedGetObject(self): """Return the object for this record Same as getObject, but does not do security checks. """ parent = aq_parent(self) if (aq_get(parent, 'REQUEST', None) is None): request = getRequest() if request is not None: # path should be absolute, starting at the physical root parent = self.getPhysicalRoot() request_container = RequestContainer(REQUEST=request) parent = aq_base(parent).__of__(request_container) return parent.unrestrictedTraverse(self.getPath())
def mailPassword(self, forgotten_userid, REQUEST): """ Email a forgotten password to a member. o Raise an exception if user ID is not found. """ mtool = getUtility(IMembershipTool) member = mtool.getMemberById(forgotten_userid) if member is None: raise ValueError( _(u'The username you entered could not be ' u'found.')) email = self._getValidEmailAddress(member) # Rather than have the template try to use the mailhost, we will # render the message ourselves and send it from here (where we # don't need to worry about 'UseMailHost' permissions). if getattr(self, 'REQUEST', None) is None: context = RequestContainer(REQUEST=REQUEST) for item in reversed(aq_chain(self)): context = aq_base(item).__of__(context) else: context = self method = context.password_email kw = {'member': member, 'password': member.getPassword()} if getattr(aq_base(method), 'isDocTemp', 0): mail_text = method(self, REQUEST, **kw) else: mail_text = method(**kw) host = getUtility(IMailHost) host.send(mail_text) return context.mail_password_response(self, REQUEST)
def rewrap_in_request_container(obj, context=None): '''Fix an object's acquisition wrapper to be able to acquire the REQUEST.''' request = getattr(context, 'REQUEST', None) or getRequest() if IAcquirer.providedBy(obj) and request is not None: chain = [] parent = obj while 1: chain.append(parent) parent = aq_parent(aq_inner(parent)) if parent in chain or parent is None or isinstance( parent, RequestContainer): break obj = RequestContainer(REQUEST=request) for ob in reversed(chain): obj = aq_base(ob).__of__(obj) return obj
def get_dmd(): """Retrieve the DMD object.""" connections = transaction.get()._synchronizers.data.values()[:] connections.reverse() # Make sure we don't get the temporary connection for cxn in connections: db = getattr(cxn, '_db', None) if db and db.database_name != 'temporary': resp = HTTPResponse(stdout=None) env = { 'SERVER_NAME': 'localhost', 'SERVER_PORT': '8080', 'REQUEST_METHOD': 'GET', } req = HTTPRequest(None, env, resp) app = cxn.root()['Application'] app = app.__of__(RequestContainer(REQUEST=req)) return app.zport.dmd
def makerequest(app, stdout=None, environ=None): """ Adds an HTTPRequest at app.REQUEST, and returns app.__of__(app.REQUEST). Useful for tests that need to acquire REQUEST. Usage: import makerequest app = makerequest.makerequest(app) You should only wrap the object used as 'root' in your tests. app is commonly a Zope2.app(), but that's not strictly necessary and frequently may be overkill; you can wrap other objects as long as they support acquisition and provide enough of the features of Zope2.app for your tests to run. For example, if you want to call getPhysicalPath() on child objects, app must provide a non-recursive implementation of getPhysicalPath(). *stdout* is an optional file-like object and is used by REQUEST.RESPONSE. The default is sys.stdout. *environ* is an optional mapping to be used in the request. Default is a fresh dictionary. Passing os.environ is not recommended; tests should not pollute the real os.environ. """ if stdout is None: stdout = BytesIO() if environ is None: environ = {} resp = HTTPResponse(stdout=stdout) environ.setdefault('SERVER_NAME', 'nohost') environ.setdefault('SERVER_PORT', '80') environ.setdefault('REQUEST_METHOD', 'GET') req = HTTPRequest(BytesIO(), environ, resp) req._steps = ['noobject'] # Fake a published object. req['ACTUAL_URL'] = req.get('URL') # Zope 2.7.4 # Set default skin so that the request is usable for view look-ups. from zope.publisher.browser import setDefaultSkin setDefaultSkin(req) requestcontainer = RequestContainer(REQUEST=req) return app.__of__(requestcontainer)
def getObject(self, REQUEST=None): path = self.getPath().split('/') if not path: return None parent = aq_parent(self) if (aq_get(parent, 'REQUEST', None) is None and _GLOBALREQUEST_INSTALLED and _REQUESTCONTAINER_EXISTS): request = getRequest() if request is not None: # path should be absolute, starting at the physical root parent = self.getPhysicalRoot() request_container = RequestContainer(REQUEST=request) parent = aq_base(parent).__of__(request_container) if len(path) > 1: parent = parent.unrestrictedTraverse(path[:-1]) try: return parent.restrictedTraverse(path[-1]) except: connection = getUtility(ISQLConnectionsUtility, name=self.portal_type) return connection.getVirtualItem(self.sql_id, context=parent)
def get_object(catalog, rid): """get an object based on the catalog rid Code based on ZCatalog.CatalogBrains.AbstractCatalogBrains.getObject """ path = catalog._catalog.getpath(rid) path = path.split('/') if not path: return None parent = aq_parent(catalog) if (aq_get(parent, 'REQUEST', None) is None and _GLOBALREQUEST_INSTALLED): request = getRequest() if request is not None: # path should be absolute, starting at the physical root parent = catalog.getPhysicalRoot() request_container = RequestContainer(REQUEST=request) parent = aq_base(parent).__of__(request_container) if len(path) > 1: parent = parent.unrestrictedTraverse(path[:-1]) return parent.restrictedTraverse(path[-1])
def getObject(self, REQUEST=None): path = self.getPath().split('/') if not path: return None parent = aq_parent(self) if (aq_get(parent, 'REQUEST', None) is None and _GLOBALREQUEST_INSTALLED and _REQUESTCONTAINER_EXISTS): request = getRequest() if request is not None: # path should be absolute, starting at the physical root parent = self.getPhysicalRoot() request_container = RequestContainer(REQUEST=request) parent = aq_base(parent).__of__(request_container) if len(path) > 1: try: parent = parent.unrestrictedTraverse(path[:-1]) except: if path[:-2] == 'data-' + self.portal_type: parent = queryMultiAdapter((None, ICollectiveBehaviorSQLLayer), IBrowserView, name='data-' + name, default=None) try: return parent.restrictedTraverse(path[-1]) except: connection = queryUtility(ISQLConnectionsUtility, name=self.portal_type, default=None) if connection == None and self.portal_type: fti = queryUtility(IDexterityFTI, name=self.portal_type, default=None) if not fti: return None updateConnectionsForFti(fti) connection = queryUtility(ISQLConnectionsUtility, name=self.portal_type, default=None) return connection.getVirtualItem(self.sql_id, context=parent)
def getObject(brain=None, path=None): """Return the object for brain record Will return None if the object cannot be found via its cataloged path (i.e., it was deleted or moved without recataloging). This method mimicks a subset of what publisher's traversal does, so it allows access if the final object can be accessed even if intermediate objects cannot. """ if brain is not None: path = brain.getPath() if not path: return None # Handle portal_factory if 'portal_factory' in path: return None # Handle relatedItems brains at_reference = None if '/at_references/' in path: path, at_reference = path.split('/at_references/') # Handle plone.app.discussion brains discussion = None if '/++conversation++default/' in path: path, discussion = path.split('/++conversation++default/') path = path.split('/') # Remove empty string from begining of the path if not path[0]: path = path[1:] if not path: return None # Remove site id from begining of the path parent = getSite() if path[0] == parent.getId(): path = path[1:] if not path: return parent # Try to add REQUEST if not present if (aq_get(parent, 'REQUEST', None) is None and _GLOBALREQUEST_INSTALLED and _REQUESTCONTAINER_EXISTS): request = getRequest() if request is not None: request_container = RequestContainer(REQUEST=request) parent = aq_base(parent).__of__(request_container) obj = parent.unrestrictedTraverse(path) if isinstance(obj, BrokenClass): logger.warn('BrokenClass found at %s', path) return None # Handle relatedItems if at_reference is not None: at_references = getattr(obj, 'at_references', {}) return at_references.get(at_reference, None) # Handle plone.app.discussion if discussion is not None: anno = getattr(obj, '__annotations__', {}) discussions = anno.get('plone.app.discussion:conversation', {}) return discussions.get(discussion, None) return obj
def subrequest(url, root=None, stdout=None, exception_handler=None): assert url is not None, 'You must pass a url' if isinstance(url, six.text_type): url = url.encode('utf-8') _, _, path, query, _ = urlsplit(url) parent_request = getRequest() assert parent_request is not None, \ 'Unable to get request, perhaps zope.globalrequest is not configured.' parent_site = getSite() security_manager = getSecurityManager() parent_app = parent_request.PARENTS[-1] if path.startswith('/'): path = normpath(path) vurl_parts = parent_request.get('VIRTUAL_URL_PARTS') if vurl_parts is not None: # Use the virtual host root path_past_root = unquote(vurl_parts[-1]) root_path = normpath(parent_request['PATH_INFO']).rstrip( '/')[:-len(path_past_root) or None] if root is None: path = root_path + path else: path = '{0}/{1}{2}'.format(root_path, root.virtual_url_path(), path) elif root is not None: path = '/{0}{1}'.format(root.virtual_url_path(), path) else: try: parent_url = parent_request['URL'] if isinstance(parent_url, six.text_type): parent_url = parent_url.encode('utf-8') # extra is the hidden part of the url, e.g. a default view extra = unquote(parent_url[len(parent_request['ACTUAL_URL']):]) except KeyError: extra = '' here = parent_request['PATH_INFO'] + extra path = urljoin(here, path) path = normpath(path) request = parent_request.clone() for name, parent_value in parent_request.other.items(): if name in OTHER_IGNORE \ or OTHER_IGNORE_RE.match(name) \ or name.startswith('_'): continue request.other[name] = parent_value for key, value in parent_request.response.cookies.items(): request.cookies[key] = value['value'] request['PARENT_REQUEST'] = parent_request alsoProvides(request, ISubRequest) try: setRequest(request) request_container = RequestContainer(REQUEST=request) app = aq_base(parent_app).__of__(request_container) request['PARENTS'] = [app] response = request.response response.__class__ = SubResponse response.stderr = None # only used on retry it seems if stdout is None: stdout = StringIO() # It might be possible to optimize this response.stdout = stdout environ = request.environ environ['PATH_INFO'] = path environ['QUERY_STRING'] = query # Clean up the request. for header in CONDITIONAL_HEADERS: environ.pop(header, None) try: request.processInputs() traversed = request.traverse(path) result = mapply(traversed, positional=request.args, keyword=request, debug=None, maybe=1, missing_name=missing_name, handle_class=dont_publish_class, context=request, bind=1) if result is not response: response.setBody(result) for key, value in request.response.cookies.items(): parent_request.response.cookies[key] = value except Exception as e: logger.exception('Error handling subrequest to {0}'.format(url)) if exception_handler is not None: exception_handler(response, e) else: view = queryMultiAdapter((e, request), name=u'index.html') if view is not None: v = view() response.setBody(v) else: response.exception() return response finally: if SAFE_WRITE_KEY in request.environ: # append this list of safe oids to parent request if SAFE_WRITE_KEY not in parent_request.environ: parent_request.environ[SAFE_WRITE_KEY] = [] new_keys = (set(request.environ[SAFE_WRITE_KEY]) - set(parent_request.environ[SAFE_WRITE_KEY])) parent_request.environ[SAFE_WRITE_KEY].extend(new_keys) if IDisableCSRFProtection.providedBy(request): alsoProvides(parent_request, IDisableCSRFProtection) request.clear() setRequest(parent_request) setSite(parent_site) setSecurityManager(security_manager)