Example #1
0
 def __init__(self, id, title, file, permissions=None, categories=None):
     self.id = id
     self.title = title
     file, ext = os.path.splitext(file)
     prefix, file = os.path.split(file)
     self.index_html = DTMLFile(file, prefix)
     if permissions is not None:
         self.permissions = permissions
     if categories is not None:
         self.categories = categories
Example #2
0
class DTMLTopic(HelpTopic):
    """
    A basic Help Topic. Holds a HTMLFile object.
    """

    def __init__(self, id, title, file, permissions=None, categories=None):
        self.id = id
        self.title = title
        file, ext = os.path.splitext(file)
        prefix, file = os.path.split(file)
        self.index_html = DTMLFile(file, prefix)
        if permissions is not None:
            self.permissions = permissions
        if categories is not None:
            self.categories = categories

    def SearchableText(self):
        "The full text of the Help Topic, for indexing purposes"
        return "%s %s" % (self.title, self.index_html.read())
class PloneControlPanel(PloneBaseTool, UniqueObject, Folder,
                        ActionProviderBase, PropertyManager):
    """Weave together the various sources of "actions" which
    are apropos to the current user and context.
    """

    security = ClassSecurityInfo()

    id = 'portal_controlpanel'
    title = 'Control Panel'
    toolicon = 'skins/plone_images/site_icon.png'
    meta_type = 'Plone Control Panel Tool'
    _actions_form = DTMLFile('www/editPloneConfiglets', globals())

    manage_options = (ActionProviderBase.manage_options +
                      PropertyManager.manage_options)

    group = dict(member=[
        ('Member', _(u'My Preferences')),
    ],
                 site=[
                     ('plone-general', _(u'General')),
                     ('plone-content', _(u'Content')),
                     ('plone-users', _(u'Users')),
                     ('plone-security', _(u'Security')),
                     ('plone-advanced', _(u'Advanced')),
                     ('Plone', _(u'Plone Configuration')),
                     ('Products', _(u'Add-on Configuration')),
                 ])

    def __init__(self, **kw):
        if kw:
            self.__dict__.update(**kw)

    security.declareProtected(ManagePortal, 'registerConfiglets')

    def registerConfiglets(self, configlets):
        for conf in configlets:
            self.registerConfiglet(**conf)

    security.declareProtected(ManagePortal, 'getGroupIds')

    def getGroupIds(self, category='site'):
        groups = self.group.get(category, [])
        return [g[0] for g in groups if g]

    security.declareProtected(View, 'getGroups')

    def getGroups(self, category='site'):
        groups = self.group.get(category, [])
        return [{'id': g[0], 'title': g[1]} for g in groups if g]

    security.declarePrivate('listActions')

    def listActions(self, info=None, object=None):
        # This exists here to shut up a deprecation warning about old-style
        # actions in CMFCore's ActionProviderBase.  It was decided not to
        # move configlets to be based on action tool categories for Plone 4
        # (see PLIP #8804), but that (or an alternative) will have to happen
        # before CMF 2.4 when support for old-style actions is removed.
        return self._actions or ()

    security.declarePublic('maySeeSomeConfiglets')

    def maySeeSomeConfiglets(self):
        groups = self.getGroups('site')

        all = []
        for group in groups:
            all.extend(self.enumConfiglets(group=group['id']))
        all = [item for item in all if item['visible']]
        return len(all) != 0

    security.declarePublic('enumConfiglets')

    def enumConfiglets(self, group=None):
        portal = getToolByName(self, 'portal_url').getPortalObject()
        context = createExprContext(self, portal, self)
        res = []
        for a in self.listActions():
            verified = 0
            for permission in a.permissions:
                if _checkPermission(permission, portal):
                    verified = 1
            if verified and a.category == group and a.testCondition(context) \
                    and a.visible:
                res.append(a.getAction(context))
        # Translate the title for sorting
        if getattr(self, 'REQUEST', None) is not None:
            for a in res:
                title = a['title']
                if not isinstance(title, Message):
                    title = Message(title, domain='plone')
                a['title'] = translate(title, context=self.REQUEST)

        def _title(v):
            return v['title']

        res.sort(key=_title)
        return res

    security.declareProtected(ManagePortal, 'unregisterConfiglet')

    def unregisterConfiglet(self, id):
        actids = [o.id for o in self.listActions()]
        selection = [actids.index(a) for a in actids if a == id]
        if not selection:
            return
        self.deleteActions(selection)

    security.declareProtected(ManagePortal, 'unregisterApplication')

    def unregisterApplication(self, appId):
        acts = list(self.listActions())
        selection = [acts.index(a) for a in acts if a.appId == appId]
        if not selection:
            return
        self.deleteActions(selection)

    def _extractAction(self, properties, index):
        # Extract an ActionInformation from the funky form properties.
        id = str(properties.get('id_%d' % index, ''))
        name = str(properties.get('name_%d' % index, ''))
        action = str(properties.get('action_%d' % index, ''))
        condition = str(properties.get('condition_%d' % index, ''))
        category = str(properties.get('category_%d' % index, ''))
        visible = properties.get('visible_%d' % index, 0)
        permissions = properties.get('permission_%d' % index, ())
        appId = properties.get('appId_%d' % index, '')
        description = properties.get('description_%d' % index, '')
        icon_expr = properties.get('icon_expr_%d' % index, '')

        if not name:
            raise ValueError('A name is required.')

        if action != '':
            action = Expression(text=action)

        if condition != '':
            condition = Expression(text=condition)

        if category == '':
            category = 'object'

        if not isinstance(visible, int):
            try:
                visible = int(visible)
            except ValueError:
                visible = 0

        if isinstance(permissions, six.string_types):
            permissions = (permissions, )

        return PloneConfiglet(
            id=id,
            title=name,
            action=action,
            condition=condition,
            permissions=permissions,
            category=category,
            visible=visible,
            appId=appId,
            description=description,
            icon_expr=icon_expr,
        )

    security.declareProtected(ManagePortal, 'addAction')

    def addAction(
        self,
        id,
        name,
        action,
        condition='',
        permission='',
        category='Plone',
        visible=1,
        appId=None,
        icon_expr='',
        description='',
        REQUEST=None,
    ):
        # Add an action to our list.
        if not name:
            raise ValueError('A name is required.')

        a_expr = action and Expression(text=str(action)) or ''
        c_expr = condition and Expression(text=str(condition)) or ''

        if not isinstance(permission, tuple):
            permission = permission and (str(permission), ) or ()

        new_actions = self._cloneActions()

        new_action = PloneConfiglet(
            id=str(id),
            title=name,
            action=a_expr,
            condition=c_expr,
            permissions=permission,
            category=str(category),
            visible=int(visible),
            appId=appId,
            description=description,
            icon_expr=icon_expr,
        )

        new_actions.append(new_action)
        self._actions = tuple(new_actions)

        if REQUEST is not None:
            return self.manage_editActionsForm(REQUEST,
                                               manage_tabs_message='Added.')

    security.declareProtected(ManagePortal, 'registerConfiglet')
    registerConfiglet = addAction

    security.declareProtected(ManagePortal, 'manage_editActionsForm')

    def manage_editActionsForm(self, REQUEST, manage_tabs_message=None):
        """ Show the 'Actions' management tab.
        """
        actions = []

        for a in self.listActions():

            a1 = {}
            a1['id'] = a.getId()
            a1['name'] = a.Title()
            p = a.getPermissions()
            if p:
                a1['permission'] = p[0]
            else:
                a1['permission'] = ''
            a1['category'] = a.getCategory() or 'object'
            a1['visible'] = a.getVisibility()
            a1['action'] = a.getActionExpression()
            a1['condition'] = a.getCondition()
            a1['appId'] = a.getAppId()
            a1['description'] = a.getDescription()
            a1['icon_expr'] = a.getIconExpression()
            actions.append(a1)

        # possible_permissions is in OFS.role.RoleManager.
        pp = self.possible_permissions()
        return self._actions_form(
            self,
            REQUEST,
            actions=actions,
            possible_permissions=pp,
            management_view='Actions',
            manage_tabs_message=manage_tabs_message,
        )

    @property
    def site_url(self):
        """Return the absolute URL to the current site, which is likely not
        necessarily the portal root.
        Used by ``portlet_prefs`` to construct the URL to
        ``@@overview-controlpanel``.
        """
        return getSite().absolute_url()
Example #4
0
from OFS.FindSupport import FindSupport
from OFS.interfaces import IFolder
from OFS.Lockable import LockableItem
from OFS.ObjectManager import ObjectManager
from OFS.PropertyManager import PropertyManager
from OFS.role import RoleManager
from OFS.SimpleItem import Item
from OFS.SimpleItem import PathReprProvider
from zope.interface import implementer

if bbb.HAS_ZSERVER:
    from webdav.Collection import Collection
else:
    Collection = bbb.Collection

manage_addFolderForm = DTMLFile('dtml/folderAdd', globals())


def manage_addFolder(self,
                     id,
                     title='',
                     createPublic=0,
                     createUserF=0,
                     REQUEST=None):
    """Add a new Folder object with id *id*.
    """
    ob = Folder(id)
    ob.title = title
    self._setObject(id, ob)
    ob = self._getOb(id)
    if REQUEST is not None:
Example #5
0
from App.special_dtml import DTMLFile
from OFS.Image import File
from Products.ERP5Type import _dtmldir

# Patch for displaying textearea in full window instead of
# remembering a quantity of lines to display in a cookie
manage_editForm = DTMLFile("fileEdit", _dtmldir)
manage_editForm._setName('manage_editForm')
File.manage_editForm = manage_editForm
File.manage = manage_editForm
File.manage_main = manage_editForm
File.manage_editDocument = manage_editForm
File.manage_editForm = manage_editForm
Example #6
0
                                  IISet([])), (self.id, ))
                else:
                    return (difference(resultset, index), (self.id, ))
        return (IISet(), (self.id, ))

    def indexSize(self):
        """Return distinct values, as an optimization we always claim 2."""
        return 2

    def items(self):
        items = []
        for v, k in self._unindex.items():
            if isinstance(v, int):
                v = IISet((v, ))
            items.append((k, v))
        return items


manage_addBooleanIndexForm = DTMLFile('dtml/addBooleanIndex', globals())


def manage_addBooleanIndex(self,
                           id,
                           extra=None,
                           REQUEST=None,
                           RESPONSE=None,
                           URL3=None):
    """Add a boolean index"""
    return self.manage_addIndex(id, 'BooleanIndex', extra=extra, \
             REQUEST=REQUEST, RESPONSE=RESPONSE, URL1=URL3)
Example #7
0
class FSDTMLMethod(RestrictedDTML, RoleManager, FSObject, HTML):

    """FSDTMLMethods act like DTML methods but are not directly
    modifiable from the management interface.
    """

    meta_type = 'Filesystem DTML Method'
    _owner = None
    _proxy_roles = ()
    _cache_namespace_keys = ()
    _reading = 0

    manage_options = (
        {'label': 'Customize', 'action': 'manage_main'},
        {'label': 'View', 'action': ''},
        {'label': 'Proxy', 'action': 'manage_proxyForm'})

    security = ClassSecurityInfo()
    security.declareObjectProtected(View)

    security.declareProtected(ViewManagementScreens, 'manage_main')
    manage_main = DTMLFile('custdtml', _dtmldir)

    def __init__(self, id, filepath, fullname=None, properties=None):
        FSObject.__init__(self, id, filepath, fullname, properties)
        # Normally called via HTML.__init__ but we don't need the rest that
        # happens there.
        self.initvars(None, {})

    def _createZODBClone(self):
        """Create a ZODB (editable) equivalent of this object."""
        return DTMLMethod(self.read(), __name__=self.getId())

    def _readFile(self, reparse):
        """Read the data from the filesystem.
        """
        file = open(self._filepath, 'r') # not 'rb', as this is a text file!
        try:
            data = file.read()
        finally:
            file.close()
        self.raw = data

        if reparse:
            self._reading = 1  # Avoid infinite recursion
            try:
                self.cook()
            finally:
                self._reading = 0

    # Hook up chances to reload in debug mode
    @security.private
    def read_raw(self):
        if not self._reading:
            self._updateFromFS()
        return HTML.read_raw(self)

    #### The following is mainly taken from OFS/DTMLMethod.py ###

    index_html = None # Prevent accidental acquisition

    # Documents masquerade as functions:
    __code__ = DTMLMethod.__code__

    default_content_type = 'text/html'

    def __call__(self, client=None, REQUEST={}, RESPONSE=None, **kw):
        """Render the document given a client object, REQUEST mapping,
        Response, and key word arguments."""

        self._updateFromFS()

        kw['document_id'] = self.getId()
        kw['document_title'] = self.title

        if client is not None:
            if _checkConditionalGET(self, kw):
                return ''

        if not self._cache_namespace_keys:
            data = self.ZCacheable_get(default=_marker)
            if data is not _marker:
                # Return cached results.
                return data

        __traceback_info__ = self._filepath
        security = getSecurityManager()
        security.addContext(self)
        try:
            r = HTML.__call__(self, client, REQUEST, **kw)

            if client is None:
                # Called as subtemplate, so don't need error propagation!
                if RESPONSE is None:
                    result = r
                else:
                    result = decapitate(r, RESPONSE)
                if not self._cache_namespace_keys:
                    self.ZCacheable_set(result)
                return result

            if not isinstance(r, six.string_types) or RESPONSE is None:
                if not self._cache_namespace_keys:
                    self.ZCacheable_set(r)
                return r

        finally:
            security.removeContext(self)

        headers = RESPONSE.headers
        if not ('content-type' in headers or 'Content-Type' in headers):
            if 'content_type' in self.__dict__:
                c = self.content_type
            else:
                if six.PY2:
                    c, _e = guess_content_type(self.getId(), r)
                else:
                    c, _e = guess_content_type(self.getId(), r.encode())

            RESPONSE.setHeader('Content-Type', c)
        if RESPONSE is not None:
            # caching policy manager hook
            _setCacheHeaders(self, {})
        result = decapitate(r, RESPONSE)
        if not self._cache_namespace_keys:
            self.ZCacheable_set(result)
        return result

    def getCacheNamespaceKeys(self):
        '''
        Returns the cacheNamespaceKeys.
        '''
        return self._cache_namespace_keys

    def setCacheNamespaceKeys(self, keys, REQUEST=None):
        '''
        Sets the list of names that should be looked up in the
        namespace to provide a cache key.
        '''
        ks = []
        for key in keys:
            key = str(key).strip()
            if key:
                ks.append(key)
        self._cache_namespace_keys = tuple(ks)
        if REQUEST is not None:
            return self.ZCacheable_manage(self, REQUEST)

    # Zope 2.3.x way:
    def validate(self, inst, parent, name, value, md=None):
        return getSecurityManager().validate(inst, parent, name, value)

    if bbb.HAS_ZSERVER:
        security.declareProtected(FTPAccess, 'manage_FTPget')
        manage_FTPget = get_unbound_function(DTMLMethod.manage_FTPget)

    security.declareProtected(ViewManagementScreens, 'PrincipiaSearchSource')
    PrincipiaSearchSource = get_unbound_function(DTMLMethod.PrincipiaSearchSource)

    security.declareProtected(ViewManagementScreens, 'document_src')
    document_src = get_unbound_function(DTMLMethod.document_src)

    security.declareProtected(ViewManagementScreens, 'manage_haveProxy')
    manage_haveProxy = get_unbound_function(DTMLMethod.manage_haveProxy)
Example #8
0
class ActionProviderBase:
    """ Provide ActionTabs and management methods for ActionProviders
    """

    implements(IActionProvider)

    security = ClassSecurityInfo()

    _actions = ()

    _actions_form = DTMLFile('editToolsActions', _dtmldir)

    manage_options = ({
        'label': 'Actions',
        'action': 'manage_editActionsForm',
        'help': ('CMFCore', 'Actions.stx')
    }, )

    #
    #   ActionProvider interface
    #
    security.declarePrivate('listActions')

    def listActions(self, info=None, object=None):
        """ List all the actions defined by a provider.
        """
        oldstyle_actions = self._actions or ()
        if oldstyle_actions:
            warn(
                'Old-style actions are deprecated and will be removed in CMF '
                '2.4. Use Action and Action Category objects instead.',
                DeprecationWarning,
                stacklevel=2)

        return oldstyle_actions

    security.declarePrivate('getActionObject')

    def getActionObject(self, action):
        """Return the actions object or None if action doesn't exist.
        """
        # separate cataegory and id from action
        sep = action.rfind('/')
        if sep == -1:
            raise ValueError('Actions must have the format <category>/<id>.')
        category, id = action[:sep], action[sep + 1:]

        # search for action and return first one found
        for ai in self.listActions():
            try:
                if id == ai.getId() and category == ai.getCategory():
                    return ai
            except AttributeError:
                continue

        # no action found
        return None

    security.declarePublic('listActionInfos')

    def listActionInfos(self,
                        action_chain=None,
                        object=None,
                        check_visibility=1,
                        check_permissions=1,
                        check_condition=1,
                        max=-1):
        # List ActionInfo objects.
        # (method is without docstring to disable publishing)
        #
        ec = self._getExprContext(object)
        actions = self.listActions(object=object)
        actions = [ActionInfo(action, ec) for action in actions]

        if action_chain:
            filtered_actions = []
            if isinstance(action_chain, basestring):
                action_chain = (action_chain, )
            for action_ident in action_chain:
                sep = action_ident.rfind('/')
                category, id = action_ident[:sep], action_ident[sep + 1:]
                for ai in actions:
                    if id == ai['id'] and category == ai['category']:
                        filtered_actions.append(ai)
            actions = filtered_actions

        action_infos = []
        for ai in actions:
            if check_visibility and not ai['visible']:
                continue
            if check_permissions and not ai['allowed']:
                continue
            if check_condition and not ai['available']:
                continue
            action_infos.append(ai)
            if max + 1 and len(action_infos) >= max:
                break
        return action_infos

    security.declarePublic('getActionInfo')

    def getActionInfo(self,
                      action_chain,
                      object=None,
                      check_visibility=0,
                      check_condition=0):
        """ Get an ActionInfo object specified by a chain of actions.
        """
        action_infos = self.listActionInfos(action_chain,
                                            object,
                                            check_visibility=check_visibility,
                                            check_permissions=False,
                                            check_condition=check_condition)
        if not action_infos:
            if object is None:
                provider = self
            else:
                provider = object
            msg = 'Action "%s" not available for %s' % (action_chain, '/'.join(
                provider.getPhysicalPath()))
            raise ValueError(msg)
        for ai in action_infos:
            if ai['allowed']:
                return ai
        raise AccessControl_Unauthorized('You are not allowed to access any '
                                         'of the specified Actions.')

    #
    #   ZMI methods
    #
    security.declareProtected(ManagePortal, 'manage_editActionsForm')

    def manage_editActionsForm(self, REQUEST, manage_tabs_message=None):
        """ Show the 'Actions' management tab.
        """
        actions = []
        for action in self.listActions():
            # The Actions tab currently only shows old-style actions,
            # so we need to weed out everything else.
            if getattr(action, 'getMapping', None) is not None:
                actions.append(action.getMapping())

        # possible_permissions is in AccessControl.Role.RoleManager.
        pp = self.possible_permissions()
        return self._actions_form(self,
                                  REQUEST,
                                  actions=actions,
                                  possible_permissions=pp,
                                  management_view='Actions',
                                  manage_tabs_message=manage_tabs_message)

    security.declareProtected(ManagePortal, 'addAction')

    def addAction(self,
                  id,
                  name,
                  action,
                  condition,
                  permission,
                  category,
                  visible=1,
                  icon_expr='',
                  link_target='',
                  REQUEST=None):
        """ Add an action to our list.
        """
        if not name:
            raise ValueError('A name is required.')

        action = action and str(action) or ''
        condition = condition and str(condition) or ''

        if not isinstance(permission, tuple):
            permission = (str(permission), )

        new_actions = self._cloneActions()

        new_action = ActionInformation(id=str(id),
                                       title=str(name),
                                       category=str(category),
                                       condition=condition,
                                       permissions=permission,
                                       visible=bool(visible),
                                       action=action,
                                       icon_expr=icon_expr,
                                       link_target=link_target)

        new_actions.append(new_action)
        self._actions = tuple(new_actions)

        if REQUEST is not None:
            return self.manage_editActionsForm(REQUEST,
                                               manage_tabs_message='Added.')

    security.declareProtected(ManagePortal, 'changeActions')

    def changeActions(self, properties=None, REQUEST=None):
        """ Update our list of actions.
        """
        if properties is None:
            properties = REQUEST

        actions = []

        for index in range(len(self._actions)):
            actions.append(self._extractAction(properties, index))

        self._actions = tuple(actions)

        if REQUEST is not None:
            return self.manage_editActionsForm(
                REQUEST, manage_tabs_message='Actions changed.')

    security.declareProtected(ManagePortal, 'deleteActions')

    def deleteActions(self, selections=(), REQUEST=None):
        """ Delete actions indicated by indexes in 'selections'.
        """
        sels = list(map(int, selections))  # Convert to a list of integers.

        old_actions = self._cloneActions()
        new_actions = []

        for index in range(len(old_actions)):
            if index not in sels:
                new_actions.append(old_actions[index])

        self._actions = tuple(new_actions)

        if REQUEST is not None:
            return self.manage_editActionsForm(
                REQUEST,
                manage_tabs_message=('Deleted %d action(s).' % len(sels)))

    security.declareProtected(ManagePortal, 'moveUpActions')

    def moveUpActions(self, selections=(), REQUEST=None):
        """ Move the specified actions up one slot in our list.
        """
        sels = list(map(int, selections))  # Convert to a list of integers.
        sels.sort()

        new_actions = self._cloneActions()

        for idx in sels:
            idx2 = idx - 1
            if idx2 < 0:
                # Wrap to the bottom.
                idx2 = len(new_actions) - 1
            # Swap.
            a = new_actions[idx2]
            new_actions[idx2] = new_actions[idx]
            new_actions[idx] = a

        self._actions = tuple(new_actions)

        if REQUEST is not None:
            return self.manage_editActionsForm(
                REQUEST,
                manage_tabs_message=('Moved up %d action(s).' % len(sels)))

    security.declareProtected(ManagePortal, 'moveDownActions')

    def moveDownActions(self, selections=(), REQUEST=None):
        """ Move the specified actions down one slot in our list.
        """
        sels = list(map(int, selections))  # Convert to a list of integers.
        sels.sort()
        sels.reverse()

        new_actions = self._cloneActions()

        for idx in sels:
            idx2 = idx + 1
            if idx2 >= len(new_actions):
                # Wrap to the top.
                idx2 = 0
            # Swap.
            a = new_actions[idx2]
            new_actions[idx2] = new_actions[idx]
            new_actions[idx] = a

        self._actions = tuple(new_actions)

        if REQUEST is not None:
            return self.manage_editActionsForm(
                REQUEST,
                manage_tabs_message=('Moved down %d action(s).' % len(sels)))

    #
    #   Helper methods
    #
    security.declarePrivate('_cloneActions')

    def _cloneActions(self):
        """ Return a list of actions, cloned from our current list.
        """
        return map(lambda x: x.clone(), list(self._actions))

    security.declarePrivate('_extractAction')

    def _extractAction(self, properties, index):
        """ Extract an ActionInformation from the funky form properties.
        """
        id = str(properties.get('id_%d' % index, ''))
        title = str(properties.get('name_%d' % index, ''))
        action = str(properties.get('action_%d' % index, ''))
        icon_expr = str(properties.get('icon_expr_%d' % index, ''))
        condition = str(properties.get('condition_%d' % index, ''))
        category = str(properties.get('category_%d' % index, ''))
        visible = bool(properties.get('visible_%d' % index, False))
        permissions = properties.get('permission_%d' % index, ())
        link_target = str(properties.get('link_target_%d' % index, ''))

        if not title:
            raise ValueError('A title is required.')

        if category == '':
            category = 'object'

        if isinstance(permissions, basestring):
            permissions = (permissions, )

        return ActionInformation(id=id,
                                 title=title,
                                 action=action,
                                 condition=condition,
                                 permissions=permissions,
                                 category=category,
                                 visible=visible,
                                 icon_expr=icon_expr,
                                 link_target=link_target)

    def _getOAI(self, object):
        return getOAI(self, object)

    def _getExprContext(self, object):
        return getExprContext(self, object)
Example #9
0
class DTMLMethod(PathReprProvider, RestrictedDTML, HTML, Implicit, RoleManager,
                 Item_w__name__, Historical, Cacheable):
    """ DocumentTemplate.HTML objects that act as methods of their containers.
    """
    meta_type = 'DTML Method'
    zmi_icon = 'far fa-file-alt'
    _proxy_roles = ()
    index_html = None  # Prevent accidental acquisition
    _cache_namespace_keys = ()
    _locked_error_text = 'This DTML Method is locked.'

    security = ClassSecurityInfo()
    security.declareObjectProtected(View)

    __code__ = Code()
    __code__.co_varnames = 'self', 'REQUEST', 'RESPONSE'
    __code__.co_argcount = 3
    __defaults__ = None

    manage_options = ((
        {
            'label': 'Edit',
            'action': 'manage_main',
        },
        {
            'label': 'View',
            'action': '',
        },
        {
            'label': 'Proxy',
            'action': 'manage_proxyForm',
        },
    ) + Historical.manage_options + RoleManager.manage_options +
                      Item_w__name__.manage_options + Cacheable.manage_options)

    # Careful in permission changes--used by DTMLDocument!
    security.declareProtected(
        change_dtml_methods,  # NOQA: D001
        'manage_historyCopy')
    security.declareProtected(
        change_dtml_methods,  # NOQA: D001
        'manage_beforeHistoryCopy')
    security.declareProtected(
        change_dtml_methods,  # NOQA: D001
        'manage_afterHistoryCopy')

    # More reasonable default for content-type for http HEAD requests.
    default_content_type = 'text/html'

    def errQuote(self, s):
        # Quoting is done when rendering the error in the template.
        return s

    @security.protected(View)
    def __call__(self, client=None, REQUEST={}, RESPONSE=None, **kw):
        """Render using the given client object

        o If client is not passed, we are being called as a sub-template:
          don't do any error propagation.

        o If supplied, use the REQUEST mapping, Response, and key word
        arguments.
        """
        if not self._cache_namespace_keys:
            data = self.ZCacheable_get(default=_marker)
            if data is not _marker:
                if IStreamIterator.isImplementedBy(data) and \
                   RESPONSE is not None:
                    # This is a stream iterator and we need to set some
                    # headers now before giving it to medusa
                    headers_get = RESPONSE.headers.get

                    if headers_get('content-length', None) is None:
                        RESPONSE.setHeader('content-length', len(data))

                    if headers_get('content-type', None) is None and \
                       headers_get('Content-type', None) is None:
                        ct = (self.__dict__.get('content_type')
                              or self.default_content_type)
                        RESPONSE.setHeader('content-type', ct)

                # Return cached results.
                return data

        __traceback_supplement__ = (PathTracebackSupplement, self)
        kw['document_id'] = self.getId()
        kw['document_title'] = self.title

        security = getSecurityManager()
        security.addContext(self)
        if 'validate' in self.__dict__:
            first_time_through = 0
        else:
            self.__dict__['validate'] = security.DTMLValidate
            first_time_through = 1
        try:

            if client is None:
                # Called as subtemplate, so don't need error propagation!
                r = HTML.__call__(self, client, REQUEST, **kw)
                if RESPONSE is None:
                    result = r
                else:
                    result = decapitate(r, RESPONSE)
                if not self._cache_namespace_keys:
                    self.ZCacheable_set(result)
                return result

            r = HTML.__call__(self, client, REQUEST, **kw)

            if RESPONSE is None or not isinstance(r, str):
                if not self._cache_namespace_keys:
                    self.ZCacheable_set(r)
                return r

        finally:
            security.removeContext(self)
            if first_time_through:
                del self.__dict__['validate']

        have_key = RESPONSE.headers.__contains__
        if not (have_key('content-type') or have_key('Content-Type')):
            if 'content_type' in self.__dict__:
                c = self.content_type
            else:
                encoding = getattr(self, 'encoding', default_encoding)
                c, e = guess_content_type(self.getId(), r.encode(encoding))
            RESPONSE.setHeader('Content-Type', c)
        result = decapitate(r, RESPONSE)
        if not self._cache_namespace_keys:
            self.ZCacheable_set(result)
        return result

    def validate(self, inst, parent, name, value, md=None):
        return getSecurityManager().validate(inst, parent, name, value)

    def ZDocumentTemplate_beforeRender(self, md, default):
        # Tries to get a cached value.
        if self._cache_namespace_keys:
            # Use the specified keys from the namespace to identify a
            # cache entry.
            kw = {}
            for key in self._cache_namespace_keys:
                try:
                    val = md[key]
                except Exception:
                    val = None
                kw[key] = val
            return self.ZCacheable_get(keywords=kw, default=default)
        return default

    def ZDocumentTemplate_afterRender(self, md, result):
        # Tries to set a cache value.
        if self._cache_namespace_keys:
            kw = {}
            for key in self._cache_namespace_keys:
                try:
                    val = md[key]
                except Exception:
                    val = None
                kw[key] = val
            self.ZCacheable_set(result, keywords=kw)

    security.declareProtected(change_dtml_methods,
                              'ZCacheable_configHTML')  # NOQA: D001,E501
    ZCacheable_configHTML = DTMLFile('dtml/cacheNamespaceKeys', globals())

    @security.protected(change_dtml_methods)
    def getCacheNamespaceKeys(self):
        # Return the cacheNamespaceKeys.
        return self._cache_namespace_keys

    @security.protected(change_dtml_methods)
    def setCacheNamespaceKeys(self, keys, REQUEST=None):
        # Set the list of names looked up to provide a cache key.
        ks = []
        for key in keys:
            key = str(key).strip()
            if key:
                ks.append(key)
        self._cache_namespace_keys = tuple(ks)

        if REQUEST is not None:
            return self.ZCacheable_manage(self, REQUEST)

    @security.protected(View)
    def get_size(self):
        return len(self.raw)

    # deprecated; use get_size!
    getSize = get_size

    security.declareProtected(change_dtml_methods, 'manage')  # NOQA: D001

    security.declareProtected(change_dtml_methods,
                              'manage_editForm')  # NOQA: D001,E501
    manage_editForm = DTMLFile('dtml/documentEdit', globals())
    manage_editForm._setName('manage_editForm')

    # deprecated!
    manage_uploadForm = manage_editForm

    security.declareProtected(change_dtml_methods, 'manage_main')  # NOQA: D001
    manage = manage_main = manage_editDocument = manage_editForm

    security.declareProtected(change_proxy_roles,
                              'manage_proxyForm')  # NOQA: D001,E501
    manage_proxyForm = DTMLFile('dtml/documentProxy', globals())

    @security.protected(change_dtml_methods)
    def manage_edit(self, data, title, SUBMIT='Change', REQUEST=None):
        """ Replace contents with 'data', title with 'title'.
        """
        self._validateProxy(REQUEST)
        if self.wl_isLocked():
            raise ResourceLockedError(self._locked_error_text)

        self.title = str(title)
        if isinstance(data, TaintedString):
            data = data.quoted()

        if hasattr(data, 'read'):
            data = data.read()
        try:
            self.munge(data)
        except ParseError as e:
            if REQUEST:
                return self.manage_main(self,
                                        REQUEST,
                                        manage_tabs_message=e,
                                        manage_tabs_type='warning')
            else:
                raise
        self.ZCacheable_invalidate()
        if REQUEST:
            message = "Saved changes."
            return self.manage_main(self, REQUEST, manage_tabs_message=message)

    @security.protected(change_dtml_methods)
    def manage_upload(self, file='', REQUEST=None):
        """ Replace the contents of the document with the text in 'file'.

        Store `file` as a native `str`.
        """
        self._validateProxy(REQUEST)
        if self.wl_isLocked():
            if REQUEST is not None:
                return self.manage_main(
                    self,
                    REQUEST,
                    manage_tabs_message=self._locked_error_text,
                    manage_tabs_type='warning')
            raise ResourceLockedError(self._locked_error_text)

        if REQUEST is not None and not file:
            return self.manage_main(self,
                                    REQUEST,
                                    manage_tabs_message='No file specified',
                                    manage_tabs_type='warning')

        self.munge(safe_file_data(file))
        self.ZCacheable_invalidate()
        if REQUEST is not None:
            message = "Content uploaded."
            return self.manage_main(self, REQUEST, manage_tabs_message=message)

    def manage_haveProxy(self, r):
        return r in self._proxy_roles

    def _validateProxy(self, request, roles=None):
        if roles is None:
            roles = self._proxy_roles
        if not roles:
            return
        user = u = getSecurityManager().getUser()
        user = user.allowed
        for r in roles:
            if r and not user(self, (r, )):
                user = None
                break

        if user is not None:
            return

        raise Forbidden(
            'You are not authorized to change <em>%s</em> because you '
            'do not have proxy roles.\n<!--%s, %s-->' %
            (self.__name__, u, roles))

    @security.protected(change_proxy_roles)
    @requestmethod('POST')
    def manage_proxy(self, roles=(), REQUEST=None):
        "Change Proxy Roles"
        self._validateProxy(REQUEST, roles)
        self._validateProxy(REQUEST)
        self._proxy_roles = tuple(roles)
        if REQUEST:
            message = "Saved changes."
            return self.manage_proxyForm(self,
                                         REQUEST,
                                         manage_tabs_message=message)

    @security.protected(view_management_screens)
    def PrincipiaSearchSource(self):
        # Support for searching - the document's contents are searched.
        return self.read()

    @security.protected(view_management_screens)
    def document_src(self, REQUEST=None, RESPONSE=None):
        # Return unprocessed document source.
        if RESPONSE is not None:
            RESPONSE.setHeader('Content-Type', 'text/plain')
        return self.read()

    def manage_historyCompare(self,
                              rev1,
                              rev2,
                              REQUEST,
                              historyComparisonResults=''):
        return DTMLMethod.inheritedAttribute('manage_historyCompare')(
            self,
            rev1,
            rev2,
            REQUEST,
            historyComparisonResults=html_diff(rev1.read(), rev2.read()))
Example #10
0

InitializeClass(ZCTextIndex)


def manage_addZCTextIndex(self, id, extra=None, REQUEST=None, RESPONSE=None):
    """Add a text index"""
    if REQUEST is None:
        URL3 = None
    else:
        URL3 = REQUEST.URL3
    return self.manage_addIndex(id, 'ZCTextIndex', extra, REQUEST, RESPONSE,
                                URL3)


manage_addZCTextIndexForm = DTMLFile('dtml/addZCTextIndex', globals())

manage_addLexiconForm = DTMLFile('dtml/addLexicon', globals())


def manage_addLexicon(self, id, title='', elements=[], REQUEST=None):
    """Add ZCTextIndex Lexicon"""

    pipeline = []
    for el_record in elements:
        if not hasattr(el_record, 'name'):
            continue  # Skip over records that only specify element group
        element = element_factory.instantiate(el_record.group, el_record.name)
        if element is not None:
            if el_record.group == 'Word Splitter':
                # I don't like hardcoding this, but its a simple solution
Example #11
0
class BrowserIdManager(Item, Persistent, Implicit, RoleManager, Owned, Tabs):
    """ browser id management class
    """
    implements(IBrowserIdManager)
    meta_type = 'Browser Id Manager'

    security = ClassSecurityInfo()
    security.declareObjectPublic()
    ok = {'meta_type': 1, 'id': 1, 'title': 1, 'icon': 1, 'title_or_id': 1}
    security.setDefaultAccess(ok)
    security.setPermissionDefault(MGMT_SCREEN_PERM, ['Manager'])
    security.setPermissionDefault(ACCESS_CONTENTS_PERM,
                                  ['Manager', 'Anonymous'])
    security.setPermissionDefault(CHANGE_IDMGR_PERM, ['Manager'])

    # BBB
    auto_url_encoding = 0
    cookie_http_only = 0

    def __init__(self,
                 id,
                 title='',
                 idname='_ZopeId',
                 location=('cookies', 'form'),
                 cookiepath=('/'),
                 cookiedomain='',
                 cookielifedays=0,
                 cookiesecure=0,
                 cookiehttponly=0,
                 auto_url_encoding=0):
        self.id = str(id)
        self.title = str(title)
        self.setBrowserIdName(idname)
        self.setBrowserIdNamespaces(location)
        self.setCookiePath(cookiepath)
        self.setCookieDomain(cookiedomain)
        self.setCookieLifeDays(cookielifedays)
        self.setCookieSecure(cookiesecure)
        self.setCookieHTTPOnly(cookiehttponly)
        self.setAutoUrlEncoding(auto_url_encoding)

    # IBrowserIdManager
    security.declareProtected(ACCESS_CONTENTS_PERM, 'hasBrowserId')

    def hasBrowserId(self):
        """ See IBrowserIdManager.
        """
        try:
            return self.getBrowserId(create=0) is not None
        except BrowserIdManagerErr:
            return False

    security.declareProtected(ACCESS_CONTENTS_PERM, 'getBrowserId')

    def getBrowserId(self, create=1):
        """ See IBrowserIdManager.
        """
        REQUEST = self.REQUEST
        # let's see if bid has already been attached to request
        bid = getattr(REQUEST, 'browser_id_', None)
        if bid is not None:
            # it's already set in this request so we can just return it
            # if it's well-formed
            if not isAWellFormedBrowserId(bid):
                # somebody screwed with the REQUEST instance during
                # this request.
                raise BrowserIdManagerErr('Ill-formed browserid in '
                                          'REQUEST.browser_id_:  %s' %
                                          escape(bid))
            return bid
        # fall through & ck form/cookie namespaces if bid is not in request.
        tk = self.browserid_name
        ns = self.browserid_namespaces
        for name in ns:
            if name == 'url':
                continue  # browser ids in url are checked by Traverser class
            current_ns = getattr(REQUEST, name, None)
            if current_ns is None:
                continue
            bid = current_ns.get(tk, None)
            if bid is not None:
                # hey, we got a browser id!
                if isAWellFormedBrowserId(bid):
                    # bid is not "plain old broken"
                    REQUEST.browser_id_ = bid
                    REQUEST.browser_id_ns_ = name
                    return bid
        # fall through if bid is invalid or not in namespaces
        if create:
            # create a brand new bid
            bid = getNewBrowserId()
            if 'cookies' in ns:
                self._setCookie(bid, REQUEST)
            REQUEST.browser_id_ = bid
            REQUEST.browser_id_ns_ = None
            return bid
        # implies a return of None if:
        # (not create=1) and (invalid or ((not in req) and (not in ns)))

    security.declareProtected(ACCESS_CONTENTS_PERM, 'getBrowserIdName')

    def getBrowserIdName(self):
        """ See IBrowserIdManager.
        """
        return self.browserid_name

    security.declareProtected(ACCESS_CONTENTS_PERM, 'isBrowserIdNew')

    def isBrowserIdNew(self):
        """ See IBrowserIdManager.
        """
        if not self.getBrowserId(create=False):
            raise BrowserIdManagerErr('There is no current browser id.')
        # ns will be None if new
        return getattr(self.REQUEST, 'browser_id_ns_', None) is None

    security.declareProtected(ACCESS_CONTENTS_PERM, 'isBrowserIdFromCookie')

    def isBrowserIdFromCookie(self):
        """ See IBrowserIdManager.
        """
        if not self.getBrowserId(create=False):
            raise BrowserIdManagerErr('There is no current browser id.')
        if getattr(self.REQUEST, 'browser_id_ns_') == 'cookies':
            return 1

    security.declareProtected(ACCESS_CONTENTS_PERM, 'isBrowserIdFromForm')

    def isBrowserIdFromForm(self):
        """ See IBrowserIdManager.
        """
        if not self.getBrowserId(create=False):
            raise BrowserIdManagerErr('There is no current browser id.')
        if getattr(self.REQUEST, 'browser_id_ns_') == 'form':
            return 1

    security.declareProtected(ACCESS_CONTENTS_PERM, 'isBrowserIdFromUrl')

    def isBrowserIdFromUrl(self):
        """ See IBrowserIdManager.
        """
        if not self.getBrowserId(create=False):
            raise BrowserIdManagerErr('There is no current browser id.')
        if getattr(self.REQUEST, 'browser_id_ns_') == 'url':
            return 1

    security.declareProtected(ACCESS_CONTENTS_PERM, 'flushBrowserIdCookie')

    def flushBrowserIdCookie(self):
        """ See IBrowserIdManager.
        """
        if 'cookies' not in self.browserid_namespaces:
            raise BrowserIdManagerErr('Cookies are not now being used as a '
                                      'browser id namespace, thus the '
                                      'browserid cookie cannot be flushed.')
        self._setCookie('deleted', self.REQUEST, remove=1)

    security.declareProtected(ACCESS_CONTENTS_PERM,
                              'setBrowserIdCookieByForce')

    def setBrowserIdCookieByForce(self, bid):
        """ See IBrowserIdManager.
        """
        if 'cookies' not in self.browserid_namespaces:
            raise BrowserIdManagerErr('Cookies are not now being used as a '
                                      'browser id namespace, thus the '
                                      'browserid cookie cannot be forced.')
        self._setCookie(bid, self.REQUEST)

    security.declareProtected(ACCESS_CONTENTS_PERM, 'getHiddenFormField')

    def getHiddenFormField(self):
        """ See IBrowserIdManager.
        """
        s = '<input type="hidden" name="%s" value="%s" />'
        return s % (self.getBrowserIdName(), self.getBrowserId())

    security.declareProtected(ACCESS_CONTENTS_PERM, 'encodeUrl')

    def encodeUrl(self, url, style='querystring', create=1):
        # See IBrowserIdManager
        bid = self.getBrowserId(create)
        if bid is None:
            raise BrowserIdManagerErr('There is no current browser id.')
        name = self.getBrowserIdName()
        if style == 'querystring':  # encode bid in querystring
            if '?' in url:
                return '%s&amp;%s=%s' % (url, name, bid)
            else:
                return '%s?%s=%s' % (url, name, bid)
        else:  # encode bid as first two URL path segments
            proto, host, path, params, query, frag = urlparse(url)
            path = '/%s/%s%s' % (name, bid, path)
            return urlunparse((proto, host, path, params, query, frag))

    # Non-IBrowserIdManager accessors / mutators.
    security.declareProtected(CHANGE_IDMGR_PERM, 'setBrowserIdName')

    def setBrowserIdName(self, k):
        """ Set browser id name string

        o Enforce "valid" values.
        """
        if not (type(k) is type('') and k and not badidnamecharsin(k)):
            raise BrowserIdManagerErr('Bad id name string %s' %
                                      escape(repr(k)))
        self.browserid_name = k

    security.declareProtected(CHANGE_IDMGR_PERM, 'setBrowserIdNamespaces')

    def setBrowserIdNamespaces(self, ns):
        """
        accepts list of allowable browser id namespaces 
        """
        for name in ns:
            if name not in ALLOWED_BID_NAMESPACES:
                raise BrowserIdManagerErr('Bad browser id namespace %s' %
                                          repr(name))
        self.browserid_namespaces = tuple(ns)

    security.declareProtected(ACCESS_CONTENTS_PERM, 'getBrowserIdNamespaces')

    def getBrowserIdNamespaces(self):
        """ """
        return self.browserid_namespaces

    security.declareProtected(CHANGE_IDMGR_PERM, 'setCookiePath')

    def setCookiePath(self, path=''):
        """ sets cookie 'path' element for id cookie """
        if not (type(path) is type('') and not badcookiecharsin(path)):
            raise BrowserIdManagerErr('Bad cookie path %s' %
                                      escape(repr(path)))
        self.cookie_path = path

    security.declareProtected(ACCESS_CONTENTS_PERM, 'getCookiePath')

    def getCookiePath(self):
        """ """
        return self.cookie_path

    security.declareProtected(CHANGE_IDMGR_PERM, 'setCookieLifeDays')

    def setCookieLifeDays(self, days):
        """ offset for id cookie 'expires' element """
        if type(days) not in (type(1), type(1.0)):
            raise BrowserIdManagerErr('Bad cookie lifetime in days %s '
                                      '(requires integer value)' %
                                      escape(repr(days)))
        self.cookie_life_days = int(days)

    security.declareProtected(ACCESS_CONTENTS_PERM, 'getCookieLifeDays')

    def getCookieLifeDays(self):
        """ """
        return self.cookie_life_days

    security.declareProtected(CHANGE_IDMGR_PERM, 'setCookieDomain')

    def setCookieDomain(self, domain):
        """ sets cookie 'domain' element for id cookie """
        if type(domain) is not type(''):
            raise BrowserIdManagerErr('Cookie domain must be string: %s' %
                                      escape(repr(domain)))
        if not domain:
            self.cookie_domain = ''
            return
        if not twodotsin(domain):
            raise BrowserIdManagerErr(
                'Cookie domain must contain at least two dots '
                '(e.g. ".zope.org" or "www.zope.org") or it must '
                'be left blank. : '
                '%s' % escape( ` domain `))
        if badcookiecharsin(domain):
            raise BrowserIdManagerErr('Bad characters in cookie domain %s' %
                                      escape( ` domain `))
        self.cookie_domain = domain

    security.declareProtected(ACCESS_CONTENTS_PERM, 'getCookieDomain')

    def getCookieDomain(self):
        """ """
        return self.cookie_domain

    security.declareProtected(CHANGE_IDMGR_PERM, 'setCookieHTTPOnly')

    def setCookieHTTPOnly(self, http_only):
        """ sets cookie 'HTTPOnly' on or off """
        self.cookie_http_only = bool(http_only)

    security.declareProtected(ACCESS_CONTENTS_PERM, 'getCookieHTTPOnly')

    def getCookieHTTPOnly(self):
        """ retrieve the 'HTTPOnly' flag """
        return self.cookie_http_only

    security.declareProtected(CHANGE_IDMGR_PERM, 'setCookieSecure')

    def setCookieSecure(self, secure):
        """ sets cookie 'secure' element for id cookie """
        self.cookie_secure = not not secure

    security.declareProtected(ACCESS_CONTENTS_PERM, 'getCookieSecure')

    def getCookieSecure(self):
        """ """
        return self.cookie_secure

    security.declareProtected(CHANGE_IDMGR_PERM, 'setAutoUrlEncoding')

    def setAutoUrlEncoding(self, auto_url_encoding):
        """ sets 'auto url encoding' on or off """
        self.auto_url_encoding = not not auto_url_encoding

    security.declareProtected(ACCESS_CONTENTS_PERM, 'getAutoUrlEncoding')

    def getAutoUrlEncoding(self):
        """ """
        return self.auto_url_encoding

    security.declareProtected(ACCESS_CONTENTS_PERM, 'isUrlInBidNamespaces')

    def isUrlInBidNamespaces(self):
        """ Returns true if 'url' is in the browser id namespaces
        for this browser id """
        return 'url' in self.browserid_namespaces

    def _setCookie(self,
                   bid,
                   REQUEST,
                   remove=0,
                   now=time.time,
                   strftime=time.strftime,
                   gmtime=time.gmtime):
        """ """
        expires = None
        if remove:
            expires = "Sun, 10-May-1971 11:59:00 GMT"
        elif self.cookie_life_days:
            expires = now() + self.cookie_life_days * 86400
            # Wdy, DD-Mon-YYYY HH:MM:SS GMT
            expires = strftime('%a %d-%b-%Y %H:%M:%S GMT', gmtime(expires))

        # cookie attributes managed by BrowserIdManager
        d = {
            'domain': self.cookie_domain,
            'path': self.cookie_path,
            'secure': self.cookie_secure,
            'http_only': self.cookie_http_only,
            'expires': expires
        }

        if self.cookie_secure:
            URL1 = REQUEST.get('URL1', None)
            if URL1 is None:
                return  # should we raise an exception?
            if string.split(URL1, ':')[0] != 'https':
                return  # should we raise an exception?

        cookies = REQUEST.RESPONSE.cookies
        cookie = cookies[self.browserid_name] = {}
        for k, v in d.items():
            if v:
                cookie[k] = v  #only stuff things with true values
        cookie['value'] = bid

    def _setId(self, id):
        if id != self.id:
            raise ValueError('Cannot rename a browser id manager')

    # Jukes for handling URI-munged browser IDS
    def hasTraversalHook(self, parent):
        name = TRAVERSAL_APPHANDLE
        return not not queryBeforeTraverse(parent, name)

    def updateTraversalData(self):
        if 'url' in self.browserid_namespaces:
            self.registerTraversalHook()
        else:
            self.unregisterTraversalHook()

    def unregisterTraversalHook(self):
        parent = aq_parent(aq_inner(self))
        name = TRAVERSAL_APPHANDLE
        if self.hasTraversalHook(parent):
            unregisterBeforeTraverse(parent, name)

    def registerTraversalHook(self):
        parent = aq_parent(aq_inner(self))
        if not self.hasTraversalHook(parent):
            hook = BrowserIdManagerTraverser()
            name = TRAVERSAL_APPHANDLE
            priority = 40  # "higher" priority than session data traverser
            registerBeforeTraverse(parent, hook, name, priority)

    # ZMI
    manage_options = (
        {
            'label': 'Settings',
            'action': 'manage_browseridmgr'
        },
        {
            'label': 'Security',
            'action': 'manage_access'
        },
        {
            'label': 'Ownership',
            'action': 'manage_owner'
        },
    )

    def manage_afterAdd(self, item, container):
        """ Maybe add our traversal hook """
        self.updateTraversalData()

    def manage_beforeDelete(self, item, container):
        """ Remove our traversal hook if it exists """
        self.unregisterTraversalHook()

    security.declareProtected(MGMT_SCREEN_PERM, 'manage_browseridmgr')
    manage_browseridmgr = DTMLFile('dtml/manageIdManager', globals())

    security.declareProtected(CHANGE_IDMGR_PERM,
                              'manage_changeBrowserIdManager')

    def manage_changeBrowserIdManager(self,
                                      title='',
                                      idname='_ZopeId',
                                      location=('cookies', 'form'),
                                      cookiepath='/',
                                      cookiedomain='',
                                      cookielifedays=0,
                                      cookiesecure=0,
                                      cookiehttponly=0,
                                      auto_url_encoding=0,
                                      REQUEST=None):
        """ """
        self.title = str(title)
        self.setBrowserIdName(idname)
        self.setCookiePath(cookiepath)
        self.setCookieDomain(cookiedomain)
        self.setCookieLifeDays(cookielifedays)
        self.setCookieSecure(cookiesecure)
        self.setCookieHTTPOnly(cookiehttponly)
        self.setBrowserIdNamespaces(location)
        self.setAutoUrlEncoding(auto_url_encoding)
        self.updateTraversalData()
        if REQUEST is not None:
            msg = '/manage_browseridmgr?manage_tabs_message=Changes saved'
            REQUEST.RESPONSE.redirect(self.absolute_url() + msg)
class VirtualHostMonster(Persistent, Item, Implicit):
    """Provide a simple drop-in solution for virtual hosting.
    """

    meta_type = 'Virtual Host Monster'
    priority = 25

    id = 'VHM'
    title = ''
    lines = ()
    have_map = 0

    security = ClassSecurityInfo()

    manage_options = ({
        'label': 'About',
        'action': 'manage_main'
    }, {
        'label': 'Mappings',
        'action': 'manage_edit'
    })

    security.declareProtected(View, 'manage_main')
    manage_main = DTMLFile('www/VirtualHostMonster',
                           globals(),
                           __name__='manage_main')

    security.declareProtected('Add Site Roots', 'manage_edit')
    manage_edit = DTMLFile('www/manage_edit', globals())

    security.declareProtected('Add Site Roots', 'set_map')

    def set_map(self, map_text, RESPONSE=None):
        "Set domain to path mappings."
        lines = map_text.split('\n')
        self.fixed_map = fixed_map = {}
        self.sub_map = sub_map = {}
        new_lines = []
        for line in lines:
            line = line.split('#!')[0].strip()
            if not line:
                continue
            try:
                # Drop the protocol, if any
                line = line.split('://')[-1]
                try:
                    host, path = [x.strip() for x in line.split('/', 1)]
                except:
                    raise ValueError(
                        'Line needs a slash between host and path: %s' % line)
                pp = filter(None, path.split('/'))
                if pp:
                    obpath = pp[:]
                    if obpath[0] == 'VirtualHostBase':
                        obpath = obpath[3:]
                    if 'VirtualHostRoot' in obpath:
                        i1 = obpath.index('VirtualHostRoot')
                        i2 = i1 + 1
                        while i2 < len(obpath) and obpath[i2][:4] == '_vh_':
                            i2 = i2 + 1
                        del obpath[i1:i2]
                    if obpath:
                        try:
                            ob = self.unrestrictedTraverse(obpath)
                        except:
                            raise ValueError, ('Path not found: %s' % obpath)
                        if not getattr(ob.aq_base, 'isAnObjectManager', 0):
                            raise ValueError, (
                                'Path must lead to an Object Manager: %s' %
                                obpath)
                    if 'VirtualHostRoot' not in pp:
                        pp.append('/')
                    pp.reverse()
                try:
                    int(host.replace('.', ''))
                    raise ValueError, ('IP addresses are not mappable: %s' %
                                       host)
                except ValueError:
                    pass
                if host[:2] == '*.':
                    host_map = sub_map
                    host = host[2:]
                else:
                    host_map = fixed_map
                hostname, port = (host.split(':', 1) + [None])[:2]
                if hostname not in host_map:
                    host_map[hostname] = {}
                host_map[hostname][port] = pp
            except 'LineError', msg:
                line = '%s #! %s' % (line, msg)
            new_lines.append(line)
        self.lines = tuple(new_lines)
        self.have_map = not not (fixed_map or sub_map)  # booleanize
        if RESPONSE is not None:
            RESPONSE.redirect(
                'manage_edit?manage_tabs_message=Changes%20Saved.')
Example #13
0
class MembershipTool(BaseTool):
    """ Implement 'portal_membership' interface using "stock" policies.
    """

    implements(IMembershipTool)

    meta_type = 'Default Membership Tool'
    membersfolder_id = 'Members'

    security = ClassSecurityInfo()

    #
    #   ZMI methods
    #
    security.declareProtected(ManagePortal, 'manage_overview')
    manage_overview = DTMLFile('explainMembershipTool', _dtmldir)

    security.declareProtected(ManagePortal, 'manage_mapRoles')
    manage_mapRoles = DTMLFile('membershipRolemapping', _dtmldir)

    security.declareProtected(ManagePortal, 'manage_setMembersFolderById')

    def manage_setMembersFolderById(self, id='', REQUEST=None):
        """ ZMI method to set the members folder object by its id.
        """
        self.setMembersFolderById(id)
        if REQUEST is not None:
            REQUEST['RESPONSE'].redirect(
                self.absolute_url() + '/manage_mapRoles' +
                '?manage_tabs_message=Members+folder+changed.')

    #
    #   'portal_membership' interface methods
    #
    security.declareProtected(ListPortalMembers, 'getRoster')

    def getRoster(self):
        """ Return a list of mappings for 'listed' members.

        If Manager, return a list of all usernames.  The mapping
        contains the id and listed variables.
        """
        isUserManager = _checkPermission(ManageUsers, self)
        roster = []
        for member in self.listMembers():
            listed = member.getProperty('listed')
            if isUserManager or listed:
                roster.append({'id': member.getId(), 'listed': listed})
        return roster

    security.declareProtected(ManagePortal, 'setMembersFolderById')

    def setMembersFolderById(self, id=''):
        """ Set the members folder object by its id.
        """
        self.membersfolder_id = id.strip()

    security.declarePublic('getMembersFolder')

    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)

    security.declarePublic('createMemberArea')

    def createMemberArea(self, member_id=''):
        """ Create a member area for 'member_id' or authenticated user.
        """
        if not self.getMemberareaCreationFlag():
            return None
        members = self.getMembersFolder()
        if members is None:
            return None
        if self.isAnonymousUser():
            return None
        if member_id:
            if not self.isMemberAccessAllowed(member_id):
                return None
            member = self.getMemberById(member_id)
            if member is None:
                return None
        else:
            member = self.getAuthenticatedMember()
            member_id = member.getId()
        if hasattr(aq_base(members), member_id):
            return None

        # Note: We can't use invokeFactory() to add folder and content because
        # the user might not have the necessary permissions.

        # Create Member's home folder.
        members.manage_addPortalFolder(id=member_id,
                                       title="%s's Home" % member_id)
        f = members._getOb(member_id)

        # Grant Ownership and Owner role to Member
        f.changeOwnership(member)
        f.__ac_local_roles__ = None
        f.manage_setLocalRoles(member_id, ['Owner'])

        # Create Member's initial content.
        if hasattr(self, 'createMemberContent'):
            self.createMemberContent(member=member,
                                     member_id=member_id,
                                     member_folder=f)
        else:
            addDocument(f, 'index_html', member_id + "'s Home",
                        member_id + "'s front page", "structured-text",
                        (DEFAULT_MEMBER_CONTENT % member_id))

            # Grant Ownership and Owner role to Member
            f.index_html.changeOwnership(member)
            f.index_html.__ac_local_roles__ = None
            f.index_html.manage_setLocalRoles(member_id, ['Owner'])

            f.index_html._setPortalTypeName('Document')
            f.index_html.reindexObject()
            f.index_html.notifyWorkflowCreated()
        return f

    security.declarePublic('createMemberarea')
    createMemberarea = createMemberArea

    def getHomeFolder(self, id=None, verifyPermission=0):
        """ Return a member's home folder object, or None.
        """
        if id is None:
            member = self.getAuthenticatedMember()
            if not hasattr(member, 'getMemberId'):
                return None
            id = member.getMemberId()
        members = self.getMembersFolder()
        if members:
            try:
                folder = members._getOb(id)
                if verifyPermission and not _checkPermission(View, folder):
                    # Don't return the folder if the user can't get to it.
                    return None
                return folder
            except (AttributeError, TypeError, KeyError):
                pass
        return None

    def getHomeUrl(self, id=None, verifyPermission=0):
        """ Return the URL to a member's home folder, or None.
        """
        home = self.getHomeFolder(id, verifyPermission)
        if home is not None:
            return home.absolute_url()
        else:
            return None
Example #14
0
class DTMLMethod(
        RestrictedDTML,
        HTML,
        Implicit,
        RoleManager,
        ElementWithTitle,
        Item_w__name__,
        Historical,
        Cacheable,
):
    """ DocumentTemplate.HTML objects that act as methods of their containers.
    """
    meta_type = 'DTML Method'
    _proxy_roles = ()
    index_html = None  # Prevent accidental acquisition
    _cache_namespace_keys = ()

    security = ClassSecurityInfo()
    security.declareObjectProtected(View)

    # Documents masquerade as functions:
    class func_code:
        pass

    func_code = func_code()
    func_code.co_varnames = 'self', 'REQUEST', 'RESPONSE'
    func_code.co_argcount = 3

    manage_options = ((
        {
            'label': 'Edit',
            'action': 'manage_main'
        },
        {
            'label': 'View',
            'action': ''
        },
        {
            'label': 'Proxy',
            'action': 'manage_proxyForm'
        },
    ) + Historical.manage_options + RoleManager.manage_options +
                      Item_w__name__.manage_options + Cacheable.manage_options)

    # Careful in permission changes--used by DTMLDocument!

    security.declareProtected(change_dtml_methods, 'manage_historyCopy')
    security.declareProtected(change_dtml_methods, 'manage_beforeHistoryCopy')
    security.declareProtected(change_dtml_methods, 'manage_afterHistoryCopy')

    # More reasonable default for content-type for http HEAD requests.
    default_content_type = 'text/html'

    security.declareProtected(View, '__call__')

    def __call__(self, client=None, REQUEST={}, RESPONSE=None, **kw):
        """Render using the given client object

        o If client is not passed, we are being called as a sub-template:
          don't do any error propagation.

        o If supplied, use the REQUEST mapping, Response, and key word
        arguments.
        """
        if not self._cache_namespace_keys:
            data = self.ZCacheable_get(default=_marker)
            if data is not _marker:
                if (IStreamIterator.isImplementedBy(data)
                        and RESPONSE is not None):
                    # This is a stream iterator and we need to set some
                    # headers now before giving it to medusa
                    if RESPONSE.headers.get('content-length', None) is None:
                        RESPONSE.setHeader('content-length', len(data))

                    if (RESPONSE.headers.get('content-type', None) is None
                            and RESPONSE.headers.get('Content-type',
                                                     None) is None):
                        ct = (self.__dict__.get('content_type')
                              or self.default_content_type)
                        RESPONSE.setHeader('content-type', ct)

                # Return cached results.
                return data

        __traceback_supplement__ = (PathTracebackSupplement, self)
        kw['document_id'] = self.getId()
        kw['document_title'] = self.title

        security = getSecurityManager()
        security.addContext(self)
        if self.__dict__.has_key('validate'):
            first_time_through = 0
        else:
            self.__dict__['validate'] = security.DTMLValidate
            first_time_through = 1
        try:

            if client is None:
                # Called as subtemplate, so don't need error propagation!
                r = apply(HTML.__call__, (self, client, REQUEST), kw)
                if RESPONSE is None:
                    result = r
                else:
                    result = decapitate(r, RESPONSE)
                if not self._cache_namespace_keys:
                    self.ZCacheable_set(result)
                return result

            r = apply(HTML.__call__, (self, client, REQUEST), kw)
            if type(r) is not str or RESPONSE is None:
                if not self._cache_namespace_keys:
                    self.ZCacheable_set(r)
                return r

        finally:
            security.removeContext(self)
            if first_time_through:
                del self.__dict__['validate']

        have_key = RESPONSE.headers.has_key
        if not (have_key('content-type') or have_key('Content-Type')):
            if self.__dict__.has_key('content_type'):
                c = self.content_type
            else:
                c, e = guess_content_type(self.getId(), r)
            RESPONSE.setHeader('Content-Type', c)
        result = decapitate(r, RESPONSE)
        if not self._cache_namespace_keys:
            self.ZCacheable_set(result)
        return result

    def validate(self, inst, parent, name, value, md=None):
        return getSecurityManager().validate(inst, parent, name, value)

    def ZDocumentTemplate_beforeRender(self, md, default):
        # Tries to get a cached value.
        if self._cache_namespace_keys:
            # Use the specified keys from the namespace to identify a
            # cache entry.
            kw = {}
            for key in self._cache_namespace_keys:
                try:
                    val = md[key]
                except:
                    val = None
                kw[key] = val
            return self.ZCacheable_get(keywords=kw, default=default)
        return default

    def ZDocumentTemplate_afterRender(self, md, result):
        # Tries to set a cache value.
        if self._cache_namespace_keys:
            kw = {}
            for key in self._cache_namespace_keys:
                try:
                    val = md[key]
                except:
                    val = None
                kw[key] = val
            self.ZCacheable_set(result, keywords=kw)

    security.declareProtected(change_dtml_methods, 'ZCacheable_configHTML')
    ZCacheable_configHTML = DTMLFile('dtml/cacheNamespaceKeys', globals())

    security.declareProtected(change_dtml_methods, 'getCacheNamespaceKeys')

    def getCacheNamespaceKeys(self):
        # Return the cacheNamespaceKeys.
        return self._cache_namespace_keys

    security.declareProtected(change_dtml_methods, 'setCacheNamespaceKeys')

    def setCacheNamespaceKeys(self, keys, REQUEST=None):
        # Set the list of names looked up to provide a cache key.
        ks = []
        for key in keys:
            key = str(key).strip()
            if key:
                ks.append(key)
        self._cache_namespace_keys = tuple(ks)
        if REQUEST is not None:
            return self.ZCacheable_manage(self, REQUEST)

    security.declareProtected(View, 'get_size')

    def get_size(self):
        return len(self.raw)

    # deprecated; use get_size!
    getSize = get_size

    security.declareProtected(change_dtml_methods, 'manage')

    security.declareProtected(change_dtml_methods, 'manage_editForm')
    manage_editForm = DTMLFile('dtml/documentEdit', globals())
    manage_editForm._setName('manage_editForm')

    # deprecated!
    manage_uploadForm = manage_editForm

    security.declareProtected(change_dtml_methods, 'manage_main')
    manage = manage_main = manage_editDocument = manage_editForm

    security.declareProtected(change_proxy_roles, 'manage_proxyForm')
    manage_proxyForm = DTMLFile('dtml/documentProxy', globals())

    _size_changes = {
        'Bigger': (5, 5),
        'Smaller': (-5, -5),
        'Narrower': (0, -5),
        'Wider': (0, 5),
        'Taller': (5, 0),
        'Shorter': (-5, 0),
    }

    def _er(self, data, title, SUBMIT, dtpref_cols, dtpref_rows, REQUEST):
        dr, dc = self._size_changes[SUBMIT]
        rows = str(max(1, int(dtpref_rows) + dr))
        cols = str(dtpref_cols)
        if cols.endswith('%'):
            cols = str(min(100, max(25, int(cols[:-1]) + dc))) + '%'
        else:
            cols = str(max(35, int(cols) + dc))
        e = (DateTime("GMT") + 365).rfc822()
        setCookie = REQUEST["RESPONSE"].setCookie
        setCookie("dtpref_rows", rows, path='/', expires=e)
        setCookie("dtpref_cols", cols, path='/', expires=e)
        REQUEST.other.update({"dtpref_cols": cols, "dtpref_rows": rows})
        return self.manage_main(self,
                                REQUEST,
                                title=title,
                                __str__=self.quotedHTML(data))

    security.declareProtected(change_dtml_methods, 'manage_edit')

    def manage_edit(self,
                    data,
                    title,
                    SUBMIT='Change',
                    dtpref_cols='100%',
                    dtpref_rows='20',
                    REQUEST=None):
        """ Replace contents with 'data', title with 'title'.

        The SUBMIT parameter is also used to change the size of the editing
        area on the default Document edit screen.  If the value is "Smaller",
        the rows and columns decrease by 5.  If the value is "Bigger", the
        rows and columns increase by 5.  If any other or no value is supplied,
        the data gets checked for DTML errors and is saved.
        """
        self._validateProxy(REQUEST)
        if self._size_changes.has_key(SUBMIT):
            return self._er(data, title, SUBMIT, dtpref_cols, dtpref_rows,
                            REQUEST)
        if self.wl_isLocked():
            raise ResourceLockedError('This item is locked via WebDAV')

        self.title = str(title)
        if isinstance(data, TaintedString):
            data = data.quoted()
        if not isinstance(data, basestring):
            data = data.read()
        self.munge(data)
        self.ZCacheable_invalidate()
        if REQUEST:
            message = "Saved changes."
            return self.manage_main(self, REQUEST, manage_tabs_message=message)

    security.declareProtected(change_dtml_methods, 'manage_upload')

    def manage_upload(self, file='', REQUEST=None):
        """ Replace the contents of the document with the text in 'file'.
        """
        self._validateProxy(REQUEST)
        if self.wl_isLocked():
            raise ResourceLockedError('This DTML Method is locked via WebDAV')

        if type(file) is not str:
            if REQUEST and not file:
                raise ValueError('No file specified')
            file = file.read()

        self.munge(file)
        self.ZCacheable_invalidate()
        if REQUEST:
            message = "Saved changes."
            return self.manage_main(self, REQUEST, manage_tabs_message=message)

    def manage_haveProxy(self, r):
        return r in self._proxy_roles

    def _validateProxy(self, request, roles=None):
        if roles is None:
            roles = self._proxy_roles
        if not roles:
            return
        user = u = getSecurityManager().getUser()
        user = user.allowed
        for r in roles:
            if r and not user(self, (r, )):
                user = None
                break

        if user is not None:
            return

        raise Forbidden(
            'You are not authorized to change <em>%s</em> because you '
            'do not have proxy roles.\n<!--%s, %s-->' %
            (self.__name__, u, roles))

    security.declareProtected(change_proxy_roles, 'manage_proxy')

    @requestmethod('POST')
    def manage_proxy(self, roles=(), REQUEST=None):
        "Change Proxy Roles"
        self._validateProxy(REQUEST, roles)
        self._validateProxy(REQUEST)
        self._proxy_roles = tuple(roles)
        self.ZCacheable_invalidate()
        if REQUEST:
            message = "Saved changes."
            return self.manage_proxyForm(self,
                                         REQUEST,
                                         manage_tabs_message=message)

    security.declareProtected(view_management_screens, 'PrincipiaSearchSource')

    def PrincipiaSearchSource(self):
        # Support for searching - the document's contents are searched.
        return self.read()

    security.declareProtected(view_management_screens, 'document_src')

    def document_src(self, REQUEST=None, RESPONSE=None):
        # Return unprocessed document source.
        if RESPONSE is not None:
            RESPONSE.setHeader('Content-Type', 'text/plain')
        return self.read()

    ## Protocol handlers

    security.declareProtected(change_dtml_methods, 'PUT')

    def PUT(self, REQUEST, RESPONSE):
        """ Handle FTP / HTTP PUT requests.
        """
        self.dav__init(REQUEST, RESPONSE)
        self.dav__simpleifhandler(REQUEST, RESPONSE, refresh=1)
        body = REQUEST.get('BODY', '')
        self._validateProxy(REQUEST)
        self.munge(body)
        self.ZCacheable_invalidate()
        RESPONSE.setStatus(204)
        return RESPONSE

    security.declareProtected(ftp_access, 'manage_FTPstat')
    security.declareProtected(ftp_access, 'manage_FTPlist')

    security.declareProtected(ftp_access, 'manage_FTPget')

    def manage_FTPget(self):
        """ Get source for FTP download.
        """
        return self.read()

    def manage_historyCompare(self,
                              rev1,
                              rev2,
                              REQUEST,
                              historyComparisonResults=''):
        return DTMLMethod.inheritedAttribute('manage_historyCompare')(
            self,
            rev1,
            rev2,
            REQUEST,
            historyComparisonResults=html_diff(rev1.read(), rev2.read()))
Example #15
0
class DiscussionTool(UniqueObject, SimpleItem):
    """ Links content to discussions.
    """

    implements(IDiscussionTool)

    id = 'portal_discussion'
    meta_type = 'Default Discussion Tool'

    security = ClassSecurityInfo()

    manage_options = (({
        'label': 'Overview',
        'action': 'manage_overview'
    }, ) + SimpleItem.manage_options)

    #
    #   ZMI methods
    #
    security.declareProtected(ManagePortal, 'manage_overview')
    manage_overview = DTMLFile('explainDiscussionTool', _dtmldir)

    #
    #   'portal_discussion' interface methods
    #

    security.declarePublic('overrideDiscussionFor')

    def overrideDiscussionFor(self, content, allowDiscussion):
        """ Override discussability for the given object or clear the setting.
        """
        if not _checkPermission(ModifyPortalContent, content):
            raise AccessControl_Unauthorized

        if allowDiscussion is None or allowDiscussion == 'None':
            disc_flag = getattr(aq_base(content), 'allow_discussion', _marker)
            if disc_flag is not _marker:
                try:
                    del content.allow_discussion
                except AttributeError:
                    # https://bugs.launchpad.net/zope-cmf/+bug/162532
                    pass
        else:
            content.allow_discussion = bool(allowDiscussion)

    security.declarePublic('getDiscussionFor')

    def getDiscussionFor(self, content):
        """ Get DiscussionItemContainer for content, create it if necessary.
        """
        if not self.isDiscussionAllowedFor(content):
            raise DiscussionNotAllowed

        if not IDiscussionResponse.providedBy(content) and \
                getattr( aq_base(content), 'talkback', None ) is None:
            # Discussion Items use the DiscussionItemContainer object of the
            # related content item, so only create one for other content items
            self._createDiscussionFor(content)

        return content.talkback  # Return wrapped talkback

    security.declarePublic('isDiscussionAllowedFor')

    def isDiscussionAllowedFor(self, content):
        """ Get boolean indicating whether discussion is allowed for content.
        """
        if hasattr(aq_base(content), 'allow_discussion'):
            return bool(content.allow_discussion)

        if IDynamicType.providedBy(content):
            # Grabbing type information objects only works for dynamic types
            typeInfo = content.getTypeInfo()
            if typeInfo:
                return bool(typeInfo.allowDiscussion())

        return False

    #
    #   Utility methods
    #
    security.declarePrivate('_createDiscussionFor')

    def _createDiscussionFor(self, content):
        """ Create DiscussionItemContainer for content, if allowed.
        """
        if not self.isDiscussionAllowedFor(content):
            raise DiscussionNotAllowed

        content.talkback = DiscussionItemContainer()
        return content.talkback
Example #16
0
class UndoTool(UniqueObject, SimpleItem):
    """ This tool is used to undo changes.
    """

    implements(IUndoTool)

    id = 'portal_undo'
    meta_type = 'CMF Undo Tool'

    security = ClassSecurityInfo()

    manage_options = (SimpleItem.manage_options + ({
        'label': 'Overview',
        'action': 'manage_overview'
    }, ))

    #
    #   ZMI methods
    #
    security.declareProtected(ManagePortal, 'manage_overview')
    manage_overview = DTMLFile('explainUndoTool', _dtmldir)

    #
    #   'IUndoTool' interface methods
    #
    security.declareProtected(ListUndoableChanges,
                              'listUndoableTransactionsFor')

    def listUndoableTransactionsFor(self,
                                    object,
                                    first_transaction=None,
                                    last_transaction=None,
                                    PrincipiaUndoBatchSize=None):
        """ List all transaction IDs the user is allowed to undo on 'object'.
        """
        transactions = object.undoable_transactions(
            first_transaction=first_transaction,
            last_transaction=last_transaction,
            PrincipiaUndoBatchSize=PrincipiaUndoBatchSize)
        for t in transactions:
            # Ensure transaction ids don't have embedded LF.
            t['id'] = t['id'].replace('\n', '')
        if not _checkPermission(ManagePortal, object):
            # Filter out transactions done by other members of the portal.
            user_id = _getAuthenticatedUser(self).getId()
            transactions = filter(lambda record, user_id=user_id: record[
                'user_name'].split()[-1] == user_id,
                                  transactions)
        return transactions

    security.declarePublic('undo')

    def undo(self, object, transaction_info):
        """
            Undo the list of transactions passed in 'transaction_info',
            first verifying that the current user is allowed to undo them.
        """
        # Belt and suspenders:  make sure that the user is actually
        # allowed to undo the transation(s) in transaction_info.

        xids = {}  # set of allowed transaction IDs

        allowed = self.listUndoableTransactionsFor(object)

        for xid in map(lambda x: x['id'], allowed):
            xids[xid] = 1

        if type(transaction_info) == type(''):
            transaction_info = [transaction_info]

        for tinfo in transaction_info:
            if not xids.get(tinfo, None):
                raise AccessControl_Unauthorized

        object.manage_undo_transactions(transaction_info)
Example #17
0
class ZCTextIndex(Persistent, Implicit, SimpleItem):
    """Persistent text index.
    """
    implements(IZCTextIndex, IPluggableIndex)

    ## Magic class attributes ##

    meta_type = 'ZCTextIndex'
    query_options = ('query', )

    manage_options = ({'label': 'Overview', 'action': 'manage_main'}, )

    security = ClassSecurityInfo()
    security.declareObjectProtected(manage_zcatalog_indexes)

    ## Constructor ##

    def __init__(self,
                 id,
                 extra=None,
                 caller=None,
                 index_factory=None,
                 field_name=None,
                 lexicon_id=None):
        self.id = id

        # Arguments can be passed directly to the constructor or
        # via the silly "extra" record.
        self._fieldname = field_name or getattr(extra, 'doc_attr', '') or id
        self._indexed_attrs = self._fieldname.split(',')
        self._indexed_attrs = [
            attr.strip() for attr in self._indexed_attrs if attr
        ]

        lexicon_id = lexicon_id or getattr(extra, 'lexicon_id', '')
        lexicon = getattr(caller, lexicon_id, None)

        if lexicon is None:
            raise LookupError, 'Lexicon "%s" not found' % escape(lexicon_id)

        if not ILexicon.providedBy(lexicon):
            raise ValueError('Object "%s" does not implement '
                             'ZCTextIndex Lexicon interface' % lexicon.getId())

        self.lexicon_id = lexicon.getId()
        self._v_lexicon = lexicon

        if index_factory is None:
            if extra.index_type not in index_types.keys():
                raise ValueError, 'Invalid index type "%s"' % escape(
                    extra.index_type)
            self._index_factory = index_types[extra.index_type]
            self._index_type = extra.index_type
        else:
            self._index_factory = index_factory

        self.index = self._index_factory(aq_base(self.getLexicon()))

    ## Private Methods ##

    security.declarePrivate('getLexicon')

    def getLexicon(self):
        """Get the lexicon for this index
        """
        if hasattr(aq_base(self), 'lexicon'):
            # Fix up old ZCTextIndexes by removing direct lexicon ref
            # and changing it to an ID
            lexicon = getattr(aq_parent(aq_inner(self)), self.lexicon.getId())
            self.lexicon_id = lexicon.getId()
            del self.lexicon

        if getattr(aq_base(self), 'lexicon_path', None):
            # Fix up slightly less old ZCTextIndexes by removing
            # the physical path and changing it to an ID.
            # There's no need to use a physical path, which otherwise
            # makes it difficult to move or rename ZCatalogs.
            self.lexicon_id = self.lexicon_path[-1]
            del self.lexicon_path

        try:
            return self._v_lexicon
        except AttributeError:
            lexicon = getattr(aq_parent(aq_inner(self)), self.lexicon_id)
            if not ILexicon.providedBy(lexicon):
                raise TypeError('Object "%s" is not a ZCTextIndex Lexicon' %
                                repr(lexicon))
            self._v_lexicon = lexicon
            return lexicon

    ## External methods not in the Pluggable Index API ##

    security.declareProtected(search_zcatalog, 'query')

    def query(self, query, nbest=10):
        """Return pair (mapping from docids to scores, num results).

        The num results is the total number of results before trimming
        to the nbest results.
        """
        tree = QueryParser(self.getLexicon()).parseQuery(query)
        results = tree.executeQuery(self.index)
        if results is None:
            return [], 0
        chooser = NBest(nbest)
        chooser.addmany(results.items())
        return chooser.getbest(), len(results)

    ## Pluggable Index APIs ##

    def index_object(self, documentId, obj, threshold=None):
        """Wrapper for  index_doc()  handling indexing of multiple attributes.

        Enter the document with the specified documentId in the index
        under the terms extracted from the indexed text attributes,
        each of which should yield either a string or a list of
        strings (Unicode or otherwise) to be passed to index_doc().
        """
        # XXX We currently ignore subtransaction threshold

        # needed for backward compatibility
        try:
            fields = self._indexed_attrs
        except:
            fields = [self._fieldname]

        res = 0
        all_texts = []
        for attr in fields:
            text = getattr(obj, attr, None)
            if text is None:
                continue
            if safe_callable(text):
                text = text()
            if text is None:
                continue
            if text:
                if isinstance(text, (
                        list,
                        tuple,
                )):
                    all_texts.extend(text)
                else:
                    all_texts.append(text)

        # Check that we're sending only strings
        all_texts = filter(lambda text: isinstance(text, basestring), \
                           all_texts)
        if all_texts:
            return self.index.index_doc(documentId, all_texts)
        return res

    def unindex_object(self, docid):
        if self.index.has_doc(docid):
            self.index.unindex_doc(docid)

    def _apply_index(self, request):
        """Apply query specified by request, a mapping containing the query.

        Returns two object on success, the resultSet containing the
        matching record numbers and a tuple containing the names of
        the fields used

        Returns None if request is not valid for this index.
        """
        record = parseIndexRequest(request, self.id, self.query_options)
        if record.keys is None:
            return None

        query_str = ' '.join(record.keys)
        if not query_str:
            return None
        tree = QueryParser(self.getLexicon()).parseQuery(query_str)
        results = tree.executeQuery(self.index)
        return results, (self.id, )

    def getEntryForObject(self, documentId, default=None):
        """Return the list of words indexed for documentId"""
        try:
            word_ids = self.index.get_words(documentId)
        except KeyError:
            return default
        get_word = self.getLexicon().get_word
        return [get_word(wid) for wid in word_ids]

    def uniqueValues(self, name=None, withLengths=0):
        raise NotImplementedError

    ## The ZCatalog Index management screen uses these methods ##

    def numObjects(self):
        """Return number of unique words in the index"""
        return self.index.length()

    def indexSize(self):
        """Return the number of indexes objects """
        return self.index.document_count()

    def clear(self):
        """reinitialize the index (but not the lexicon)"""
        try:
            # Remove the cached reference to the lexicon
            # So that it is refreshed
            del self._v_lexicon
        except (AttributeError, KeyError):
            pass
        self.index = self._index_factory(aq_base(self.getLexicon()))

    ## User Interface Methods ##

    manage_main = DTMLFile('dtml/manageZCTextIndex', globals())

    def getIndexSourceNames(self):
        """Return sequence of names of indexed attributes"""
        try:
            return self._indexed_attrs
        except:
            return [self._fieldname]

    def getIndexType(self):
        """Return index type string"""
        return getattr(self, '_index_type', self._index_factory.__name__)

    def getLexiconURL(self):
        """Return the url of the lexicon used by the index"""
        try:
            lex = self.getLexicon()
        except (KeyError, AttributeError):
            return None
        else:
            return lex.absolute_url()
Example #18
0
class PLexicon(Lexicon, Implicit, SimpleItem):
    """Lexicon for ZCTextIndex.
    """

    implements(IZCLexicon)

    meta_type = 'ZCTextIndex Lexicon'

    manage_options = (
        {
            'label': 'Overview',
            'action': 'manage_main'
        },
        {
            'label': 'Query',
            'action': 'queryLexicon'
        },
    ) + SimpleItem.manage_options

    security = ClassSecurityInfo()
    security.declareObjectProtected(LexiconQueryPerm)

    def __init__(self, id, title='', *pipeline):
        self.id = str(id)
        self.title = str(title)
        PLexicon.inheritedAttribute('__init__')(self, *pipeline)

    ## User Interface Methods ##

    def getPipelineNames(self):
        """Return list of names of pipeline element classes"""
        return [element.__class__.__name__ for element in self._pipeline]

    _queryLexicon = DTMLFile('dtml/queryLexicon', globals())

    security.declareProtected(LexiconQueryPerm, 'queryLexicon')

    def queryLexicon(self, REQUEST, words=None, page=0, rows=20, cols=4):
        """Lexicon browser/query user interface
        """
        if words:
            wids = []
            for word in self.parseTerms(words):
                wids.extend(self.globToWordIds(word))
            words = [self.get_word(wid) for wid in wids]
        else:
            words = self.words()

        word_count = len(words)
        rows = max(min(rows, 500), 1)
        cols = max(min(cols, 12), 1)
        page_count = word_count / (rows * cols) + \
                     (word_count % (rows * cols) > 0)
        page = max(min(page, page_count - 1), 0)
        start = rows * cols * page
        end = min(rows * cols * (page + 1), word_count)

        if word_count:
            words = list(words[start:end])
        else:
            words = []

        columns = []
        i = 0
        while i < len(words):
            columns.append(words[i:i + rows])
            i += rows

        info = dict(page=page,
                    rows=rows,
                    cols=cols,
                    start_word=start + 1,
                    end_word=end,
                    word_count=word_count,
                    page_count=page_count,
                    page_range=xrange(page_count),
                    page_columns=columns)

        if REQUEST is not None:
            return self._queryLexicon(self, REQUEST, **info)

        return info

    security.declareProtected(LexiconMgmtPerm, 'manage_main')
    manage_main = DTMLFile('dtml/manageLexicon', globals())
Example #19
0
from Products.Sessions.interfaces import IBrowserIdManager
from Products.Sessions.interfaces import BrowserIdManagerErr
from Products.Sessions.SessionPermissions import ACCESS_CONTENTS_PERM
from Products.Sessions.SessionPermissions import CHANGE_IDMGR_PERM
from Products.Sessions.SessionPermissions import MGMT_SCREEN_PERM

b64_trans = string.maketrans('+/', '-.')
b64_untrans = string.maketrans('-.', '+/')

badidnamecharsin = re.compile('[\?&;,<> ]').search
badcookiecharsin = re.compile('[;,<>& ]').search
twodotsin = re.compile('(\w*\.){2,}').search

_marker = []

constructBrowserIdManagerForm = DTMLFile('dtml/addIdManager', globals())

BROWSERID_MANAGER_NAME = 'browser_id_manager'  # imported by SessionDataManager
ALLOWED_BID_NAMESPACES = ('form', 'cookies', 'url')
ADD_BROWSER_ID_MANAGER_PERM = "Add Browser Id Manager"
TRAVERSAL_APPHANDLE = 'BrowserIdManager'

LOG = logging.getLogger('Zope.BrowserIdManager')

# Use the system PRNG if possible
import random
try:
    random = random.SystemRandom()
    using_sysrandom = True
except NotImplementedError:
    using_sysrandom = False
        self.unindex_objectKeywords(documentId, keywords)
        try:
            del self._unindex[documentId]
        except KeyError:
            LOG.debug('%s: Attempt to unindex nonexistent '
                      'document with id %s' %
                      (self.__class__.__name__, documentId),
                      exc_info=True)

    manage = manage_main = DTMLFile('dtml/manageKeywordIndex', globals())
    manage_main._setName('manage_main')
    manage_browse = DTMLFile('../dtml/browseIndex', globals())


manage_addKeywordIndexForm = DTMLFile('dtml/addKeywordIndex', globals())


def manage_addKeywordIndex(self,
                           id,
                           extra=None,
                           REQUEST=None,
                           RESPONSE=None,
                           URL3=None):
    """Add a keyword index"""
    return self.manage_addIndex(id,
                                'KeywordIndex',
                                extra=extra,
                                REQUEST=REQUEST,
                                RESPONSE=RESPONSE,
                                URL1=URL3)
class DavLockManager(Item, Implicit):
    id = 'DavLockManager'
    name = title = 'WebDAV Lock Manager'
    meta_type = 'WebDAV Lock Manager'
    zmi_icon = 'fa fa-lock'

    security = ClassSecurityInfo()

    security.declareProtected(
        webdav_manage_locks,  # NOQA: D001
        'manage_davlocks')
    manage_davlocks = manage_main = manage = manage_workspace = DTMLFile(
        'dtml/davLockManager', globals())
    manage_davlocks._setName('manage_davlocks')
    manage_options = (
        {
            'label': 'Control Panel',
            'action': '../manage_main'
        },
        {
            'label': 'Databases',
            'action': '../Database/manage_main'
        },
        {
            'label': 'Configuration',
            'action': '../Configuration/manage_main'
        },
        {
            'label': 'DAV Locks',
            'action': 'manage_main'
        },
        {
            'label': 'Debug Information',
            'action': '../DebugInfo/manage_main'
        },
    )

    @security.protected(webdav_manage_locks)
    def findLockedObjects(self, frompath=''):
        app = self.getPhysicalRoot()

        if frompath:
            if frompath[0] == '/':
                frompath = frompath[1:]
            # since the above will turn '/' into an empty string, check
            # for truth before chopping a final slash
            if frompath and frompath[-1] == '/':
                frompath = frompath[:-1]

        # Now we traverse to the node specified in the 'frompath' if
        # the user chose to filter the search, and run a ZopeFind with
        # the expression 'wl_isLocked()' to find locked objects.
        obj = app.unrestrictedTraverse(frompath)
        lockedobjs = self._findapply(obj, path=frompath)

        return lockedobjs

    @security.private
    def unlockObjects(self, paths=[]):
        app = self.getPhysicalRoot()

        for path in paths:
            ob = app.unrestrictedTraverse(path)
            ob.wl_clearLocks()

    @security.protected(webdav_manage_locks)
    def manage_unlockObjects(self, paths=[], REQUEST=None):
        " Management screen action to unlock objects. "
        if paths:
            self.unlockObjects(paths)
        if REQUEST is not None:
            m = '%s objects unlocked.' % len(paths)
            return self.manage_davlocks(self, REQUEST, manage_tabs_message=m)

    def _findapply(self, obj, result=None, path=''):
        # recursive function to actually dig through and find the locked
        # objects.

        if result is None:
            result = []
        base = aq_base(obj)
        if not hasattr(base, 'objectItems'):
            return result
        try:
            items = obj.objectItems()
        except Exception:
            return result

        addresult = result.append
        for id, ob in items:
            if path:
                p = f'{path}/{id}'
            else:
                p = id

            dflag = hasattr(ob, '_p_changed') and (ob._p_changed is None)
            bs = aq_base(ob)
            if wl_isLocked(ob):
                li = []
                addlockinfo = li.append
                for token, lock in ob.wl_lockItems():
                    addlockinfo({
                        'owner': lock.getCreatorPath(),
                        'token': token
                    })
                addresult((p, li))
                dflag = 0
            if hasattr(bs, 'objectItems'):
                self._findapply(ob, result, p)
            if dflag:
                ob._p_deactivate()

        return result
class KeywordIndex(UnIndex):
    """Like an UnIndex only it indexes sequences of items.

    Searches match any keyword.

    This should have an _apply_index that returns a relevance score
    """
    meta_type = "KeywordIndex"
    query_options = ('query', 'range', 'not', 'operator')

    manage_options = (
        {
            'label': 'Settings',
            'action': 'manage_main'
        },
        {
            'label': 'Browse',
            'action': 'manage_browse'
        },
    )

    def _index_object(self, documentId, obj, threshold=None, attr=''):
        """ index an object 'obj' with integer id 'i'

        Ideally, we've been passed a sequence of some sort that we
        can iterate over. If however, we haven't, we should do something
        useful with the results. In the case of a string, this means
        indexing the entire string as a keyword."""

        # First we need to see if there's anything interesting to look at
        # self.id is the name of the index, which is also the name of the
        # attribute we're interested in.  If the attribute is callable,
        # we'll do so.

        newKeywords = self._get_object_keywords(obj, attr)

        oldKeywords = self._unindex.get(documentId, None)

        if oldKeywords is None:
            # we've got a new document, let's not futz around.
            try:
                for kw in newKeywords:
                    self.insertForwardIndexEntry(kw, documentId)
                if newKeywords:
                    self._unindex[documentId] = list(newKeywords)
            except TypeError:
                return 0
        else:
            # we have an existing entry for this document, and we need
            # to figure out if any of the keywords have actually changed
            if type(oldKeywords) is not OOSet:
                oldKeywords = OOSet(oldKeywords)
            newKeywords = OOSet(newKeywords)
            fdiff = difference(oldKeywords, newKeywords)
            rdiff = difference(newKeywords, oldKeywords)
            if fdiff or rdiff:
                # if we've got forward or reverse changes
                if newKeywords:
                    self._unindex[documentId] = list(newKeywords)
                else:
                    del self._unindex[documentId]
                if fdiff:
                    self.unindex_objectKeywords(documentId, fdiff)
                if rdiff:
                    for kw in rdiff:
                        self.insertForwardIndexEntry(kw, documentId)
        return 1

    def _get_object_keywords(self, obj, attr):
        newKeywords = getattr(obj, attr, ())
        if safe_callable(newKeywords):
            try:
                newKeywords = newKeywords()
            except (AttributeError, TypeError):
                return ()
        if not newKeywords:
            return ()
        elif isinstance(newKeywords, basestring):
            return (newKeywords, )
        else:
            try:
                # unique
                newKeywords = set(newKeywords)
            except TypeError:
                # Not a sequence
                return (newKeywords, )
            else:
                return tuple(newKeywords)

    def unindex_objectKeywords(self, documentId, keywords):
        """ carefully unindex the object with integer id 'documentId'"""

        if keywords is not None:
            for kw in keywords:
                self.removeForwardIndexEntry(kw, documentId)

    def unindex_object(self, documentId):
        """ carefully unindex the object with integer id 'documentId'"""

        keywords = self._unindex.get(documentId, None)

        # Couldn't we return 'None' immediately
        # if keywords is 'None' (or _marker)???

        if keywords is not None:
            self._increment_counter()

        self.unindex_objectKeywords(documentId, keywords)
        try:
            del self._unindex[documentId]
        except KeyError:
            LOG.debug('%s: Attempt to unindex nonexistent '
                      'document with id %s' %
                      (self.__class__.__name__, documentId),
                      exc_info=True)

    manage = manage_main = DTMLFile('dtml/manageKeywordIndex', globals())
    manage_main._setName('manage_main')
    manage_browse = DTMLFile('../dtml/browseIndex', globals())
Example #23
0
<!DOCTYPE html>
<html>
  <head>
    <title><dtml-var title_or_id></title>
    <meta charset="utf-8" />
  </head>
  <body>
    <h2><dtml-var title_or_id> <dtml-var document_title></h2>
    <p>
    This is the <dtml-var document_id> Document
    in the <dtml-var title_and_id> Folder.
    </p>
  </body>
</html>"""

addForm = DTMLFile('dtml/methodAdd', globals())


def addDTMLMethod(self, id, title='', file='', REQUEST=None, submit=None):
    """Add a DTML Method object with the contents of file. If
    'file' is empty, default document text is used.
    """
    data = safe_file_data(file)
    if not data:
        data = default_dm_html
    id = str(id)
    title = str(title)
    ob = DTMLMethod(data, __name__=id)
    ob.title = title
    id = self._setObject(id, ob)
    if REQUEST is not None:
Example #24
0
from App.special_dtml import DTMLFile
from Persistence import Persistent, PersistentMapping
from Acquisition import aq_base
from BTrees.OOBTree import OOBTree
from BTrees.Length import Length
from ZODB.POSException import ConflictError
from OFS.ObjectManager import BadRequestException, BeforeDeleteException
from OFS.Folder import Folder
from AccessControl import getSecurityManager, ClassSecurityInfo
from AccessControl.Permissions import access_contents_information, \
     view_management_screens
from zLOG import LOG, ERROR
from AccessControl.SimpleObjectPolicies import ContainerAssertions


manage_addHBTreeFolder2Form = DTMLFile('folderAdd', globals())

def manage_addHBTreeFolder2(dispatcher, id, title='', REQUEST=None):
    """Adds a new HBTreeFolder object with id *id*.
    """
    id = str(id)
    ob = HBTreeFolder2(id)
    ob.title = str(title)
    dispatcher._setObject(id, ob)
    ob = dispatcher._getOb(id)
    if REQUEST is not None:
        return dispatcher.manage_main(dispatcher, REQUEST, update_menu=1)


listtext0 = '''<select name="ids:list" multiple="multiple" size="%s">
'''
Example #25
0
        'title': self.meta_type
    }, )
    if self.haveProxyRole():
        icons = ({
            'path': 'p_/PythonScript_ProxyRole_icon',
            'alt': 'Proxy Roled Python Script',
            'title': 'This script has proxy role.'
        }, )
    return icons


pyscript_proxyrole = ImageFile('pyscript_proxyrole.gif', globals())

#
# Add proxy role icon in ZMI
#
PythonScript.haveProxyRole = haveProxyRole
PythonScript.om_icons = om_icons
p_.PythonScript_ProxyRole_icon = pyscript_proxyrole

# Patch for displaying textearea in full window instead of
# remembering a quantity of lines to display in a cookie
manage_editForm = DTMLFile("pyScriptEdit", _dtmldir)
manage_editForm._setName('manage_editForm')
PythonScript.ZPythonScriptHTML_editForm = manage_editForm
PythonScript.manage_editForm = manage_editForm
PythonScript.manage = manage_editForm
PythonScript.manage_main = manage_editForm
PythonScript.manage_editDocument = manage_editForm
PythonScript.manage_editForm = manage_editForm
Example #26
0
class HBTreeFolder2Base (Persistent):
    """Base for BTree-based folders.

    BUG: Due to wrong design, we can't store 2 objects <A> and <A>-<B>
         where <A> does not contain '-'. We detect conflicts at the
         root level using 'type(ob) is OOBTree'
    """

    security = ClassSecurityInfo()

    manage_options=(
        ({'label':'Contents', 'action':'manage_main',},
         ) + Folder.manage_options[1:]
        )

    security.declareProtected(view_management_screens,
                              'manage_main')
    manage_main = DTMLFile('contents', globals())

    _htree = None      # OOBTree: { id -> object }
    _count = None     # A BTrees.Length
    _v_nextid = 0     # The integer component of the next generated ID
    title = ''


    def __init__(self, id=None):
        if id is not None:
            self.id = id
        self._initBTrees()

    def _initBTrees(self):
        self._htree = OOBTree()
        self._count = Length()

    def _populateFromFolder(self, source):
        """Fill this folder with the contents of another folder.
        """
        for name, value in source.objectItems():
            self._setOb(name, aq_base(value))

    security.declareProtected(view_management_screens, 'manage_fixCount')
    def manage_fixCount(self, dry_run=0):
        """Calls self._fixCount() and reports the result as text.
        """
        old, new = self._fixCount(dry_run)
        path = '/'.join(self.getPhysicalPath())
        if old == new:
            return "No count mismatch detected in HBTreeFolder2 at %s." % path
        else:
            return ("Fixed count mismatch in HBTreeFolder2 at %s. "
                    "Count was %d; corrected to %d" % (path, old, new))


    def _fixCount(self, dry_run=0):
        """Checks if the value of self._count disagrees with the content of
        the htree. If so, corrects self._count. Returns the old and new count
        values. If old==new, no correction was performed.
        """
        old = self._count()
        new = sum(1 for x in self._htree_iteritems())
        if old != new and not dry_run:
            self._count.set(new)
        return old, new

    def hashId(self, id):
        return id.split(H_SEPARATOR)

    def _htree_get(self, id):
        id_list = self.hashId(id)
        if len(id_list) == 1:
          ob = self._htree[id]
          if type(ob) is OOBTree:
            raise KeyError
        else:
          ob = self._htree[id_list.pop(0)]
          if type(ob) is not OOBTree:
            raise KeyError
          id_list[-1] = id
          for sub_id in id_list:
            ob = ob[sub_id]
        return ob

    def _getOb(self, id, default=_marker):
        """Return the named object from the folder
        """
        try:
          return self._htree_get(id).__of__(self)
        except KeyError:
          if default is _marker:
            raise KeyError(id)
        return default

    def __getitem__(self, id):
        try:
          return self._htree_get(id).__of__(self)
        except KeyError:
          raise KeyError(id)

    def _setOb(self, id, object):
        """Store the named object in the folder.
        """
        if type(object) is OOBTree:
          raise ValueError('HBTreeFolder2 can not store OOBTree objects')
        htree = self._htree
        for sub_id in self.hashId(id)[:-1]:
          try:
            htree = htree[sub_id]
          except KeyError:
            htree[sub_id] = htree = OOBTree()
            continue
          if type(htree) is not OOBTree:
            assert self._htree[sub_id] is htree, (htree, id)
            raise KeyError('There is already an item whose id is %r' % sub_id)
        if htree.has_key(id):
          raise KeyError('There is already an item named %r.' % id)
        htree[id] = object
        self._count.change(1)

    def _delOb(self, id):
        """Remove the named object from the folder.
        """
        htree = self._htree
        h = []
        for sub_id in self.hashId(id)[:-1]:
          h.append((htree, sub_id))
          htree = htree.get(sub_id)
          if type(htree) is not OOBTree:
            raise KeyError(id)
        if type(htree[id]) is OOBTree:
          raise KeyError(id)
        del htree[id]
        self._count.change(-1)
        while h and not htree:
          htree, sub_id = h.pop()
          del htree[sub_id]

    security.declareProtected(view_management_screens, 'getBatchObjectListing')
    def getBatchObjectListing(self, REQUEST=None):
        """Return a structure for a page template to show the list of objects.
        """
        if REQUEST is None:
            REQUEST = {}
        pref_rows = int(REQUEST.get('dtpref_rows', 20))
        b_start = int(REQUEST.get('b_start', 1))
        b_count = int(REQUEST.get('b_count', 1000))
        b_end = b_start + b_count - 1
        url = self.absolute_url() + '/manage_main'
        count = self.objectCount()

        if b_end < count:
            next_url = url + '?b_start=%d' % (b_start + b_count)
        else:
            b_end = count
            next_url = ''

        if b_start > 1:
            prev_url = url + '?b_start=%d' % max(b_start - b_count, 1)
        else:
            prev_url = ''

        formatted = [listtext0 % pref_rows]
        for optID in islice(self.objectIds(), b_start - 1, b_end):
            optID = escape(optID)
            formatted.append(listtext1 % (escape(optID, quote=1), optID))
        formatted.append(listtext2)
        return {'b_start': b_start, 'b_end': b_end,
                'prev_batch_url': prev_url,
                'next_batch_url': next_url,
                'formatted_list': ''.join(formatted)}


    security.declareProtected(view_management_screens,
                              'manage_object_workspace')
    def manage_object_workspace(self, ids=(), REQUEST=None):
        '''Redirects to the workspace of the first object in
        the list.'''
        if ids and REQUEST is not None:
            REQUEST.RESPONSE.redirect(
                '%s/%s/manage_workspace' % (
                self.absolute_url(), quote(ids[0])))
        else:
            return self.manage_main(self, REQUEST)


    security.declareProtected(access_contents_information,
                              'tpValues')
    def tpValues(self):
        """Ensures the items don't show up in the left pane.
        """
        return ()


    security.declareProtected(access_contents_information,
                              'objectCount')
    def objectCount(self):
        """Returns the number of items in the folder."""
        return self._count()


    security.declareProtected(access_contents_information, 'has_key')
    def has_key(self, id):
        """Indicates whether the folder has an item by ID.
        """
        try:
          self._htree_get(id)
        except KeyError:
          return 0
        return 1

    # Work around for the performance regression introduced in Zope 2.12.23.
    # Otherwise, we use superclass' __contains__ implementation, which uses
    # objectIds, which is inefficient in HBTreeFolder2 to lookup a single key.
    __contains__ = has_key

    def _htree_iteritems(self, min=None):
        # BUG: Due to bad design of HBTreeFolder2, buckets other than the root
        #      one must not contain both buckets & leafs. Otherwise, this method
        #      fails.
        h = self._htree
        recurse_stack = []
        try:
          for sub_id in self.hashId(min) if min else ('',):
            if recurse_stack:
              i.next()
              if type(h) is not OOBTree:
                break
              id += H_SEPARATOR + sub_id
              if type(h.itervalues().next()) is not OOBTree:
                sub_id = id
            else:
              id = sub_id
            i = h.iteritems(sub_id)
            recurse_stack.append(i)
            h = h[sub_id]
        except (KeyError, StopIteration):
          pass
        while recurse_stack:
          i = recurse_stack.pop()
          try:
            while 1:
              id, h = i.next()
              if type(h) is OOBTree:
                recurse_stack.append(i)
                i = h.iteritems()
              else:
                yield id, h
          except StopIteration:
            pass

    security.declareProtected(access_contents_information,
                              'getTreeIdList')
    def getTreeIdList(self, htree=None):
        """ Return list of all tree ids
        """
        r = []
        s = [(None, self._htree.iteritems())]
        while s:
          base_id, items = s.pop()
          if base_id:
            for k, v in items:
              if type(v) is not OOBTree:
                r.append(base_id)
                # As an optimization, and because _htree_iteritems does not
                # support mixed buckets except at the root, we consider that
                # this one only contains leafs.
                break
              s.append((base_id + H_SEPARATOR + k, v.iteritems()))
          else:
            for k, v in items:
              if type(v) is not OOBTree:
                r.append(base_id)
                for k, v in items:
                  if type(v) is OOBTree:
                    s.append((k, v.iteritems()))
                break
              s.append((k, v.iteritems()))
        r.sort()
        return r

    security.declareProtected(access_contents_information,
                              'objectValues')
    def objectValues(self, base_id=_marker):
        return HBTreeObjectValues(self, base_id)

    security.declareProtected(access_contents_information,
                              'objectIds')
    def objectIds(self, base_id=_marker):
        return HBTreeObjectIds(self, base_id)

    security.declareProtected(access_contents_information,
                              'objectItems')
    def objectItems(self, base_id=_marker):
        # Returns a list of (id, subobject) tuples of the current object.
        return HBTreeObjectItems(self, base_id)

    # superValues() looks for the _objects attribute, but the implementation
    # would be inefficient, so superValues() support is disabled.
    _objects = ()


    security.declareProtected(access_contents_information,
                              'objectIds_d')
    def objectIds_d(self, t=None):
        return dict.fromkeys(self.objectIds(t), 1)

    def _checkId(self, id, allow_dup=0):
        if not allow_dup and self.has_key(id):
            raise BadRequestException, ('The id "%s" is invalid--'
                                        'it is already in use.' % id)


    def _setObject(self, id, object, roles=None, user=None, set_owner=1):
        v=self._checkId(id)
        if v is not None: id=v

        # If an object by the given id already exists, remove it.
        if self.has_key(id):
            self._delObject(id)

        self._setOb(id, object)
        object = self._getOb(id)

        if set_owner:
            object.manage_fixupOwnershipAfterAdd()

            # Try to give user the local role "Owner", but only if
            # no local roles have been set on the object yet.
            if hasattr(object, '__ac_local_roles__'):
                if object.__ac_local_roles__ is None:
                    user=getSecurityManager().getUser()
                    if user is not None:
                        userid=user.getId()
                        if userid is not None:
                            object.manage_setLocalRoles(userid, ['Owner'])

        object.manage_afterAdd(object, self)
        return id


    def _delObject(self, id, dp=1):
        object = self._getOb(id)
        try:
            object.manage_beforeDelete(object, self)
        except BeforeDeleteException, ob:
            raise
        except ConflictError:
            raise
Example #27
0
class BooleanIndex(UnIndex):
    """Index for booleans

       self._index = set([documentId1, documentId2])
       self._unindex = {documentId:[True/False]}

       False doesn't have actual entries in _index.
    """

    meta_type = "BooleanIndex"

    manage_options = (
        {
            'label': 'Settings',
            'action': 'manage_main'
        },
        {
            'label': 'Browse',
            'action': 'manage_browse'
        },
    )

    query_options = ["query"]

    manage = manage_main = DTMLFile('dtml/manageBooleanIndex', globals())
    manage_main._setName('manage_main')
    manage_browse = DTMLFile('../dtml/browseIndex', globals())

    def clear(self):
        self._length = BTrees.Length.Length()
        self._index = IITreeSet()
        self._unindex = IIBTree()

    def insertForwardIndexEntry(self, entry, documentId):
        """If True, insert directly into treeset
        """
        if entry:
            self._index.insert(documentId)
            self._length.change(1)

    def removeForwardIndexEntry(self, entry, documentId):
        """Take the entry provided and remove any reference to documentId
        in its entry in the index.
        """
        try:
            if entry:
                self._index.remove(documentId)
                self._length.change(-1)
        except ConflictError:
            raise
        except Exception:
            LOG.exception(
                '%s: unindex_object could not remove '
                'documentId %s from index %s. This '
                'should not happen.' %
                (self.__class__.__name__, str(documentId), str(self.id)))

    def _index_object(self, documentId, obj, threshold=None, attr=''):
        """ index and object 'obj' with integer id 'documentId'"""
        returnStatus = 0

        # First we need to see if there's anything interesting to look at
        datum = self._get_object_datum(obj, attr)

        # Make it boolean, int as an optimization
        datum = int(bool(datum))

        # We don't want to do anything that we don't have to here, so we'll
        # check to see if the new and existing information is the same.
        oldDatum = self._unindex.get(documentId, _marker)
        if datum != oldDatum:
            if oldDatum is not _marker:
                self.removeForwardIndexEntry(oldDatum, documentId)
                if datum is _marker:
                    try:
                        del self._unindex[documentId]
                    except ConflictError:
                        raise
                    except Exception:
                        LOG.error('Should not happen: oldDatum was there, now '
                                  'its not, for document with id %s' %
                                  documentId)

            if datum is not _marker:
                if datum:
                    self.insertForwardIndexEntry(datum, documentId)
                self._unindex[documentId] = datum

            returnStatus = 1

        return returnStatus

    def _apply_index(self, request, resultset=None):
        record = parseIndexRequest(request, self.id, self.query_options)
        if record.keys is None:
            return None

        index = self._index

        for key in record.keys:
            if key:
                # If True, check index
                return (intersection(index, resultset), (self.id, ))
            else:
                # Otherwise, remove from resultset or _unindex
                if resultset is None:
                    return (union(difference(self._unindex, index),
                                  IISet([])), (self.id, ))
                else:
                    return (difference(resultset, index), (self.id, ))
        return (IISet(), (self.id, ))

    def indexSize(self):
        """Return distinct values, as an optimization we always claim 2."""
        return 2

    def items(self):
        items = []
        for v, k in self._unindex.items():
            if isinstance(v, int):
                v = IISet((v, ))
            items.append((k, v))
        return items
Example #28
0
class RegistrationTool(UniqueObject, SimpleItem):
    """ Create and modify users by making calls to portal_membership.
    """

    id = 'portal_registration'
    meta_type = 'CMF Registration Tool'
    member_id_pattern = ''
    default_member_id_pattern = "^[A-Za-z][A-Za-z0-9_]*$"
    _ALLOWED_MEMBER_ID_PATTERN = re.compile(default_member_id_pattern)

    security = ClassSecurityInfo()

    manage_options = (({
        'label': 'Overview',
        'action': 'manage_overview'
    }, {
        'label': 'Configure',
        'action': 'manage_configuration'
    }) + SimpleItem.manage_options)

    #
    #   ZMI methods
    #
    security.declareProtected(ManagePortal, 'manage_overview')
    manage_overview = DTMLFile('explainRegistrationTool', _dtmldir)

    security.declareProtected(ManagePortal, 'manage_configuration')
    manage_configuration = DTMLFile('configureRegistrationTool', _dtmldir)

    @security.protected(ManagePortal)
    def manage_editIDPattern(self, pattern, REQUEST=None):
        """Edit the allowable member ID pattern TTW"""
        pattern.strip()

        if len(pattern) > 0:
            self.member_id_pattern = pattern
            self._ALLOWED_MEMBER_ID_PATTERN = re.compile(pattern)
        else:
            self.member_id_pattern = ''
            self._ALLOWED_MEMBER_ID_PATTERN = re.compile(
                self.default_member_id_pattern)

        if REQUEST is not None:
            msg = 'Member ID Pattern changed'
            return self.manage_configuration(manage_tabs_message=msg)

    @security.protected(ManagePortal)
    def getIDPattern(self):
        """ Return the currently-used member ID pattern """
        return self.member_id_pattern

    @security.protected(ManagePortal)
    def getDefaultIDPattern(self):
        """ Return the currently-used member ID pattern """
        return self.default_member_id_pattern

    #
    #   'portal_registration' interface methods
    #
    @security.public
    def isRegistrationAllowed(self, REQUEST):
        '''Returns a boolean value indicating whether the user
        is allowed to add a member to the portal.
        '''
        return _checkPermission(AddPortalMember, self.aq_inner.aq_parent)

    @security.public
    def testPasswordValidity(self, password, confirm=None):
        '''If the password is valid, returns None.  If not, returns
        a string explaining why.
        '''
        return None

    @security.public
    def testPropertiesValidity(self, new_properties, member=None):
        '''If the properties are valid, returns None.  If not, returns
        a string explaining why.
        '''
        return None

    @security.public
    def generatePassword(self):
        """ Generate a valid password.
        """
        # we don't use these to avoid typos: OQ0Il1
        chars = 'ABCDEFGHJKLMNPRSTUVWXYZabcdefghijkmnopqrstuvwxyz23456789'
        return ''.join([choice(chars) for i in range(6)])

    @security.protected(AddPortalMember)
    def addMember(self,
                  id,
                  password,
                  roles=('Member', ),
                  domains='',
                  properties=None,
                  REQUEST=None):
        # XXX Do not make this a normal method comment. Doing so makes
        # this method publishable

        # Creates a PortalMember and returns it. The properties argument
        # can be a mapping with additional member properties. Raises an
        # exception if the given id already exists, the password does not
        # comply with the policy in effect, or the authenticated user is not
        # allowed to grant one of the roles listed (where Member is a special
        # role that can always be granted); these conditions should be
        # detected before the fact so that a cleaner message can be printed.

        if not self.isMemberIdAllowed(id):
            raise ValueError(
                _(u'The login name you selected is already in '
                  u'use or is not valid. Please choose another.'))

        failMessage = self.testPasswordValidity(password)
        if failMessage is not None:
            raise ValueError(failMessage)

        if properties is not None:
            failMessage = self.testPropertiesValidity(properties)
            if failMessage is not None:
                raise ValueError(failMessage)

        # Limit the granted roles.
        # Anyone is always allowed to grant the 'Member' role.
        _limitGrantedRoles(roles, self, ('Member', ))

        mtool = getUtility(IMembershipTool)
        mtool.addMember(id, password, roles, domains, properties)

        member = mtool.getMemberById(id)
        self.afterAdd(member, id, password, properties)
        return member

    @security.protected(AddPortalMember)
    def isMemberIdAllowed(self, id):
        '''Returns 1 if the ID is not in use and is not reserved.
        '''
        if len(id) < 1 or id == 'Anonymous User':
            return 0
        if not self._ALLOWED_MEMBER_ID_PATTERN.match(id):
            return 0
        mtool = getUtility(IMembershipTool)
        if mtool.getMemberById(id) is not None:
            return 0
        return 1

    @security.public
    def afterAdd(self, member, id, password, properties):
        '''Called by portal_registration.addMember()
        after a member has been added successfully.'''
        pass

    @security.protected(MailForgottenPassword)
    def mailPassword(self, forgotten_userid, REQUEST):
        '''Email a forgotten password to a member.  Raises an exception
        if user ID is not found.
        '''
        raise NotImplementedError
class DirectoryViewSurrogate(Folder):
    """ Folderish DirectoryView.
    """

    meta_type = 'Filesystem Directory View'
    zmi_icon = 'far fa-folder-open'
    all_meta_types = ()

    security = ClassSecurityInfo()

    def __init__(self, real, data, objects):
        d = self.__dict__
        d.update(data)
        d.update(real.__dict__)
        d['_real'] = real
        d['_objects'] = objects

    def __setattr__(self, name, value):
        d = self.__dict__
        d[name] = value
        setattr(d['_real'], name, value)

    def __delattr__(self, name):
        d = self.__dict__
        del d[name]
        delattr(d['_real'], name)

    security.declareProtected(ManagePortal, 'manage_propertiesForm')
    manage_propertiesForm = DTMLFile('dirview_properties', _dtmldir)

    @security.protected(ManagePortal)
    def manage_properties(self, reg_key, REQUEST=None):
        """ Update the directory path of the DirectoryView.
        """
        self.__dict__['_real']._dirpath = reg_key
        if REQUEST is not None:
            REQUEST['RESPONSE'].redirect('%s/manage_propertiesForm' %
                                         self.absolute_url())

    @security.protected(ACI)
    def getCustomizableObject(self):
        ob = aq_parent(aq_inner(self))
        while ob:
            if IDirectoryView.providedBy(ob):
                ob = aq_parent(ob)
            else:
                break
        return ob

    @security.protected(ACI)
    def listCustFolderPaths(self, adding_meta_type=None):
        """ List possible customization folders as key, value pairs.
        """
        rval = []
        ob = self.getCustomizableObject()
        listFolderHierarchy(ob, '', rval, adding_meta_type)
        rval.sort()
        return rval

    @security.protected(ACI)
    def getDirPath(self):
        return self.__dict__['_real']._dirpath

    @security.public
    def getId(self):
        return self.id
Example #30
0
class SkinsTool(UniqueObject, SkinsContainer, Folder, ActionProviderBase):
    """ This tool is used to supply skins to a portal.
    """

    id = 'portal_skins'
    meta_type = 'CMF Skins Tool'
    allow_any = 0
    cookie_persistence = 0
    default_skin = ''
    request_varname = 'portal_skin'
    selections = None

    security = ClassSecurityInfo()

    manage_options = (modifiedOptions() + ({
        'label': 'Overview',
        'action': 'manage_overview'
    }, ) + ActionProviderBase.manage_options)

    def __init__(self):
        self.selections = PersistentMapping()

    def _getSelections(self):
        sels = self.selections
        if sels is None:
            # Backward compatibility.
            self.selections = sels = PersistentMapping()
        return sels

    #
    #   ZMI methods
    #
    security.declareProtected(ManagePortal, 'manage_overview')
    manage_overview = DTMLFile('explainSkinsTool', _dtmldir)

    security.declareProtected(ManagePortal, 'manage_propertiesForm')
    manage_propertiesForm = DTMLFile('dtml/skinProps', globals())

    # the following two methods override those in FindSupport, to
    # support marking of objects used in specific skins
    security.declareProtected(ManagePortal, 'manage_findResult')
    manage_findResult = DTMLFile('findResult',
                                 _dtmldir,
                                 management_view='Find')

    security.declareProtected(ManagePortal, 'manage_findForm')
    manage_findForm = DTMLFile('findForm', _dtmldir, management_view='Find')

    security.declareProtected(ManagePortal, 'manage_compareResults')
    manage_compareResults = DTMLFile('compareResults',
                                     _dtmldir,
                                     management_view='Compare')

    @security.protected(ManagePortal)
    def manage_skinLayers(self,
                          chosen=(),
                          add_skin=0,
                          del_skin=0,
                          skinname='',
                          skinpath='',
                          REQUEST=None):
        """ Change the skinLayers.
        """
        sels = self._getSelections()
        if del_skin:
            for name in chosen:
                del sels[name]

        if REQUEST is not None:
            for key in sels.keys():
                fname = 'skinpath_%s' % key
                val = REQUEST[fname]

                # if val is a list from the new lines field
                # then munge it back into a comma delimited list
                # for hysterical reasons
                if isinstance(val, list):
                    val = ','.join([layer.strip() for layer in val])

                if sels[key] != val:
                    self.testSkinPath(val)
                    sels[key] = val

        if add_skin:
            skinpath = ','.join([layer.strip() for layer in skinpath])
            self.testSkinPath(skinpath)
            sels[str(skinname)] = skinpath

        if REQUEST is not None:
            return self.manage_propertiesForm(
                self,
                REQUEST,
                management_view='Properties',
                manage_tabs_message='Skins changed.')

    @security.protected(ManagePortal)
    def isFirstInSkin(self, template_path, skin=None):
        """
        Is the specified template the one that would get returned from the current
        skin?
        """
        if skin is None or skin == 'None':
            skin = self.getDefaultSkin()
        template = self.restrictedTraverse(template_path)
        name = template.getId()
        skin_path = self.getSkinPath(skin)
        if not skin_path:
            return 0
        parts = list(skin_path.split(","))
        found = ""
        for part in parts:
            part = part.strip()
            if part[0] == "_":
                continue
            partob = getattr(self, part, None)
            if partob:
                skin_template = getattr(partob.aq_base, name, None)
                if skin_template:
                    found = skin_template
                    break
        if found == template:
            return 1
        else:
            return 0

    @security.protected(ManagePortal)
    def manage_properties(self,
                          default_skin='',
                          request_varname='',
                          allow_any=0,
                          chosen=(),
                          add_skin=0,
                          del_skin=0,
                          skinname='',
                          skinpath='',
                          cookie_persistence=0,
                          REQUEST=None):
        """ Changes portal_skin properties. """
        self.default_skin = str(default_skin)
        self.request_varname = str(request_varname)
        self.allow_any = allow_any and 1 or 0
        self.cookie_persistence = cookie_persistence and 1 or 0
        if REQUEST is not None:
            return self.manage_propertiesForm(
                self,
                REQUEST,
                management_view='Properties',
                manage_tabs_message='Properties changed.')

    @security.private
    def PUT_factory(self, name, typ, body):
        """
            Dispatcher for PUT requests to non-existent IDs.  Returns
            an object of the appropriate type (or None, if we don't
            know what to do).
        """
        major, minor = typ.split('/', 1)

        if major == 'image':
            return Image(id=name, title='', file='', content_type=typ)

        if major == 'text':

            if minor == 'x-python':
                return PythonScript(id=name)

            if minor in ('html', 'xml'):
                return ZopePageTemplate(name)

            return DTMLMethod(__name__=name)

        return None

    # Make the PUT_factory replaceable
    PUT_factory__replaceable__ = REPLACEABLE

    @security.private
    def testSkinPath(self, p):
        """ Calls SkinsContainer.getSkinByPath().
        """
        self.getSkinByPath(p, raise_exc=1)

    #
    #   'SkinsContainer' interface methods
    #
    @security.protected(AccessContentsInformation)
    def getSkinPath(self, name):
        """ Convert a skin name to a skin path.
        """
        sels = self._getSelections()
        p = sels.get(name, None)
        if p is None:
            if self.allow_any:
                return name
        return p  # Can be None

    @security.protected(AccessContentsInformation)
    def getDefaultSkin(self):
        """ Get the default skin name.
        """
        return self.default_skin

    @security.protected(AccessContentsInformation)
    def getRequestVarname(self):
        """ Get the variable name to look for in the REQUEST.
        """
        return self.request_varname

    #
    #   UI methods
    #
    @security.protected(AccessContentsInformation)
    def getAllowAny(self):
        '''
        Used by the management UI.  Returns a flag indicating whether
        users are allowed to use arbitrary skin paths.
        '''
        return self.allow_any

    @security.protected(AccessContentsInformation)
    def getCookiePersistence(self):
        '''
        Used by the management UI.  Returns a flag indicating whether
        the skins cookie is persistent or not.
        '''
        return self.cookie_persistence

    @security.protected(AccessContentsInformation)
    def getSkinPaths(self):
        '''
        Used by the management UI.  Returns the list of skin name to
        skin path mappings as a sorted list of tuples.
        '''
        sels = self._getSelections()
        rval = []
        for key, value in sels.items():
            rval.append((key, value))
        rval.sort()
        return rval

    #
    #   'portal_skins' interface methods
    #
    @security.public
    def getSkinSelections(self):
        """ Get the sorted list of available skin names.
        """
        sels = self._getSelections()
        rval = list(sels.keys())
        rval.sort()
        return rval

    @security.protected(View)
    def updateSkinCookie(self):
        """ If needed, updates the skin cookie based on the member preference.
        """
        mtool = getUtility(IMembershipTool)
        member = mtool.getAuthenticatedMember()
        if hasattr(aq_base(member), 'getProperty'):
            mskin = member.getProperty('portal_skin')
            if mskin:
                req = getRequest()
                cookie = req.cookies.get(self.request_varname, None)
                if cookie != mskin:
                    resp = req.RESPONSE
                    utool = getUtility(IURLTool)
                    portal_path = req['BASEPATH1'] + '/' + utool(1)

                    if not self.cookie_persistence:
                        # *Don't* make the cookie persistent!
                        resp.setCookie(self.request_varname,
                                       mskin,
                                       path=portal_path)
                    else:
                        expires = (DateTime('GMT') + 365).rfc822()
                        resp.setCookie(self.request_varname,
                                       mskin,
                                       path=portal_path,
                                       expires=expires)
                    # Ensure updateSkinCookie() doesn't try again
                    # within this request.
                    req.cookies[self.request_varname] = mskin
                    req[self.request_varname] = mskin
                    return 1
        return 0

    @security.protected(View)
    def clearSkinCookie(self):
        """ Expire the skin cookie.
        """
        req = getRequest()
        resp = req.RESPONSE
        utool = getUtility(IURLTool)
        portal_path = req['BASEPATH1'] + '/' + utool(1)
        resp.expireCookie(self.request_varname, path=portal_path)

    @security.protected(ManagePortal)
    def addSkinSelection(self, skinname, skinpath, test=0, make_default=0):
        '''
        Adds a skin selection.
        '''
        sels = self._getSelections()
        skinpath = str(skinpath)

        # Basic precaution to make sure the stuff we want to ignore in
        # DirectoryViews gets prevented from ending up in a skin path
        path_elems = [x.strip() for x in skinpath.split(',')]
        ignored = base_ignore + ignore

        for elem in path_elems[:]:
            if elem in ignored or ignore_re.match(elem):
                path_elems.remove(elem)

        skinpath = ','.join(path_elems)

        if test:
            self.testSkinPath(skinpath)
        sels[str(skinname)] = skinpath
        if make_default:
            self.default_skin = skinname

    @security.protected(AccessContentsInformation)
    def getDiff(self, item_one_path, item_two_path, reverse=0):
        """ Return a diff between one and two.
        """
        if not reverse:
            item_one = self.unrestrictedTraverse(item_one_path)
            item_two = self.unrestrictedTraverse(item_two_path)
        else:
            item_one = self.unrestrictedTraverse(item_two_path)
            item_two = self.unrestrictedTraverse(item_one_path)

        res = unified_diff(item_one.read().splitlines(),
                           item_two.read().splitlines(),
                           item_one_path,
                           item_two_path,
                           '',
                           '',
                           lineterm="")
        return res
Example #31
0
 def __init__(self, name, _prefix=None, **kw):
     DTMLFile.__init__(self, name, _prefix, **kw)
     DomainAware.__init__(self, _prefix)
Example #32
0
                ids = folder.objectIds()
            for idx, id in enumerate(ids):
                rid = rids.get(id)
                if rid:
                    pos[rid] = idx
            return pos
        else:
            # otherwise the entire map needs to be constructed...
            for rid, container, id in items:
                if getattr(aq_base(container), 'getObjectPosition', None):
                    pos[rid] = container.getObjectPosition(id)
                else:
                    # fallback for unordered folders
                    pos[rid] = 0
            return pos


manage_addGopipForm = DTMLFile('dtml/addGopipIndex', globals())


def manage_addGopipIndex(self, identifier, REQUEST=None, RESPONSE=None,
    URL3=None):
    """ add a fake gopip index """
    return self.manage_addIndex(
        identifier,
        'GopipIndex',
        REQUEST=REQUEST,
        RESPONSE=RESPONSE,
        URL1=URL3
    )
Example #33
0
 def _exec(self, bound_data, args, kw):
     request = getRequest()
     if request is not None:
         request.response.setHeader('X-Theme-Disabled', '1')
     return DTMLFile._exec(self, bound_data, args, kw)
Example #34
0
class MethodDoc(Persistent):
    """ Describes a method of an API.

    required - a sequence of required arguments
    optional - a sequence of tuples (name, default value)
    varargs - the name of the variable argument or None
    kwargs - the name of the kw argument or None
    """

    security = ClassSecurityInfo()
    security.setDefaultAccess({
        'doc': True,
        'kwargs': True,
        'name': True,
        'optional': True,
        'required': True,
        'varargs': True
    })

    varargs = None
    kwargs = None

    def __init__(self, func, isInterface=0):
        if isInterface:
            self._createFromInterfaceMethod(func)
        else:
            self._createFromFunc(func)

    def _createFromInterfaceMethod(self, func):
        self.name = func.__name__
        self.doc = trim_doc_string(func.__doc__)
        self.required = func.required
        opt = []
        for p in func.positional[len(func.required):]:
            opt.append((p, func.optional[p]))
        self.optional = tuple(opt)
        if func.varargs:
            self.varargs = func.varargs
        if func.kwargs:
            self.kwargs = func.kwargs

    def _createFromFunc(self, func):
        if hasattr(func, 'im_func'):
            func = func.im_func

        self.name = func.__name__
        self.doc = trim_doc_string(func.__doc__)

        # figure out the method arguments
        # mostly stolen from pythondoc
        CO_VARARGS = 4
        CO_VARKEYWORDS = 8
        names = func.func_code.co_varnames
        nrargs = func.func_code.co_argcount
        if func.func_defaults:
            nrdefaults = len(func.func_defaults)
        else:
            nrdefaults = 0
        self.required = names[:nrargs - nrdefaults]
        if func.func_defaults:
            self.optional = tuple(
                map(None, names[nrargs - nrdefaults:nrargs],
                    func.func_defaults))
        else:
            self.optional = ()
        varargs = []
        ix = nrargs
        if func.func_code.co_flags & CO_VARARGS:
            self.varargs = names[ix]
            ix = ix + 1
        if func.func_code.co_flags & CO_VARKEYWORDS:
            self.kwargs = names[ix]

    view = DTMLFile('dtml/methodView', globals())
Example #35
0
class APIDoc(Persistent):
    """ Describes an API.
    """

    security = ClassSecurityInfo()
    security.setDefaultAccess({
        'attributes': True,
        'constructor': True,
        'doc': True,
        'extends': True,
        'name': True,
        'methods': True
    })

    extends = ()

    def __init__(self, klass, isInterface=0):
        if isInterface:
            self._createFromInterface(klass)
        else:
            self._createFromClass(klass)

    def _createFromInterface(self, klass):
        # Creates an APIDoc instance given an interface object.
        self.name = klass.__name__
        self.doc = trim_doc_string(klass.__doc__)

        # inheritence information
        self.extends = []

        # Get info on methods and attributes, ignore special items
        self.attributes = []
        self.methods = []
        for k, v in klass.namesAndDescriptions():
            if hasattr(v, 'getSignatureInfo'):
                self.methods.append(MethodDoc(v, 1))
            else:
                self.attributes.append(AttributeDoc(k, v.__doc__))

    def _createFromClass(self, klass):
        # Creates an APIDoc instance given a python class.
        # the class describes the API; it contains
        # methods, arguments and doc strings.
        #
        # The name of the API is deduced from the name
        # of the class.

        self.name = klass.__name__
        self.doc = trim_doc_string(klass.__doc__)

        # Get info on methods and attributes, ignore special items
        self.attributes = []
        self.methods = []
        for k, v in klass.__dict__.items():
            if k not in ('__extends__', '__doc__', '__constructor__'):
                if type(v) == types.FunctionType:
                    self.methods.append(MethodDoc(v, 0))
                else:
                    self.attributes.append(AttributeDoc(k, v))

    def SearchableText(self):
        """
        The full text of the API, for indexing purposes.
        """
        text = "%s %s" % (self.name, self.doc)
        for attribute in self.attributes:
            text = "%s %s" % (text, attribute.name)
        for method in self.methods:
            text = "%s %s %s" % (text, method.name, method.doc)
        return text

    view = DTMLFile('dtml/APIView', globals())
Example #36
0
 def _exec(self, bound_data, args, kw):
     getRequest().response.setHeader('X-Theme-Disabled', '1')
     return DTMLFile._exec(self, bound_data, args, kw)