Beispiel #1
0
    def _importOldAction(self, old_action):
        """Convert a CMF action to an ERP5 action

      This is used to update an existing site or to import a BT.
      """
        import erp5.portal_type
        ActionInformation = getattr(erp5.portal_type, 'Action Information')
        old_action = old_action.__getstate__()
        action_type = old_action.pop('category', None)
        action = ActionInformation(self.generateNewId())
        for k, v in old_action.iteritems():
            if k in ('action', 'condition', 'icon'):
                if not v:
                    continue
                v = v.__class__(v.text)
            setattr(
                action, {
                    'id': 'reference',
                    'priority': 'float_index',
                    'permissions': 'action_permission',
                }.get(k, k), v)
        action.uid = None
        action = self[self._setObject(action.id, action, set_owner=0)]
        if action_type:
            action._setCategoryMembership('action_type', action_type)
        return action
Beispiel #2
0
def fixActionsForType(portal_type, typesTool):
    if 'actions' in portal_type.installMode:
        typeInfo = getattr(typesTool, portal_type.portal_type, None)
        if typeInfo is None:
            return
        if hasattr(portal_type, 'actions'):
            # Look for each action we define in portal_type.actions in
            # typeInfo.action replacing it if its there and just
            # adding it if not
            # rr: this is now trial-and-error programming
            # I really don't know what's going on here
            # most importantly I don't know why the default
            # actions are not set in some cases :-(
            # (maybe they are removed afterwards sometimes???)
            # if getattr(portal_type,'include_default_actions', True):
            if True:
                default = [
                    ActionInformation(**action)
                    for action in base_factory_type_information[0]['actions']
                ]
                next = list(typeInfo._actions)
                all = next + default
                new = [a.clone() for a in all]
            else:
                # If no standard actions are wished don't display them
                new = []

            for action in portal_type.actions:
                # DM: "Expression" derives from "Persistent" and
                # we must not put persistent objects into class attributes.
                # Thus, copy "action"
                action = action.copy()
                hits = [a for a in new if a.id == action['id']]

                # Change action and condition into expressions, if
                # they are still strings
                if 'action' in action and \
                        type(action['action']) in (type(''), type(u'')):
                    action['action'] = Expression(action['action'])
                if 'condition' in action and \
                        type(action['condition']) in (type(''), type(u'')):
                    action['condition'] = Expression(action['condition'])
                if 'name' in action:
                    action['title'] = action['name']
                    del action['name']
                if hits:
                    hits[0].__dict__.update(action)
                else:
                    new.append(ActionInformation(**action))

            typeInfo._actions = tuple(new)
            typeInfo._p_changed = True

        if hasattr(portal_type, 'factory_type_information'):
            typeInfo.__dict__.update(portal_type.factory_type_information)
            typeInfo._p_changed = True
Beispiel #3
0
 def test_basic_construction(self):
     ai = ActionInformation(id='view')
     self.assertEqual(ai.getId(), 'view')
     self.assertEqual(ai.Title(), 'view')
     self.assertEqual(ai.Description(), '')
     self.assertEqual(ai.getCondition(), '')
     self.assertEqual(ai.getActionExpression(), '')
     self.assertEqual(ai.getVisibility(), 1)
     self.assertEqual(ai.getCategory(), 'object')
     self.assertEqual(ai.getPermissions(), ())
Beispiel #4
0
 def test_Condition(self):
     portal = self.portal
     folder = self.folder
     object = self.object
     ai = ActionInformation(id='view',
                            title='View',
                            action=Expression(text='view'),
                            condition=Expression(text='member'),
                            category='global',
                            visible=1)
     ec = createExprContext(folder, portal, object)
     self.failIf(ai.testCondition(ec))
Beispiel #5
0
 def test_Condition(self):
     portal = self.portal 
     folder = self.folder
     object = self.object 
     ai = ActionInformation(id='view'
                          , title='View'
                          , action=Expression(
          text='view')
                          , condition=Expression(
          text='member')
                          , category='global'
                          , visible=1)
     ec = createExprContext(folder, portal, object)
     self.failIf(ai.testCondition(ec))
Beispiel #6
0
 def test_construction_with_Expressions(self):
     ai = ActionInformation(id='view',
                            title='View',
                            action=Expression(text='view'),
                            condition=Expression(text='member'),
                            category='global',
                            visible=0)
     self.assertEqual(ai.getId(), 'view')
     self.assertEqual(ai.Title(), 'View')
     self.assertEqual(ai.Description(), '')
     self.assertEqual(ai.getCondition(), 'member')
     self.assertEqual(ai.getActionExpression(), 'string:view')
     self.assertEqual(ai.getVisibility(), 0)
     self.assertEqual(ai.getCategory(), 'global')
     self.assertEqual(ai.getPermissions(), ())
    def test_create_from_ActionInformation(self):
        from Products.CMFCore.ActionInformation import ActionInformation

        WANTED = {
            'allowed': True,
            'available': True,
            'category': 'object',
            'description': '',
            'id': 'foo',
            'title': 'foo',
            'url': '',
            'visible': True,
            'icon': '',
            'link_target': None
        }

        action = ActionInformation(id='foo')
        ec = None
        ai = self._makeOne(action, ec)

        self.assertEqual(ai['id'], WANTED['id'])
        self.assertEqual(ai['title'], WANTED['title'])
        self.assertEqual(ai['description'], WANTED['description'])
        self.assertEqual(ai['url'], WANTED['url'])
        self.assertEqual(ai['icon'], WANTED['icon'])
        self.assertEqual(ai['category'], WANTED['category'])
        self.assertEqual(ai['visible'], WANTED['visible'])
        self.assertEqual(ai['available'], WANTED['available'])
        self.assertEqual(ai['allowed'], WANTED['allowed'])
        self.assertEqual(ai, WANTED)
    def test_listActionInformationActions(self):
        # Check that listFilteredActionsFor works for objects that return
        # ActionInformation objects
        tool = self.tool
        tool._actions = (
              ActionInformation(id='folderContents',
                                title='Folder contents',
                                action=Expression(text='string:'
                                             '${folder_url}/folder_contents'),
                                icon_expr=Expression(text='string:'
                                             '${folder_url}/icon.gif'),
                                condition=Expression(text='python: '
                                                      'folder is not object'),
                                permissions=('List folder contents',),
                                category='folder',
                                link_target='_top',
                                visible=1),)

        newSecurityManager(None, OmnipotentUser().__of__(self.app.acl_users))
        self.assertEqual(tool.listFilteredActionsFor(self.app.foo),
                         {'workflow': [],
                          'user': [],
                          'object': [],
                          'folder': [{'id': 'folderContents',
                                      'url': 'http://nohost/folder_contents',
                                      'icon': 'http://nohost/icon.gif',
                                      'title': 'Folder contents',
                                      'description': '',
                                      'visible': True,
                                      'available': True,
                                      'allowed': True,
                                      'category': 'folder',
                                      'link_target': '_top'}],
                          'global': []})
Beispiel #9
0
 def test_DuplicateActions(self):
     """
     Check that listFilteredActionsFor
     filters out duplicate actions.
     """
     root = self.root
     tool = self.tool
     action = ActionInformation(id='test',
                                title='Test',
                                action=Expression(text='string: a_url'),
                                condition='',
                                permissions=(),
                                category='object',
                                visible=1)
     tool._actions = [action, action]
     self.tool.action_providers = ('portal_actions', )
     self.assertEqual(
         tool.listFilteredActionsFor(root)['object'], [{
             'permissions': (),
             'id': 'test',
             'url': ' a_url',
             'name': 'Test',
             'visible': 1,
             'category': 'object'
         }])
Beispiel #10
0
def doubleCheckDefaultTypeActions(self, ftypes):
    # rr: for some reason, AT's magic wrt adding the default type actions
    # stopped working when moving to CMF-2.0
    # Instead of trying to resurect the old way (which I tried but couldn't)
    # I make it brute force here

    typesTool = getToolByName(self, 'portal_types')
    defaultTypeActions = [
        ActionInformation(**action)
        for action in base_factory_type_information[0]['actions']
    ]

    for ftype in ftypes:
        portal_type = ftype.portal_type
        fti = typesTool.get(portal_type, None)
        if fti is None:
            continue
        actions = list(fti._actions)
        action_ids = [a.id for a in actions]
        prepend = []
        for a in defaultTypeActions:
            if a.id not in action_ids:
                prepend.append(a.clone())
        if prepend:
            fti._actions = tuple(prepend + actions)
Beispiel #11
0
    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)
Beispiel #12
0
    def test_create_from_ActionInformation(self):
        from Products.CMFCore.ActionInformation import ActionInformation

        wanted = {
            'allowed': True,
            'available': True,
            'category': 'object',
            'id': 'foo',
            'name': 'foo',
            'permissions': (),
            'title': 'foo',
            'url': '',
            'visible': True
        }

        action = ActionInformation(id='foo')
        ec = None
        ai = self._makeOne(action, ec)

        self.assertEqual(ai['id'], wanted['id'])
        self.assertEqual(ai['title'], wanted['title'])
        self.assertEqual(ai['url'], wanted['url'])
        self.assertEqual(ai['permissions'], wanted['permissions'])
        self.assertEqual(ai['category'], wanted['category'])
        self.assertEqual(ai['visible'], wanted['visible'])
        self.assertEqual(ai['available'], wanted['available'])
        self.assertEqual(ai['allowed'], wanted['allowed'])
        self.assertEqual(ai, wanted)
Beispiel #13
0
 def test_listActionInformationActions(self):
     # Check that listFilteredActionsFor works for objects that return
     # ActionInformation objects
     root = self.root
     tool = self.tool
     tool._actions = (ActionInformation(
         id='folderContents',
         title='Folder contents',
         action=Expression(text='string:'
                           '${folder_url}/folder_contents'),
         icon_expr=Expression(text='string:'
                              '${folder_url}/icon.gif'),
         condition=Expression(text='python: '
                              'folder is not object'),
         permissions=('List folder contents', ),
         category='folder',
         visible=1), )
     self.assertEqual(
         tool.listFilteredActionsFor(root.foo), {
             'workflow': [],
             'user': [],
             'object': [],
             'folder': [{
                 'id': 'folderContents',
                 'url': 'http://nohost/folder_contents',
                 'icon': 'http://nohost/icon.gif',
                 'title': 'Folder contents',
                 'description': '',
                 'visible': True,
                 'available': True,
                 'allowed': True,
                 'category': 'folder'
             }],
             'global': []
         })
Beispiel #14
0
 def test_editing(self):
     ai = ActionInformation(id='view',
                            category='folder',
                           )
     ai.edit(id='new_id', title='blah')
     self.assertEqual(ai.getId(), 'new_id')
     self.assertEqual(ai.Title(), 'blah')
     self.assertEqual(ai.Description(), '')
     self.assertEqual(ai.getCondition(), '')
     self.assertEqual(ai.getActionExpression(), '')
     self.assertEqual(ai.getVisibility(), 1)
     self.assertEqual(ai.getCategory(), 'folder')
     self.assertEqual(ai.getPermissions(), ())
class DummyProvider(ActionProviderBase, DummyTool):

    _actions = (ActionInformation(id='an_id',
                                  title='A Title',
                                  action='',
                                  condition='',
                                  permissions=(),
                                  category='',
                                  visible=False), )
Beispiel #16
0
def importActionProviders( context ):

    """ Import action providers and their actions from an XML file.

    o 'context' must implement IImportContext.

    o Register via Python:

      registry = site.portal_setup.getImportStepRegistry()
      registry.registerStep( 'importActionProviders'
                           , '20040518-01'
                           , Products.CMFSetup.actions.importActionProviders
                           , ()
                           , 'Action Provider import'
                           , 'Import  action providers registered with '
                             'the actions tool, and their actions.'
                           )

    o Register via XML:

      <setup-step id="importActionProviders"
                  version="20040524-01"
                  handler="Products.CMFSetup.actions.importActionProviders"
                  title="Action Provider import"
      >Import action providers registered with the actions tool,
       and their actions.</setup-step>

    """
    site = context.getSite()
    encoding = context.getEncoding()

    actions_tool = getToolByName( site, 'portal_actions' )

    if context.shouldPurge():

        for provider_id in actions_tool.listActionProviders():
            actions_tool.deleteActionProvider( provider_id )

    text = context.readDataFile( _FILENAME )

    if text is not None:

        apc = ActionProvidersConfigurator( site ).__of__( site )
        info_list = apc.parseXML( text, encoding )

        for p_info in info_list:

            if p_info[ 'id' ] not in actions_tool.listActionProviders():

                actions_tool.addActionProvider( p_info[ 'id' ] )

            provider = getToolByName( site, p_info[ 'id' ] )
            provider._actions = [ ActionInformation(**a_info)
                                  for a_info in p_info['actions'] ]

    return 'Action providers imported.'
Beispiel #17
0
class PropertiesTool(UniqueObject, SimpleItem, ActionProviderBase):
    id = 'portal_properties'
    meta_type = 'Default Properties Tool'
    _actions = [ActionInformation(id='configPortal'
                            , title='Reconfigure Portal'
                            , description='Reconfigure the portal'
                            , action=Expression(
            text='string: ${portal_url}/reconfig_form')
                            , permissions=(CMFCorePermissions.ManagePortal,)
                            , category='global'
                            , condition=None
                            , visible=1
                             )] 

    security = ClassSecurityInfo()

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

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

    #
    #   'portal_properties' interface methods
    #
    security.declarePrivate('listActions')
    def listActions(self, info=None):
        """
        Return actions provided by tool.
        """
        return self._actions

    security.declareProtected( CMFCorePermissions.ManagePortal
                             , 'editProperties' )
    def editProperties(self, props):
        '''Change portal settings'''
        aq_parent(aq_inner(self)).manage_changeProperties(props)
        self.MailHost.smtp_host = props['smtp_server']
        if hasattr(self, 'propertysheets'):
            ps = self.propertysheets
            if hasattr(ps, 'props'):
                ps.props.manage_changeProperties(props)

    def title(self):
        return self.aq_inner.aq_parent.title

    def smtp_server(self):
        return self.MailHost.smtp_host
Beispiel #18
0
class DummyProvider(ActionProviderBase):

    _actions = [
        ActionInformation(id='an_id',
                          title='A Title',
                          action='',
                          condition='',
                          permissions='',
                          category='',
                          visible=0)
    ]
Beispiel #19
0
def ActionProviderBase_extractAction( self, properties, index ):

    """ Extract an ActionInformation from the funky form properties.
    """
    id          = str( properties.get( 'id_%d'          % index, '' ) )
    title        = str( properties.get( 'title_%d'        % index, '' ) )
    description = str( properties.get( 'description_%d'        % index, '' ) )
    action      = str( properties.get( 'action_%d'      % index, '' ) )
    icon        = str( properties.get( 'icon_%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, () )
    priority    = float( properties.get( 'priority_%d'    % index, 1.0 ))

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

    if action is not '':
        action = Expression( text=action )

    if icon is not '':
        icon = Expression( text=icon )

    if condition is not '':
        condition = Expression( text=condition )

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

    if type( visible ) is not type( 0 ):
        try:
            visible = int( visible )
        except TypeError:
            visible = 0

    if type( permissions ) is type( '' ):
        permissions = ( permissions, )

    if type( priority ) is not type(1.0):
        priority = float(priority)

    return ActionInformation( id=id
                            , title=title
                            , description=description
                            , action=action
                            , icon=icon
                            , condition=condition
                            , permissions=permissions
                            , category=category
                            , visible=visible
                            , priority=priority
                            )
def hitCountUpgrade(self):
    """Upgrade the installed tool"""
    out = StringIO()
    out.write("Upgrading Risa Repository\n")

    content = getToolByName(self, 'content')

    fi = FieldIndex('sortTitle')
    content.catalog._catalog.addIndex('sortTitle', fi)
    fi._updateProperty('PrenormalizeTerm', 'python: value.lower()')
    fi._updateProperty('TermType', 'string')
    fi.sortTitle._updateProperty('Name', 'title')
    fi.sortTitle._updateProperty('Normalizer',
                                 'python: here.stripArticles(value)')

    extra = Empty()
    extra.indexed_attrs = 'keywords'
    content.catalog.addIndex('keywordscase', 'KeywordIndex', extra)

    content.catalog.delColumn('icon')
    content.catalog.addColumn('getIcon')
    content.catalog.addColumn('url')
    content.catalog.addColumn('authors')
    content.catalog.addColumn('instructor')

    out.write("Upgraded catalog\n")

    types_tool = getToolByName(self, 'portal_types')
    # Plone1 version
    #types_tool.Repository._actions = ({'id':'view', 'name':'Browse', 'action':'browse_content', 'permissions':('View',),'visible':0},)

    types_tool.Repository._actions = [
        ActionInformation('view',
                          title='Browse',
                          action='browse_content',
                          permissions=(CMFCorePermissions.View),
                          visible=0)
    ]

    out.write("Upgraded actions\n")

    right_slots = [
        'here/portlet_newest_content/macros/portlet',
        'here/portlet_hits/macros/portlet'
    ]
    content._setProperty('right_slots', right_slots, type='lines')

    out.write("Upgraded portlets\n")

    content.catalog.refreshCatalog()
    out.write("Refreshed catalog\n")

    return out.getvalue()
 def setUp(self):
     SecurityTest.setUp(self)
     app = self.app
     app._setObject('portal', DummyContent('portal', url='url_portal'))
     self.portal = app.portal
     self.folder = DummyContent('foo', url='url_foo')
     self.object = DummyContent('bar', url='url_bar')
     self.ai = ActionInformation(id='view',
                                 title='View',
                                 action=Expression(text='view'),
                                 condition=Expression(text='member'),
                                 category='global',
                                 visible=1)
Beispiel #22
0
 def test_basic_construction(self):
     ai = ActionInformation(id='view'
                           )
     self.assertEqual(ai.getId(), 'view')
     self.assertEqual(ai.Title(), 'view')
     self.assertEqual(ai.Description(), '')
     self.assertEqual(ai.getCondition(), '')
     self.assertEqual(ai.getActionExpression(), '')
     self.assertEqual(ai.getVisibility(), 1)
     self.assertEqual(ai.getCategory(), 'object')
     self.assertEqual(ai.getPermissions(), ())
Beispiel #23
0
    def _importOldAction(self, old_action):
        """Convert a CMF action to an ERP5 action

      This is used to update an existing site or to import a BT.
      """
        import erp5.portal_type

        ActionInformation = getattr(erp5.portal_type, "Action Information")
        old_action = old_action.__getstate__()
        action_type = old_action.pop("category", None)
        action = ActionInformation(self.generateNewId())
        for k, v in old_action.iteritems():
            if k in ("action", "condition", "icon"):
                if not v:
                    continue
                v = v.__class__(v.text)
            setattr(
                action, {"id": "reference", "priority": "float_index", "permissions": "action_permission"}.get(k, k), v
            )
        action.uid = None
        action = self[self._setObject(action.id, action, set_owner=0)]
        if action_type:
            action._setCategoryMembership("action_type", action_type)
        return action
Beispiel #24
0
    def _importOldAction(self, old_action):
      """Convert a CMF action to an ERP5 action

      This is used to update an existing site or to import a BT.
      """
      import erp5.portal_type
      ActionInformation = getattr(erp5.portal_type, 'Action Information')
      old_action = old_action.__getstate__()
      action_type = old_action.pop('category', None)
      action = ActionInformation(self.generateNewId())
      for k, v in old_action.iteritems():
        if k in ('action', 'condition', 'icon'):
          if not v:
            continue
          v = v.__class__(v.text)
        setattr(action, {'id': 'reference',
                         'priority': 'float_index',
                         'permissions': 'action_permission',
                        }.get(k, k), v)
      action.uid = None
      action = self[self._setObject(action.id, action, set_owner=0)]
      if action_type:
        action._setCategoryMembership('action_type', action_type)
      return action
Beispiel #25
0
 def setUp(self):
     get_transaction().begin()
     self._policy = PermissiveSecurityPolicy()
     self._oldPolicy = SecurityManager.setSecurityPolicy(self._policy)
     self.connection = Zope.DB.open()
     root = self.root = self.connection.root()['Application']
     newSecurityManager(None, UnitTestUser().__of__(self.root))
     root._setObject('portal', DummyContent('portal', 'url_portal'))
     portal = self.portal = self.root.portal
     self.folder = DummyContent('foo', 'url_foo')
     self.object = DummyContent('bar', 'url_bar')
     self.ai = ActionInformation(id='view',
                                 title='View',
                                 action=Expression(text='view'),
                                 condition=Expression(text='member'),
                                 category='global',
                                 visible=1)
Beispiel #26
0
    def listActions(self, info=None, object=None):
        """ List all the actions defined by a provider.
        """
        if object is None:
            if info is None:
                # There is no support for global actions
                return ()
            else:
                object = info.content

        actions = []
        for menu_id in _listMenuIds():
            for entry in getMenu(menu_id, object, self.REQUEST):
                # The action needs a unique name, so I'll build one
                # from the object_id and the action url. That is sure
                # to be unique.
                action = str(entry['action'])
                if object is None:
                    act_id = 'action_%s' % action
                else:
                    act_id = 'action_%s_%s' % (object.getId(), action)

                if entry.get('filter') is None:
                    filter = None
                else:
                    filter = Expression(text=str(entry['filter']))

                title = entry['title']
                # Having bits of unicode here can make rendering very confused,
                # so we convert it to plain strings, but NOT if it is a
                # messageID. In Zope 3.2 there are two types of messages,
                # Message and MessageID, where MessageID is depracated. We can
                # type-check for both but that provokes a deprecation warning,
                # so we check for the "domain" attribute instead.
                if not hasattr(title, 'domain'):
                    title = str(title)
                act = ActionInformation(id=act_id,
                                        title=title,
                                        action=Expression(text='string:%s' %
                                                          action),
                                        condition=filter,
                                        category=str(menu_id),
                                        visible=1)
                actions.append(act)

        return tuple(actions)
Beispiel #27
0
def ActionProviderBase_addAction( self
              , id
              , name
              , action
              , condition
              , permission
              , category
              , icon=None
              , visible=1
              , priority=1.0
              , REQUEST=None
              , description=''
              ):
    """ Add an action to our list.
    """
    if not name:
        raise ValueError('A name is required.')

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

    if type( permission ) != type( () ):
        permission = permission and (str(permission),) or ()

    new_actions = self._cloneActions()

    new_action = ActionInformation( id=str(id)
                                  , title=str(name)
                                  , description=str(description)
                                  , action=a_expr
                                  , icon=i_expr
                                  , condition=c_expr
                                  , permissions=permission
                                  , category=str(category)
                                  , visible=int(visible)
                                  , priority=float(priority)
                                  )

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

    if REQUEST is not None:
        return self.manage_editActionsForm(
            REQUEST, manage_tabs_message='Added.')
Beispiel #28
0
 def test_construction_with_Expressions(self):
     ai = ActionInformation(id='view'
                          , title='View'
                          , action=Expression(
          text='view')
                          , condition=Expression(
          text='member')
                          , category='global'
                          , visible=0)
     self.assertEqual(ai.getId(), 'view')
     self.assertEqual(ai.Title(), 'View')
     self.assertEqual(ai.Description(), '')
     self.assertEqual(ai.getCondition(), 'member')
     self.assertEqual(ai.getActionExpression(), 'string:view')
     self.assertEqual(ai.getVisibility(), 0)
     self.assertEqual(ai.getCategory(), 'global')
     self.assertEqual(ai.getPermissions(), ())
Beispiel #29
0
    def _exportOldAction(self, action):
      """Convert an ERP5 action to a CMF action

      This is used to export a BT.
      """
      from Products.CMFCore.ActionInformation import ActionInformation
      old_action = ActionInformation(action.reference,
        category=action.getActionType(),
        priority=action.getFloatIndex(),
        permissions=tuple(action.getActionPermissionList()))
      for k, v in action.__dict__.iteritems():
        if k in ('action', 'condition', 'icon'):
          if not v:
            continue
          v = v.__class__(v.text)
        elif k in ('id', 'float_index', 'action_permission', 'reference'):
          continue
        setattr(old_action, k, v)
      return old_action
Beispiel #30
0
    def addAction(self,
                  id,
                  name,
                  action,
                  condition,
                  permission,
                  category,
                  visible=1,
                  icon_expr='',
                  link_target='',
                  description='',
                  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),
                                       description=str(description),
                                       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.')
Beispiel #31
0
    def actions_add_type_action(self, portal_type, after, action_id, **kwargs):
        """Add a ``portal_type`` action from the type identified
        by ``portal_type``, the position could be definded by the
        ``after`` attribute. If the after action could not be found,
        the action will be inserted at the end of the list."""

        actions = []
        found = False

        ttool = self.getToolByName('portal_types')
        fti = ttool.get(portal_type)

        new_action = ActionInformation(id=action_id, **kwargs)

        for action in fti._actions:  # pylint: disable=W0212
            actions.append(action)
            if action.id == after:
                actions.append(new_action)
                found = True

        if not found:
            actions.append(new_action)

        fti._actions = tuple(actions)  # pylint: disable=W0212
    def _makeOne(self, *args, **kw):
        from Products.CMFCore.ActionInformation import ActionInformation

        return ActionInformation(*args, **kw)
Beispiel #33
0
 def getAction(self, ec):
     res = ActionInformation.getAction(self, ec)
     res['description'] = self.getDescription()
     return res
Beispiel #34
0
 def __init__(self, appId, **kwargs):
     self.appId = appId
     ActionInformation.__init__(self, **kwargs)
Beispiel #35
0
class DiscussionTool(UniqueObject, SimpleItem, ActionProviderBase):
    """ Links content to discussions.
    """

    __implements__ = (IDiscussionTool, ActionProviderBase.__implements__)

    id = 'portal_discussion'
    meta_type = 'Default Discussion Tool'
    _actions = (ActionInformation(
        id='reply',
        title='Reply',
        action=Expression(text='string:${object_url}/discussion_reply_form'),
        condition=Expression(
            text='python: object is not None and ' +
            'portal.portal_discussion.isDiscussionAllowedFor(object)'),
        permissions=(ReplyToItem, ),
        category='object',
        visible=1), )

    security = ClassSecurityInfo()

    manage_options = (ActionProviderBase.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.
        """
        mtool = getToolByName(self, 'portal_membership')
        if not mtool.checkPermission(ModifyPortalContent, content):
            raise AccessControl_Unauthorized

        if allowDiscussion is None or allowDiscussion == 'None':
            if hasattr(aq_base(content), 'allow_discussion'):
                del content.allow_discussion
        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.isImplementedBy(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)
        typeInfo = getToolByName(self, 'portal_types').getTypeInfo(content)
        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
Beispiel #36
0
class RegistrationTool(BaseTool):
    """ Manage through-the-web signup policies.
    """

    __implements__ = BaseTool.__implements__

    meta_type = 'Default Registration Tool'
    _actions = ( ActionInformation( id='join'
                                  , title='Join'
                                  , description='Click here to Join'
                                  , action=Expression(
                                     text='string:${portal_url}/join_form')
                                  , permissions=(AddPortalMember,)
                                  , category='user'
                                  , condition=Expression(text='not: member')
                                  , visible=1
                                  )
               ,
               )

    security = ClassSecurityInfo()

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

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

    #
    #   'portal_registration' interface
    #
    security.declarePublic( 'testPasswordValidity' )
    def testPasswordValidity(self, password, confirm=None):

        """ Verify that the password satisfies the portal's requirements.
        
        o If the password is valid, return None.
        o If not, return a string explaining why.
        """
        if len(password) < 5 and not _checkPermission('Manage portal', self):
            return 'Your password must contain at least 5 characters.'

        if confirm is not None and confirm != password:
            return ( 'Your password and confirmation did not match. ' 
                   + 'Please try again.' )

        return None

    security.declarePublic( 'testPropertiesValidity' )
    def testPropertiesValidity(self, props, member=None):

        """ Verify that the properties supplied satisfy portal's requirements.

        o If the properties are valid, return None.
        o If not, return a string explaining why.
        """
        if member is None: # New member.

            username = props.get('username', '')
            if not username:
                return 'You must enter a valid name.'

            if not self.isMemberIdAllowed(username):
                return ('The login name you selected is already '
                        'in use or is not valid. Please choose another.')

            if not props.get('email'):
                return 'You must enter a valid email address.'

        else: # Existing member.
            # Not allowed to clear an existing non-empty email.
            if (member.getProperty('email') and
                not props.get('email', 'NoPropIsOk')):
                return 'You must enter a valid email address.'

        return None

    security.declarePublic( 'mailPassword' )
    def mailPassword(self, forgotten_userid, REQUEST):

        """ Email a forgotten password to a member.
        
        o Raise an exception if user ID is not found.
        """
        membership = getToolByName(self, 'portal_membership')
        member = membership.getMemberById(forgotten_userid)

        if member is None:
            raise 'NotFound', 'The username you entered could not be found.'
    
        # assert that we can actually get an email address, otherwise
        # the template will be made with a blank To:, this is bad
        if not member.getProperty('email'):
            raise 'ValueError', 'That user does not have an email address.'
        
        # Rather than have the template try to use the mailhost, we will
        # render the message ourselves and send it from here (where we
        # don't need to worry about 'UseMailHost' permissions).
        mail_text = self.mail_password_template( self
                                               , REQUEST
                                               , member=member
                                               , password=member.getPassword()
                                               )
    
        host = self.MailHost
        host.send( mail_text )

        return self.mail_password_response( self, REQUEST )

    security.declarePublic( 'registeredNotify' )
    def registeredNotify( self, new_member_id ):

        """ Handle mailing the registration / welcome message.
        """
        membership = getToolByName( self, 'portal_membership' )
        member = membership.getMemberById( new_member_id )

        if member is None:
            raise 'NotFound', 'The username you entered could not be found.'

        password = member.getPassword()
        email = member.getProperty( 'email' )

        if email is None:
            raise ValueError( 'Member %s has no e-mail address!'
                            % new_member_id )
    
        # Rather than have the template try to use the mailhost, we will
        # render the message ourselves and send it from here (where we
        # don't need to worry about 'UseMailHost' permissions).
        mail_text = self.registered_notify_template( self
                                                   , self.REQUEST
                                                   , member=member
                                                   , password=password
                                                   , email=email
                                                   )
    
        host = self.MailHost
        host.send( mail_text )

        return self.mail_password_response( self, self.REQUEST )

    security.declareProtected(ManagePortal, 'editMember')
    def editMember( self
                  , member_id
                  , properties=None
                  , password=None
                  , roles=None
                  , domains=None
                  ):
        """ Edit a user's properties and security settings

        o Checks should be done before this method is called using
          testPropertiesValidity and testPasswordValidity
        """
        
        mtool = getToolByName(self, 'portal_membership')
        member = mtool.getMemberById(member_id)
        member.setMemberProperties(properties)
        member.setSecurityProfile(password,roles,domains)

        return member
 def __init__(self, appId, **kwargs):
     self.appId = appId
     ActionInformation.__init__(self, **kwargs)
 def getAction(self, ec):
     res = ActionInformation.getAction(self, ec)
     res['description'] = self.getDescription()
     return res