1

PloneのRegistrationToolとPasswordResetToolに問題があることを発見しました

テンプレートmail_password_response.ptは、HTTPRequestが作成されていない場合でもレンダリングされます。このテンプレートは、main_templateに依存するフルフレームのPloneページです。main_templateには、実際のHTTPRequestオブジェクトの存在、つまりACTUAL_URLパラメーターに依存するビューレットがあります。

このような状況を修正するにはどうすればよいですか?結果を表示するブラウザがない場合は、明らかにmail_password_response.ptをレンダリングしないでください。しかし、HTTPRequestが「本物」であるかどうかをディープPloneコードでチェックする方法は、UI応答につながるはずです。ひどいZMImanage_xxxハックです。

問題の適切な修正は何でしょうか?RegistrationToolがテンプレートをレンダリングしないようにしているのでしょうか、それとも不完全なテストスタブのHTTPRequestオブジェクトに対してビューレットを安全にしているのでしょうか。

これは、palayout.viewlets.commonのACTUAL_URLを必要とするビューレットビットです。

class ContentViewsViewlet(ViewletBase):


    @memoize
    def prepareObjectTabs(self, default_tab='view', sort_first=['folderContents']):
        """Prepare the object tabs by determining their order and working
        out which tab is selected. Used in global_contentviews.pt
        """
        context = aq_inner(self.context)
        context_url = context.absolute_url()

        request_url = self.request['ACTUAL_URL']
        request_url_path = request_url[len(context_url):]

        if request_url_path.startswith('/'):
            request_url_path = request_url_path[1:]

これは、CMFPlone RegistrationToolの違反呼び出しでmain_template.ptあり、コンシューマーがない場合でもフルレンダリングをトリガーします。

security.declarePublic('registeredNotify')
def registeredNotify(self, new_member_id):
    """ Wrapper around registeredNotify """
    membership = getToolByName(self, 'portal_membership')
    utils = getToolByName(self, 'plone_utils')
    member = membership.getMemberById(new_member_id)

    ...

    return self.mail_password_response(self, self.REQUEST)

サンプルトレースバック:

  Error in test test_logout_smartcard (xxxtesting.ui.test_smartcard.TestSmartcard)
    Traceback (most recent call last):
      File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/unittest/case.py", line 318, in run
        self.setUp()
      File "/Users/mikko/code/xxx-dev/src/xxx-packages/xxxtesting/xxxtesting/ui/test_smartcard.py", line 193, in setUp
        self.xxx_helper.create_all()
      File "/Users/mikko/code/xxx-dev/src/xxx-packages/xxxtesting/xxxtesting/xxxhelper.py", line 594, in create_all
        self.create_xxx_manager("xxx_manager")
      File "/Users/mikko/code/xxx-dev/src/xxx-packages/xxxtesting/xxxtesting/xxxhelper.py", line 412, in create_xxx_manager
        mem.update(**data)
      File "/Users/mikko/code/buildout-cache/eggs/Products.remember-1.9.1-py2.7.egg/Products/remember/content/member.py", line 653, in update
        triggerAutomaticTransitions(self)
      File "/Users/mikko/code/buildout-cache/eggs/Products.remember-1.9.1-py2.7.egg/Products/remember/Extensions/workflow.py", line 34, in triggerAutomaticTransitions
        wf_tool.doActionFor(ob, 'trigger')
      File "/Users/mikko/code/buildout-cache/eggs/Products.CMFCore-2.2.6-py2.7.egg/Products/CMFCore/WorkflowTool.py", line 241, in doActionFor
        wfs, ob, action, wf.doActionFor, (ob, action) + args, kw)
      File "/Users/mikko/code/buildout-cache/eggs/Products.CMFCore-2.2.6-py2.7.egg/Products/CMFCore/WorkflowTool.py", line 552, in _invokeWithNotification
        res = func(*args, **kw)
      File "/Users/mikko/code/buildout-cache/eggs/Products.DCWorkflow-2.2.4-py2.7.egg/Products/DCWorkflow/DCWorkflow.py", line 282, in doActionFor
        self._changeStateOf(ob, tdef, kw)
      File "/Users/mikko/code/buildout-cache/eggs/Products.DCWorkflow-2.2.4-py2.7.egg/Products/DCWorkflow/DCWorkflow.py", line 421, in _changeStateOf
        sdef = self._executeTransition(ob, tdef, kwargs)
      File "/Users/mikko/code/buildout-cache/eggs/Products.DCWorkflow-2.2.4-py2.7.egg/Products/DCWorkflow/DCWorkflow.py", line 474, in _executeTransition
        script(sci)  # May throw an exception.
      File "/Users/mikko/code/buildout-cache/eggs/Products.ExternalMethod-2.13.0-py2.7.egg/Products/ExternalMethod/ExternalMethod.py", line 241, in __call__
        return f(self.aq_parent.this(), *args, **kw)
       - __traceback_info__: ((<Products.DCWorkflow.Expression.StateChangeInfo instance at 0x107492e18>,), {}, None)
      File "/Users/mikko/code/buildout-cache/eggs/Products.remember-1.9.1-py2.7.egg/Products/remember/Extensions/workflow.py", line 64, in register
        return obj.register()
      File "/Users/mikko/code/xxx-dev/src/xxx-eggs/Products.xxxHospital/Products/xxxHospital/content/xxxUser.py", line 194, in register
        BaseMember.register(self)
      File "/Users/mikko/code/buildout-cache/eggs/Products.remember-1.9.1-py2.7.egg/Products/remember/content/member.py", line 718, in register
        rtool.registeredNotify(self.getId())
      File "/Users/mikko/code/buildout-cache/eggs/Products.CMFPlone-4.1.6-py2.7.egg/Products/CMFPlone/RegistrationTool.py", line 345, in registeredNotify
        return self.mail_password_response(self, self.REQUEST)
      File "/Users/mikko/code/buildout-cache/eggs/Zope2-2.13.15-py2.7.egg/Shared/DC/Scripts/Bindings.py", line 322, in __call__
        return self._bindAndExec(args, kw, None)
      File "/Users/mikko/code/buildout-cache/eggs/Zope2-2.13.15-py2.7.egg/Shared/DC/Scripts/Bindings.py", line 359, in _bindAndExec
        return self._exec(bound_data, args, kw)
      File "/Users/mikko/code/buildout-cache/eggs/Products.CMFCore-2.2.6-py2.7.egg/Products/CMFCore/FSPageTemplate.py", line 237, in _exec
        result = self.pt_render(extra_context=bound_names)
      File "/Users/mikko/code/buildout-cache/eggs/Products.CMFCore-2.2.6-py2.7.egg/Products/CMFCore/FSPageTemplate.py", line 177, in pt_render
        self, source, extra_context
      File "/Users/mikko/code/buildout-cache/eggs/Zope2-2.13.15-py2.7.egg/Products/PageTemplates/PageTemplate.py", line 79, in pt_render
        showtal=showtal)
      File "/Users/mikko/code/buildout-cache/eggs/zope.pagetemplate-3.5.2-py2.7.egg/zope/pagetemplate/pagetemplate.py", line 113, in pt_render
        strictinsert=0, sourceAnnotations=sourceAnnotations)()
      File "/Users/mikko/code/buildout-cache/eggs/zope.tal-3.5.2-py2.7.egg/zope/tal/talinterpreter.py", line 271, in __call__
        self.interpret(self.program)
      File "/Users/mikko/code/buildout-cache/eggs/zope.tal-3.5.2-py2.7.egg/zope/tal/talinterpreter.py", line 343, in interpret
        handlers[opcode](self, args)
      File "/Users/mikko/code/buildout-cache/eggs/zope.tal-3.5.2-py2.7.egg/zope/tal/talinterpreter.py", line 888, in do_useMacro
        self.interpret(macro)
      File "/Users/mikko/code/buildout-cache/eggs/zope.tal-3.5.2-py2.7.egg/zope/tal/talinterpreter.py", line 343, in interpret
        handlers[opcode](self, args)
      File "/Users/mikko/code/buildout-cache/eggs/zope.tal-3.5.2-py2.7.egg/zope/tal/talinterpreter.py", line 533, in do_optTag_tal
        self.do_optTag(stuff)
      File "/Users/mikko/code/buildout-cache/eggs/zope.tal-3.5.2-py2.7.egg/zope/tal/talinterpreter.py", line 518, in do_optTag
        return self.no_tag(start, program)
      File "/Users/mikko/code/buildout-cache/eggs/zope.tal-3.5.2-py2.7.egg/zope/tal/talinterpreter.py", line 513, in no_tag
        self.interpret(program)
      File "/Users/mikko/code/buildout-cache/eggs/zope.tal-3.5.2-py2.7.egg/zope/tal/talinterpreter.py", line 343, in interpret
        handlers[opcode](self, args)
      File "/Users/mikko/code/buildout-cache/eggs/zope.tal-3.5.2-py2.7.egg/zope/tal/talinterpreter.py", line 954, in do_defineSlot
        self.interpret(block)
      File "/Users/mikko/code/buildout-cache/eggs/zope.tal-3.5.2-py2.7.egg/zope/tal/talinterpreter.py", line 343, in interpret
        handlers[opcode](self, args)
      File "/Users/mikko/code/buildout-cache/eggs/zope.tal-3.5.2-py2.7.egg/zope/tal/talinterpreter.py", line 533, in do_optTag_tal
        self.do_optTag(stuff)
      File "/Users/mikko/code/buildout-cache/eggs/zope.tal-3.5.2-py2.7.egg/zope/tal/talinterpreter.py", line 518, in do_optTag
        return self.no_tag(start, program)
      File "/Users/mikko/code/buildout-cache/eggs/zope.tal-3.5.2-py2.7.egg/zope/tal/talinterpreter.py", line 513, in no_tag
        self.interpret(program)
      File "/Users/mikko/code/buildout-cache/eggs/zope.tal-3.5.2-py2.7.egg/zope/tal/talinterpreter.py", line 343, in interpret
        handlers[opcode](self, args)
      File "/Users/mikko/code/buildout-cache/eggs/zope.tal-3.5.2-py2.7.egg/zope/tal/talinterpreter.py", line 858, in do_defineMacro
        self.interpret(macro)
      File "/Users/mikko/code/buildout-cache/eggs/zope.tal-3.5.2-py2.7.egg/zope/tal/talinterpreter.py", line 343, in interpret
        handlers[opcode](self, args)
      File "/Users/mikko/code/buildout-cache/eggs/zope.tal-3.5.2-py2.7.egg/zope/tal/talinterpreter.py", line 852, in do_condition
        self.interpret(block)
      File "/Users/mikko/code/buildout-cache/eggs/zope.tal-3.5.2-py2.7.egg/zope/tal/talinterpreter.py", line 343, in interpret
        handlers[opcode](self, args)
      File "/Users/mikko/code/buildout-cache/eggs/zope.tal-3.5.2-py2.7.egg/zope/tal/talinterpreter.py", line 742, in do_insertStructure_tal
        structure = self.engine.evaluateStructure(expr)
      File "/Users/mikko/code/buildout-cache/eggs/Zope2-2.13.15-py2.7.egg/Products/PageTemplates/Expressions.py", line 218, in evaluateStructure
        text = super(ZopeContext, self).evaluateStructure(expr)
      File "/Users/mikko/code/buildout-cache/eggs/zope.tales-3.5.2-py2.7.egg/zope/tales/tales.py", line 696, in evaluate
        return expression(self)
       - file:/Users/mikko/code/xxx-dev/src/xxx-packages/plonetheme.xxxexternal/plonetheme/xxxexternal/skins/plonetheme_xxxexternal_custom_templates/main_template.pt
       - Line 83, Column 20
       - Expression: <StringExpr u'plone.contentviews'>
       - Names:
          {'container': <PloneSite at /plone>,
           'context': <RegistrationTool at /plone/portal_registration used for /plone/portal_memberdata/xxx_manager>,
           'default': <object object at 0x10204e970>,
           'here': <RegistrationTool at /plone/portal_registration used for /plone/portal_memberdata/xxx_manager>,
           'loop': {},
           'nothing': None,
           'options': {'args': (<RegistrationTool at /plone/portal_registration used for /plone/portal_memberdata/xxx_manager>,
                                <HTTPRequest, URL=http://localhost:55001>)},
           'repeat': <Products.PageTemplates.Expressions.SafeMapping object at 0x107704c00>,
           'request': <HTTPRequest, URL=http://localhost:55001>,
           'root': <Application at >,
           'template': <FSPageTemplate at /plone/mail_password_response used for /plone/portal_registration>,
           'traverse_subpath': [],
           'user': <PloneUser 'admin'>}
      File "/Users/mikko/code/buildout-cache/eggs/zope.contentprovider-3.7.2-py2.7.egg/zope/contentprovider/tales.py", line 80, in __call__
        return provider.render()
      File "/Users/mikko/code/buildout-cache/eggs/plone.app.viewletmanager-2.0.2-py2.7.egg/plone/app/viewletmanager/manager.py", line 154, in render
        return BaseOrderedViewletManager.render(self)
      File "/Users/mikko/code/buildout-cache/eggs/plone.app.viewletmanager-2.0.2-py2.7.egg/plone/app/viewletmanager/manager.py", line 85, in render
        return u'\n'.join([viewlet.render() for viewlet in self.viewlets])
      File "/Users/mikko/code/buildout-cache/eggs/plone.app.layout-2.1.13-py2.7.egg/plone/app/layout/viewlets/common.py", line 48, in render
        return self.index()
      File "/Users/mikko/code/buildout-cache/eggs/Zope2-2.13.15-py2.7.egg/Products/Five/browser/pagetemplatefile.py", line 125, in __call__
        return self.im_func(im_self, *args, **kw)
      File "/Users/mikko/code/buildout-cache/eggs/Zope2-2.13.15-py2.7.egg/Products/Five/browser/pagetemplatefile.py", line 59, in __call__
        sourceAnnotations=getattr(debug_flags, 'sourceAnnotations', 0),
      File "/Users/mikko/code/buildout-cache/eggs/zope.pagetemplate-3.5.2-py2.7.egg/zope/pagetemplate/pagetemplate.py", line 113, in pt_render
        strictinsert=0, sourceAnnotations=sourceAnnotations)()
      File "/Users/mikko/code/buildout-cache/eggs/zope.tal-3.5.2-py2.7.egg/zope/tal/talinterpreter.py", line 271, in __call__
        self.interpret(self.program)
      File "/Users/mikko/code/buildout-cache/eggs/zope.tal-3.5.2-py2.7.egg/zope/tal/talinterpreter.py", line 343, in interpret
        handlers[opcode](self, args)
      File "/Users/mikko/code/buildout-cache/eggs/zope.tal-3.5.2-py2.7.egg/zope/tal/talinterpreter.py", line 852, in do_condition
        self.interpret(block)
      File "/Users/mikko/code/buildout-cache/eggs/zope.tal-3.5.2-py2.7.egg/zope/tal/talinterpreter.py", line 343, in interpret
        handlers[opcode](self, args)
      File "/Users/mikko/code/buildout-cache/eggs/zope.tal-3.5.2-py2.7.egg/zope/tal/talinterpreter.py", line 531, in do_optTag_tal
        self.no_tag(stuff[-2], stuff[-1])
      File "/Users/mikko/code/buildout-cache/eggs/zope.tal-3.5.2-py2.7.egg/zope/tal/talinterpreter.py", line 513, in no_tag
        self.interpret(program)
      File "/Users/mikko/code/buildout-cache/eggs/zope.tal-3.5.2-py2.7.egg/zope/tal/talinterpreter.py", line 343, in interpret
        handlers[opcode](self, args)
      File "/Users/mikko/code/buildout-cache/eggs/zope.tal-3.5.2-py2.7.egg/zope/tal/talinterpreter.py", line 583, in do_setLocal_tal
        self.engine.setLocal(name, self.engine.evaluateValue(expr))
      File "/Users/mikko/code/buildout-cache/eggs/zope.tales-3.5.2-py2.7.egg/zope/tales/tales.py", line 696, in evaluate
        return expression(self)
       - /Users/mikko/code/buildout-cache/eggs/plone.app.layout-2.1.13-py2.7.egg/plone/app/layout/viewlets/contentviews.pt
       - Line 6, Column 4
       - Expression: <PathExpr standard:u'view/prepareObjectTabs'>
       - Names:
          {'args': (),
           'container': <RegistrationTool at /plone/portal_registration used for /plone/portal_memberdata/xxx_manager>,
           'context': <RegistrationTool at /plone/portal_registration used for /plone/portal_memberdata/xxx_manager>,
           'default': <object object at 0x10204e970>,
           'here': <RegistrationTool at /plone/portal_registration used for /plone/portal_memberdata/xxx_manager>,
           'loop': {},
           'nothing': None,
           'options': {},
           'repeat': <Products.PageTemplates.Expressions.SafeMapping object at 0x107afe050>,
           'request': <HTTPRequest, URL=http://localhost:55001>,
           'root': <Application at >,
           'template': <Products.Five.browser.pagetemplatefile.ViewPageTemplateFile object at 0x105dfb810>,
           'traverse_subpath': [],
           'user': <PloneUser 'admin'>,
           'view': <Products.Five.viewlet.metaconfigure.ContentViewsViewlet object at 0x10868c050>,
           'views': <Products.Five.browser.pagetemplatefile.ViewMapper object at 0x107ff1f90>}
      File "/Users/mikko/code/buildout-cache/eggs/zope.tales-3.5.2-py2.7.egg/zope/tales/expressions.py", line 217, in __call__
        return self._eval(econtext)
      File "/Users/mikko/code/buildout-cache/eggs/Zope2-2.13.15-py2.7.egg/Products/PageTemplates/Expressions.py", line 155, in _eval
        return render(ob, econtext.vars)
      File "/Users/mikko/code/buildout-cache/eggs/Zope2-2.13.15-py2.7.egg/Products/PageTemplates/Expressions.py", line 117, in render
        ob = ob()
      File "/Users/mikko/code/buildout-cache/eggs/plone.memoize-1.1.1-py2.7.egg/plone/memoize/view.py", line 47, in memogetter
        value = cache[key] = func(*args, **kwargs)
      File "/Users/mikko/code/buildout-cache/eggs/plone.app.layout-2.1.13-py2.7.egg/plone/app/layout/viewlets/common.py", line 258, in prepareObjectTabs
        request_url = self.request['ACTUAL_URL']
      File "/Users/mikko/code/buildout-cache/eggs/Zope2-2.13.15-py2.7.egg/ZPublisher/HTTPRequest.py", line 1372, in __getitem__
        raise KeyError, key
    KeyError: 'ACTUAL_URL'
4

0 に答える 0