如何在IPython调试shell中搜索未发布的Plone内容?

时间:2008-11-10 20:51:36

标签: python plone

我喜欢使用IPython的zope配置文件来检查我的Plone实例,但是与插入断点并与管理员用户进行匹配相比,会出现一些恼人的权限差异。

例如,我想迭代未发布的测试文件夹中的内容对象。此查询将在shell中不返回任何结果,但是从断点开始工作。

$ bin/instance shell
$ ipython --profile=zope

from Products.CMFPlone.utils import getToolByName
catalog = getToolByName(context, 'portal_catalog')
catalog({'path':'Plone/testing'})

我可以作为管理员进行身份验证,还是重新调整从ipython完全操纵我的网站的权限?

2 个答案:

答案 0 :(得分:2)

这是我用来从调试shell管理我的plone应用程序的(非常脏)代码。根据您的Zope和Plone版本,它可能需要一些更新。

from sys import stdin, stdout, exit
import base64
from thread import get_ident
from ZPublisher.HTTPRequest import HTTPRequest
from ZPublisher.HTTPResponse import HTTPResponse
from ZPublisher.BaseRequest import RequestContainer
from ZPublisher import Publish

from AccessControl import ClassSecurityInfo, getSecurityManager
from AccessControl.SecurityManagement import newSecurityManager
from AccessControl.User import UnrestrictedUser

def loginAsUnrestrictedUser():
    """Exemple of use :
        old_user = loginAsUnrestrictedUser()
        # Manager stuff
        loginAsUser(old_user)
    """
    current_user = getSecurityManager().getUser()
    newSecurityManager(None, UnrestrictedUser('manager', '', ['Manager'], []))
    return current_user

def loginAsUser(user):
    newSecurityManager(None, user)

def makerequest(app, stdout=stdout, query_string=None, user_pass=None):
    """Make a request suitable for CMF sites & Plone
      - user_pass = "user:pass"
    """
    # copy from Testing.makerequest
    resp = HTTPResponse(stdout=stdout)
    env = {}
    env['SERVER_NAME'] = 'lxtools.makerequest.fr'
    env['SERVER_PORT'] = '80'
    env['REQUEST_METHOD'] = 'GET'
    env['REMOTE_HOST'] = 'a.distant.host'
    env['REMOTE_ADDR'] = '77.77.77.77'
    env['HTTP_HOST']   = '127.0.0.1'
    env['HTTP_USER_AGENT'] = 'LxToolsUserAgent/1.0'
    env['HTTP_ACCEPT']='image/gif, image/x-xbitmap, image/jpeg, */* '
    if user_pass:
        env['HTTP_AUTHORIZATION']="Basic %s" % base64.encodestring(user_pass)
    if query_string:
        p_q = query_string.split('?')
        if   len(p_q) == 1: 
            env['PATH_INFO'] = p_q[0]
        elif len(p_q) == 2: 
            (env['PATH_INFO'], env['QUERY_STRING'])=p_q
        else: 
            raise TypeError, ''
    req = HTTPRequest(stdin, env, resp)
    req['URL1']=req['URL'] # fix for CMFQuickInstaller
    #
    # copy/hacked from Localizer __init__ patches
    # first put the needed values in the request
    req['HTTP_ACCEPT_CHARSET'] = 'latin-9'
    #req.other['AcceptCharset'] = AcceptCharset(req['HTTP_ACCEPT_CHARSET'])
    #
    req['HTTP_ACCEPT_LANGUAGE'] = 'fr'
    #accept_language = AcceptLanguage(req['HTTP_ACCEPT_LANGUAGE'])
    #req.other['AcceptLanguage'] = accept_language 
    # XXX For backwards compatibility
    #req.other['USER_PREF_LANGUAGES'] = accept_language
    #req.other['AcceptLanguage'] = accept_language 
    #
    # Plone stuff
    #req['plone_skin'] = 'Plone Default'
    #
    # then store the request in Publish._requests
    # with the thread id
    id = get_ident()
    if hasattr(Publish, '_requests'):
        # we do not have _requests inside ZopeTestCase
        Publish._requests[id] = req
    # add a brainless session container
    req['SESSION'] = {}
    #
    # ok, let's wrap
    return app.__of__(RequestContainer(REQUEST = req))


def debug_init(app):
    loginAsUnrestrictedUser()
    app = makerequest(app)
    return app

这生活在一个wshelpers Zope产品中。一旦调试shell启动,它只是一个问题;

>> from Products.wshelpers import wsdebug
>> app = wsdebug.debug_init(app)
>> # now you're logged in as admin

答案 1 :(得分:1)

只需使用catalog.search({'path':'Plone / testing'})。它执行与catalog()相同的查询,但不会根据当前用户的权限过滤结果。

IPython的zope配置文件确实提供了一个方法utils.su('username')来更改当前用户,但它不识别admin用户(在/ acl_users中定义而不是/ Plone / acl_users)并在调用后续调用之后使用AttributeError使catalog()失败:'module'对象没有属性'checkPermission'。