Example #1
0
    def patch_class_security(self, klass, method_name, new_permission):
        """Monkey patch class security definitions to protect a method with
        a different permission.
        """
        def reset_security_for_attribute(name, klass):
            """Remove security declarations for a particular method /
            attribute by filtering declarations for that attribute from
            __ac_permissions__.
            """
            new_ac_permissions = []

            for permission_mapping in klass.__ac_permissions__:
                permission, names = permission_mapping
                if name not in names:
                    new_ac_permissions.append(permission_mapping)
                else:
                    new_names = tuple([n for n in names if n != name])
                    modified_mapping = (permission, new_names)
                    new_ac_permissions.append(modified_mapping)

            klass.__ac_permissions__ = tuple(new_ac_permissions)

        reset_security_for_attribute(method_name, klass)
        sec = ClassSecurityInfo()
        sec.declareProtected(new_permission, method_name)
        sec.apply(klass)
        InitializeClass(klass)
Example #2
0
def disablePasResources(event):
    """Disable access to users/groups/roles management PAS plugins from browser
    as they have no protection from CSRF attacks.
    """
    try:
        zport = getattr(event.app, 'zport', None)
        if not zport or getattr(zport.dmd, 'allowManageAccess', False):
            return
        for class_ in (ZODBUserManager.ZODBUserManager,
                       ZODBGroupManager.ZODBGroupManager,
                       ZODBRoleManager.ZODBRoleManager):
            security = ClassSecurityInfo()
            security.declareObjectPrivate()
            security.apply(class_)
    except AttributeError:
        pass
Example #3
0
  def test_security_defined_on_class(self):
    # wrapping a method in an interaction workflow adds a default security to
    # this method, but does not override existing security definition (defined
    # on the class)
    Organisation = Products.ERP5.Document.Organisation.Organisation
    security = ClassSecurityInfo()
    security.declarePrivate('doSomethingStupid')
    security.apply(Organisation)

    self.createInteractionWorkflow()
    self.interaction.setProperties(
            'default',
            method_id='doSomethingStupid',
            after_script_name=('afterEdit',))
    self.script.ZPythonScript_edit('sci', '')
    self.createData()

    self.assertEqual(self.organisation.doSomethingStupid__roles__, ())
Example #4
0
class TransformsChain(Implicit, Item, RoleManager, Persistent):
    """ a transforms chain is suite of transforms to apply in order.
    It follows the transform API so that a chain is itself a transform.
    """

    module = 'N/A'
    meta_type = 'TransformsChain'

    meta_types = all_meta_types = ()

    manage_options = (
                      ({'label':'Configure',
                       'action':'manage_main'},
                       {'label':'Reload',
                       'action':'manage_reloadTransform'},) +
                      Item.manage_options
                      )

    manage_main = PageTemplateFile('editTransformsChain', _www)
    manage_reloadTransform = PageTemplateFile('reloadTransform', _www)

    security = ClassSecurityInfo()

    def __init__(self, id, description, ids=()):
        self.id = id
        self.description = description
        self._object_ids = list(ids)
        self.inputs = ('application/octet-stream',)
        self.output = 'application/octet-stream'
        self._chain = None

    def _chain_init(self):
        """ build the transforms chain """
        tr_tool = getToolByName(self, 'portal_transforms')
        self._chain = c = chain()
        for id in self._object_ids:
            object = getattr(tr_tool, id)
            c.registerTransform(object)
        self.inputs = c.inputs or ('application/octet-stream',)
        self.output = c.output or 'application/octet-stream'

    security.declarePublic('convert')
    def convert(self, *args, **kwargs):
        """ return apply the transform and return the result """
        if self._chain is None:
            self._chain_init()
        return self._chain.convert(*args, **kwargs)

    security.declarePublic('name')
    def name(self):
        """return the name of the transform instance"""
        return self.id

    security.declarePrivate('manage_beforeDelete')
    def manage_beforeDelete(self, item, container):
        Item.manage_beforeDelete(self, item, container)
        if self is item:
            # unregister self from catalog on deletion
            tr_tool = getToolByName(self, 'portal_transforms')
            tr_tool.unregisterTransform(self.id)

    security.declareProtected(ManagePortal, 'manage_addObject')
    def manage_addObject(self, id, REQUEST=None):
        """ add a new transform or chain to the chain """
        assert id not in self._object_ids
        self._object_ids.append(id)
        self._chain_init()
        if REQUEST is not None:
            REQUEST['RESPONSE'].redirect(self.absolute_url()+'/manage_main')

    security.declareProtected(ManagePortal, 'manage_delObjects')
    def manage_delObjects(self, ids, REQUEST=None):
        """ delete the selected mime types """
        for id in ids:
            self._object_ids.remove(id)
        self._chain_init()
        if REQUEST is not None:
            REQUEST['RESPONSE'].redirect(self.absolute_url()+'/manage_main')


    # transforms order handling #

    security.declareProtected(ManagePortal, 'move_object_to_position')
    def move_object_to_position(self, id, newpos):
        """ overriden from OrderedFolder to store id instead of objects
        """
        oldpos = self._object_ids.index(id)
        if (newpos < 0 or newpos == oldpos or newpos >= len(self._object_ids)):
            return 0
        self._object_ids.pop(oldpos)
        self._object_ids.insert(newpos, id)
        self._chain_init()
        return 1

    security.declareProtected(ManageProperties, 'move_object_up')
    def move_object_up(self, id, REQUEST=None):
        """  move object with the given id up in the list """
        newpos = self._object_ids.index(id) - 1
        self.move_object_to_position(id, newpos)
        if REQUEST is not None:
            REQUEST['RESPONSE'].redirect(self.absolute_url()+'/manage_main')

    security.declareProtected(ManageProperties, 'move_object_down')
    def move_object_down(self, id, REQUEST=None):
        """  move object with the given id down in the list """
        newpos = self._object_ids.index(id) + 1
        self.move_object_to_position(id, newpos)
        if REQUEST is not None:
            REQUEST['RESPONSE'].redirect(self.absolute_url()+'/manage_main')


    # Z transform interface #

    security.declareProtected(ManagePortal, 'reload')
    def reload(self):
        """ reload the module where the transformation class is defined """
        for tr in self.objectValues():
            tr.reload()
        self._chain_init()

    # utilities #

    security.declareProtected(ManagePortal, 'listAddableObjectIds')
    def listAddableObjectIds(self):
        """ return a list of addable transform """
        tr_tool = getToolByName(self, 'portal_transforms')
        return [id for id in tr_tool.objectIds() if not (id == self.id or id in self._object_ids)]

    security.declareProtected(ManagePortal, 'objectIds')
    def objectIds(self):
        """ return a list of addable transform """
        return tuple(self._object_ids)

    security.declareProtected(ManagePortal, 'objectValues')
    def objectValues(self):
        """ return a list of addable transform """
        tr_tool = getToolByName(self, 'portal_transforms')
        return [getattr(tr_tool, id) for id in self.objectIds()]
Example #5
0
LOGGER.info('Monkey patched webdav.LockItem.DEFAULTTIMEOUT')

# --------

from plone.dexterity.content import Container
# Change permission for manage_pasteObjects to "Add portal content"
# See https://dev.plone.org/ticket/9177

# XXX Find a way to do this without patching __ac_permissions__ directly

def drop_protected_attr_from_ac_permissions(attribute, classobj):
    new_mappings = []
    for mapping in Container.__ac_permissions__:
        perm, attrs = mapping
        if not attribute in attrs:
            new_mappings.append(mapping)
        else:
            modified_attrs = tuple([a for a in attrs if not a == attribute])
            modified_mapping = (perm, modified_attrs)
            new_mappings.append(modified_mapping)
    classobj.__ac_permissions__ = tuple(new_mappings)

drop_protected_attr_from_ac_permissions('manage_pasteObjects', Container)
sec = ClassSecurityInfo()
sec.declareProtected(Products.CMFCore.permissions.AddPortalContent,
                    'manage_pasteObjects')
sec.apply(Container)
InitializeClass(Container)

LOGGER.info('Monkey patched plone.dexterity.content.Container')
Example #6
0
except ImportError: from Globals import InitializeClass

from AdvancedQuery import Eq, In, Le, Ge, \
     MatchGlob, MatchRegexp, \
     Between, Not, And, Or, Generic, Indexed, \
     _CompositeQuery, LiteralResultSet

from eval import eval as _eval

from ranking import RankByQueries_Sum, RankByQueries_Max


############################################################################
## Security
_allow_module('Products.AdvancedQuery')
_s = ClassSecurityInfo(); _s.declarePublic('addSubquery')
_CompositeQuery._s = _s; InitializeClass(_CompositeQuery)


############################################################################
## ZCatalog extension
def _makeAdvancedQuery(self,catalogSearchSpec):
  '''advanced query corresponding to *catalogSearchSpec* (a dictionary).'''
  q = And(); get = catalogSearchSpec.get
  for i in self.Indexes.objectIds():
    vi = get(i)
    if vi is None or vi == '': continue
    if not (isinstance(vi, dict) and vi.get('query') is not None
            or getattr(vi, 'query', None) is not None):
      usage = get(i+'_usage')
      if usage is not None:
    def default_encoding(self):
        try:
            from Products.LDAPUserFolder.utils import encoding
        except Exception, e:
            return "utf-8"
        else:
            return encoding

    def __init__(self, id, source_obj, title):
        """ constructor """
        super(plugLDAPUserFolder, self).__init__(id, source_obj, title)
        self._user_objs = {}
        self.located = {}
        self.buffer = {}

    security = ClassSecurityInfo()

    def getUserLocation(self, user):
        return self.located.get(user, "-")

    def setUserLocation(self, user, user_location):
        self.located[user] = user_location
        self._p_changed = 1

    def delUserLocation(self, user):
        try:
            del self.located[user]
            self._p_changed = 1
        except:
            pass
Example #8
0
    security.declareProtected(PERMISSION_VIEW, 'getPages')
    getPages = BaseContainer.getItems
     
    security.declareProtected(PERMISSION_MANAGE_CONTENT, 'deletePage')
    deletePage = BaseContainer.deleteItem
            
    security.declareProtected(PERMISSION_VIEW, 'countPages')
    countPages = BaseContainer.countItems
    
templates = (
    'zpt/page/PagesManagementHome',
    'zpt/page/addPageForm',
    'zpt/page/deletePageForm',)            
addTemplates2Class(PageContainer, templates, globals_=globals())
                
security = ClassSecurityInfo()
security.declareProtected(PERMISSION_MANAGE_CONTENT, 'PagesManagementHome')
security.declareProtected(PERMISSION_MANAGE_CONTENT, 'addPageForm')
security.declareProtected(PERMISSION_MANAGE_CONTENT, 'deletePageForm')
security.apply(PageContainer)
InitializeClass(PageContainer)


######################################################################
## Page 
######################################################################

manage_addPageForm = PTF('zpt/page/addPageForm', globals())
def manage_addPage(context, id, title, abstract = u'',
                   body=u'',publish_date=None,
                   REQUEST=None):
Example #9
0
        assert getattr(self, id).meta_type == METATYPE_NEWSITEM
        self.manage_delObjects([id])
        
        if REQUEST is not None:
            msg = "News item deleted"
            url = self.absolute_url()+'/NewsManagement'
            self.http_redirect(url, msg=msg)
        

templates = ('zpt/NewsManagement',
             'zpt/deleteNewsItemForm',
            )
addTemplates2Class(NewsContainer, templates, globals_=globals())
setattr(NewsContainer, 'rss.xml', NewsContainer.RSS)

security = ClassSecurityInfo()
security.declareProtected(MANAGE_CONTENT_PERMISSIONS, 'deleteNewsItemForm')
security.apply(NewsContainer)


InitializeClass(NewsContainer)
        
        
#-------------------------------------------------------------------------------

manage_addNewsItemForm = PTF('zpt/addNewsItemForm', globals())

def manage_suggestNewsItemId(self):
    """ suggest a new id """
    return DateTime().strftime('newsitem-%d%b%Y')
Example #10
0
             'zpt/BlogManagementHome',             
             'zpt/FileManagementHome',
             'zpt/search',
             'dtml/manage_MenuItems',
             ('zpt/AdvancedManagement', 'manage_AdvancedManagement'),
             'zpt/ManagementHeaderFooter',
             'zpt/DocumentManagementHome',
             ('dtml/cms.js', 'cms_js_template'),
             'zpt/page/PagesManagementHome',
             'zpt/page/deletePageForm',
             'zpt/faq/FAQManagementHome',             
            )
            
addTemplates2Class(Homepage, templates)
                
security = ClassSecurityInfo()
security.declareProtected(MANAGE_CONTENT_PERMISSIONS, 'Management')
security.declareProtected(MANAGE_CONTENT_PERMISSIONS, 'NewsManagementHome')
security.declareProtected(MANAGE_CONTENT_PERMISSIONS, 'BlogManagementHome')
security.declareProtected(MANAGE_CONTENT_PERMISSIONS, 'FileManagementHome')
security.declareProtected(MANAGE_CONTENT_PERMISSIONS, 'DocumentManagementHome')
security.declareProtected(MANAGE_CONTENT_PERMISSIONS, 'PagesManagementHome')
security.declareProtected(MANAGE_CONTENT_PERMISSIONS, 'FAQManagementHome')
#security.declareProtected(MANAGE_CONTENT_PERMISSIONS, 'addPageForm')
security.declareProtected(MANAGE_CONTENT_PERMISSIONS, 'deletePageForm')
security.apply(Homepage)

setattr(Homepage, 'cms.js', Homepage.cms_js)
InitializeClass(Homepage)
        
        
Example #11
0
class AnalysisService(BaseContent, HistoryAwareMixin):
    security = ClassSecurityInfo()
    schema = schema
    displayContentsTab = False
    implements(IAnalysisService)

    _at_rename_after_creation = True

    def _renameAfterCreation(self, check_auto_id=False):
        from bika.lims.idserver import renameAfterCreation
        return renameAfterCreation(self)

    security.declarePublic('getDiscountedPrice')

    def getDiscountedPrice(self):
        """ compute discounted price excl. vat """
        price = self.getPrice()
        price = price and price or 0
        discount = self.bika_setup.getMemberDiscount()
        discount = discount and discount or 0
        return float(price) - (float(price) * float(discount)) / 100

    security.declarePublic('getDiscountedCorporatePrice')

    def getDiscountedCorporatePrice(self):
        """ compute discounted corporate price excl. vat """
        price = self.getCorporatePrice()
        price = price and price or 0
        discount = self.bika_setup.getMemberDiscount()
        discount = discount and discount or 0
        return float(price) - (float(price) * float(discount)) / 100

    def getTotalPrice(self):
        """ compute total price """
        price = self.getPrice()
        vat = self.getVAT()
        price = price and price or 0
        vat = vat and vat or 0
        return float(price) + (float(price) * float(vat)) / 100

    def getTotalCorporatePrice(self):
        """ compute total price """
        price = self.getCorporatePrice()
        vat = self.getVAT()
        price = price and price or 0
        vat = vat and vat or 0
        return float(price) + (float(price) * float(vat)) / 100

    security.declarePublic('getTotalDiscountedPrice')

    def getTotalDiscountedPrice(self):
        """ compute total discounted price """
        price = self.getDiscountedPrice()
        vat = self.getVAT()
        price = price and price or 0
        vat = vat and vat or 0
        return float(price) + (float(price) * float(vat)) / 100

    security.declarePublic('getTotalDiscountedCorporatePrice')

    def getTotalDiscountedCorporatePrice(self):
        """ compute total discounted corporate price """
        price = self.getDiscountedCorporatePrice()
        vat = self.getVAT()
        price = price and price or 0
        vat = vat and vat or 0
        return float(price) + (float(price) * float(vat)) / 100

    def getDefaultVAT(self):
        """ return default VAT from bika_setup """
        try:
            vat = self.bika_setup.getVAT()
            return vat
        except ValueError:
            return "0.00"

    security.declarePublic('getVATAmount')

    def getVATAmount(self):
        """ Compute VATAmount
        """
        try:
            return "%.2f" % (self.getTotalPrice() - self.getPrice())
        except:
            return "0.00"

    def getAnalysisCategories(self):
        bsc = getToolByName(self, 'bika_setup_catalog')
        items = [('', '')] + [(o.UID, o.Title)
                              for o in bsc(portal_type='AnalysisCategory',
                                           inactive_state='active')]
        o = self.getCategory()
        if o and o.UID() not in [i[0] for i in items]:
            items.append((o.UID(), o.Title()))
        items.sort(lambda x, y: cmp(x[1], y[1]))
        return DisplayList(list(items))

    def getMethods(self):
        bsc = getToolByName(self, 'bika_setup_catalog')
        items = [('', '')] + [
            (o.UID, o.Title)
            for o in bsc(portal_type='Method', inactive_state='active')
        ]
        o = self.getMethod()
        if o and o.UID() not in [i[0] for i in items]:
            items.append((o.UID(), o.Title()))
        items.sort(lambda x, y: cmp(x[1], y[1]))
        return DisplayList(list(items))

    def getInstruments(self):
        bsc = getToolByName(self, 'bika_setup_catalog')
        items = [('', '')] + [
            (o.UID, o.Title)
            for o in bsc(portal_type='Instrument', inactive_state='active')
        ]
        o = self.getInstrument()
        if o and o.UID() not in [i[0] for i in items]:
            items.append((o.UID(), o.Title()))
        items.sort(lambda x, y: cmp(x[1], y[1]))
        return DisplayList(list(items))

    def getCalculations(self):
        bsc = getToolByName(self, 'bika_setup_catalog')
        items = [('', '')] + [
            (o.UID, o.Title)
            for o in bsc(portal_type='Calculation', inactive_state='active')
        ]
        o = self.getCalculation()
        if o and o.UID() not in [i[0] for i in items]:
            items.append((o.UID(), o.Title()))
        items.sort(lambda x, y: cmp(x[1], y[1]))
        return DisplayList(list(items))

    def getDepartments(self):
        bsc = getToolByName(self, 'bika_setup_catalog')
        items = [('', '')] + [
            (o.UID, o.Title)
            for o in bsc(portal_type='Department', inactive_state='active')
        ]
        o = self.getDepartment()
        if o and o.UID() not in [i[0] for i in items]:
            items.append((o.UID(), o.Title()))
        items.sort(lambda x, y: cmp(x[1], y[1]))
        return DisplayList(list(items))

    def getUncertainty(self, result=None):
        """ Return the uncertainty value, if the result falls within specified
            ranges for this service. """

        if result is None:
            return None

        uncertainties = self.getUncertainties()
        if uncertainties:
            try:
                result = float(result)
            except:
                # if analysis result is not a number, then we assume in range
                return None

            for d in uncertainties:
                if float(d['intercept_min']) <= result <= float(
                        d['intercept_max']):
                    return d['errorvalue']
            return None
        else:
            return None

    security.declarePublic('getContainers')

    def getContainers(self, instance=None):
        # On first render, the containers must be limited according to
        # self.Preservation(). After that, the JS takes care of it with
        # getContainers above.
        instance = instance or self
        return DisplayList(
            getContainers(instance,
                          preservation=self.getPreservation(),
                          allow_blank=False))

    def getPreservations(self):
        bsc = getToolByName(self, 'bika_setup_catalog')
        items = [
            (o.UID, o.Title)
            for o in bsc(portal_type='Preservation', inactive_state='active')
        ]
        items.sort(lambda x, y: cmp(x[1], y[1]))
        return DisplayList(list(items))
Example #12
0
class PartitionSetupField(RecordsField):
    _properties = RecordsField._properties.copy()
    _properties.update({
        'subfields': (
            'sampletype',
            'preservation',
            'container',
            'separate',
            'vol',
            #'retentionperiod',
        ),
        'subfield_labels': {
            'sampletype': _('Sample Type'),
            'preservation': _('Preservation'),
            'container': _('Container'),
            'separate': _('Separate Partition'),
            'vol': _('Required Volume'),
            #'retentionperiod': _('Retention Period'),
        },
        'subfield_types': {
            'separate': 'boolean',
            'vol': 'int',
            'container': 'selection',
            'preservation': 'selection',
        },
        'subfield_vocabularies': {
            'sampletype': 'SampleTypes',
            'preservation': 'Preservations',
            'container': 'Containers',
        },
        'subfield_sizes': {
            'sampletype': 1,
            'vol': 5,
            'container': 5,
            'preservation': 5,
            #'retentionperiod':10,
        }
    })
    security = ClassSecurityInfo()

    security.declarePublic('SampleTypes')

    def SampleTypes(self, instance=None):
        instance = instance or self
        bsc = getToolByName(instance, 'bika_setup_catalog')
        items = []
        for st in bsc(portal_type='SampleType',
                      inactive_state='active',
                      sort_on='sortable_title'):
            st = st.getObject()
            title = st.Title()
            if st.getUnit():
                title += " %s" % (st.getUnit())
            items.append((st.UID(), title))
        items = [['', '']] + list(items)
        return DisplayList(items)

    security.declarePublic('Preservations')

    def Preservations(self, instance=None):
        instance = instance or self
        bsc = getToolByName(instance, 'bika_setup_catalog')
        items = [(c.UID, c.title) for c in bsc(portal_type='Preservation',
                                               inactive_state='active',
                                               sort_on='sortable_title')]
        items = [['', _('Any')]] + list(items)
        return DisplayList(items)

    security.declarePublic('Containers')

    def Containers(self, instance=None):
        instance = instance or self
        items = getContainers(instance, allow_blank=False)
        items = [['', _('Any')]] + list(items)
        return DisplayList(items)
Example #13
0
from json import dumps
from Products.CMFCore.utils import getToolByName
from Products.ZCatalog.ZCatalog import manage_addZCatalog
from Products.ZenModel.Device import Device
from Products.ZenUtils.Search import makeCaseInsensitiveFieldIndex
from Products.ZenUtils.NetworkTree import NetworkLink
from Products.Zuul import getFacade
from Products.ZenEvents.events2.processing import Manager
from zenoss.protocols.protobufs.zep_pb2 import (SEVERITY_CRITICAL,
                                                SEVERITY_ERROR,
                                                SEVERITY_WARNING,
                                                SEVERITY_INFO, SEVERITY_DEBUG,
                                                SEVERITY_CLEAR)
from zenoss.protocols.protobufs.zep_pb2 import STATUS_NEW, STATUS_ACKNOWLEDGED

security = ClassSecurityInfo()

NODE_IDS = dict(layer_3={
    'IpNetwork': 'networkId',
    'Device': 'deviceId'
},
                layer_2={
                    'LAN': 'lanId',
                    'Device': 'deviceId'
                })


def _getComplement(context, layer=3):
    key = 'layer_%d' % layer
    nodestuff = NODE_IDS[key]
    if not isinstance(context, basestring):
Example #14
0
class FSImage(Acquisition.Implicit, Item_w__name__):
    """FSImages act like images but are not directly
    modifiable from the management interface."""
    # Note that OFS.Image.Image is not a base class because it is mutable.

    meta_type = 'Filesystem Image'
    title = ''

    manage_options = ({
        'label': 'Customize',
        'action': 'manage_main'
    },
                      #{'label':'View', 'action':'view_image_or_file'},
                      )

    security = ClassSecurityInfo()
    security.declareObjectProtected(CMFCorePermissions.View)

    file_mod_time = 0

    def __init__(self, id, filepath, fullname=None, properties=None):
        if properties:
            # Since props come from the filesystem, this should be
            # safe.
            self.__dict__.update(properties)
        self.__name__ = fullname or id  # Use the whole filename.
        self.title = ''
        self._filepath = filepath
        fp = expandpath(self._filepath)
        try:
            self.file_mod_time = stat(fp)[8]
        except:
            pass
        self._readFile()

    security.declareProtected(ViewManagementScreens, 'manage_main')
    manage_main = HTMLFile('dtml/custimage', globals())

    security.declareProtected(ViewManagementScreens, 'manage_doCustomize')

    def manage_doCustomize(self, folder_path, data=None, RESPONSE=None):
        '''
        Makes an Image with the same data.
        '''
        custFolder = self.getCustomizableObject()
        fpath = tuple(split(folder_path, '/'))
        folder = self.restrictedTraverse(fpath)
        if data is None:
            data = self._readFile()
        id = self.getId()
        obj = Image(id, '', data)
        folder._verifyObjectPaste(obj, validate_src=0)
        folder._setObject(id, obj)
        if RESPONSE is not None:
            RESPONSE.redirect('%s/%s/manage_main' %
                              (folder.absolute_url(), id))

    security.declareProtected(View, 'getImageFSPath')

    def getImageFSPath(self):
        '''
        '''
        return self._filepath

    def _readFile(self):
        fp = expandpath(self._filepath)
        file = open(fp, 'rb')
        try:
            data = file.read()
        finally:
            file.close()
        (self.content_type, self.width, self.height) = getImageInfo(data)
        return data

    def _updateFromFS(self):
        if Globals.DevelopmentMode:
            fp = expandpath(self._filepath)
            try:
                mtime = stat(fp)[8]
            except:
                mtime = 0
            if mtime != self.file_mod_time:
                self.file_mod_time = mtime
                self._readFile()

    def getId(self):
        return self.__name__

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

    def __str__(self):
        return self.tag()

    security.declareProtected(View, 'tag')

    def tag(self,
            height=None,
            width=None,
            alt=None,
            scale=0,
            xscale=0,
            yscale=0,
            **args):
        """
        Generate an HTML IMG tag for this image, with customization.
        Arguments to self.tag() can be any valid attributes of an IMG tag.
        'src' will always be an absolute pathname, to prevent redundant
        downloading of images. Defaults are applied intelligently for
        'height', 'width', and 'alt'. If specified, the 'scale', 'xscale',
        and 'yscale' keyword arguments will be used to automatically adjust
        the output height and width values of the image tag.
        """
        self._updateFromFS()
        if height is None: height = self.height
        if width is None: width = self.width

        # Auto-scaling support
        xdelta = xscale or scale
        ydelta = yscale or scale

        if xdelta and width:
            width = str(int(width) * xdelta)
        if ydelta and height:
            height = str(int(height) * ydelta)

        result = '<img src="%s"' % (self.absolute_url())

        if alt is None:
            alt = getattr(self, 'title', '')
        result = '%s alt="%s"' % (result, alt)

        if height:
            result = '%s height="%s"' % (result, height)

        if width:
            result = '%s width="%s"' % (result, width)

        if not 'border' in map(string.lower, args.keys()):
            result = '%s border="0"' % result

        for key in args.keys():
            value = args.get(key)
            result = '%s %s="%s"' % (result, key, value)

        return '%s />' % result

    def id(self):
        return self.__name__

    security.declareProtected(View, 'index_html')

    def index_html(self, REQUEST, RESPONSE):
        """
        The default view of the contents of a File or Image.

        Returns the contents of the file or image.  Also, sets the
        Content-Type HTTP header to the objects content type.
        """
        # HTTP If-Modified-Since header handling.
        data = self._readFile()
        header = REQUEST.get_header('If-Modified-Since', None)
        if header is not None:
            header = string.split(header, ';')[0]
            # Some proxies seem to send invalid date strings for this
            # header. If the date string is not valid, we ignore it
            # rather than raise an error to be generally consistent
            # with common servers such as Apache (which can usually
            # understand the screwy date string as a lucky side effect
            # of the way they parse it).
            try:
                mod_since = long(DateTime(header).timeTime())
            except:
                mod_since = None
            if mod_since is not None:
                last_mod = self.file_mod_time
                if last_mod > 0 and last_mod <= mod_since:
                    RESPONSE.setStatus(304)
                    return ''

        RESPONSE.setHeader('Last-Modified', rfc1123_date(self.file_mod_time))
        RESPONSE.setHeader('Content-Type', self.content_type)
        RESPONSE.setHeader('Content-Length', len(data))

        return data

    security.declareProtected(View, 'view_image_or_file')

    def view_image_or_file(self, URL1):
        """
        The default view of the contents of the File or Image.
        """
        raise 'Redirect', URL1

    security.declareProtected(View, 'get_size')

    def get_size(self):
        """Get the size of a file or image.

        Returns the size of the file or image.
        """
        fp = expandpath(self._filepath)
        return path.getsize(fp)

    security.declareProtected(View, 'getContentType')

    def getContentType(self):
        """Get the content type of a file or image.

        Returns the content type (MIME type) of a file or image.
        """
        self._updateFromFS()
        return self.content_type

    security.declareProtected(View, 'getModTime')

    def getModTime(self):
        '''
        '''
        self._updateFromFS()
        return DateTime(self.file_mod_time)

    security.declareProtected(View, 'manage_FTPget')
    manage_FTPget = index_html
Example #15
0
class Person(Node, LoginAccountProviderMixin, EncryptedPasswordMixin):
    """
      An Person object holds the information about
      an person (ex. you, me, someone in the company,
      someone outside of the company, a member of the portal,
      etc.).

      Person objects can contain Coordinate objects
      (ex. Telephone, Url) as well a documents of various types.

      Person objects can be synchronized accross multiple
      sites.

      Person objects inherit from the Node base class
      (one of the 5 base classes in the ERP5 universal business model)
    """

    meta_type = 'ERP5 Person'
    portal_type = 'Person'
    add_permission = Permissions.AddPortalContent

    zope.interface.implements(interfaces.INode)

    # Declarative security
    security = ClassSecurityInfo()
    security.declareObjectProtected(Permissions.AccessContentsInformation)

    # Declarative properties
    property_sheets = (PropertySheet.Base, PropertySheet.XMLObject,
                       PropertySheet.CategoryCore, PropertySheet.DublinCore,
                       PropertySheet.Reference, PropertySheet.Person,
                       PropertySheet.Login, PropertySheet.Mapping,
                       PropertySheet.Task)

    def _setTitle(self, value):
        """
        Here we see that we must define a notion
        of priority in the way fields are updated
      """
        if value != self.getTitle():
            self.title = value

    security.declareProtected(Permissions.AccessContentsInformation,
                              'getTitle')

    def getTitle(self, **kw):
        """
        Returns the title if it exists or a combination of
        first name, middle name and last name
      """
        if not self.title:
            return ' '.join([
                x for x in (self.getFirstName(), self.getMiddleName(),
                            self.getLastName()) if x
            ])
        else:
            return self.title

    security.declareProtected(Permissions.AccessContentsInformation,
                              'getTranslatedTitle')

    def getTranslatedTitle(self, **kw):
        """
        Returns the title if it exists or a combination of
        first name, middle name and last name
      """
        if not self.title:
            return ' '.join([
                x for x in (self.getTranslatedFirstName(**kw),
                            self.getTranslatedMiddleName(**kw),
                            self.getTranslatedLastName(**kw)) if x
            ])
        else:
            return self.title

    security.declareProtected(Permissions.AccessContentsInformation,
                              'title_or_id')

    def title_or_id(self):
        return self.getTitleOrId()

    security.declareProtected(Permissions.AccessContentsInformation,
                              'hasTitle')

    def hasTitle(self):
        return not not self.getTitle()

    def _setReference(self, value):
        """
        Set the user id. This method is defined explicitly, because:

        - we want to apply a different permission

        - we want to prevent duplicated user ids, but only when
          PAS _AND_ ERP5UserManager are used
      """
        activate_kw = {}
        portal = self.getPortalObject()
        if value:
            # Encode reference to hex to prevent uppercase/lowercase conflict in
            # activity table (when calling countMessageWithTag)
            activate_kw['tag'] = tag = 'Person_setReference_' + value.encode(
                'hex')
            # Check that there no existing user
            acl_users = portal.acl_users
            if PluggableAuthService is not None and isinstance(
                    acl_users, PluggableAuthService.PluggableAuthService.
                    PluggableAuthService):
                plugin_list = acl_users.plugins.listPlugins(
                    PluggableAuthService.interfaces.plugins.
                    IUserEnumerationPlugin)
                for plugin_name, plugin_value in plugin_list:
                    if isinstance(plugin_value, ERP5UserManager):
                        user_list = acl_users.searchUsers(id=value,
                                                          exact_match=True)
                        if len(user_list) > 0:
                            raise RuntimeError, 'user id %s already exist' % (
                                value, )
                        break
            # Check that there is no reindexation related to reference indexation
            if portal.portal_activities.countMessageWithTag(tag):
                raise RuntimeError, 'user id %s already exist' % (value, )

            # Prevent concurrent transaction to set the same reference on 2
            # different persons
            self.getParentValue().serialize()
            # Prevent to set the same reference on 2 different persons during the
            # same transaction
            transactional_variable = getTransactionalVariable()
            if tag in transactional_variable:
                raise RuntimeError, 'user id %s already exist' % (value, )
            else:
                transactional_variable[tag] = None

        self._baseSetReference(value)
        self.reindexObject(activate_kw=activate_kw)
        # invalid the cache for ERP5Security
        portal_caches = portal.portal_caches
        portal_caches.clearCache(cache_factory_list=('erp5_content_short', ))

    # Time management
    security.declareProtected(Permissions.AccessContentsInformation,
                              'getAvailableTime')

    def getAvailableTime(self, *args, **kw):
        """
      Calculate available time for a person

      See SimulationTool.getAvailableTime
      """
        kw['node'] = [self.getUid()]

        portal_simulation = self.getPortalObject().portal_simulation
        return portal_simulation.getAvailableTime(*args, **kw)

    security.declareProtected(Permissions.AccessContentsInformation,
                              'getAvailableTimeSequence')

    def getAvailableTimeSequence(self, *args, **kw):
        """
      Calculate available time for a person in a sequence

      See SimulationTool.getAvailableTimeSequence
      """
        kw['node'] = [self.getUid()]

        portal_simulation = self.getPortalObject().portal_simulation
        return portal_simulation.getAvailableTimeSequence(*args, **kw)

    # Notifiation API
    security.declareProtected(Permissions.AccessContentsInformation,
                              'notifyMessage')

    def notifyMessage(self, message):
        """
Example #16
0
class PlominoDocument(CatalogAware, CMFBTreeFolder, Contained):
    """ These represent the contents in a Plomino database.

    A document contains *items* that may or may not correspond to fields on
    one or more forms.
    """

    security = ClassSecurityInfo()
    implements(interfaces.IPlominoDocument, IAttributeAnnotatable)
    
    portal_type = "PlominoDocument"
    meta_type = "PlominoDocument"
    
    security.declarePublic('__init__')
    def __init__(self, id):
        """ Initialization
        """
        CMFBTreeFolder.__init__(self, id)
        self.id = id
        self.items = PersistentDict()
        self.plomino_modification_time = DateTime().toZone('UTC')

    security.declarePublic('checkBeforeOpenDocument')
    def checkBeforeOpenDocument(self):
        """ Check read permission and open view.

        .. NOTE:: if ``READ_PERMISSION`` is set on the ``view`` action
            itself, it causes an error ('maximum recursion depth exceeded')
            if user hasn't permission.
        """
        if self.isReader():
            return self.OpenDocument()
        else:
            raise Unauthorized, "You cannot read this content"
        
    def doc_path(self):
        return self.getPhysicalPath()

    def doc_url(self):
        """ return valid and nice url:
        - hide plomino_documents
        - use physicalPathToURL if REQUEST available
        """
        path = self.doc_path()
        short_path = [p for p in path if p!="plomino_documents"]
        if hasattr(self, "REQUEST"):
            return self.REQUEST.physicalPathToURL(short_path)
        else:
            return "/".join(short_path)
    
    security.declarePublic('setItem')
    def setItem(self,name,value):
        """
        """
        items = self.items
        if type(value) == type(''):
            db = self.getParentDatabase()
            translation_service = getToolByName(db, 'translation_service')
            value = translation_service.asunicodetype(value)
        items[name] = value
        self.items = items
        self.plomino_modification_time = DateTime().toZone('UTC')

    security.declarePublic('getItem')
    def getItem(self,name, default=''):
        """
        """
        if(self.items.has_key(name)):
            return deepcopy(self.items[name])
        else:
            return default

    security.declarePublic('hasItem')
    def hasItem(self,name):
        """
        """
        return self.items.has_key(name)

    security.declarePublic('removeItem')
    def removeItem(self,name):
        """
        """
        if(self.items.has_key(name)):
            items = self.items
            del items[name]
            self.items = items

    security.declarePublic('getItems')
    def getItems(self):
        """
        """
        return self.items.keys()

    security.declarePublic('getItemClassname')
    def getItemClassname(self,name):
        """
        """
        return self.getItem(name).__class__.__name__

    security.declarePublic('getLastModified')
    def getLastModified(self,asString=False):
        """
        """
        if not hasattr(self, 'plomino_modification_time'):
            self.plomino_modification_time = self.bobobase_modification_time().toZone('UTC')
        if asString:
            return str(self.plomino_modification_time)
        else:
            return self.plomino_modification_time

    security.declarePublic('getRenderedItem')
    def getRenderedItem(self, itemname, form=None, formid=None, convertattachments=False):
        """ Return the item rendered according to the corresponding field. 

        The used form can be, in order of precedence:
        - passed as the `form` parameter,
        - specified with the `formid` parameter and looked up,
        - looked up from the document.

        If no form or field is found, return the empty string.

        If `convertattachments` is True, then we assume that field
        attachments are text and append them to the rendered value. 
        """
        db = self.getParentDatabase()
        result = ''
        if not form:
            if formid:
                form = db.getForm(formid)
            else:
                form = self.getForm()
        if form:
            field = form.getFormField(itemname)
            if field:
                result = field.getFieldRender(form, self, False)
                if (field.getFieldType() == 'ATTACHMENT' and 
                    convertattachments):
                    result += ' ' + db.getIndex().convertFileToText(self, itemname).decode('utf-8')
                    result = result.encode('utf-8')

        return result

    security.declarePublic('tojson')
    def tojson(self, REQUEST=None, item=None, formid=None, rendered=False):
        """return item value as JSON
        (return all items if item=None)
        """
        if not self.isReader():
            raise Unauthorized, "You cannot read this content"
        
        datatables_format = False
        if REQUEST:
            REQUEST.RESPONSE.setHeader('content-type', 'application/json; charset=utf-8')
            item = REQUEST.get('item', item)
            formid = REQUEST.get('formid', formid)
            rendered_str = REQUEST.get('rendered', None)
            if rendered_str:
                rendered = True
            datatables_format_str = REQUEST.get('datatables', None)
            if datatables_format_str:
                datatables_format = True
        if not item:
            return json.dumps(self.items.data)

        if not formid:
            form = self.getForm()
        else:
            form = self.getParentDatabase().getForm(formid)
        if form:
            field = form.getFormField(item)
            if field:
                if field.getFieldType() == 'DATAGRID':
                    adapt = field.getSettings()
                    fieldvalue = adapt.getFieldValue(form, self, False, False, REQUEST)
                    fieldvalue = adapt.rows(fieldvalue, rendered=rendered)
                    if datatables_format:
                        fieldvalue = { 'iTotalRecords': len(fieldvalue), 'aaData': fieldvalue }
                else:
                    if rendered:
                        fieldvalue = self.getRenderedItem(item, form)
                    else:
                        adapt = field.getSettings()
                        fieldvalue = adapt.getFieldValue(form, self, False, False, REQUEST)
            else:
                fieldvalue = self.getItem(item)
        else:
            fieldvalue = self.getItem(item)

        return json.dumps(fieldvalue) 

    security.declarePublic('computeItem')
    def computeItem(self, itemname, form=None, formid=None, store=True, report=True):
        """ return the item value according the formula of the field defined in
        the given form (use default doc form if None)
        and store the value in the doc (if store=True)
        """
        result = None
        db = self.getParentDatabase()
        if not form:
            if not formid:
                form = self.getForm()
            else:
                form = db.getForm(formid)
        if form:
            result = form.computeFieldValue(itemname, self, report=report)
            if store:
                self.setItem(itemname, result)
        return result

    security.declarePublic('getPlominoReaders')
    def getPlominoReaders(self):
        """
        """
        if self.hasItem('Plomino_Readers'):
            return asList(self.Plomino_Readers)
        else:
            return ['*']

    security.declarePublic('isReader')
    def isReader(self):
        """
        """
        return self.getParentDatabase().isCurrentUserReader(self)
        
    security.declarePublic('isAuthor')
    def isAuthor(self):
        """
        """
        return self.getParentDatabase().isCurrentUserAuthor(self)

    security.declareProtected(REMOVE_PERMISSION, 'delete')
    def delete(self, REQUEST=None):
        """delete the current doc
        """
        db = self.getParentDatabase()
        db.deleteDocument(self)
        if not REQUEST is None:
            return_url = REQUEST.get('returnurl')
            REQUEST.RESPONSE.redirect(return_url)

    security.declareProtected(EDIT_PERMISSION, 'validation_errors')
    def validation_errors(self, REQUEST):
        """check submitted values
        """
        db = self.getParentDatabase()
        form = db.getForm(REQUEST.get('Form'))

        errors=form.validateInputs(REQUEST, doc=self)
        if len(errors)>0:
            return self.errors_json(errors=json.dumps({'success': False,'errors':errors}))
        else:
            return self.errors_json(errors=json.dumps({'success': True}))
        
    security.declareProtected(EDIT_PERMISSION, 'saveDocument')
    def saveDocument(self, REQUEST, creation=False):
        """save a document using the form submitted content
        """
        db = self.getParentDatabase()
        form = db.getForm(REQUEST.get('Form'))

        errors=form.validateInputs(REQUEST, doc=self)
        if len(errors)>0:
            return form.notifyErrors(errors)

        self.setItem('Form', form.getFormName())

        # process editable fields (we read the submitted value in the request)
        form.readInputs(self, REQUEST, process_attachments=True)

        # refresh computed values, run onSave, reindex
        self.save(form, creation)

        redirect = REQUEST.get('plominoredirecturl')
        if not redirect:
            redirect = self.getItem("plominoredirecturl")
        if not redirect:
            redirect = self.absolute_url()
        REQUEST.RESPONSE.redirect(redirect)


    security.declareProtected(EDIT_PERMISSION, 'refresh')
    def refresh(self, form=None):
        """ re-compute fields and re-index document
        (onSave event is not called, and authors are not updated 
        """
        self.save(form, creation=False, refresh_index=True, asAuthor=False, onSaveEvent=False)

    security.declareProtected(EDIT_PERMISSION, 'save')
    def save(self, form=None, creation=False, refresh_index=True, asAuthor=True, onSaveEvent=True):
        """refresh values according form, and reindex the document
        """
        # we process computed fields (refresh the value)
        if form is None:
            form = self.getForm()
        else:
            self.setItem('Form', form.getFormName())

        db=self.getParentDatabase()
        if form:
            for f in form.getFormFields(includesubforms=True, doc=self, applyhidewhen=False):
                mode = f.getFieldMode()
                fieldname = f.id
                if mode in ["COMPUTED", "COMPUTEDONSAVE"] or (mode=="CREATION" and creation):
                    result = form.computeFieldValue(fieldname, self)
                    self.setItem(fieldname, result)
                else:
                    # computed for display field are not stored
                    pass

            # compute the document title
            title_formula = form.getDocumentTitle()
            if title_formula:
                # Use the formula if we have one
                try:
                    title = self.runFormulaScript("form_"+form.id+"_title", self, form.DocumentTitle)
                    if title != self.Title():
                        self.setTitle(title)
                except PlominoScriptException, e:
                    e.reportError('Title formula failed')
            elif creation:
                # If we have no formula and we're creating, use Form's title
                title = form.Title()
                if title != self.Title():
                    # We may be calling save with 'creation=True' on
                    # existing documents, in which case we may already have
                    # a title.
                    self.setTitle(title)

            # update the document id
            if creation and form.getDocumentId():
                new_id = self.generateNewId()
                if new_id:
                    transaction.savepoint(optimistic=True)
                    db.documents.manage_renameObject(self.id, new_id)
            
        # update the Plomino_Authors field with the current user name
        if asAuthor:
            authors = self.getItem('Plomino_Authors')
            name = db.getCurrentUser().getUserName()
            if authors == '':
                authors = []
                authors.append(name)
            elif name in authors:
                pass
            else:
                authors.append(name)
            self.setItem('Plomino_Authors', authors)

        # execute the onSaveDocument code of the form
        if form and onSaveEvent:
            try:
                result = self.runFormulaScript("form_"+form.id+"_onsave", self, form.onSaveDocument)
                if result and hasattr(self, 'REQUEST'):
                    self.REQUEST.set('plominoredirecturl', result)
            except PlominoScriptException, e:
                if hasattr(self, 'REQUEST'):
                    e.reportError('Document has been saved but onSave event failed.')
                    doc_path = self.REQUEST.physicalPathToURL(self.doc_path())
                    self.REQUEST.RESPONSE.redirect(doc_path)
Example #17
0
class PortalFolderBase(DynamicType, CMFCatalogAware, Folder):
    """Base class for portal folder
    """
    meta_type = 'Portal Folder Base'

    implements(IFolderish)
    __implements__ = (z2IFolderish, DynamicType.__implements__,
                      Folder.__implements__)

    security = ClassSecurityInfo()

    description = ''

    manage_options = (Folder.manage_options + CMFCatalogAware.manage_options)

    def __init__(self, id, title=''):
        self.id = id
        self.title = title

    #
    #   'MutableDublinCore' interface methods
    #
    security.declareProtected(ManageProperties, 'setTitle')

    def setTitle(self, title):
        """ Set Dublin Core Title element - resource name.
        """
        self.title = title

    security.declareProtected(ManageProperties, 'setDescription')

    def setDescription(self, description):
        """ Set Dublin Core Description element - resource summary.
        """
        self.description = description

    #
    #   other methods
    #
    security.declareProtected(ManageProperties, 'edit')

    def edit(self, title='', description=''):
        """
        Edit the folder title (and possibly other attributes later)
        """
        self.setTitle(title)
        self.setDescription(description)
        self.reindexObject()

    security.declarePublic('allowedContentTypes')

    def allowedContentTypes(self):
        """
            List type info objects for types which can be added in
            this folder.
        """
        result = []
        portal_types = getToolByName(self, 'portal_types')
        myType = portal_types.getTypeInfo(self)

        if myType is not None:
            for contentType in portal_types.listTypeInfo(self):
                if myType.allowType(contentType.getId()):
                    result.append(contentType)
        else:
            result = portal_types.listTypeInfo()

        return filter(
            lambda typ, container=self: typ.isConstructionAllowed(container),
            result)

    def _filteredItems(self, ids, filt):
        """
            Apply filter, a mapping, to child objects indicated by 'ids',
            returning a sequence of ( id, obj ) tuples.
        """
        # Restrict allowed content types
        if filt is None:
            filt = {}
        else:
            # We'll modify it, work on a copy.
            filt = filt.copy()
        pt = filt.get('portal_type', [])
        if type(pt) is type(''):
            pt = [pt]
        types_tool = getToolByName(self, 'portal_types')
        allowed_types = types_tool.listContentTypes()
        if not pt:
            pt = allowed_types
        else:
            pt = [t for t in pt if t in allowed_types]
        if not pt:
            # After filtering, no types remain, so nothing should be
            # returned.
            return []
        filt['portal_type'] = pt

        query = ContentFilter(**filt)
        result = []
        append = result.append
        get = self._getOb
        for id in ids:
            obj = get(id)
            if query(obj):
                append((id, obj))
        return result

    #
    #   'Folderish' interface methods
    #
    security.declarePublic('contentItems')

    def contentItems(self, filter=None):
        # List contentish and folderish sub-objects and their IDs.
        # (method is without docstring to disable publishing)
        #
        ids = self.objectIds()
        return self._filteredItems(ids, filter)

    security.declarePublic('contentIds')

    def contentIds(self, filter=None):
        # List IDs of contentish and folderish sub-objects.
        # (method is without docstring to disable publishing)
        #
        return [item[0] for item in self.contentItems(filter)]

    security.declarePublic('contentValues')

    def contentValues(self, filter=None):
        # List contentish and folderish sub-objects.
        # (method is without docstring to disable publishing)
        #
        return [item[1] for item in self.contentItems(filter)]

    security.declareProtected(ListFolderContents, 'listFolderContents')

    def listFolderContents(self, contentFilter=None):
        """ List viewable contentish and folderish sub-objects.
        """
        l = []
        for id, obj in self.contentItems(contentFilter):
            # validate() can either raise Unauthorized or return 0 to
            # mean unauthorized.
            try:
                if getSecurityManager().validate(self, self, id, obj):
                    l.append(obj)
            except zExceptions_Unauthorized:  # Catch *all* Unauths!
                pass
        return l

    #
    #   webdav Resource method
    #

    # protected by 'WebDAV access'
    def listDAVObjects(self):
        # List sub-objects for PROPFIND requests.
        # (method is without docstring to disable publishing)
        #
        if _checkPermission(ManagePortal, self):
            return self.objectValues()
        else:
            return self.listFolderContents()

    #
    #   'DublinCore' interface methods
    #
    security.declareProtected(View, 'Title')

    def Title(self):
        """ Dublin Core Title element - resource name.
        """
        return self.title

    security.declareProtected(View, 'Description')

    def Description(self):
        """ Dublin Core Description element - resource summary.
        """
        return self.description

    security.declareProtected(View, 'Type')

    def Type(self):
        """ Dublin Core Type element - resource type.
        """
        ti = self.getTypeInfo()
        return ti is not None and ti.Title() or 'Unknown'

    #
    #   other methods
    #
    security.declarePublic('encodeFolderFilter')

    def encodeFolderFilter(self, REQUEST):
        """
            Parse cookie string for using variables in dtml.
        """
        filter = {}
        for key, value in REQUEST.items():
            if key[:10] == 'filter_by_':
                filter[key[10:]] = value
        encoded = base64.encodestring(marshal.dumps(filter)).strip()
        encoded = ''.join(encoded.split('\n'))
        return encoded

    security.declarePublic('decodeFolderFilter')

    def decodeFolderFilter(self, encoded):
        """
            Parse cookie string for using variables in dtml.
        """
        filter = {}
        if encoded:
            filter.update(marshal.loads(base64.decodestring(encoded)))
        return filter

    def content_type(self):
        """
            WebDAV needs this to do the Right Thing (TM).
        """
        return None

    # Ensure pure PortalFolders don't get cataloged.
    # XXX We may want to revisit this.

    def indexObject(self):
        pass

    def unindexObject(self):
        pass

    def reindexObject(self, idxs=[]):
        pass

    def reindexObjectSecurity(self):
        pass

    def PUT_factory(self, name, typ, body):
        """ Factory for PUT requests to objects which do not yet exist.

        Used by NullResource.PUT.

        Returns -- Bare and empty object of the appropriate type (or None, if
        we don't know what to do)
        """
        registry = getToolByName(self, 'content_type_registry', None)
        if registry is None:
            return None

        typeObjectName = registry.findTypeName(name, typ, body)
        if typeObjectName is None:
            return None

        self.invokeFactory(typeObjectName, name)

        # invokeFactory does too much, so the object has to be removed again
        obj = aq_base(self._getOb(name))
        self._delObject(name)
        return obj

    security.declareProtected(AddPortalContent, 'invokeFactory')

    def invokeFactory(self, type_name, id, RESPONSE=None, *args, **kw):
        """ Invokes the portal_types tool.
        """
        pt = getToolByName(self, 'portal_types')
        myType = pt.getTypeInfo(self)

        if myType is not None:
            if not myType.allowType(type_name):
                raise ValueError('Disallowed subobject type: %s' % type_name)

        return pt.constructContent(type_name, self, id, RESPONSE, *args, **kw)

    security.declareProtected(AddPortalContent, 'checkIdAvailable')

    def checkIdAvailable(self, id):
        try:
            self._checkId(id)
        except BadRequest:
            return False
        else:
            return True

    def MKCOL_handler(self, id, REQUEST=None, RESPONSE=None):
        """
            Handle WebDAV MKCOL.
        """
        self.manage_addFolder(id=id, title='')

    def _checkId(self, id, allow_dup=0):
        PortalFolderBase.inheritedAttribute('_checkId')(self, id, allow_dup)

        if allow_dup:
            return

        # FIXME: needed to allow index_html for join code
        if id == 'index_html':
            return

        # Another exception: Must allow "syndication_information" to enable
        # Syndication...
        if id == 'syndication_information':
            return

        # This code prevents people other than the portal manager from
        # overriding skinned names and tools.
        if not getSecurityManager().checkPermission(ManagePortal, self):
            ob = self
            while ob is not None and not getattr(ob, '_isPortalRoot', False):
                ob = aq_parent(aq_inner(ob))
            if ob is not None:
                # If the portal root has a non-contentish object by this name,
                # don't allow an override.
                if (hasattr(ob, id) and id not in ob.contentIds() and
                        # Allow root doted prefixed object name overrides
                        not id.startswith('.')):
                    raise BadRequest('The id "%s" is reserved.' % id)
            # Don't allow ids used by Method Aliases.
            ti = self.getTypeInfo()
            if ti and ti.queryMethodID(id, context=self):
                raise BadRequest('The id "%s" is reserved.' % id)
        # Otherwise we're ok.

    def _verifyObjectPaste(self, object, validate_src=1):
        # This assists the version in OFS.CopySupport.
        # It enables the clipboard to function correctly
        # with objects created by a multi-factory.
        securityChecksDone = False
        sm = getSecurityManager()
        parent = aq_parent(aq_inner(object))
        object_id = object.getId()
        mt = getattr(object, '__factory_meta_type__', None)
        meta_types = getattr(self, 'all_meta_types', None)

        if mt is not None and meta_types is not None:
            method_name = None
            permission_name = None

            if callable(meta_types):
                meta_types = meta_types()

            for d in meta_types:

                if d['name'] == mt:
                    method_name = d['action']
                    permission_name = d.get('permission', None)
                    break

            if permission_name is not None:

                if not sm.checkPermission(permission_name, self):
                    raise AccessControl_Unauthorized, method_name

                if validate_src:

                    if not sm.validate(None, parent, None, object):
                        raise AccessControl_Unauthorized, object_id

                if validate_src > 1:
                    if not sm.checkPermission(DeleteObjects, parent):
                        raise AccessControl_Unauthorized

                # validation succeeded
                securityChecksDone = 1

            #
            # Old validation for objects that may not have registered
            # themselves in the proper fashion.
            #
            elif method_name is not None:

                meth = self.unrestrictedTraverse(method_name)

                factory = getattr(meth, 'im_self', None)

                if factory is None:
                    factory = aq_parent(aq_inner(meth))

                if not sm.validate(None, factory, None, meth):
                    raise AccessControl_Unauthorized, method_name

                # Ensure the user is allowed to access the object on the
                # clipboard.
                if validate_src:

                    if not sm.validate(None, parent, None, object):
                        raise AccessControl_Unauthorized, object_id

                if validate_src > 1:  # moving
                    if not sm.checkPermission(DeleteObjects, parent):
                        raise AccessControl_Unauthorized

                securityChecksDone = 1

        # Call OFS' _verifyObjectPaste if necessary
        if not securityChecksDone:
            PortalFolderBase.inheritedAttribute('_verifyObjectPaste')(
                self, object, validate_src)

        # Finally, check allowed content types
        if hasattr(aq_base(object), 'getPortalTypeName'):

            type_name = object.getPortalTypeName()

            if type_name is not None:

                pt = getToolByName(self, 'portal_types')
                myType = pt.getTypeInfo(self)

                if myType is not None and not myType.allowType(type_name):
                    raise ValueError('Disallowed subobject type: %s' %
                                     type_name)

    security.setPermissionDefault(AddPortalContent, ('Owner', 'Manager'))

    security.declareProtected(AddPortalFolders, 'manage_addFolder')

    def manage_addFolder(self, id, title='', REQUEST=None):
        """ Add a new folder-like object with id *id*.

        IF present, use the parent object's 'mkdir' alias; otherwise, just add
        a PortalFolder.
        """
        ti = self.getTypeInfo()
        method_id = ti and ti.queryMethodID('mkdir', context=self)
        if method_id:
            # call it
            getattr(self, method_id)(id=id)
        else:
            self.invokeFactory(type_name='Folder', id=id)

        ob = self._getOb(id)
        ob.setTitle(title)
        try:
            ob.reindexObject()
        except AttributeError:
            pass

        if REQUEST is not None:
            return self.manage_main(self, REQUEST, update_menu=1)
Example #18
0
# Rights Reserved.
#
# Authors:
#
# Cornel Nitu, Eau de Web Romania
from Products import Naaya

from Products.Naaya.NyFolder import NyFolder
from AccessControl import ClassSecurityInfo
from Products.NaayaBase.constants import PERMISSION_PUBLISH_OBJECTS, MESSAGE_SAVEDCHANGES
from Products.Naaya.constants import METATYPE_FOLDER
from naaya.content.semide.news.semnews_item import METATYPE_OBJECT as METATYPE_NYSEMNEWS
from naaya.content.semide.event.semevent_item import METATYPE_OBJECT as METATYPE_NYSEMEVENT
from Globals import InitializeClass

security = ClassSecurityInfo()

def getFolders(self): 
    return [x for x in self.objectValues(METATYPE_FOLDER) if x.submitted==1]
NyFolder.getFolders = getFolders

def hasContent(self): 
    return (len(self.getObjects()) > 0) or (len(self.objectValues(METATYPE_FOLDER)) > 0)
NyFolder.hasContent = hasContent

def getPublishedFolders(self): 
    return self.utSortObjsListByAttr([x for x in self.objectValues(METATYPE_FOLDER) if x.approved==1 and x.submitted==1], 'sortorder', 0)
NyFolder.getPublishedFolders = getPublishedFolders

security.declareProtected(PERMISSION_PUBLISH_OBJECTS, 'basketofapprovals_published_html')
def basketofapprovals_published_html(self, REQUEST=None, RESPONSE=None):
Example #19
0
    security.declareProtected(PERMISSION_VIEW, 'getFAQs')
    getFAQs = CategoriesContainer.getItems
    
    security.declareProtected(PERMISSION_MANAGE_CONTENT, 'deleteFAQ')
    deleteFAQ = BaseContainer.deleteItem
            
    security.declareProtected(PERMISSION_VIEW, 'countFAQ')
    countFAQ = BaseContainer.countItems    
        
templates = ('zpt/faq/FAQManagement',
             #'zpt/faq/addPageForm',
             'zpt/faq/deleteFAQForm',
            )
addTemplates2Class(FAQContainer, templates, globals_=globals())

security = ClassSecurityInfo()
#security.declareProtected(MANAGE_CONTENT_PERMISSIONS, 'addFAQForm')
security.declareProtected(MANAGE_CONTENT_PERMISSIONS, 'deleteFAQForm')
security.declareProtected(MANAGE_CONTENT_PERMISSIONS, 'FAQManagement')
security.apply(FAQContainer)
InitializeClass(FAQContainer)
        
        
######################################################################
## FAQ
######################################################################
manage_addFAQForm = PTF('zpt/faq/addFAQForm', globals())
def manage_addFAQ(dispatcher, id, title,
                  abstract='', body='', publish_date=None,
                  category = None, REQUEST=None):
    """
Example #20
0
class ActionsTool(UniqueObject, Folder, ActionProviderBase):
    """
        Weave together the various sources of "actions" which are apropos
        to the current user and context.
    """

    __implements__ = (IActionsTool, ActionProviderBase.__implements__)

    id = 'portal_actions'
    meta_type = 'CMF Actions Tool'
    _actions = (ActionInformation(
        id='folderContents',
        title='Folder contents',
        action=Expression(text='string:${folder_url}/folder_contents'),
        condition=Expression(text='python: folder is not object'),
        permissions=(ListFolderContents, ),
        category='folder',
        visible=1), )

    action_providers = ('portal_membership', 'portal_actions',
                        'portal_registration', 'portal_types',
                        'portal_discussion', 'portal_undo',
                        'portal_syndication', 'portal_workflow',
                        'portal_properties')

    security = ClassSecurityInfo()

    manage_options = (ActionProviderBase.manage_options +
                      ({
                          'label': 'Action Providers',
                          'action': 'manage_actionProviders'
                      }, {
                          'label': 'Overview',
                          'action': 'manage_overview'
                      }) + Folder.manage_options)

    #
    #   ZMI methods
    #
    security.declareProtected(ManagePortal, 'manage_overview')
    manage_overview = DTMLFile('explainActionsTool', _dtmldir)
    manage_actionProviders = DTMLFile('manageActionProviders', _dtmldir)

    security.declareProtected(ManagePortal, 'manage_aproviders')

    def manage_aproviders(self,
                          apname='',
                          chosen=(),
                          add_provider=0,
                          del_provider=0,
                          REQUEST=None):
        """
        Manage action providers through-the-web.
        """
        providers = list(self.listActionProviders())
        new_providers = []
        if add_provider:
            providers.append(apname)
        elif del_provider:
            for item in providers:
                if item not in chosen:
                    new_providers.append(item)
            providers = new_providers
        self.action_providers = tuple(providers)
        if REQUEST is not None:
            return self.manage_actionProviders(
                self, REQUEST, manage_tabs_message='Providers changed.')

    #
    #   Programmatically manipulate the list of action providers
    #
    security.declareProtected(ManagePortal, 'listActionProviders')

    def listActionProviders(self):
        """ List the ids of all Action Providers queried by this tool.
        """
        return self.action_providers

    security.declareProtected(ManagePortal, 'addActionProvider')

    def addActionProvider(self, provider_name):
        """ Add an Action Provider id to the providers queried by this tool.
        """
        ap = list(self.action_providers)
        if hasattr(self, provider_name) and provider_name not in ap:
            ap.append(provider_name)
            self.action_providers = tuple(ap)

    security.declareProtected(ManagePortal, 'deleteActionProvider')

    def deleteActionProvider(self, provider_name):
        """ Delete an Action Provider id from providers queried by this tool.
        """
        ap = list(self.action_providers)
        if provider_name in ap:
            ap.remove(provider_name)
            self.action_providers = tuple(ap)

    #
    #   'portal_actions' interface methods
    #
    security.declarePublic('listFilteredActionsFor')

    def listFilteredActionsFor(self, object=None):
        """ List all actions available to the user.
        """
        #cache = None
        #cache_mgr = getToolByName(self, 'portal_actionscache', None)

        #if cache_mgr is not None:
        #    cache = cache_mgr.ZCacheManager_getCache()

        #if cache is not None:
        #    pm = getToolByName(self, 'portal_membership')
        #    if object is None:
        #        object_url = ''
        #    else:
        #        object_url = object.absolute_url()
        #    if pm.isAnonymousUser():
        #        member = None
        #    else:
        #        member = pm.getAuthenticatedMember()
        #    # Prepare a cache key.
        #    keyset = {'object_url': object_url,
        #              'member': member,
        #             }
        #    result = cache.ZCache_get(ob=self, keywords=keyset)
        #    if result is not None:
        #        # Got a cached value.
        #        return result

        actions = []
        ec = getExprContext(self, object)

        # Include actions from specific tools.
        for provider_name in self.listActionProviders():
            provider = getattr(self, provider_name)
            if IActionProvider.isImplementedBy(provider):
                start = time()
                actions.extend(provider.listActionInfos(object=object, ec=ec))
                stop = time()
                open('/tmp/provider_times',
                     'a').write('%-20s: %8.3f\n' % (provider_name,
                                                    (stop - start) * 1000))
            else:
                # for Action Providers written for CMF versions before 1.5
                actions.extend(self._listActionInfos(provider, object))

        # Include actions from object.
        if object is not None:
            base = aq_base(object)
            if IActionProvider.isImplementedBy(base):
                actions.extend(object.listActionInfos(object=object))
            elif hasattr(base, 'listActions'):
                # for objects written for CMF versions before 1.5
                actions.extend(self._listActionInfos(object, object))

        # Reorganize the actions by category.
        filtered_actions = {
            'user': [],
            'folder': [],
            'object': [],
            'global': [],
            'workflow': [],
        }

        for action in actions:
            catlist = filtered_actions.setdefault(action['category'], [])
            catlist.append(action)

        #if cache is not None:
        #    result = cache.ZCache_set(ob=self, data=filtered_actions,
        #                              keywords=keyset)
        return filtered_actions

    # listFilteredActions() is an alias.
    security.declarePublic('listFilteredActions')
    listFilteredActions = listFilteredActionsFor

    security.declarePrivate('ZCacheable_getModTime')

    def ZCacheable_getModTime(self, mtime_func=None):
        '''Returns the highest of the last mod times.'''
        # Based on:
        #   mtime_func
        #   self.mtime
        #   self.__class__.mtime
        #   (if in a ZClass) zclass_instance.mtime
        #                    zclass_instance.__class__.mtime
        mtime = mtime_func and mtime_func() or 0
        base = aq_base(self)
        return max(getattr(base, '_p_mtime', mtime), mtime)

    #
    #   Helper method for backwards compatibility
    #
    def _listActionInfos(self, provider, object):
        """ for Action Providers written for CMF versions before 1.5
        """
        warn(
            'ActionProvider interface not up to date. In CMF 1.6 '
            'portal_actions will ignore listActions() of \'%s\'.' %
            provider.getId(), DeprecationWarning)
        info = getOAI(self, object)
        actions = provider.listActions(info)

        action_infos = []
        if actions and not isinstance(actions[0], dict):
            ec = getExprContext(self, object)
            for ai in actions:
                if not ai.getVisibility():
                    continue
                permissions = ai.getPermissions()
                if permissions:
                    category = ai.getCategory()
                    if (object is not None
                            and (category.startswith('object')
                                 or category.startswith('workflow'))):
                        context = object
                    elif (info['folder'] is not None
                          and category.startswith('folder')):
                        context = info['folder']
                    else:
                        context = info['portal']
                    for permission in permissions:
                        allowed = _checkPermission(permission, context)
                        if allowed:
                            break
                    if not allowed:
                        continue
                if not ai.testCondition(ec):
                    continue
                action_infos.append(ai.getAction(ec))
        else:
            for i in actions:
                if not i.get('visible', 1):
                    continue
                permissions = i.get('permissions', None)
                if permissions:
                    category = i['category']
                    if (object is not None
                            and (category.startswith('object')
                                 or category.startswith('workflow'))):
                        context = object
                    elif (info['folder'] is not None
                          and category.startswith('folder')):
                        context = info['folder']
                    else:
                        context = info['portal']

                    for permission in permissions:
                        allowed = _checkPermission(permission, context)
                        if allowed:
                            break
                    if not allowed:
                        continue
                action_infos.append(i)
        return action_infos
Example #21
0
from Products.DCWorkflow.utils import Message as _
from Products.DCWorkflow.Transitions import TRIGGER_USER_ACTION

from Products.CMFCore.utils import getToolByName
from Products.ZSQLCatalog.SQLCatalog import SimpleQuery, AutoQuery, ComplexQuery, NegatedQuery
from Products.CMFCore.utils import _getAuthenticatedUser
from Products.ERP5Type import Permissions
from Products.ERP5Type.Cache import CachingMethod
from sets import ImmutableSet
from Acquisition import aq_base
from Persistence import Persistent
from Products.ERP5Type.Globals import PersistentMapping
from MySQLdb import ProgrammingError, OperationalError
from DateTime import DateTime

security = ClassSecurityInfo()
WorkflowTool.security = security


def DCWorkflowDefinition_notifyWorkflowMethod(self, ob, transition_list, args=None, kw=None):
    """
    Allows the system to request a workflow action.  This method
    must perform its own security checks.
    """
    if type(transition_list) in StringTypes:
        method_id = transition_list
    elif len(transition_list) == 1:
        method_id = transition_list[0]
    else:
        raise ValueError("WorkflowMethod should be attached to exactly 1 transition per DCWorkflow instance.")
    sdef = self._getWorkflowStateOf(ob)
Example #22
0
class BusinessProcessConfiguratorItem(ConfiguratorItemMixin, XMLObject):
    """ Setup Rules. """

    meta_type = 'ERP5 Business Process Configurator Item'
    portal_type = 'Business Process Configurator Item'
    add_permission = Permissions.AddPortalContent
    isPortalContent = 1
    isRADContent = 1

    # Declarative security
    security = ClassSecurityInfo()
    security.declareObjectProtected(Permissions.AccessContentsInformation)

    # Declarative interfaces
    zope.interface.implements(interfaces.IConfiguratorItem)

    # Declarative properties
    property_sheets = (PropertySheet.Base, PropertySheet.XMLObject,
                       PropertySheet.CategoryCore, PropertySheet.DublinCore,
                       PropertySheet.ConfiguratorItem, PropertySheet.Reference)

    def _build(self, business_configuration):
        portal = self.getPortalObject()
        business_process = portal.business_process_module.newContent(
            portal_type="Business Process",
            reference=self.getReference(),
            title=self.getTitle())

        business_configuration.setGlobalConfigurationAttr(\
                      business_process_id=business_process.getId())

        business_process_dict = self._getBusinessProcessDict()
        int_index = 0
        for path_dict in business_process_dict["Trade Model Path"]:
            int_index += 1
            path_dict.setdefault("int_index", int_index)
            title = path_dict.pop('title')
            trade_phase = path_dict.pop('trade_phase')
            trade_date = path_dict.pop('trade_date')
            for key in path_dict:
                if path_dict[key] is None:
                    path_dict.pop(key)
            self._addTradeModelPath(business_process=business_process,
                                    title=title,
                                    trade_phase=trade_phase,
                                    trade_date=trade_date,
                                    **path_dict)

        int_index = 0
        for link_dict in business_process_dict["Business Link"]:
            int_index += 1
            link_dict.setdefault("int_index", int_index)
            title = link_dict.pop('title')
            trade_phase = link_dict.pop('trade_phase')
            delivery_builder = link_dict.pop('delivery_builder', None)
            predecessor = link_dict.pop('predecessor', None)
            successor = link_dict.pop('successor', None)
            for key in path_dict:
                if path_dict[key] is None:
                    path_dict.pop(key)

            self._addBusinessLink(business_process=business_process,
                                  title=title,
                                  trade_phase=trade_phase,
                                  predecessor=predecessor,
                                  successor=successor,
                                  delivery_builder=delivery_builder,
                                  **link_dict)

        business_process.validate(
            comment=translateString('Validated by configurator'))
        self.install(business_process, business_configuration)

    def _getBusinessProcessDict(self):
        """ Read the spreadsheet and return the configuration for
        Trade Model Paths and Business Links.
    """
        return self.ConfigurationTemplate_readOOCalcFile(
            "standard_business_process.ods",
            data=self.getDefaultConfigurationSpreadsheetData())

    def _addTradeModelPath(self, business_process, title, trade_phase,
                           trade_date, **kw):
        """ Add a trade model path to the business process.
    """
        reference = "TMP-%s" % "-".join(title.upper().strip().split(" "))
        path_id = "%s_path" % "_".join(title.lower().strip().split(" "))
        trade_model_path = business_process.newContent(
            portal_type="Trade Model Path",
            id=path_id,
            title=title,
            reference=reference,
            **kw)

        trade_model_path.setTradePhase(trade_phase)
        if trade_date is not None:
            trade_model_path.setTradeDate('trade_phase/%s' % trade_date)

    def _addBusinessLink(self, business_process, title, trade_phase,
                         predecessor, successor, delivery_builder, **kw):
        link_id = "%s_link" % "_".join(title.lower().strip().split(" "))
        business_link = business_process.newContent(
            portal_type="Business Link", id=link_id, title=title, **kw)

        completed_state = kw.pop("completed_state", None)
        if completed_state is not None:
            business_link.setCompletedStateList(completed_state.split(","))

        frozen_state = kw.pop("frozen_state", None)
        if frozen_state is not None:
            business_link.setFrozenStateList(frozen_state.split(","))

        business_link.setTradePhase(trade_phase)
        if successor is not None:
            business_link.setSuccessor("trade_state/%s" % successor)
        if predecessor is not None:
            business_link.setPredecessor("trade_state/%s" % predecessor)

        if delivery_builder is not None:
            business_link.setDeliveryBuilderList(
                   ["delivery_builder/portal_deliveries/%s" % \
                        i for i in delivery_builder.split(",")])
Example #23
0
        try:
            return int(num)
        except ValueError:
            raise e

    def page(self, number, softlimit=False):
        try:
            return super(ExPaginator, self).page(number)
        except InvalidPage, e:
            number = self._ensure_int(number, e)
            if number > self.num_pages and softlimit:
                return self.page(self.num_pages, softlimit=False)
            else:
                raise e

    security = ClassSecurityInfo()
    security.setDefaultAccess("allow")

InitializeClass(ExPaginator)

class DiggPaginator(ExPaginator):
    """
    Based on Django's default paginator, it adds "Digg-style" page ranges
    with a leading block of pages, an optional middle block, and another
    block at the end of the page range. They are available as attributes
    on the page:

    {# with: page = digg_paginator.page(1) #}
    {% for num in page.leading_range %} ...
    {% for num in page.main_range %} ...
    {% for num in page.trailing_range %} ...
class AvailabilityColl(object):
    security = ClassSecurityInfo()
    security.setDefaultAccess('allow')

    @staticmethod
    def getDefaultAvailabilityStart(dmd):
        return time.time(
        ) - dmd.ZenEventManager.defaultAvailabilityDays * 24 * 60 * 60

    @staticmethod
    def getDefaultAvailabilityEnd():
        return time.time()

    # Simple record for holding availability information
    def __init__(self,
                 device,
                 component,
                 downtime,
                 total,
                 DeviceGroup='',
                 System='',
                 Location='',
                 DeviceClass='',
                 link='',
                 title=''):
        self.device = device
        self.component = component
        self.systems = System
        self.location = Location
        self.groups = DeviceGroup
        self.DeviceClass = DeviceClass
        self.link = link
        self.title = title

        # Guard against endDate being equal to or less than startDate.
        if total <= 0:
            self.availability = 0 if downtime else 1
        else:
            self.availability = max(0, 1 - (float(downtime) / total))

    def floatStr(self):
        return '%2.3f%%' % (self.availability * 100)

    def __str__(self):
        return self.floatStr()

    def __repr__(self):
        return '[%s %s %s]' % (self.device, self.component, self.floatStr())

    def __float__(self):
        return float(self.availability)

    def __int__(self):
        return int(self.availability * 100)

    def __cmp__(self, other):
        return cmp((self.availability, self.device, self.component()),
                   (other.availability, other.device, other.component()))

    def getDevice(self, dmd):
        return dmd.Devices.findDevice(self.device)

    def getComponent(self, dmd):
        if self.device and self.component:
            device = self.getDevice(dmd)
            if device:
                return _findComponent(device, self.component)
        return None

    def getDeviceLink(self, dmd=None):
        if self.link:
            return self.link
        if dmd:
            device = self.getDevice(dmd)
        if device:
            return device.getDeviceLink()
        return None
Example #25
0
                REQUEST['msg'] = msg
                return self.editCommentsForm(self,REQUEST)
        else:
            return msg
    
templates = ('zpt/tabComments',
             'zpt/editCommentsForm',
             'zpt/mail_newCommentToWebmaster',
             'zpt/mail_newCommentToParent',
             'zpt/mail_rejectCommentToAuthor',
             'zpt/mail_deleteCommentToAuthor',
             'zpt/mail_approveCommentToAuthor',
            )
addTemplates2Class(CommentsStorage, templates, globals_=globals())

security = ClassSecurityInfo()
security.declareProtected(VMS, 'tabComments')
security.declareProtected(MANAGE_CONTENT_PERMISSIONS, 'editCommentsForm')
security.declarePrivate('mail_newCommentToWebmaster')
security.declarePrivate('mail_newCommentToParent')
security.declarePrivate('mail_rejectCommentToAuthor')
security.declarePrivate('mail_deleteCommentToAuthor')
security.declarePrivate('mail_approveCommentToAuthor')
security.apply(CommentsStorage)


import unittest
import sys
class CommentsStorageTests(unittest.TestCase):
    """
    Test class for CommentsStorage class 
Example #26
0
class ScriptChannel(PythonScript, utils):
    """ """

    implements(IScriptChannel)

    meta_type = METATYPE_SCRIPTCHANNEL
    icon = 'misc_/NaayaCore/ScriptChannel.gif'

    manage_options = (({
        'label': 'Properties',
        'action': 'manage_properties_html'
    }, ) + (PythonScript.manage_options[0], ) +
                      PythonScript.manage_options[2:])

    security = ClassSecurityInfo()

    def __init__(self, id, title, description, language, type, numberofitems):
        """ """
        PythonScript.__dict__['__init__'](self, id)
        self.id = id
        self.title = title
        self.description = description
        self.language = language
        self.type = type
        self.numberofitems = numberofitems

    def ZPythonScript_setTitle(self, title):
        if isinstance(title, str):
            title = title.decode('utf-8')
        self.title = title
        self.ZCacheable_invalidate()

    security.declarePrivate('syndicateThis')

    def syndicateThis(self):
        xml = rss_item_for_channel(self)
        return etree.tostring(xml, xml_declaration=False, encoding="utf-8")

    security.declareProtected(view_management_screens, 'manageProperties')

    def manageProperties(self,
                         title='',
                         description='',
                         language=None,
                         type='',
                         numberofitems='',
                         REQUEST=None):
        """ """
        if language is None:
            language = self.gl_get_selected_language()
        try:
            numberofitems = abs(int(numberofitems))
        except:
            numberofitems = 0
        self.title = title
        self.description = description
        self.language = language
        self.type = type
        self.numberofitems = numberofitems
        self._p_changed = 1
        if REQUEST:
            REQUEST.RESPONSE.redirect('manage_properties_html')

    def get_objects_for_rdf(self, attr=None, reversed=False):
        # return the objects to be syndicated
        # sorted by the attribute attr
        objects = self._exec({'context': self, 'container': self}, {}, {})
        if not objects:
            objects = []
        now = DateTime()
        objects = [
            ob for ob in objects if getattr(ob, 'topitem', None)
            or getattr(ob, 'expirationdate', now) is None
            or getattr(ob, 'expirationdate', now) + 1 > now
        ]
        if attr is not None:
            return utils.utSortObjsListByAttr(self, objects, attr, reversed)
        return objects

    security.declareProtected(view, 'index_html')

    def index_html(self, feed='', REQUEST=None, RESPONSE=None):
        """ """
        if feed == 'atom':
            return self.syndicateAtom(self, self.get_objects_for_rdf(),
                                      self.language)

        s = self.getSite()
        lang = self.language
        if lang == 'auto':
            lang = self.gl_get_selected_language()
        l_items = self.get_objects_for_rdf()
        namespaces = self.getNamespaceItemsList()
        nsmap = get_nsmap(namespaces)
        header = []
        for n in namespaces:
            header.append(str(n))
        rdf_namespace = nsmap['rdf']
        Rdf = ElementMaker(namespace=rdf_namespace, nsmap=nsmap)
        E = ElementMaker(None, nsmap=nsmap)

        xml = Rdf.RDF(rss_channel_for_channel(self, lang))

        channel = xml[0]
        items = channel[-1]
        seq = etree.SubElement(items, '{%s}Seq' % rdf_namespace)
        for i in l_items:
            x = etree.SubElement(seq,
                                 '{%s}li' % rdf_namespace,
                                 resource=i.absolute_url())
        if self.hasImage():
            image = E.image(E.title(self.title), E.url(self.getImagePath()),
                            E.link(s.absolute_url()),
                            E.description(self.utToUtf8(self.description)))
            xml.append(image)
        received_items = ''.join([i.syndicateThis() for i in l_items])
        received = '<rdf:RDF %s>%s</rdf:RDF>' % (''.join(header),
                                                 received_items)
        xml_received = etree.XML(received, etree.XMLParser(strip_cdata=False))
        xml.extend(xml_received)
        self.REQUEST.RESPONSE.setHeader('content-type', 'text/xml')
        return etree.tostring(xml, xml_declaration=True, encoding="utf-8")

    # zmi pages
    security.declareProtected(view_management_screens,
                              'manage_properties_html')
    manage_properties_html = PageTemplateFile('zpt/scriptchannel_properties',
                                              globals())
Example #27
0
        extension = filename.lower()[filename.rfind('.')+1:]
        if ICON_ASSOCIATIONS.has_key(extension):
            return '%s/%s'%(icon_location, ICON_ASSOCIATIONS[extension])
        else:
            return default

        
    
    #security.declareProtected(MANAGE_CONTENT_PERMISSIONS, 'FileManagement')

templates = ('zpt/FileManagement', 
             'zpt/deleteFileForm',
            )
addTemplates2Class(FilesContainer, templates, globals_=globals())

security = ClassSecurityInfo()
security.declareProtected(MANAGE_CONTENT_PERMISSIONS, 'FileManagement')
security.apply(FilesContainer)


InitializeClass(FilesContainer)
        
        
#-------------------------------------------------------------------------------

manage_addFileForm = PTF('zpt/addFileForm', globals())

def manage_addFile(dispatcher, title, file, fileid='',
                            abstract=u'', REQUEST=None):
    """ create """
Example #28
0
class SetupTool(Folder):
    """ Profile-based site configuration manager.
    """

    implements(ISetupTool)

    meta_type = 'Generic Setup Tool'

    _baseline_context_id = ''
    # BBB _import_context_id is a vestige of a stateful import context
    _import_context_id = ''

    _profile_upgrade_versions = {}

    security = ClassSecurityInfo()

    def __init__(self, id):
        self.id = str(id)
        self._import_registry = ImportStepRegistry()
        self._export_registry = ExportStepRegistry()
        self._toolset_registry = ToolsetRegistry()

    #
    #   ISetupTool API
    #
    security.declareProtected(ManagePortal, 'getEncoding')

    def getEncoding(self):
        """ See ISetupTool.
        """
        return 'utf-8'

    security.declareProtected(ManagePortal, 'getImportContextID')

    def getImportContextID(self):
        """ See ISetupTool.
        """
        warn(
            'getImportContextId, and the very concept of a stateful '
            'active import context, is deprecated.  You can find the '
            'base profile that was applied using getBaselineContextID.',
            DeprecationWarning,
            stacklevel=2)
        return self._import_context_id

    security.declareProtected(ManagePortal, 'getBaselineContextID')

    def getBaselineContextID(self):
        """ See ISetupTool.
        """
        return self._baseline_context_id

    security.declareProtected(ManagePortal, 'setImportContext')

    def setImportContext(self, context_id, encoding=None):
        """ See ISetupTool.
        """
        warn(
            'setImportContext is deprecated.  Use setBaselineContext to '
            'specify the baseline context, and/or runImportStepFromProfile '
            'to run the steps from a specific import context.',
            DeprecationWarning,
            stacklevel=2)
        self._import_context_id = context_id

        context_type = BASE  # snapshots are always baseline contexts
        if context_id.startswith('profile-'):
            profile_info = _profile_registry.getProfileInfo(context_id[8:])
            context_type = profile_info['type']

        if context_type == BASE:
            self.setBaselineContext(context_id, encoding)

    security.declareProtected(ManagePortal, 'setBaselineContext')

    def setBaselineContext(self, context_id, encoding=None):
        """ See ISetupTool.
        """
        self._baseline_context_id = context_id
        self.applyContextById(context_id, encoding)

    security.declareProtected(ManagePortal, 'applyContextById')

    def applyContextById(self, context_id, encoding=None):
        context = self._getImportContext(context_id)
        self.applyContext(context, encoding)

    security.declareProtected(ManagePortal, 'applyContext')

    def applyContext(self, context, encoding=None):
        self._updateImportStepsRegistry(context, encoding)
        self._updateExportStepsRegistry(context, encoding)

    security.declareProtected(ManagePortal, 'getImportStepRegistry')

    def getImportStepRegistry(self):
        """ See ISetupTool.
        """
        return self._import_registry

    security.declareProtected(ManagePortal, 'getExportStepRegistry')

    def getExportStepRegistry(self):
        """ See ISetupTool.
        """
        return self._export_registry

    security.declareProtected(ManagePortal, 'getExportStep')

    def getExportStep(self, step, default=None):
        """Simple wrapper to query both the global and local step registry."""
        res = _export_step_registry.getStep(step, default)
        if res is not default:
            return res
        return self._export_registry.getStep(step, default)

    security.declareProtected(ManagePortal, 'listExportSteps')

    def listExportSteps(self):
        steps = _export_step_registry.listSteps() + \
                self._export_registry.listSteps()
        return tuple(set(steps))

    security.declareProtected(ManagePortal, 'getImportStep')

    def getImportStep(self, step, default=None):
        """Simple wrapper to query both the global and local step registry."""
        res = _import_step_registry.getStep(step, default)
        if res is not default:
            return res
        return self._import_registry.getStep(step, default)

    security.declareProtected(ManagePortal, 'getSortedImportSteps')

    def getSortedImportSteps(self):
        steps = _import_step_registry.listSteps() + \
                self._import_registry.listSteps()
        step_infos = [self.getImportStepMetadata(step) for step in set(steps)]
        return tuple(_computeTopologicalSort(step_infos))

    security.declareProtected(ManagePortal, 'getImportStepMetadata')

    def getImportStepMetadata(self, step, default=None):
        """Simple wrapper to query both the global and local step registry."""
        res = self._import_registry.getStepMetadata(step, default)
        if res is not default:
            return res
        return _import_step_registry.getStepMetadata(step, default)

    security.declareProtected(ManagePortal, 'getExportStepMetadata')

    def getExportStepMetadata(self, step, default=None):
        """Simple wrapper to query both the global and local step registry."""
        res = self._export_registry.getStepMetadata(step, default)
        if res is not default:
            return res
        return _export_step_registry.getStepMetadata(step, default)

    security.declareProtected(ManagePortal, 'getToolsetRegistry')

    def getToolsetRegistry(self):
        """ See ISetupTool.
        """
        return self._toolset_registry

    security.declareProtected(ManagePortal, 'runImportStepFromProfile')

    def runImportStepFromProfile(self,
                                 profile_id,
                                 step_id,
                                 run_dependencies=True,
                                 purge_old=None):
        """ See ISetupTool.
        """
        old_context = self._import_context_id
        context = self._getImportContext(profile_id, purge_old)

        self.applyContext(context)

        info = self.getImportStepMetadata(step_id)

        if info is None:
            self._import_context_id = old_context
            raise ValueError, 'No such import step: %s' % step_id

        dependencies = info.get('dependencies', ())

        messages = {}
        steps = []

        if run_dependencies:
            for dependency in dependencies:
                if dependency not in steps:
                    steps.append(dependency)
        steps.append(step_id)

        full_import = (set(steps) == set(self.getSortedImportSteps()))
        event.notify(
            BeforeProfileImportEvent(self, profile_id, steps, full_import))

        for step in steps:
            message = self._doRunImportStep(step, context)
            messages[step] = message or ''

        message_list = filter(None, [message])
        message_list.extend(['%s: %s' % x[1:] for x in context.listNotes()])
        messages[step_id] = '\n'.join(message_list)

        self._import_context_id = old_context

        event.notify(ProfileImportedEvent(self, profile_id, steps,
                                          full_import))

        return {'steps': steps, 'messages': messages}

    security.declareProtected(ManagePortal, 'runImportStep')

    def runImportStep(self, step_id, run_dependencies=True, purge_old=None):
        """ See ISetupTool.
        """
        warn(
            'The runImportStep method is deprecated.  Please use '
            'runImportStepFromProfile instead.',
            DeprecationWarning,
            stacklevel=2)
        return self.runImportStepFromProfile(
            self._import_context_id,
            step_id,
            run_dependencies,
            purge_old,
        )

    security.declareProtected(ManagePortal, 'runAllImportStepsFromProfile')

    def runAllImportStepsFromProfile(self,
                                     profile_id,
                                     purge_old=None,
                                     ignore_dependencies=False,
                                     archive=None):
        """ See ISetupTool.
        """
        __traceback_info__ = profile_id

        old_context = self._import_context_id

        result = self._runImportStepsFromContext(
            purge_old=purge_old,
            profile_id=profile_id,
            archive=archive,
            ignore_dependencies=ignore_dependencies)
        if profile_id is None:
            prefix = 'import-all-from-tar'
        else:
            prefix = 'import-all-%s' % profile_id.replace(':', '_')
        name = self._mangleTimestampName(prefix, 'log')
        self._createReport(name, result['steps'], result['messages'])

        self._import_context_id = old_context

        return result

    security.declareProtected(ManagePortal, 'runAllImportSteps')

    def runAllImportSteps(self, purge_old=None):
        """ See ISetupTool.
        """
        warn(
            'The runAllImportSteps method is deprecated.  Please use '
            'runAllImportStepsFromProfile instead.',
            DeprecationWarning,
            stacklevel=2)
        context_id = self._import_context_id
        return self.runAllImportStepsFromProfile(self._import_context_id,
                                                 purge_old)

    security.declareProtected(ManagePortal, 'runExportStep')

    def runExportStep(self, step_id):
        """ See ISetupTool.
        """
        return self._doRunExportSteps([step_id])

    security.declareProtected(ManagePortal, 'runAllExportSteps')

    def runAllExportSteps(self):
        """ See ISetupTool.
        """
        return self._doRunExportSteps(self.listExportSteps())

    security.declareProtected(ManagePortal, 'createSnapshot')

    def createSnapshot(self, snapshot_id):
        """ See ISetupTool.
        """
        context = SnapshotExportContext(self, snapshot_id)
        messages = {}
        steps = self.listExportSteps()

        for step_id in steps:

            handler = self.getExportStep(step_id)

            if handler is None:
                logger = logging.getLogger('GenericSetup')
                logger.error('Step %s has an invalid handler' % step_id)
                continue

            messages[step_id] = handler(context)

        return {
            'steps': steps,
            'messages': messages,
            'url': context.getSnapshotURL(),
            'snapshot': context.getSnapshotFolder()
        }

    security.declareProtected(ManagePortal, 'compareConfigurations')

    def compareConfigurations(
        self,
        lhs_context,
        rhs_context,
        missing_as_empty=False,
        ignore_blanks=False,
        skip=SKIPPED_FILES,
    ):
        """ See ISetupTool.
        """
        differ = ConfigDiff(
            lhs_context,
            rhs_context,
            missing_as_empty,
            ignore_blanks,
            skip,
        )

        return differ.compare()

    security.declareProtected(ManagePortal, 'markupComparison')

    def markupComparison(self, lines):
        """ See ISetupTool.
        """
        result = []

        for line in lines.splitlines():

            if line.startswith('** '):

                if line.find('File') > -1:
                    if line.find('replaced') > -1:
                        result.append(('file-to-dir', line))
                    elif line.find('added') > -1:
                        result.append(('file-added', line))
                    else:
                        result.append(('file-removed', line))
                else:
                    if line.find('replaced') > -1:
                        result.append(('dir-to-file', line))
                    elif line.find('added') > -1:
                        result.append(('dir-added', line))
                    else:
                        result.append(('dir-removed', line))

            elif line.startswith('@@'):
                result.append(('diff-range', line))

            elif line.startswith(' '):
                result.append(('diff-context', line))

            elif line.startswith('+'):
                result.append(('diff-added', line))

            elif line.startswith('-'):
                result.append(('diff-removed', line))

            elif line == '\ No newline at end of file':
                result.append(('diff-context', line))

            else:
                result.append(('diff-header', line))

        return '<pre>\n%s\n</pre>' % ('\n'.join(
            [('<span class="%s">%s</span>' % (cl, escape(l)))
             for cl, l in result]))

    #
    #   ZMI
    #
    manage_options = (
        Folder.manage_options[:1] + (
            {
                'label': 'Profiles',
                'action': 'manage_tool'
            },
            {
                'label': 'Import',
                'action': 'manage_importSteps'
            },
            {
                'label': 'Export',
                'action': 'manage_exportSteps'
            },
            {
                'label': 'Upgrades',
                'action': 'manage_upgrades'
            },
            {
                'label': 'Snapshots',
                'action': 'manage_snapshots'
            },
            {
                'label': 'Comparison',
                'action': 'manage_showDiff'
            },
            {
                'label': 'Manage',
                'action': 'manage_stepRegistry'
            },
        ) + Folder.manage_options[3:]  # skip "View", "Properties"
    )

    security.declareProtected(ManagePortal, 'manage_tool')
    manage_tool = PageTemplateFile('sutProperties', _wwwdir)

    security.declareProtected(ManagePortal, 'manage_updateToolProperties')

    def manage_updateToolProperties(self, context_id, RESPONSE):
        """ Update the tool's settings.
        """
        self.setBaselineContext(context_id)

        RESPONSE.redirect('%s/manage_tool?manage_tabs_message=%s' %
                          (self.absolute_url(), 'Properties+updated.'))

    security.declareProtected(ManagePortal, 'manage_importSteps')
    manage_importSteps = PageTemplateFile('sutImportSteps', _wwwdir)

    security.declareProtected(ManagePortal, 'manage_importSelectedSteps')

    def manage_importSelectedSteps(self,
                                   ids,
                                   run_dependencies,
                                   context_id=None):
        """ Import the steps selected by the user.
        """
        messages = {}
        if not ids:
            summary = 'No steps selected.'

        else:
            if context_id is None:
                context_id = self.getBaselineContextID()
            steps_run = []
            for step_id in ids:
                result = self.runImportStepFromProfile(context_id, step_id,
                                                       run_dependencies)
                steps_run.extend(result['steps'])
                messages.update(result['messages'])

            summary = 'Steps run: %s' % ', '.join(steps_run)

            name = self._mangleTimestampName('import-selected', 'log')
            self._createReport(name, result['steps'], result['messages'])

        return self.manage_importSteps(manage_tabs_message=summary,
                                       messages=messages)

    security.declareProtected(ManagePortal, 'manage_importSelectedSteps')

    def manage_importAllSteps(self, context_id=None):
        """ Import all steps.
        """
        if context_id is None:
            context_id = self.getBaselineContextID()
        result = self.runAllImportStepsFromProfile(context_id, purge_old=None)

        steps_run = 'Steps run: %s' % ', '.join(result['steps'])

        return self.manage_importSteps(manage_tabs_message=steps_run,
                                       messages=result['messages'])

    security.declareProtected(ManagePortal, 'manage_importExtensions')

    def manage_importExtensions(self, RESPONSE, profile_ids=()):
        """ Import all steps for the selected extension profiles.
        """
        detail = {}
        if len(profile_ids) == 0:
            message = 'Please select one or more extension profiles.'
            RESPONSE.redirect('%s/manage_tool?manage_tabs_message=%s' %
                              (self.absolute_url(), message))
        else:
            message = 'Imported profiles: %s' % ', '.join(profile_ids)

            for profile_id in profile_ids:

                result = self.runAllImportStepsFromProfile(profile_id)

                for k, v in result['messages'].items():
                    detail['%s:%s' % (profile_id, k)] = v

            return self.manage_importSteps(manage_tabs_message=message,
                                           messages=detail)

    security.declareProtected(ManagePortal, 'manage_importTarball')

    def manage_importTarball(self, tarball):
        """ Import steps from the uploaded tarball.
        """
        if getattr(tarball, 'read', None) is not None:
            tarball = tarball.read()

        result = self.runAllImportStepsFromProfile(None, True, archive=tarball)

        steps_run = 'Steps run: %s' % ', '.join(result['steps'])

        return self.manage_importSteps(manage_tabs_message=steps_run,
                                       messages=result['messages'])

    security.declareProtected(ManagePortal, 'manage_exportSteps')
    manage_exportSteps = PageTemplateFile('sutExportSteps', _wwwdir)

    security.declareProtected(ManagePortal, 'manage_exportSelectedSteps')

    def manage_exportSelectedSteps(self, ids, RESPONSE):
        """ Export the steps selected by the user.
        """
        if not ids:
            RESPONSE.redirect('%s/manage_exportSteps?manage_tabs_message=%s' %
                              (self.absolute_url(), 'No+steps+selected.'))

        result = self._doRunExportSteps(ids)
        RESPONSE.setHeader('Content-type', 'application/x-gzip')
        RESPONSE.setHeader('Content-disposition',
                           'attachment; filename=%s' % result['filename'])
        return result['tarball']

    security.declareProtected(ManagePortal, 'manage_exportAllSteps')

    def manage_exportAllSteps(self, RESPONSE):
        """ Export all steps.
        """
        result = self.runAllExportSteps()
        RESPONSE.setHeader('Content-type', 'application/x-gzip')
        RESPONSE.setHeader('Content-disposition',
                           'attachment; filename=%s' % result['filename'])
        return result['tarball']

    security.declareProtected(ManagePortal, 'manage_upgrades')
    manage_upgrades = PageTemplateFile('setup_upgrades', _wwwdir)

    security.declareProtected(ManagePortal, 'upgradeStepMacro')
    upgradeStepMacro = PageTemplateFile('upgradeStep', _wwwdir)

    security.declareProtected(ManagePortal, 'manage_snapshots')
    manage_snapshots = PageTemplateFile('sutSnapshots', _wwwdir)

    security.declareProtected(ManagePortal, 'listSnapshotInfo')

    def listSnapshotInfo(self):
        """ Return a list of mappings describing available snapshots.

        o Keys include:

          'id' -- snapshot ID

          'title' -- snapshot title or ID

          'url' -- URL of the snapshot folder
        """
        result = []
        snapshots = self._getOb('snapshots', None)

        if snapshots:

            for id, folder in snapshots.objectItems('Folder'):

                result.append({
                    'id': id,
                    'title': folder.title_or_id(),
                    'url': folder.absolute_url()
                })
        return result

    security.declareProtected(ManagePortal, 'listProfileInfo')

    def listProfileInfo(self):
        """ Return a list of mappings describing registered profiles.
        Base profile is listed first, extensions are sorted.

        o Keys include:

          'id' -- profile ID

          'title' -- profile title or ID

          'description' -- description of the profile

          'path' -- path to the profile within its product

          'product' -- name of the registering product
        """
        base = []
        ext = []
        for info in _profile_registry.listProfileInfo():
            if info.get('type', BASE) == BASE:
                base.append(info)
            else:
                ext.append(info)
        ext.sort(lambda x, y: cmp(x['id'], y['id']))
        return base + ext

    security.declareProtected(ManagePortal, 'listContextInfos')

    def listContextInfos(self):
        """ List registered profiles and snapshots.
        """
        def readableType(x):
            if x is BASE:
                return 'base'
            elif x is EXTENSION:
                return 'extension'
            return 'unknown'

        s_infos = [{
            'id': 'snapshot-%s' % info['id'],
            'title': info['title'],
            'type': 'snapshot',
        } for info in self.listSnapshotInfo()]
        p_infos = [{
            'id': 'profile-%s' % info['id'],
            'title': info['title'],
            'type': readableType(info['type']),
        } for info in self.listProfileInfo()]

        return tuple(s_infos + p_infos)

    security.declareProtected(ManagePortal, 'getProfileImportDate')

    def getProfileImportDate(self, profile_id):
        """ See ISetupTool.
        """
        prefix = ('import-all-%s-' % profile_id).replace(':', '_')
        candidates = [
            x for x in self.objectIds('File')
            if x[:-18] == prefix and x.endswith('.log')
        ]
        if len(candidates) == 0:
            return None
        candidates.sort()
        last = candidates[-1]
        stamp = last[-18:-4]
        return '%s-%s-%sT%s:%s:%sZ' % (
            stamp[0:4],
            stamp[4:6],
            stamp[6:8],
            stamp[8:10],
            stamp[10:12],
            stamp[12:14],
        )

    security.declareProtected(ManagePortal, 'manage_createSnapshot')

    def manage_createSnapshot(self, RESPONSE, snapshot_id=None):
        """ Create a snapshot with the given ID.

        o If no ID is passed, generate one.
        """
        if snapshot_id is None:
            snapshot_id = self._mangleTimestampName('snapshot')

        self.createSnapshot(snapshot_id)

        RESPONSE.redirect('%s/manage_snapshots?manage_tabs_message=%s' %
                          (self.absolute_url(), 'Snapshot+created.'))
        return ""

    security.declareProtected(ManagePortal, 'manage_showDiff')
    manage_showDiff = PageTemplateFile('sutCompare', _wwwdir)

    def manage_downloadDiff(
        self,
        lhs,
        rhs,
        missing_as_empty,
        ignore_blanks,
        RESPONSE,
    ):
        """ Crack request vars and call compareConfigurations.

        o Return the result as a 'text/plain' stream, suitable for framing.
        """
        comparison = self.manage_compareConfigurations(
            lhs,
            rhs,
            missing_as_empty,
            ignore_blanks,
        )
        RESPONSE.setHeader('Content-Type', 'text/plain')
        return _PLAINTEXT_DIFF_HEADER % (lhs, rhs, comparison)

    security.declareProtected(ManagePortal, 'manage_compareConfigurations')

    def manage_compareConfigurations(
        self,
        lhs,
        rhs,
        missing_as_empty,
        ignore_blanks,
    ):
        """ Crack request vars and call compareConfigurations.
        """
        lhs_context = self._getImportContext(lhs)
        rhs_context = self._getImportContext(rhs)

        return self.compareConfigurations(
            lhs_context,
            rhs_context,
            missing_as_empty,
            ignore_blanks,
        )

    security.declareProtected(ManagePortal, 'manage_stepRegistry')
    manage_stepRegistry = PageTemplateFile('sutManage', _wwwdir)

    security.declareProtected(ManagePortal, 'manage_deleteImportSteps')

    def manage_deleteImportSteps(self, ids, request=None):
        if request is None:
            request = self.REQUEST
        for id in ids:
            self._import_registry.unregisterStep(id)
        self._p_changed = True
        url = self.absolute_url()
        request.RESPONSE.redirect("%s/manage_stepRegistry" % url)

    security.declareProtected(ManagePortal, 'manage_deleteExportSteps')

    def manage_deleteExportSteps(self, ids, request=None):
        if request is None:
            request = self.REQUEST
        for id in ids:
            self._export_registry.unregisterStep(id)
        self._p_changed = True
        url = self.absolute_url()
        request.RESPONSE.redirect("%s/manage_stepRegistry" % url)

    #
    # Upgrades management
    #
    security.declareProtected(ManagePortal, 'getLastVersionForProfile')

    def getLastVersionForProfile(self, profile_id):
        """Return the last upgraded version for the specified profile.
        """
        version = self._profile_upgrade_versions.get(profile_id, 'unknown')
        return version

    security.declareProtected(ManagePortal, 'setLastVersionForProfile')

    def setLastVersionForProfile(self, profile_id, version):
        """Set the last upgraded version for the specified profile.
        """
        if isinstance(version, basestring):
            version = tuple(version.split('.'))
        prof_versions = self._profile_upgrade_versions.copy()
        prof_versions[profile_id] = version
        self._profile_upgrade_versions = prof_versions

    security.declareProtected(ManagePortal, 'getVersionForProfile')

    def getVersionForProfile(self, profile_id):
        """Return the registered filesystem version for the specified
        profile.
        """
        return self.getProfileInfo(profile_id).get('version', 'unknown')

    security.declareProtected(ManagePortal, 'profileExists')

    def profileExists(self, profile_id):
        """Check if a profile exists."""
        try:
            self.getProfileInfo(profile_id)
        except KeyError:
            return False
        else:
            return True

    security.declareProtected(ManagePortal, "getProfileInfo")

    def getProfileInfo(self, profile_id):
        if profile_id.startswith("profile-"):
            profile_id = profile_id[len('profile-'):]
        elif profile_id.startswith("snapshot-"):
            profile_id = profile_id[len('snapshot-'):]
        return _profile_registry.getProfileInfo(profile_id)

    security.declareProtected(ManagePortal, 'getDependenciesForProfile')

    def getDependenciesForProfile(self, profile_id):
        if profile_id.startswith("snapshot-"):
            return ()

        if not self.profileExists(profile_id):
            raise KeyError, profile_id
        try:
            return self.getProfileInfo(profile_id).get('dependencies', ())
        except KeyError:
            return ()

    security.declareProtected(ManagePortal, 'listProfilesWithUpgrades')

    def listProfilesWithUpgrades(self):
        return listProfilesWithUpgrades()

    security.declarePrivate('_massageUpgradeInfo')

    def _massageUpgradeInfo(self, info):
        """Add a couple of data points to the upgrade info dictionary.
        """
        info = info.copy()
        info['haspath'] = info['source'] and info['dest']
        info['ssource'] = '.'.join(info['source'] or ('all', ))
        info['sdest'] = '.'.join(info['dest'] or ('all', ))
        return info

    security.declareProtected(ManagePortal, 'listUpgrades')

    def listUpgrades(self, profile_id, show_old=False):
        """Get the list of available upgrades.
        """
        if show_old:
            source = None
        else:
            source = self.getLastVersionForProfile(profile_id)
        upgrades = listUpgradeSteps(self, profile_id, source)
        res = []
        for info in upgrades:
            if type(info) == list:
                subset = []
                for subinfo in info:
                    subset.append(self._massageUpgradeInfo(subinfo))
                res.append(subset)
            else:
                res.append(self._massageUpgradeInfo(info))
        return res

    security.declareProtected(ManagePortal, 'manage_doUpgrades')

    def manage_doUpgrades(self, request=None):
        """Perform all selected upgrade steps.
        """
        if request is None:
            request = self.REQUEST
        logger = logging.getLogger('GenericSetup')
        steps_to_run = request.form.get('upgrades', [])
        profile_id = request.get('profile_id', '')
        for step_id in steps_to_run:
            step = _upgrade_registry.getUpgradeStep(profile_id, step_id)
            if step is not None:
                step.doStep(self)
                msg = "Ran upgrade step %s for profile %s" % (step.title,
                                                              profile_id)
                logger.log(logging.INFO, msg)

        # XXX should be a bit smarter about deciding when to up the
        #     profile version
        profile_info = _profile_registry.getProfileInfo(profile_id)
        version = profile_info.get('version', None)
        if version is not None:
            self.setLastVersionForProfile(profile_id, version)

        url = self.absolute_url()
        request.RESPONSE.redirect("%s/manage_upgrades?saved=%s" %
                                  (url, profile_id))

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

    def _getImportContext(self, context_id, should_purge=None, archive=None):
        """ Crack ID and generate appropriate import context.
        """
        encoding = self.getEncoding()

        if context_id is not None:
            if context_id.startswith('profile-'):
                context_id = context_id[len('profile-'):]
                info = _profile_registry.getProfileInfo(context_id)

                if info.get('product'):
                    path = os.path.join(_getProductPath(info['product']),
                                        info['path'])
                else:
                    path = info['path']
                if should_purge is None:
                    should_purge = (info.get('type') != EXTENSION)
                return DirectoryImportContext(self, path, should_purge,
                                              encoding)

            elif context_id.startswith('snapshot-'):
                context_id = context_id[len('snapshot-'):]
                if should_purge is None:
                    should_purge = True
                return SnapshotImportContext(self, context_id, should_purge,
                                             encoding)

        if archive is not None:
            return TarballImportContext(
                tool=self,
                archive_bits=archive,
                encoding='UTF8',
                should_purge=should_purge,
            )

        raise KeyError, 'Unknown context "%s"' % context_id

    security.declarePrivate('_updateImportStepsRegistry')

    def _updateImportStepsRegistry(self, context, encoding):
        """ Update our import steps registry from our profile.
        """
        if context is None:
            context = self._getImportContext(self._import_context_id)
        xml = context.readDataFile(IMPORT_STEPS_XML)
        if xml is None:
            return

        info_list = self._import_registry.parseXML(xml, encoding)

        for step_info in info_list:

            id = step_info['id']
            version = step_info['version']
            handler = step_info['handler']
            dependencies = tuple(step_info.get('dependencies', ()))
            title = step_info.get('title', id)
            description = ''.join(step_info.get('description', []))

            self._import_registry.registerStep(
                id=id,
                version=version,
                handler=handler,
                dependencies=dependencies,
                title=title,
                description=description,
            )

    security.declarePrivate('_updateExportStepsRegistry')

    def _updateExportStepsRegistry(self, context, encoding):
        """ Update our export steps registry from our profile.
        """
        if context is None:
            context = self._getImportContext(self._import_context_id)
        xml = context.readDataFile(EXPORT_STEPS_XML)
        if xml is None:
            return

        info_list = self._export_registry.parseXML(xml, encoding)

        for step_info in info_list:

            id = step_info['id']
            handler = step_info['handler']
            title = step_info.get('title', id)
            description = ''.join(step_info.get('description', []))

            self._export_registry.registerStep(
                id=id,
                handler=handler,
                title=title,
                description=description,
            )

    security.declarePrivate('_doRunImportStep')

    def _doRunImportStep(self, step_id, context):
        """ Run a single import step, using a pre-built context.
        """
        __traceback_info__ = step_id
        marker = object()

        handler = self.getImportStep(step_id)

        if handler is marker:
            raise ValueError('Invalid import step: %s' % step_id)

        if handler is None:
            msg = 'Step %s has an invalid import handler' % step_id
            logger = logging.getLogger('GenericSetup')
            logger.error(msg)
            return 'ERROR: ' + msg

        return handler(context)

    security.declarePrivate('_doRunExportSteps')

    def _doRunExportSteps(self, steps):
        """ See ISetupTool.
        """
        context = TarballExportContext(self)
        messages = {}
        marker = object()

        for step_id in steps:

            handler = self.getExportStep(step_id, marker)

            if handler is marker:
                raise ValueError('Invalid export step: %s' % step_id)

            if handler is None:
                msg = 'Step %s has an invalid import handler' % step_id
                logger = logging.getLogger('GenericSetup')
                logger.error(msg)
                messages[step_id] = msg
            else:
                messages[step_id] = handler(context)

        return {
            'steps': steps,
            'messages': messages,
            'tarball': context.getArchive(),
            'filename': context.getArchiveFilename()
        }

    security.declareProtected(ManagePortal, 'getProfileDependencyChain')

    def getProfileDependencyChain(self, profile_id, seen=None):
        if seen is None:
            seen = set()
        elif profile_id in seen:
            return []  # cycle break
        seen.add(profile_id)
        chain = []

        dependencies = self.getDependenciesForProfile(profile_id)
        for dependency in dependencies:
            chain.extend(self.getProfileDependencyChain(dependency, seen))

        chain.append(profile_id)

        return chain

    security.declarePrivate('_runImportStepsFromContext')

    def _runImportStepsFromContext(self,
                                   steps=None,
                                   purge_old=None,
                                   profile_id=None,
                                   archive=None,
                                   ignore_dependencies=False,
                                   seen=None):

        if profile_id is not None and not ignore_dependencies:
            try:
                chain = self.getProfileDependencyChain(profile_id)
            except KeyError, e:
                logger = logging.getLogger('GenericSetup')
                logger.error('Unknown step in dependency chain: %s' % str(e))
                raise
        else:
Example #29
0
        cropbox = (0, 0, 50, 50)
        img = img.crop(cropbox)
        
        img.save(imagefilepath, fmt)
        
        thumbimage = open(imagefilepath, 'rb')
        ext = p.getId().split('.')[-1]
        id = 'tumnagel.%s' % ext
        self.uploadThumbnail(file=thumbimage.read(), id=id)

templates = (#'dtml/something',
             'zpt/editBustForm',
            )
addTemplates2Class(Bust, templates)
 
security = ClassSecurityInfo()
security.declareProtected(VMS, 'editBustForm')
security.apply(Bust)

InitializeClass(Bust)


#-----------------------------------------------------------------------------
        
manage_addBustFolderForm = PTF('zpt/addBustFolderForm', globals())
def manage_addBustFolder(dispatcher, id, title, REQUEST=None,
                   redirect_to=None):
    """ create instance """
    
    dest = dispatcher.Destination()
        
Example #30
0

    security.declareProtected(VMS, 'manage_UpdatePlogRank')
    def manage_UpdatePlogRank(self):
        """ use PlogMatrix to calculate every plogrank """
        return UpdatePlogRank(self)






zpts = (('zpt/blogcontainer_index', 'index_html'),)
addTemplates2Class(PeterbeBlogContainer, zpts, extension='zpt')

dtmls = (('dtml/blogcontainer_stats','manage_Statistics'),
         'dtml/blogcontainer_calendar',
         )
addTemplates2Class(PeterbeBlogContainer, dtmls, extension='dtml')

setattr(PeterbeBlogContainer, 'rss.xml', PeterbeBlogContainer.RSS10)

security = ClassSecurityInfo()
security.declareProtected(VMS, 'manage_Statistics')
security.apply(PeterbeBlogContainer)




InitializeClass(PeterbeBlogContainer)
Example #31
0
class BadFile(FSObject):
    """
        Represent a file which was not readable or parseable
        as its intended type.
    """
    meta_type = 'Bad File'
    icon = 'p_/broken'

    BAD_FILE_VIEW = """\
<dtml-var manage_page_header>
<dtml-var manage_tabs>
<h2> Bad Filesystem Object: &dtml-getId; </h2>

<h3> File Path </h3>
<pre>
<dtml-var getFilePath>
</pre>

<h3> File Contents </h3>
<pre>
<dtml-var getFileContents>
</pre>

<h3> Exception </h3>
<pre>
<dtml-var getExceptionText>
</pre>
<dtml-var manage_page_footer>
"""

    manage_options = ({'label': 'Error', 'action': 'manage_showError'}, )

    def __init__(self,
                 id,
                 package=None,
                 entry_subpath=None,
                 filepath=None,
                 fullname=None,
                 properties=None,
                 exc_str=''):
        id = fullname or id  # Use the whole filename.
        self.exc_str = exc_str
        self.file_contents = ''
        FSObject.__init__(self, id, package, entry_subpath, filepath, fullname,
                          properties)

    security = ClassSecurityInfo()

    security.declarePrivate('showError')
    showError = Globals.HTML(BAD_FILE_VIEW)

    security.declarePrivate('_readFile')

    def _readFile(self, reparse):
        """ Stub this out.
        """
        pass

    security.declareProtected(ManagePortal, 'manage_showError')

    def manage_showError(self, REQUEST):
        """ Render the error page.
        """
        return self.showError(self, REQUEST)

    security.declarePublic('getFilePath')

    def getFilePath(self):
        """
            Return the path to the file.
        """
        if self._filepath:
            return self._filepath
        else:
            return 'package: %s, subpath: %s' % (self._package,
                                                 self._entry_subpath)

    security.declarePublic('getFileContents')

    def getFileContents(self):
        """
            Return the contents of the file, if we could read it.
        """
        return self.file_contents

    security.declarePublic('getExceptionText')

    def getExceptionText(self):
        """
            Return the exception thrown while reading or parsing
            the file.
        """
        return self.exc_str
Example #32
0
class ERP5UserManager(BasePlugin):
    """ PAS plugin for managing users in ERP5
  """

    meta_type = 'ERP5 User Manager'

    security = ClassSecurityInfo()

    def __init__(self, id, title=None):
        self._id = self.id = id
        self.title = title

    #
    #   IAuthenticationPlugin implementation
    #
    security.declarePrivate('authenticateCredentials')

    def authenticateCredentials(self, credentials):
        """ See IAuthenticationPlugin.

    o We expect the credentials to be those returned by
      ILoginPasswordExtractionPlugin.
    """
        login = credentials.get('login')
        ignore_password = False
        if not login:
            # fallback to support plugins using external tools to extract login
            # those are not using login/password pair, they just extract login
            # from remote system (eg. SSL certificates)
            login = credentials.get('external_login')
            ignore_password = True
        # Forbidden the usage of the super user.
        if login == ERP5Security.SUPER_USER:
            return None

        @UnrestrictedMethod
        def _authenticateCredentials(login,
                                     password,
                                     path,
                                     ignore_password=False):
            if not login or not (password or ignore_password):
                return None

            user_list = self.getUserByLogin(login)

            if not user_list:
                raise _AuthenticationFailure()

            user = user_list[0]

            try:

                if (ignore_password or pw_validate(user.getPassword(), password)) and \
                    len(getValidAssignmentList(user)) and user  \
                    .getValidationState() != 'deleted': #user.getCareerRole() == 'internal':
                    return login, login  # use same for user_id and login
            finally:
                pass
            raise _AuthenticationFailure()

        _authenticateCredentials = CachingMethod(
            _authenticateCredentials,
            id='ERP5UserManager_authenticateCredentials',
            cache_factory='erp5_content_short')
        try:
            authentication_result = _authenticateCredentials(
                login=login,
                password=credentials.get('password'),
                path=self.getPhysicalPath(),
                ignore_password=ignore_password)

        except _AuthenticationFailure:
            authentication_result = None

        if not self.getPortalObject(
        ).portal_preferences.isAuthenticationPolicyEnabled():
            # stop here, no authentication policy enabled
            # so just return authentication check result
            return authentication_result

        # authentication policy enabled, we need person object anyway
        user_list = self.getUserByLogin(credentials.get('login'))
        if not user_list:
            # not an ERP5 Person object
            return None
        user = user_list[0]

        if authentication_result is None:
            # file a failed authentication attempt
            user.notifyLoginFailure()
            return None

        # check if password is expired
        if user.isPasswordExpired():
            user.notifyPasswordExpire()
            return None

        # check if user account is blocked
        if user.isLoginBlocked():
            return None

        return authentication_result

    #
    #   IUserEnumerationPlugin implementation
    #
    security.declarePrivate('enumerateUsers')

    def enumerateUsers(self,
                       id=None,
                       login=None,
                       exact_match=False,
                       sort_by=None,
                       max_results=None,
                       **kw):
        """ See IUserEnumerationPlugin.
    """
        # Note: this plugin totally ignores the distinction between login and id.
        if id is None:
            id = login
        if isinstance(id, str):
            id = (id, )

        unrestrictedSearchResults = self.getPortalObject(
        ).portal_catalog.unrestrictedSearchResults
        searchUser = lambda **kw: unrestrictedSearchResults(
            select_list=('reference',
                         ), portal_type='Person', **kw).dictionaries()
        # Only search by id if login is not given. Same logic as in
        # PluggableAuthService.searchUsers.
        if isinstance(id, str):
            id = (id, )
        id_list = []
        has_super_user = False
        for user_id in id:
            if user_id == ERP5Security.SUPER_USER:
                has_super_user = True
            elif user_id:
                id_list.append(user_id)
        if id_list:
            if exact_match:
                requested = set(id_list).__contains__
            else:
                requested = lambda x: True
            user_list = [
                x for x in searchUser(
                    reference={
                        'query': id_list,
                        'key': 'ExactMatch' if exact_match else 'Keyword',
                    },
                    limit=max_results,
                ) if requested(x['reference'])
            ]
        else:
            user_list = []
        if has_super_user:
            user_list.append({
                'uid': None,
                'path': None,
                'reference': ERP5Security.SUPER_USER
            })
        plugin_id = self.getId()
        return tuple([
            {
                'id':
                user['reference'],
                # Note: PAS forbids us from returning more than one entry per given id,
                # so take any available login.
                'login':
                user['reference'],
                'pluginid':
                plugin_id,

                # Extra properties, specific to ERP5
                'path':
                user['path'],
                'uid':
                user['uid'],
                'login_list':
                user['path'] and [{
                    'reference': user['reference'],
                    'path': user['path'],
                    'uid': user['uid'],
                }] or [],
            } for user in user_list
        ])

    security.declarePrivate('updateUser')

    def updateUser(self, user_id, login_name):
        # Operation not supported here
        return False

    security.declarePrivate('updateEveryLoginName')

    def updateEveryLoginName(self, quit_on_first_error=True):
        # Operation not supported here
        raise NotImplementedError()

    def getUserByLogin(self, login, exact_match=True):
        # Search the Catalog for login and return a list of person objects
        # login can be a string or a list of strings
        # (no docstring to prevent publishing)
        if not login:
            return []
        if isinstance(login, list):
            login = tuple(login)
        elif not isinstance(login, (tuple, str)):
            login = login.getUserName()
        try:
            return getUserByLogin(self.getPortalObject(), login, exact_match)
        except ConflictError:
            raise
        except:
            LOG('ERP5Security', PROBLEM, 'getUserByLogin failed', error=True)
            # Here we must raise an exception to prevent callers from caching
            # a result of a degraded situation.
            # The kind of exception does not matter as long as it's catched by
            # PAS and causes a lookup using another plugin or user folder.
            # As PAS does not define explicitely such exception, we must use
            # the _SWALLOWABLE_PLUGIN_EXCEPTIONS list.
            raise _SWALLOWABLE_PLUGIN_EXCEPTIONS[0]
from AccessControl import ClassSecurityInfo
from Products.CMFCore.permissions import View
from collective.downloadtracker import add_download_record

security = ClassSecurityInfo()


security.declareProtected(View, 'index_html')
def index_html(self, instance, REQUEST=None, RESPONSE=None, **kwargs):
    """ make it directly viewable when entering the objects URL """
    blob = self.get(instance, raw=True)    # TODO: why 'raw'?
    charset = instance.getCharset()
    add_download_record(instance)
    return blob.index_html(
        REQUEST=REQUEST, RESPONSE=RESPONSE,
        charset=charset, **kwargs
        )
Example #34
0
class FSObject(Implicit, Item, RoleManager, Cacheable):
    """FSObject is a base class for all filesystem based look-alikes.

    Subclasses of this class mimic ZODB based objects like Image and
    DTMLMethod, but are not directly modifiable from the management
    interface. They provide means to create a TTW editable copy, however.
    """

    # Always empty for FS based, non-editable objects.
    title = ''

    security = ClassSecurityInfo()
    security.declareObjectProtected(View)

    _filepath = None
    _package = None
    _entry_subpath = None
    _file_mod_time = 0
    _file_size = 0
    _parsed = 0

    def __init__(self,
                 id,
                 package=None,
                 entry_subpath=None,
                 filepath=None,
                 fullname=None,
                 properties=None):
        MESSAGE = ("Either 'filepath' or 'package' + 'entry_subpath' must "
                   "be supplied.")
        if filepath is None:
            if package is None or entry_subpath is None:
                raise ValueError(MESSAGE)
            self._package = package
            self._entry_subpath = entry_subpath
        else:
            if package is not None or entry_subpath is not None:
                raise ValueError(MESSAGE)
            self._filepath = filepath

        if properties:
            # Since props come from the filesystem, this should be
            # safe.
            self.__dict__.update(properties)
            if fullname and properties.get('keep_extension', 0):
                id = fullname

            cache = properties.get('cache')
            if cache:
                self.ZCacheable_setManagerId(cache)

        self.id = id
        self.__name__ = id  # __name__ is used in traceback reporting
        self._updateFromFS(reparse=1)

    security.declareProtected(ViewManagementScreens, 'manage_doCustomize')

    def manage_doCustomize(self, folder_path, RESPONSE=None):
        """Makes a ZODB Based clone with the same data.

        Calls _createZODBClone for the actual work.
        """

        obj = self._createZODBClone()
        parent = aq_parent(aq_inner(self))

        # Preserve cache manager associations
        cachemgr_id = self.ZCacheable_getManagerId()
        if (cachemgr_id
                and getattr(obj, 'ZCacheable_setManagerId', None) is not None):
            obj.ZCacheable_setManagerId(cachemgr_id)

        # If there are proxy roles we preserve them
        proxy_roles = getattr(aq_base(self), '_proxy_roles', None)
        if proxy_roles is not None and isinstance(proxy_roles, tuple):
            obj._proxy_roles = tuple(self._proxy_roles)

        # Also, preserve any permission settings that might have come
        # from a metadata file or from fiddling in the ZMI
        old_info = [x[:2] for x in self.ac_inherited_permissions(1)]
        for old_perm, value in old_info:
            p = Permission(old_perm, value, self)
            acquired = int(isinstance(p.getRoles(default=[]), list))
            rop_info = self.rolesOfPermission(old_perm)
            roles = [x['name'] for x in rop_info if x['selected'] != '']
            try:
                # if obj is based on OFS.ObjectManager an acquisition context is
                # required for _subobject_permissions()
                obj.__of__(parent).manage_permission(old_perm,
                                                     roles=roles,
                                                     acquire=acquired)
            except ValueError:
                # The permission was invalid, never mind
                pass

        skins_tool_namegetter = getattr(self, 'getSkinsFolderName', None)
        if skins_tool_namegetter is not None:
            skins_tool_name = skins_tool_namegetter()
        else:
            skins_tool_name = 'portal_skins'

        id = obj.getId()
        fpath = tuple(folder_path.split('/'))
        portal_skins = getToolByName(self, skins_tool_name)
        folder = portal_skins.restrictedTraverse(fpath)
        if id in folder.objectIds():
            # we cant catch the badrequest so
            # we'll that to check before hand
            obj = folder._getOb(id)
            if RESPONSE is not None:
                RESPONSE.redirect(
                    '%s/manage_main?manage_tabs_message=%s' %
                    (obj.absolute_url(),
                     html_quote("An object with this id already exists")))
        else:
            folder._verifyObjectPaste(obj, validate_src=0)
            folder._setObject(id, obj)

            if RESPONSE is not None:
                RESPONSE.redirect('%s/%s/manage_main' %
                                  (folder.absolute_url(), id))

        if RESPONSE is not None:
            RESPONSE.redirect('%s/%s/manage_main' %
                              (folder.absolute_url(), id))

    def _createZODBClone(self):
        """Create a ZODB (editable) equivalent of this object."""
        raise NotImplementedError, "This should be implemented in a subclass."

    def _readFile(self, reparse):
        """Read the data from the filesystem.

        Read the file indicated by exandpath(self._filepath), and parse the
        data if necessary.  'reparse' is set when reading the second
        time and beyond.
        """
        raise NotImplementedError, "This should be implemented in a subclass."

    # Refresh our contents from the filesystem if that is newer and we are
    # running in debug mode.
    def _updateFromFS(self, reparse=1):
        parsed = self._parsed

        if parsed and not Globals.DevelopmentMode:
            return

        if self._filepath:
            fp = expandpath(self._filepath)
            try:
                statinfo = os.stat(fp)
                size, mtime = statinfo[6], statinfo[8]
            except:
                size = mtime = 0
        else:
            size, mtime = _getResourceStatInfo(self._package,
                                               self._entry_subpath)

        if not parsed or mtime != self._file_mod_time:
            # if we have to read the file again, remove the cache
            self.ZCacheable_invalidate()
            data = self._readFile(reparse)
            self._file_mod_time = mtime
            self._file_size = size
            self._parsed = 1

    security.declareProtected(View, 'get_size')

    def get_size(self):
        """Get the size of the underlying file.
        """
        self._updateFromFS()
        return self._file_size

    security.declareProtected(View, 'getModTime')

    def getModTime(self):
        """Return the last_modified date of the file we represent.

        Returns a DateTime instance.
        """
        self._updateFromFS()
        return DateTime(self._file_mod_time)

    security.declareProtected(ViewManagementScreens, 'getObjectFSPath')

    def getObjectFSPath(self):
        """Return the path of the file we represent"""
        self._updateFromFS()
        if self._filepath is not None:
            return self._filepath
        return '<zipimport: %s, %s>' % self._package, self._entry_subpath

    security.declarePrivate('_readFileAsResourceOrDirect')

    def _readFileAsResourceOrDirect(self):
        """ Return our file's bits, looking in the appropriate place.
        """
        if self._filepath is None:
            return resource_string(self._package, self._entry_subpath)
        else:
            fp = expandpath(self._filepath)
            file = open(fp, 'r')  # not 'rb', as this is a text file!
            try:
                return file.read()
            finally:
                file.close()
Example #35
0
from zope import schema
from zope.annotation.interfaces import IAnnotations
from zope.component import queryUtility
from zope.container.contained import ObjectRemovedEvent
from zope import event
from zope.interface import implements

from .. import _, config
from ..accesscontrol import AccessControl
from ..exceptions import PlominoCacheException, PlominoScriptException
from ..interfaces import IPlominoContext
from ..design import DesignManager
from ..replication import ReplicationManager
from ..document import addPlominoDocument

security = ClassSecurityInfo()


class IPlominoDatabase(model.Schema):
    """ Plomino database schema
    """

    indexAttachments = schema.Bool(
        title=_('CMFPlomino_label_IndexAttachments',
            default="Index file attachments"),
        description=_('CMFPlomino_help_IndexAttachments',
            default="If enabled, files attached in File Attachment fields "
            "will be indexed. It might increase the index size."),
        default=False,
    )
Example #36
0
class ElementSpec(SimpleItem):
    """
        Represent all the tool knows about a single metadata element.
    """

    security = ClassSecurityInfo()

    #
    #   Default values.
    #
    is_multi_valued = 0

    def __init__(self, is_multi_valued):
        self.is_multi_valued = is_multi_valued
        self.policies = PersistentMapping()
        self.policies[None] = self._makePolicy()  # set default policy

    security.declarePrivate('_makePolicy')

    def _makePolicy(self):
        return MetadataElementPolicy(self.is_multi_valued)

    security.declareProtected(View, 'isMultiValued')

    def isMultiValued(self):
        """
            Is this element multi-valued?
        """
        return self.is_multi_valued

    security.declareProtected(View, 'getPolicy')

    def getPolicy(self, typ=None):
        """
            Find the policy this element for objects whose type
            object name is 'typ';  return a default, if none found.
        """
        try:
            return self.policies[typ].__of__(self)
        except KeyError:
            return self.policies[None].__of__(self)

    security.declareProtected(View, 'listPolicies')

    def listPolicies(self):
        """
            Return a list of all policies for this element.
        """
        res = []
        for k, v in self.policies.items():
            res.append((k, v.__of__(self)))
        return res

    security.declareProtected(ManagePortal, 'addPolicy')

    def addPolicy(self, typ):
        """
            Add a policy to this element for objects whose type
            object name is 'typ'.
        """
        if typ is None:
            raise MetadataError, "Can't replace default policy."

        if self.policies.has_key(typ):
            raise MetadataError, "Existing policy for content type:" + typ

        self.policies[typ] = self._makePolicy()

    security.declareProtected(ManagePortal, 'removePolicy')

    def removePolicy(self, typ):
        """
            Remove the policy from this element for objects whose type
            object name is 'typ' (*not* the default, however).
        """
        if typ is None:
            raise MetadataError, "Can't remove default policy."
        del self.policies[typ]
Example #37
0
try: from IOBTree import Bucket
except: Bucket=lambda:{}
from Shared.DC.ZRDB.Aqueduct import decodestring, parse
from Shared.DC.ZRDB.DA import DA, DatabaseError, SQLMethodTracebackSupplement
from Shared.DC.ZRDB import RDB
from Shared.DC.ZRDB.Results import Results
from App.Extensions import getBrain
from AccessControl import ClassSecurityInfo, getSecurityManager 
from Products.ERP5Type.Globals import InitializeClass
from Acquisition import aq_base, aq_parent
from zLOG import LOG, INFO, ERROR
from cStringIO import StringIO
from Products.ERP5Type import Permissions
import sys

security = ClassSecurityInfo()
DA.security = security

def DA_fromFile(self, filename):
  """
    Read the file and update self
  """
  f = file(filename)
  s = f.read()
  f.close()
  self.fromText(s)

def DA_fromText(self, text):
  """
    Read the string 'text' and updates self
  """
Example #38
0
class MetadataTool(UniqueObject, SimpleItem, ActionProviderBase):

    implements(IMetadataTool)
    __implements__ = (z2IMetadataTool, ActionProviderBase.__implements__)

    id = 'portal_metadata'
    meta_type = 'Default Metadata Tool'

    #
    #   Default values.
    #
    publisher = ''
    element_specs = None
    #initial_values_hook = None
    #validation_hook     = None

    security = ClassSecurityInfo()

    def __init__(
            self,
            publisher=None
        #, initial_values_hook=None
        #, validation_hook=None
        ,
            element_specs=DEFAULT_ELEMENT_SPECS):

        self.editProperties(publisher
                            #, initial_values_hook
                            #, validation_hook
                            )

        self.element_specs = PersistentMapping()

        for name, is_multi_valued in element_specs:
            self.element_specs[name] = ElementSpec(is_multi_valued)

    #
    #   ZMI methods
    #
    manage_options = (
        ActionProviderBase.manage_options +
        ({
            'label': 'Overview',
            'action': 'manage_overview'
        }, {
            'label': 'Properties',
            'action': 'propertiesForm'
        }, {
            'label': 'Elements',
            'action': 'elementPoliciesForm'
        }
         # TODO     , { 'label'      : 'Types'
         #            , 'action'     : 'typesForm'
         #            }
         ) + SimpleItem.manage_options)

    security.declareProtected(ManagePortal, 'manage_overview')
    manage_overview = DTMLFile('explainMetadataTool', _dtmldir)

    security.declareProtected(ManagePortal, 'propertiesForm')
    propertiesForm = DTMLFile('metadataProperties', _dtmldir)

    security.declareProtected(ManagePortal, 'editProperties')

    def editProperties(
            self,
            publisher=None
        # TODO , initial_values_hook=None
        # TODO , validation_hook=None
        ,
            REQUEST=None):
        """
            Form handler for "tool-wide" properties (including list of
            metadata elements).
        """
        if publisher is not None:
            self.publisher = publisher

        # TODO self.initial_values_hook = initial_values_hook
        # TODO self.validation_hook = validation_hook

        if REQUEST is not None:
            REQUEST['RESPONSE'].redirect(self.absolute_url() +
                                         '/propertiesForm' +
                                         '?manage_tabs_message=Tool+updated.')

    security.declareProtected(ManagePortal, 'elementPoliciesForm')
    elementPoliciesForm = DTMLFile('metadataElementPolicies', _dtmldir)

    security.declareProtected(ManagePortal, 'addElementPolicy')

    def addElementPolicy(self,
                         element,
                         content_type,
                         is_required,
                         supply_default,
                         default_value,
                         enforce_vocabulary,
                         allowed_vocabulary,
                         REQUEST=None):
        """
            Add a type-specific policy for one of our elements.
        """
        if content_type == '<default>':
            content_type = None

        spec = self.getElementSpec(element)
        spec.addPolicy(content_type)
        policy = spec.getPolicy(content_type)
        policy.edit(is_required, supply_default, default_value,
                    enforce_vocabulary, allowed_vocabulary)
        if REQUEST is not None:
            REQUEST['RESPONSE'].redirect(self.absolute_url() +
                                         '/elementPoliciesForm' + '?element=' +
                                         element +
                                         '&manage_tabs_message=Policy+added.')

    security.declareProtected(ManagePortal, 'removeElementPolicy')

    def removeElementPolicy(self, element, content_type, REQUEST=None):
        """
            Remvoe a type-specific policy for one of our elements.
        """
        if content_type == '<default>':
            content_type = None

        spec = self.getElementSpec(element)
        spec.removePolicy(content_type)
        if REQUEST is not None:
            REQUEST['RESPONSE'].redirect(
                self.absolute_url() + '/elementPoliciesForm' + '?element=' +
                element + '&manage_tabs_message=Policy+removed.')

    security.declareProtected(ManagePortal, 'updateElementPolicy')

    def updateElementPolicy(self,
                            element,
                            content_type,
                            is_required,
                            supply_default,
                            default_value,
                            enforce_vocabulary,
                            allowed_vocabulary,
                            REQUEST=None):
        """
            Update a policy for one of our elements ('content_type'
            will be '<default>' when we edit the default).
        """
        if content_type == '<default>':
            content_type = None
        spec = self.getElementSpec(element)
        policy = spec.getPolicy(content_type)
        policy.edit(is_required, supply_default, default_value,
                    enforce_vocabulary, allowed_vocabulary)
        if REQUEST is not None:
            REQUEST['RESPONSE'].redirect(
                self.absolute_url() + '/elementPoliciesForm' + '?element=' +
                element + '&manage_tabs_message=Policy+updated.')

    #
    #   Element spec manipulation.
    #
    security.declareProtected(ManagePortal, 'listElementSpecs')

    def listElementSpecs(self):
        """
            Return a list of ElementSpecs representing
            the elements managed by the tool.
        """
        res = []
        for k, v in self.element_specs.items():
            res.append((k, v.__of__(self)))
        return res

    security.declareProtected(ManagePortal, 'getElementSpec')

    def getElementSpec(self, element):
        """
            Return an ElementSpec representing the tool's knowledge
            of 'element'.
        """
        return self.element_specs[element].__of__(self)

    security.declareProtected(ManagePortal, 'addElementSpec')

    def addElementSpec(self, element, is_multi_valued, REQUEST=None):
        """
            Add 'element' to our list of managed elements.
        """
        # Don't replace.
        if self.element_specs.has_key(element):
            return

        self.element_specs[element] = ElementSpec(is_multi_valued)

        if REQUEST is not None:
            REQUEST['RESPONSE'].redirect(self.absolute_url() +
                                         '/propertiesForm' +
                                         '?manage_tabs_message=Element+' +
                                         element + '+added.')

    security.declareProtected(ManagePortal, 'removeElementSpec')

    def removeElementSpec(self, element, REQUEST=None):
        """
            Remove 'element' from our list of managed elements.
        """
        del self.element_specs[element]

        if REQUEST is not None:
            REQUEST['RESPONSE'].redirect(self.absolute_url() +
                                         '/propertiesForm' +
                                         '?manage_tabs_message=Element+' +
                                         element + '+removed.')

    security.declareProtected(ManagePortal, 'listPolicies')

    def listPolicies(self, typ=None):
        """
            Show all policies for a given content type, or the default
            if None.
        """
        result = []
        for element, spec in self.listElementSpecs():
            result.append((element, spec.getPolicy(typ)))
        return result

    #
    #   'portal_metadata' interface
    #
    security.declarePrivate('getFullName')

    def getFullName(self, userid):
        """
            Convert an internal userid to a "formal" name, if
            possible, perhaps using the 'portal_membership' tool.

            Used to map userid's for Creator, Contributor DCMI
            queries.
        """
        return userid  # TODO: do lookup here

    security.declarePublic('getPublisher')

    def getPublisher(self):
        """
            Return the "formal" name of the publisher of the
            portal.
        """
        return self.publisher

    security.declarePublic('listAllowedVocabulary')

    def listAllowedVocabulary(self, element, content=None, content_type=None):
        """
            List allowed keywords for a given portal_type, or all
            possible keywords if none supplied.
        """
        spec = self.getElementSpec(element)
        if content_type is None and content:
            content_type = content.getPortalTypeName()
        return spec.getPolicy(content_type).allowedVocabulary()

    security.declarePublic('listAllowedSubjects')

    def listAllowedSubjects(self, content=None, content_type=None):
        """
            List allowed keywords for a given portal_type, or all
            possible keywords if none supplied.
        """
        return self.listAllowedVocabulary('Subject', content, content_type)

    security.declarePublic('listAllowedFormats')

    def listAllowedFormats(self, content=None, content_type=None):
        """
            List the allowed 'Content-type' values for a particular
            portal_type, or all possible formats if none supplied.
        """
        return self.listAllowedVocabulary('Format', content, content_type)

    security.declarePublic('listAllowedLanguages')

    def listAllowedLanguages(self, content=None, content_type=None):
        """
            List the allowed language values.
        """
        return self.listAllowedVocabulary('Language', content, content_type)

    security.declarePublic('listAllowedRights')

    def listAllowedRights(self, content=None, content_type=None):
        """
            List the allowed values for a "Rights"
            selection list;  this gets especially important where
            syndication is involved.
        """
        return self.listAllowedVocabulary('Rights', content, content_type)

    security.declareProtected(ModifyPortalContent, 'setInitialMetadata')

    def setInitialMetadata(self, content):
        """
            Set initial values for content metatdata, supplying
            any site-specific defaults.
        """
        for element, policy in self.listPolicies(content.getPortalTypeName()):

            if not getattr(content, element)():

                if policy.supplyDefault():
                    setter = getattr(content, 'set%s' % element)
                    setter(policy.defaultValue())
                elif policy.isRequired():
                    raise MetadataError, \
                          'Metadata element %s is required.' % element

        # TODO:  Call initial_values_hook, if present

    security.declareProtected(View, 'validateMetadata')

    def validateMetadata(self, content):
        """
            Enforce portal-wide policies about DCI, e.g.,
            requiring non-empty title/description, etc.  Called
            by the CMF immediately before saving changes to the
            metadata of an object.
        """
        for element, policy in self.listPolicies(content.getPortalTypeName()):

            value = getattr(content, element)()
            if not value and policy.isRequired():
                raise MetadataError, \
                        'Metadata element %s is required.' % element

            if value and policy.enforceVocabulary():
                values = policy.isMultiValued() and value or [value]
                for value in values:
                    if not value in policy.allowedVocabulary():
                        raise MetadataError, \
                        'Value %s is not in allowed vocabulary for ' \
                        'metadata element %s.' % ( value, element )
Example #39
0
    Or,
    Generic,
    Indexed,
    _CompositeQuery,
    LiteralResultSet,
)

from eval import eval as _eval

from ranking import RankByQueries_Sum, RankByQueries_Max


############################################################################
## Security
_allow_module("Products.AdvancedQuery")
_s = ClassSecurityInfo()
_s.declarePublic("addSubquery")
_CompositeQuery._s = _s
InitializeClass(_CompositeQuery)


############################################################################
## ZCatalog extension
def _makeAdvancedQuery(self, catalogSearchSpec):
    """advanced query corresponding to *catalogSearchSpec* (a dictionary)."""
    q = And()
    get = catalogSearchSpec.get
    for i in self.Indexes.objectIds():
        vi = get(i)
        if vi is None or vi == "":
            continue
Example #40
0
class MetadataElementPolicy(SimpleItem):
    """
        Represent a type-specific policy about a particular DCMI element.
    """

    security = ClassSecurityInfo()
    #
    #   Default values.
    #
    is_required = 0
    supply_default = 0
    default_value = ''
    enforce_vocabulary = 0
    allowed_vocabulary = ()

    def __init__(self, is_multi_valued=False):
        self.is_multi_valued = bool(is_multi_valued)

    #
    #   Mutator.
    #
    security.declareProtected(ManagePortal, 'edit')

    def edit(self, is_required, supply_default, default_value,
             enforce_vocabulary, allowed_vocabulary):
        self.is_required = bool(is_required)
        self.supply_default = bool(supply_default)
        self.default_value = default_value
        self.enforce_vocabulary = bool(enforce_vocabulary)
        self.allowed_vocabulary = tuple(allowed_vocabulary)

    #
    #   Query interface
    #
    security.declareProtected(View, 'isMultiValued')

    def isMultiValued(self):
        """
            Can this element hold multiple values?
        """
        return self.is_multi_valued

    security.declareProtected(View, 'isRequired')

    def isRequired(self):
        """
            Must this element be supplied?
        """
        return self.is_required

    security.declareProtected(View, 'supplyDefault')

    def supplyDefault(self):
        """
            Should the tool supply a default?
        """
        return self.supply_default

    security.declareProtected(View, 'defaultValue')

    def defaultValue(self):
        """
            If so, what is the default?
        """
        return self.default_value

    security.declareProtected(View, 'enforceVocabulary')

    def enforceVocabulary(self):
        """
        """
        return self.enforce_vocabulary

    security.declareProtected(View, 'allowedVocabulary')

    def allowedVocabulary(self):
        """
        """
        return self.allowed_vocabulary
Example #41
0
""" Patches for Products.CMFCore
"""
from AccessControl import ClassSecurityInfo
from eea.workflow.events import InitialStateCreatedEvent
from zope.event import notify


security = ClassSecurityInfo()

security.declarePrivate('notifyCreated')
def notifyCreated(self, ob):
    """ Notify all applicable workflows that an object has been created
        and put in its new place.

    The patch adds a single line that uses zope.event to notify of
    the IInitialStateCreatedEvent event
    """
    self._old_notifyCreated(ob)
    notify(InitialStateCreatedEvent(ob))
Example #42
0
class UniqueIdHandlerTool(UniqueObject, SimpleItem):

    __doc__ = __doc__  # copy from module

    implements(IUniqueIdHandler, IUniqueIdBrainQuery,
               IUniqueIdUnrestrictedQuery)
    __implements__ = (SimpleItem.__implements__, )

    id = 'portal_uidhandler'

    manage_options = (({
        'label': 'Query',
        'action': 'manage_queryObject'
    }, ) + SimpleItem.manage_options)

    alternative_id = "portal_standard_uidhandler"
    meta_type = 'Unique Id Handler Tool'

    # make the uid attribute name available for the unit tests
    # not meant to be altered as long you don't know what you do!!!
    UID_ATTRIBUTE_NAME = UID_ATTRIBUTE_NAME

    # make the exception class available through the tool
    UniqueIdError = UniqueIdError

    security = ClassSecurityInfo()

    def _reindexObject(self, obj):
        # XXX: this method violates the rules for tools/utilities:
        # it depends on a non-utility tool
        # add uid index and colums to catalog if not yet done
        UID_ATTRIBUTE_NAME = self.UID_ATTRIBUTE_NAME
        catalog = getToolByName(obj, 'portal_catalog')
        if UID_ATTRIBUTE_NAME not in catalog.indexes():
            catalog.addIndex(UID_ATTRIBUTE_NAME, 'FieldIndex')
            catalog.addColumn(UID_ATTRIBUTE_NAME)

        # reindex
        catalog.reindexObject(obj, idxs=[UID_ATTRIBUTE_NAME])

    def _setUid(self, obj, uid):
        """Attaches a unique id to the object and does reindexing.
        """
        # attach a unique id annotation to the object
        anno_tool = getUtility(IUniqueIdAnnotationManagement)
        annotation = anno_tool(obj, self.UID_ATTRIBUTE_NAME)
        annotation.setUid(uid)

        # reindex the object
        self._reindexObject(obj)

    security.declarePublic('register')

    def register(self, obj):
        """See IUniqueIdSet.
        """
        uid = self.queryUid(obj, default=None)
        if uid is None:
            # generate a new unique id and set it
            generator = getUtility(IUniqueIdGenerator)
            uid = generator()
            self._setUid(obj, uid)

        return uid

    security.declareProtected(ManagePortal, 'unregister')

    def unregister(self, obj):
        """See IUniqueIdSet.
        """
        UID_ATTRIBUTE_NAME = self.UID_ATTRIBUTE_NAME
        if getattr(aq_base(obj), UID_ATTRIBUTE_NAME, None) is None:
            raise UniqueIdError, \
                  "No unique id available to be unregistered on '%s'" % obj

        # delete the uid and reindex
        delattr(obj, UID_ATTRIBUTE_NAME)
        self._reindexObject(obj)

    security.declarePublic('queryUid')

    def queryUid(self, obj, default=None):
        """See IUniqueIdQuery.
        """
        uid = getattr(aq_base(obj), self.UID_ATTRIBUTE_NAME, None)
        # If 'obj' is a content object the 'uid' attribute is usually a
        # callable object. If 'obj' is a catalog brain the uid attribute
        # is non callable and possibly equals the 'Missing.MV' value.
        if uid is Missing.MV or uid is None:
            return default
        if callable(uid):
            return uid()
        return uid

    security.declarePublic('getUid')

    def getUid(self, obj):
        """See IUniqueIdQuery.
        """
        uid = self.queryUid(obj, None)
        if uid is None:
            raise UniqueIdError, "No unique id available on '%s'" % obj
        return uid

    security.declarePrivate('setUid')

    def setUid(self, obj, uid, check_uniqueness=True):
        """See IUniqueIdSet.
        """
        # None is the only value a unique id shall never have!
        if uid is None:
            raise UniqueIdError, "It's forbidden to set a unique id to 'None'."

        # check for uniqueness if enabled
        if check_uniqueness:
            result = self.queryObject(uid)
            if result is not None and result != obj:
                if callable(uid):
                    uid = uid()
                raise UniqueIdError, \
                      "The unique id '%s' is already in use" % uid

        # everything is ok: set it!
        self._setUid(obj, uid)

    def _queryBrain(self, uid, searchMethodName, default=None):
        """This helper method does the "hard work" of querying the catalog
           and interpreting the results.
        """
        # XXX: this method violates the rules for tools/utilities:
        # it depends on a non-utility tool
        if uid is None:
            return default

        # convert the uid to the right format
        generator = getUtility(IUniqueIdGenerator)
        uid = generator.convert(uid)

        catalog = getToolByName(self, 'portal_catalog')
        searchMethod = getattr(catalog, searchMethodName)
        result = searchMethod({self.UID_ATTRIBUTE_NAME: uid})
        len_result = len(result)

        # return None if no object found with this uid
        if len_result == 0:
            return default

        # print a message to the log  if more than one object has
        # the same uid (uups!)
        if len_result > 1:
            logging.getLogger('CMFUid').error(
                "ASSERT: %d objects have %r as uid!!!", len_result, uid)

        return result[0]

    security.declarePublic('queryBrain')

    def queryBrain(self, uid, default=None):
        """See IUniqueIdBrainQuery.
        """
        return self._queryBrain(uid, 'searchResults', default)

    def _getBrain(self, uid, queryBrainMethod):
        brain = queryBrainMethod(uid, default=None)
        if brain is None:
            raise UniqueIdError, "No object found with '%s' as uid." % uid
        return brain

    security.declarePublic('getBrain')

    def getBrain(self, uid):
        """See IUniqueIdBrainQuery.
        """
        return self._getBrain(uid, self.queryBrain)

    security.declarePublic('getObject')

    def getObject(self, uid):
        """See IUniqueIdQuery.
        """
        return self.getBrain(uid).getObject()

    security.declarePublic('queryObject')

    def queryObject(self, uid, default=None):
        """See IUniqueIdQuery.
        """
        try:
            return self.getObject(uid)
        except UniqueIdError:
            return default

    security.declarePrivate('unrestrictedQueryBrain')

    def unrestrictedQueryBrain(self, uid, default=None):
        """See IUniqueIdUnrestrictedQuery.
        """
        return self._queryBrain(uid, 'unrestrictedSearchResults', default)

    security.declarePrivate('unrestrictedGetBrain')

    def unrestrictedGetBrain(self, uid):
        """See IUniqueIdUnrestrictedQuery.
        """
        return self._getBrain(uid, self.unrestrictedQueryBrain)

    security.declarePrivate('unrestrictedGetObject')

    def unrestrictedGetObject(self, uid):
        """See IUniqueIdUnrestrictedQuery.
        """
        return self.unrestrictedGetBrain(uid).getObject()

    security.declarePrivate('unrestrictedQueryObject')

    def unrestrictedQueryObject(self, uid, default=None):
        """See IUniqueIdUnrestrictedQuery.
        """
        try:
            return self.unrestrictedGetObject(uid)
        except UniqueIdError:
            return default

    security.declareProtected(ManagePortal, 'manage_queryObject')
    manage_queryObject = PageTemplateFile('queryUID.pt', _wwwdir)
Example #43
0
## BetterSiteErrorLog
## An attempt to make the Zope error_log a bit more useful.
## License: ZPL
## By: Peter Bengtsson, Fry-IT, [email protected]
##

import logging
import os

from Globals import package_home
from AccessControl import ClassSecurityInfo
from Products.PageTemplates.PageTemplateFile import PageTemplateFile
from Products.SiteErrorLog.SiteErrorLog import SiteErrorLog

logger = logging.getLogger('BetterSiteErrorLog')
security = ClassSecurityInfo()


# Set __version__ to SiteErrorLog
__version__=open(os.path.join(package_home(globals()), 'version.txt')).read().strip()
setattr(SiteErrorLog, 'BetterSiteErrorLog_version', __version__)


# Patch manage_main
_www = os.path.join(os.path.dirname(__file__), 'www')
setattr(SiteErrorLog, 'manage_main', PageTemplateFile('main.pt', _www))
#logger.info("Patched SiteErrorLog's manage_main")

# Add an RSS version
_www = os.path.join(os.path.dirname(__file__), 'www')
setattr(SiteErrorLog, 'manage_rss_errorlog', PageTemplateFile('rss.pt', _www))
Example #44
0
class CachingPolicyManager(SimpleItem):
    """
        Manage the set of CachingPolicy objects for the site;  dispatch
        to them from skin methods.
    """

    __implements__ = ICachingPolicyManager

    id = 'caching_policy_manager'
    meta_type = 'CMF Caching Policy Manager'

    security = ClassSecurityInfo()

    def __init__(self):
        self._policy_ids = ()
        self._policies = PersistentMapping()

    #
    #   ZMI
    #
    manage_options = (({
        'label': 'Policies',
        'action': 'manage_cachingPolicies',
        'help': ('CMFCore', 'CPMPolicies.stx')
    }, ) + SimpleItem.manage_options)

    security.declareProtected(ManagePortal, 'manage_cachingPolicies')
    manage_cachingPolicies = DTMLFile('cachingPolicies', _dtmldir)

    security.declarePublic('listPolicies')

    def listPolicies(self):
        """
            Return a sequence of tuples,
            '( policy_id, ( policy, typeObjectName ) )'
            for all policies in the registry 
        """
        result = []
        for policy_id in self._policy_ids:
            result.append((policy_id, self._policies[policy_id]))
        return tuple(result)

    security.declareProtected(ManagePortal, 'addPolicy')

    def addPolicy(
            self,
            policy_id,
            predicate  # TALES expr (def. 'python:1')
        ,
            mtime_func  # TALES expr (def. 'object/modified')
        ,
            max_age_secs  # integer, seconds (def. 0)
        ,
            no_cache  # boolean (def. 0)
        ,
            no_store  # boolean (def. 0)
        ,
            must_revalidate  # boolean (def. 0)
        ,
            vary  # string value
        ,
            etag_func  # TALES expr (def. '')
        ,
            REQUEST=None):
        """
            Add a caching policy.
        """
        self._addPolicy(policy_id, predicate, mtime_func, max_age_secs,
                        no_cache, no_store, must_revalidate, vary, etag_func)
        if REQUEST is not None:
            REQUEST['RESPONSE'].redirect(self.absolute_url() +
                                         '/manage_cachingPolicies' +
                                         '?manage_tabs_message=' +
                                         'Policy+added.')

    security.declareProtected(ManagePortal, 'updatePolicy')

    def updatePolicy(
            self,
            policy_id,
            predicate  # TALES expr (def. 'python:1')
        ,
            mtime_func  # TALES expr (def. 'object/modified')
        ,
            max_age_secs  # integer, seconds
        ,
            no_cache  # boolean (def. 0)
        ,
            no_store  # boolean (def. 0)
        ,
            must_revalidate  # boolean (def. 0)
        ,
            vary  # string value
        ,
            etag_func  # TALES expr (def. '')
        ,
            REQUEST=None):
        """
            Update a caching policy.
        """
        self._updatePolicy(policy_id, predicate, mtime_func, max_age_secs,
                           no_cache, no_store, must_revalidate, vary,
                           etag_func)
        if REQUEST is not None:
            REQUEST['RESPONSE'].redirect(self.absolute_url() +
                                         '/manage_cachingPolicies' +
                                         '?manage_tabs_message=' +
                                         'Policy+updated.')

    security.declareProtected(ManagePortal, 'movePolicyUp')

    def movePolicyUp(self, policy_id, REQUEST=None):
        """
            Move a caching policy up in the list.
        """
        policy_ids = list(self._policy_ids)
        ndx = policy_ids.index(policy_id)
        if ndx == 0:
            msg = "Policy+already+first."
        else:
            self._reorderPolicy(policy_id, ndx - 1)
            msg = "Policy+moved."
        if REQUEST is not None:
            REQUEST['RESPONSE'].redirect(self.absolute_url() +
                                         '/manage_cachingPolicies' +
                                         '?manage_tabs_message=%s' % msg)

    security.declareProtected(ManagePortal, 'movePolicyDown')

    def movePolicyDown(self, policy_id, REQUEST=None):
        """
            Move a caching policy down in the list.
        """
        policy_ids = list(self._policy_ids)
        ndx = policy_ids.index(policy_id)
        if ndx == len(policy_ids) - 1:
            msg = "Policy+already+last."
        else:
            self._reorderPolicy(policy_id, ndx + 1)
            msg = "Policy+moved."
        if REQUEST is not None:
            REQUEST['RESPONSE'].redirect(self.absolute_url() +
                                         '/manage_cachingPolicies' +
                                         '?manage_tabs_message=%s' % msg)

    security.declareProtected(ManagePortal, 'removePolicy')

    def removePolicy(self, policy_id, REQUEST=None):
        """
            Remove a caching policy.
        """
        self._removePolicy(policy_id)
        if REQUEST is not None:
            REQUEST['RESPONSE'].redirect(
                self.absolute_url() + '/manage_cachingPolicies' +
                '?manage_tabs_message=Policy+removed.')

    #
    #   Policy manipulation methods.
    #
    security.declarePrivate('_addPolicy')

    def _addPolicy(self, policy_id, predicate, mtime_func, max_age_secs,
                   no_cache, no_store, must_revalidate, vary, etag_func):
        """
            Add a policy to our registry.
        """
        policy_id = str(policy_id).strip()

        if not policy_id:
            raise ValueError, "Policy ID is required!"

        if policy_id in self._policy_ids:
            raise KeyError, "Policy %s already exists!" % policy_id

        self._policies[policy_id] = CachingPolicy(policy_id, predicate,
                                                  mtime_func, max_age_secs,
                                                  no_cache, no_store,
                                                  must_revalidate, vary,
                                                  etag_func)
        idlist = list(self._policy_ids)
        idlist.append(policy_id)
        self._policy_ids = tuple(idlist)

    security.declarePrivate('_updatePolicy')

    def _updatePolicy(self, policy_id, predicate, mtime_func, max_age_secs,
                      no_cache, no_store, must_revalidate, vary, etag_func):
        """
            Update a policy in our registry.
        """
        if policy_id not in self._policy_ids:
            raise KeyError, "Policy %s does not exist!" % policy_id

        self._policies[policy_id] = CachingPolicy(policy_id, predicate,
                                                  mtime_func, max_age_secs,
                                                  no_cache, no_store,
                                                  must_revalidate, vary,
                                                  etag_func)

    security.declarePrivate('_reorderPolicy')

    def _reorderPolicy(self, policy_id, newIndex):
        """
            Reorder a policy in our registry.
        """
        if policy_id not in self._policy_ids:
            raise KeyError, "Policy %s does not exist!" % policy_id

        idlist = list(self._policy_ids)
        ndx = idlist.index(policy_id)
        pred = idlist[ndx]
        idlist = idlist[:ndx] + idlist[ndx + 1:]
        idlist.insert(newIndex, pred)
        self._policy_ids = tuple(idlist)

    security.declarePrivate('_removePolicy')

    def _removePolicy(self, policy_id):
        """
            Remove a policy from our registry.
        """
        if policy_id not in self._policy_ids:
            raise KeyError, "Policy %s does not exist!" % policy_id

        del self._policies[policy_id]
        idlist = list(self._policy_ids)
        ndx = idlist.index(policy_id)
        idlist = idlist[:ndx] + idlist[ndx + 1:]
        self._policy_ids = tuple(idlist)

    #
    #   'portal_caching' interface methods
    #
    security.declareProtected(View, 'getHTTPCachingHeaders')

    def getHTTPCachingHeaders(self, content, view_method, keywords, time=None):
        """
            Return a list of HTTP caching headers based on 'content',
            'view_method', and 'keywords'.
        """
        context = createCPContext(content, view_method, keywords, time=time)
        for policy_id, policy in self.listPolicies():

            headers = policy.getHeaders(context)
            if headers:
                return headers

        return ()
Example #45
0
    p = subprocess.Popen((DCWorkflowGraph.bin_search(DOT_EXE),
                          '-Nfontname=IPAexGothic', '-Nfontsize=10',
                          '-Efontname=IPAexGothic', '-Efontsize=10',
                          '-T%s' % format),
                         stdin=subprocess.PIPE, stdout=subprocess.PIPE)
    result = p.communicate(pot)[0]

    setHeader('Content-Type', 'image/%s' % format)
  else:
    filename = wf_id or self.getId()
    setHeader('Content-Type', 'text/x-graphviz')
    setHeader('Content-Disposition', 'attachment; filename=%s.dot' % filename)

  if not result:
    LOG("ERP5Type.patches.DCWorkflowGraph", WARNING,
        "Empty %s graph file" % format)

  return result

DCWorkflowGraph.getGraph = getGraph

from Products.DCWorkflow.DCWorkflow import DCWorkflowDefinition
DCWorkflowDefinition.getGraph = getGraph
DCWorkflowDefinition.getPOT = DCWorkflowGraph.getPOT

security = ClassSecurityInfo()
security.declareProtected(Permissions.ManagePortal, 'getPOT')
security.declareProtected(Permissions.ManagePortal, 'getGraph')
DCWorkflowDefinition.security = security
InitializeClass(DCWorkflowDefinition)
Example #46
0
class RolemapConfigurator(ConfiguratorBase):
    """ Synthesize XML description of sitewide role-permission settings.
    """
    security = ClassSecurityInfo()

    security.declareProtected(ManagePortal, 'listRoles')

    def listRoles(self):
        """ List the valid role IDs for our site.
        """
        return self._site.valid_roles()

    security.declareProtected(ManagePortal, 'listPermissions')

    def listPermissions(self):
        """ List permissions for export.

        o Returns a sqeuence of mappings describing locally-modified
          permission / role settings.  Keys include:

          'permission' -- the name of the permission

          'acquire' -- a flag indicating whether to acquire roles from the
              site's container

          'roles' -- the list of roles which have the permission.

        o Do not include permissions which both acquire and which define
          no local changes to the acquired policy.
        """
        permissions = []
        valid_roles = self.listRoles()

        for perm in self._site.ac_inherited_permissions(1):

            name = perm[0]
            p = Permission(name, perm[1], self._site)
            roles = p.getRoles(default=[])
            acquire = isinstance(roles, list)  # tuple means don't acquire
            roles = [r for r in roles if r in valid_roles]

            if roles or not acquire:
                permissions.append({
                    'name': name,
                    'acquire': acquire,
                    'roles': roles
                })

        return permissions

    def _getExportTemplate(self):

        return PageTemplateFile('rmeExport.xml', _xmldir)

    def _getImportMapping(self):

        return {
            'rolemap': {
                'roles': {
                    CONVERTER: self._convertToUnique
                },
                'permissions': {
                    CONVERTER: self._convertToUnique
                }
            },
            'roles': {
                'role': {
                    KEY: None
                }
            },
            'role': {
                'name': {
                    KEY: None
                }
            },
            'permissions': {
                'permission': {
                    KEY: None,
                    DEFAULT: ()
                }
            },
            'permission': {
                'name': {},
                'role': {
                    KEY: 'roles'
                },
                'acquire': {
                    CONVERTER: self._convertToBoolean
                }
            }
        }
Example #47
0
  """
  Folder_original__setOb(self, id, object)
  aq_chain = getattr(self, 'aq_chain', None)
  if aq_chain is None: # Not in acquisition context
    return
  if len(aq_chain) < 2: # Acquisition context is not deep enough for context to possibly be below portal skins.
    return
  portal_skins = aq_chain[1]
  if getattr(portal_skins, 'meta_type', '') != 'CMF Skins Tool' : # It is not a skin tool we're below.
    return
  _updateCacheEntry = getattr(portal_skins.aq_base, '_updateCacheEntry', None)
  if _updateCacheEntry is None:
    return
  _updateCacheEntry(self.id, id)

Folder._setOb = Folder_setOb

def Folder_isERP5SitePresent(self):
  """ Return True if a ERP5 Site is present as subobject. This is
      usefull to identify if a erp5 is present already on a Zope
      Setup.
  """
  return len(self.objectIds("ERP5 Site")) > 0

Folder.isERP5SitePresent = Folder_isERP5SitePresent

security = ClassSecurityInfo()
security.declareProtected(Permissions.ManagePortal, 'isERP5SitePresent')
Folder.security = security
InitializeClass(Folder)
Example #48
0
class VariableDefinition(SimpleItem):
    """Variable definition"""

    meta_type = 'Workflow Variable'

    security = ClassSecurityInfo()
    security.declareObjectProtected(ManagePortal)

    description = ''
    for_catalog = 1
    for_status = 1
    default_value = ''
    default_expr = None  # Overrides default_value if set
    info_guard = None
    update_always = 1

    manage_options = (
        {'label': 'Properties', 'action': 'manage_properties'},
        )

    def __init__(self, id):
        self.id = id

    def getDefaultExprText(self):
        if not self.default_expr:
            return ''
        else:
            return self.default_expr.text

    def getInfoGuard(self):
        if self.info_guard is not None:
            return self.info_guard
        else:
            return Guard().__of__(self)  # Create a temporary guard.

    def getInfoGuardSummary(self):
        res = None
        if self.info_guard is not None:
            res = self.info_guard.getSummary()
        return res

    _properties_form = DTMLFile('variable_properties', _dtmldir)

    def manage_properties(self, REQUEST, manage_tabs_message=None):
        '''
        '''
        return self._properties_form(REQUEST,
                                     management_view='Properties',
                                     manage_tabs_message=manage_tabs_message,
                                     )

    def setProperties(self, description,
                      default_value='', default_expr='',
                      for_catalog=0, for_status=0,
                      update_always=0,
                      props=None, REQUEST=None):
        '''
        '''
        self.description = str(description)
        self.default_value = str(default_value)
        if default_expr:
            self.default_expr = Expression(default_expr)
        else:
            self.default_expr = None

        g = Guard()
        if g.changeFromProperties(props or REQUEST):
            self.info_guard = g
        else:
            self.info_guard = None
        self.for_catalog = bool(for_catalog)
        self.for_status = bool(for_status)
        self.update_always = bool(update_always)
        if REQUEST is not None:
            return self.manage_properties(REQUEST, 'Properties changed.')
Example #49
0
# FOR A PARTICULAR PURPOSE
#
##############################################################################
from Products.DCWorkflow.Guard import Guard
from Products.PythonScripts.PythonScript import PythonScript
from App.special_dtml import DTMLFile
from Products.ERP5Type import _dtmldir
from AccessControl import ClassSecurityInfo, getSecurityManager
from AccessControl.class_init import InitializeClass
from AccessControl.PermissionRole import rolesForPermissionOn
from OFS.misc_ import p_
from App.ImageFile import ImageFile
from Acquisition import aq_base, aq_parent
from zExceptions import Forbidden

security = ClassSecurityInfo()
PythonScript.security = security

def haveProxyRole(self):
  """if a script has proxy role, return True"""
  return bool(self._proxy_roles)

def om_icons(self):
  """Return a list of icon URLs to be displayed by an ObjectManager"""
  icons = ({'path': 'misc_/PythonScripts/pyscript.gif',
            'alt': self.meta_type, '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
Example #50
0
class VersionsTool(UniqueObject, SimpleItemWithProperties):
    __doc__ = __doc__  # copy from module
    id = 'portal_versions'
    meta_type = 'Portal Versions Tool'

    security = ClassSecurityInfo()

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

    # With auto_copy_forward turned on, the versions tool lets users
    # check out an object even if it is not updated to the latest
    # revision.  It copies the old revision forward.  Note that
    # this feature really shouldn't be enabled unless users also have the
    # ability to revert to specific revisions.
    auto_copy_forward = 1

    repository_name = 'VersionRepository'

    _properties = (
        {
            'id': 'repository_name',
            'type': 'string',
            'mode': 'w',
            'label': 'ID of the version repository'
        },
        {
            'id': 'auto_copy_forward',
            'type': 'boolean',
            'mode': 'w',
            'label': 'Copy old revisions forward rather than disallow checkout'
        },
    )

    security.declareProtected(ManagePortal, 'manage_overview')
    manage_overview = DTMLFile('explainVersionsTool', _wwwdir)

    # helper methods

    def _getVersionRepository(self):
        repo = aq_acquire(self, self.repository_name, containment=1)
        return repo

    def _getBranchName(self, info):
        parts = info.version_id.split('.')
        if len(parts) > 1:
            return parts[-2]
        return 'mainline'

    # public methods

    security.declarePublic('isUnderVersionControl')

    def isUnderVersionControl(self, obj):
        """Returns a true value if the object is under version control.
        """
        obj = unproxied(obj)
        repo = self._getVersionRepository()
        return repo.isUnderVersionControl(obj)

    security.declarePublic('isCheckedOut')

    def isCheckedOut(self, obj):
        """Returns a true value if the object is checked out.
        """
        obj = unproxied(obj)
        repo = self._getVersionRepository()
        if not repo.isUnderVersionControl(obj):
            return 0
        info = repo.getVersionInfo(obj)
        return (info.status == info.CHECKED_OUT)

    security.declarePublic('isResourceUpToDate')

    def isResourceUpToDate(self, obj, require_branch=0):
        """Return true if a version-controlled resource is up to date.
        """
        obj = unproxied(obj)
        repo = self._getVersionRepository()
        return repo.isResourceUpToDate(obj, require_branch)

    # protected methods

    security.declarePublic('checkout')

    def checkout(self, obj):
        """Opens the object for development.

        Returns the object, which might be different from what was passed to
        the method if the object was replaced.
        """
        verifyPermission(UseVersionControl, obj)
        obj = unproxied(obj)
        repo = self._getVersionRepository()
        old_state = None
        if not repo.isUnderVersionControl(obj):
            repo.applyVersionControl(obj)
        elif self.auto_copy_forward:
            if not repo.isResourceUpToDate(obj, require_branch=1):
                # The object is not at the latest revision or has a
                # sticky tag.  Get it unstuck by copying the old state
                # forward after the object has been checked out.
                info = repo.getVersionInfo(obj)
                old_state = repo.getVersionOfResource(info.history_id,
                                                      info.version_id)
                # Momentarily revert to the branch.
                obj = repo.updateResource(obj, self._getBranchName(info))
                obj = repo.checkoutResource(obj)

                # Copy the old state into the object, minus __vc_info__.
                # XXX There ought to be some way to do this more cleanly.
                obj._p_changed = 1
                for key in obj.__dict__.keys():
                    if key != '__vc_info__':
                        if not old_state.__dict__.has_key(key):
                            del obj.__dict__[key]
                for key, value in old_state.__dict__.items():
                    if key != '__vc_info__':
                        obj.__dict__[key] = value
                # Check in as a copy.
                obj = repo.checkinResource(
                    obj, 'Copied from revision %s' % info.version_id)
        repo.checkoutResource(obj)
        return None

    security.declarePublic('checkin')

    def checkin(self, obj, message=None):
        """Checks in a new version.
        """
        verifyPermission(UseVersionControl, obj)
        obj = unproxied(obj)
        repo = self._getVersionRepository()
        if not repo.isUnderVersionControl(obj):
            repo.applyVersionControl(obj, message)
        else:
            if (not repo.isResourceUpToDate(obj, require_branch=1)
                    and self.isCheckedOut(obj)):
                # This is a strange state, but it can be fixed.
                # Revert the object to the branch, replace the
                # reverted state with the new state, and check in.
                new_dict = obj.__dict__.copy()
                # Uncheckout
                obj = repo.uncheckoutResource(obj)
                info = repo.getVersionInfo(obj)
                obj = repo.updateResource(obj, self._getBranchName(info))
                # Checkout
                obj = repo.checkoutResource(obj)
                # Restore the new state
                for key in obj.__dict__.keys():
                    if key != '__vc_info__':
                        if not new_dict.has_key(key):
                            del obj.__dict__[key]
                for key, value in new_dict.items():
                    if key != '__vc_info__':
                        obj.__dict__[key] = value
            repo.checkinResource(obj, message or '')
        return None

    security.declarePublic('getLogEntries')

    def getLogEntries(self, obj, only_checkins=0):
        """Returns the log entries for an object as a sequence of mappings.
        """
        verifyPermission(UseVersionControl, obj)
        obj = unproxied(obj)
        repo = self._getVersionRepository()
        if not repo.isUnderVersionControl(obj):
            return []
        entries = repo.getLogEntries(obj)
        res = []
        for entry in entries:
            a = entry.action
            if a == entry.ACTION_CHECKOUT:
                action = 'checkout'
            elif a == entry.ACTION_CHECKIN:
                action = 'checkin'
            elif a == entry.ACTION_UNCHECKOUT:
                action = 'uncheckout'
            elif a == entry.ACTION_UPDATE:
                action = 'update'
            else:
                action = '?'
            if only_checkins and action != 'checkin':
                continue
            res.append({
                'timestamp': entry.timestamp,
                'version_id': entry.version_id,
                'action': action,
                'message': entry.message,
                'user_id': entry.user_id,
                'path': entry.path,
            })
        return res

    security.declarePublic('getVersionId')

    def getVersionId(self, obj, plus=0):
        """Returns the version ID of the current revision.

        If the 'plus' flag is set and the object is checked out, the
        version ID will include a plus sign to indicate that when the
        object is checked in, it will have a higher version number.
        """
        obj = unproxied(obj)
        repo = self._getVersionRepository()
        if repo.isUnderVersionControl(obj):
            info = repo.getVersionInfo(obj)
            res = info.version_id
            if plus and info.status == info.CHECKED_OUT:
                res += '+'
            return res
        else:
            return ''

    security.declarePublic('getVersionIds')

    def getVersionIds(self, obj):
        """Returns the version IDs of all revisions for an object.
        """
        verifyPermission(UseVersionControl, obj)
        obj = unproxied(obj)
        repo = self._getVersionRepository()
        ids = repo.getVersionIds(obj)
        ids = map(int, ids)
        ids.sort()
        return map(str, ids)

    security.declarePublic('getHistoryId')

    def getHistoryId(self, obj):
        """Returns the version history ID of the object.
        """
        verifyPermission(UseVersionControl, obj)
        obj = unproxied(obj)
        repo = self._getVersionRepository()
        return repo.getVersionInfo(obj).history_id

    security.declarePublic('revertToVersion')

    def revertToVersion(self, obj, version_id):
        """Reverts the object to the given version.

        If make_new_revision, a new revision is created, so that
        the object's state can progress along a new line without
        making the user deal with branches, labels, etc.
        """
        verifyPermission(UseVersionControl, obj)
        obj = unproxied(obj)
        repo = self._getVersionRepository()
        # Verify the object is under version control.
        repo.getVersionInfo(obj)
        if self.isCheckedOut(obj):
            # Save the current data.
            self.checkin(obj, 'Auto-saved')
        repo.updateResource(obj, version_id)
Example #51
0
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################

import logging

logger = logging.getLogger(__name__)

from Products.ERP5Type.Globals import InitializeClass
from AccessControl import ClassSecurityInfo
from Products.CMFCore.ActionsTool import ActionsTool
from Products.CMFCore.interfaces import IActionProvider
from Products.CMFCore.permissions import ManagePortal

security = ClassSecurityInfo()

def migrateNonProviders(portal_actions):
  portal_actions_path = '/'.join(portal_actions.getPhysicalPath())
  portal = portal_actions.getPortalObject()
  action_providers = list(portal_actions.action_providers)
  for provider_name in portal_actions.listActionProviders():
    provider = getattr(portal, provider_name)
    if ( getattr(provider, '_actions', ()) and
         getattr(provider, 'listActionInfos', None) is None ):
      logger.info('migrating actions from %r to %r',
         portal_actions_path, '/'.join(provider.getPhysicalPath()))
      portal_actions._actions += provider._actions
      del provider._actions
    if (getattr(provider, 'listActionInfos', None) is None and
        getattr(provider, 'getActionListFor', None) is None and
Example #52
0
class SkinnableObjectManager(ObjectManager):

    _v_skindata = None

    security = ClassSecurityInfo()

    security.declarePrivate('getSkinsFolderName')

    def getSkinsFolderName(self):
        # Not implemented.
        return None

    def __getattr__(self, name):
        '''
        Looks for the name in an object with wrappers that only reach
        up to the root skins folder.  This should be fast, flexible,
        and predictable.
        '''
        if not name.startswith('_') and not name.startswith('aq_'):
            sd = self._v_skindata
            if sd is not None:
                request, ob, ignore = sd
                if not ignore.has_key(name):
                    subob = getattr(ob, name, _marker)
                    if subob is not _marker:
                        # Return it in context of self, forgetting
                        # its location and acting as if it were located
                        # in self.
                        return aq_base(subob)
                    else:
                        ignore[name] = 1
        if superGetAttr is None:
            raise AttributeError, name
        return superGetAttr(self, name)

    security.declarePublic('setupCurrentSkin')

    def setupCurrentSkin(self, REQUEST=None):
        '''
        Sets up _v_skindata so that __getattr__ can find it.
        Can also be called manually, allowing the user to change
        skins in the middle of a request.
        '''
        if REQUEST is None:
            REQUEST = getattr(self, 'REQUEST', None)
        if REQUEST is None:
            # We are traversing without a REQUEST at the root.
            # Don't change the skin right now. (Otherwise
            # [un]restrictedTraverse messes up the skin data.)
            return
        if self._v_skindata is not None and self._v_skindata[0] is REQUEST:
            # Already set up for this request.
            return
        self._v_skindata = None
        sfn = self.getSkinsFolderName()
        if sfn is not None:
            # Note that our custom __getattr__ won't get confused
            # by skins at the moment because _v_skindata is None.
            sf = getattr(self, sfn, None)
            if sf is not None:
                try:
                    sd = sf.getSkin(REQUEST)
                except:
                    import sys
                    from zLOG import LOG, ERROR
                    LOG('CMFCore',
                        ERROR,
                        'Unable to get skin',
                        error=sys.exc_info())
                else:
                    if sd is not None:
                        # Hide from acquisition.
                        self._v_skindata = (REQUEST, sd, {})

    def __of__(self, parent):
        '''
        Sneakily sets up the portal skin then returns the wrapper
        that Acquisition.Implicit.__of__() would return.
        '''
        w_self = ImplicitAcquisitionWrapper(self, parent)
        w_self.setupCurrentSkin()
        return w_self

    def _checkId(self, id, allow_dup=0):
        '''
        Override of ObjectManager._checkId().  Allows the user
        to create objects with IDs that match the ID of a skin
        object.
        '''
        superCheckId = SkinnableObjectManager.inheritedAttribute('_checkId')
        if not allow_dup:
            # Temporarily disable _v_skindata.
            # Note that this depends heavily on Zope's current thread
            # behavior.
            sd = self._v_skindata
            self._v_skindata = None
            try:
                base = getattr(self, 'aq_base', self)
                if not hasattr(base, id):
                    # Cause _checkId to not check for duplication.
                    return superCheckId(self, id, allow_dup=1)
            finally:
                self._v_skindata = sd
        return superCheckId(self, id, allow_dup)
Example #53
0
"""
Very simple volatile-attribute-based caching.

Especially useful to cache processed pseudo-constants in PythonScripts: cached
value will be set as a volatile on the PythonScript, so it gets flushed when
script is edited.
For such use, it would be even better to be able to put evaluate-once code
in PythonScripts (ie, make python scripts really become Python *Scripts*, not
"python-function-body-and-parameters").

NOTE: This patches OFS.Item.SimpleItem as it's the lowest patchable class
before persistence.Persistent, where this patch would actually belong.
"""

security = ClassSecurityInfo()
security.declarePublic('volatileCached')
def volatileCached(self, func):
  """
  Cache "func()" return value using a volatile on self.
  Return that value, calling func only if needed.

  Usual volatile rules apply:
  - outlives transaction duration
  - bound to a thread only while a transaction is executed (ie, it can be
    reused by a different thread on next processed transaction)
  - destroyed when object is modified by another transaction
  - destroyed when object is modified by transaction and transaction gets
    aborted
  - destroyed when connection cache is minimized and holder (self) is pruned
    (minimization can be triggered in many places...)
Example #54
0
class Delivery(XMLObject, ImmobilisationDelivery, SimulableMixin,
               CompositionMixin, AmountGeneratorMixin):
    """
        Each time delivery is modified, it MUST launch a reindexing of
        inventories which are related to the resources contained in the Delivery
    """
    # CMF Type Definition
    meta_type = 'ERP5 Delivery'
    portal_type = 'Delivery'
    isDelivery = ConstantGetter('isDelivery', value=True)

    # Declarative security
    security = ClassSecurityInfo()
    security.declareObjectProtected(Permissions.AccessContentsInformation)

    # Default Properties
    property_sheets = ( PropertySheet.Base
                      , PropertySheet.XMLObject
                      , PropertySheet.CategoryCore
                      , PropertySheet.DublinCore
                      , PropertySheet.Task
                      , PropertySheet.Arrow
                      , PropertySheet.Movement
                      , PropertySheet.Delivery
                      , PropertySheet.Reference
                      , PropertySheet.Price
                      )

    # Declarative interfaces
    zope.interface.implements(interfaces.IAmountGenerator,
                              interfaces.IDivergenceController,
                              interfaces.IMovementCollection)

    security.declareProtected(Permissions.AccessContentsInformation, 'isAccountable')
    def isAccountable(self):
      """
        Returns 1 if this needs to be accounted
        Only account movements which are not associated to a delivery
        Whenever delivery is there, delivery has priority
      """
      return 1

    security.declareProtected( Permissions.AccessContentsInformation,
                               'getTotalPrice')
    def getTotalPrice(self, fast=0, src__=0, base_contribution=None, rounding=False, **kw):
      """ Returns the total price for this order

        if the `fast` argument is set to a true value, then it use
        SQLCatalog to compute the price, otherwise it sums the total
        price of objects one by one.

        So if the order is not in the catalog, getTotalPrice(fast=1)
        will return 0, this is not a bug.

        base_contribution must be a relative url of a category. If passed, then
        fast parameter is ignored.
      """
      if 'portal_type' not in kw:
        kw['portal_type'] = self.getPortalObject() \
          .getPortalDeliveryMovementTypeList()
      if base_contribution is None:
        if fast:
          # XXX fast ignores base_contribution for now, but it should be possible
          # to use a related key
          kw['section_uid'] = self.getDestinationSectionUid()
          kw['stock.explanation_uid'] = self.getUid()
          return self.getPortalObject()\
            .portal_simulation.getInventoryAssetPrice(**kw)

        result = sum([ line.getTotalPrice(fast=0) for line in
                       self.objectValues(**kw) ])
      else:
        # Find amounts from movements in the delivery.
        if isinstance(base_contribution, (tuple, list)):
          base_contribution_list = base_contribution
        else:
          base_contribution_list = (base_contribution,)
        base_contribution_value_list = []
        portal_categories = self.portal_categories
        for relative_url in base_contribution_list:
          base_contribution_value = portal_categories.getCategoryValue(relative_url)
          if base_contribution_value is not None:
            base_contribution_value_list.append(base_contribution_value)
        if not base_contribution_value_list:
          # We cannot find any amount so that the result is 0.
          result = 0
        else:
          matched_movement_list = [
              movement
              for movement in self.getMovementList()
              if set(movement.getBaseContributionValueList()).intersection(base_contribution_value_list)]
          if rounding:
            portal_roundings = self.portal_roundings
            matched_movement_list = [
                portal_roundings.getRoundingProxy(movement)
                for movement in matched_movement_list]
          result = sum([movement.getTotalPrice()
                        for movement in matched_movement_list])

      method = self._getTypeBasedMethod('convertTotalPrice')
      if method is not None:
        return method(result)
      return result

    security.declareProtected(Permissions.AccessContentsInformation,
                              'getTotalNetPrice')
    def getTotalNetPrice(self, fast=0, src__=0, **kw):
      """
        Same as getTotalPrice, but including Tax and Discount (from legacy
        simulation).

        This method is deprecated because it uses deprecated Tax & Discount
        portal types. You should use getTotalPrice(base_contribution=) instead.
      """
      total_price = self.getTotalPrice(fast=fast, src__=src__, **kw)
      kw['portal_type'] = self.getPortalObject().getPortalTaxMovementTypeList()
      return total_price + self.getTotalPrice(fast=fast, src__=src__, **kw)

    security.declareProtected(Permissions.AccessContentsInformation,
                              'getTotalQuantity')
    def getTotalQuantity(self, fast=0, src__=0, **kw):
      """ Returns the total quantity of this order.

        if the `fast` argument is set to a true value, then it use
        SQLCatalog to compute the quantity, otherwise it sums the total
        quantity of objects one by one.

        So if the order is not in the catalog, getTotalQuantity(fast=1)
        will return 0, this is not a bug.
      """
      if 'portal_type' not in kw:
        kw['portal_type'] = self.getPortalObject() \
          .getPortalDeliveryMovementTypeList()
      if fast:
        kw['section_uid'] = self.getDestinationSectionUid()
        kw['stock.explanation_uid'] = self.getUid()
        return self.getPortalObject().portal_simulation.getInventory(**kw)
      return sum([ line.getTotalQuantity(fast=0) for line in
                      self.objectValues(**kw) ])

    security.declareProtected(Permissions.AccessContentsInformation,
                              'getDeliveryUid')
    def getDeliveryUid(self):
      return self.getUid()

    security.declareProtected(Permissions.AccessContentsInformation,
                              'getDeliveryValue')
    def getDeliveryValue(self):
      """
      Deprecated, we should use getRootDeliveryValue instead
      """
      return self

    security.declareProtected(Permissions.AccessContentsInformation,
                              'getRootDeliveryValue')
    def getRootDeliveryValue(self):
      """
      This method returns the delivery, it is usefull to retrieve the delivery
      from a line or a cell
      """
      return self

    security.declareProtected(Permissions.AccessContentsInformation,
                              'getDelivery')
    def getDelivery(self):
      return self.getRelativeUrl()

    security.declareProtected(Permissions.AccessContentsInformation,
                             '_getMovementList')
    def _getMovementList(self, portal_type=None, **kw):
      """
      Return a list of movements
      """
      movement_portal_type_set = set(
        self.getPortalObject().getPortalMovementTypeList())
      movement_list = self.objectValues(
        portal_type=movement_portal_type_set, **kw)
      if movement_list:

        if isinstance(portal_type, str):
          portal_type = portal_type,
        elif isinstance(portal_type, (list, tuple)):
          portal_type = set(portal_type)

        # Browse lines recursively and collect leafs.
        stack = [iter(movement_list)]
        movement_list = []
        while stack:
          for sub_object in stack[-1]:
            content_list = sub_object.objectValues(
              portal_type=movement_portal_type_set, **kw)
            if sub_object.hasCellContent():
              cell_list = sub_object.getCellValueList()
              if len(cell_list) != len(content_list):
                content_list = set(content_list).difference(cell_list)
                if content_list:
                  stack.append(iter(content_list))
                  break
              else:
                movement_list.extend(x for x in content_list
                  if portal_type is None or x.getPortalType() in portal_type)
            elif content_list:
              stack.append(iter(content_list))
              break
            elif portal_type is None or \
                 sub_object.getPortalType() in portal_type:
              movement_list.append(sub_object)
          else:
            del stack[-1]

      return movement_list

    security.declareProtected(Permissions.AccessContentsInformation,
                              'getMovementList')
    def getMovementList(self, portal_type=None, **kw):
      """
       Return a list of movements.
      """
      return self._getMovementList(portal_type=portal_type, **kw)

    security.declareProtected(Permissions.AccessContentsInformation,
                              'getSimulatedMovementList')
    def getSimulatedMovementList(self):
      """
        Return a list of simulated movements.
        This does not contain Container Line or Container Cell.
      """
      return self.getMovementList(portal_type=
        self.getPortalObject().getPortalSimulatedMovementTypeList())

    security.declareProtected(Permissions.AccessContentsInformation,
                              'getInvoiceMovementList')
    def getInvoiceMovementList(self):
      """
        Return a list of simulated movements.
        This does not contain Container Line or Container Cell.
      """
      return self.getMovementList(portal_type=
        self.getPortalObject().getPortalInvoiceMovementTypeList())

    security.declareProtected(Permissions.AccessContentsInformation,
                              'getContainerList')
    def getContainerList(self):
      """
        Return a list of root containers.
        This does not contain sub-containers.
      """
      return self.objectValues(portal_type=
        self.getPortalObject().getPortalContainerTypeList())

    #######################################################
    # Causality computation
    security.declareProtected(Permissions.AccessContentsInformation, 'isConvergent')
    def isConvergent(self,**kw):
      """
        Returns 0 if the target is not met
      """
      return bool(not self.isDivergent(**kw))

    security.declareProtected(Permissions.AccessContentsInformation, 'isSimulated')
    def isSimulated(self):
      """
        Returns 1 if all non-null movements have a delivery counterpart
        in the simulation
      """
      for m in self.getMovementList():
        if m.getQuantity() and not m.isSimulated():
          return 0
      return 1

    security.declareProtected(Permissions.AccessContentsInformation, 'isDivergent')
    def isDivergent(self, fast=0, **kw):
      """Return True if this movement diverges from the its simulation.
      """
      ## Note that fast option was removed. Now, fast=1 is ignored.

      # Check if the total quantity equals the total of each simulation movement quantity
      for simulation_movement in self._getAllRelatedSimulationMovementList():
        if simulation_movement.isDivergent():
          return True
      return False

    security.declareProtected(Permissions.AccessContentsInformation, 'getDivergenceList')
    def getDivergenceList(self, **kw):
      """
      Return a list of messages that contains the divergences
      """
      divergence_list = []
      for simulation_movement in self._getAllRelatedSimulationMovementList():
         divergence_list.extend(simulation_movement.getDivergenceList())
      return divergence_list

    security.declareProtected(Permissions.AccessContentsInformation, 'updateCausalityState')
    @UnrestrictedMethod
    def updateCausalityState(self, solve_automatically=True, **kw):
      """
      This is often called as an activity, it will check if the
      deliver is convergent, and if so it will put the delivery
      in a solved state, if not convergent in a diverged state
      """
      isTransitionPossible = \
          self.getPortalObject().portal_workflow.isTransitionPossible
      if isTransitionPossible(self, 'diverge') and \
          isTransitionPossible(self, 'converge'):
        if self.isDivergent(**kw):
          if solve_automatically and \
              isTransitionPossible(self, 'solve_automatically'):
            self.solveAutomatically()
          else:
            self.diverge()
        else:
          self.converge()

    def updateSimulation(self, calculate=False, **kw):
      if calculate:
        path = self.getPath()
        self.activate(
          after_tag='build:'+path,
          after_path_and_method_id=(path, '_localBuild'),
          ).updateCausalityState()
      if kw:
        super(Delivery, self).updateSimulation(**kw)

    security.declareProtected(Permissions.AccessContentsInformation,
                              'splitAndDeferMovementList')
    def splitAndDeferMovementList(self, start_date=None, stop_date=None,
        movement_uid_list=[], delivery_solver=None,
        target_solver='CopyToTarget', delivery_builder=None):
      """
      this method will unlink and delete movements in movement_uid_list and
      rebuild a new Packing List with them.
      1/ change date in simulation, call TargetSolver and expand
      2/ detach simulation movements from to-be-deleted movements
      3/ delete movements
        XXX make sure that all detached movements are deleted at the same
        time, else the interaction workflow would reattach them to a delivery
        rule.
      4/ call builder
      """
      tag_list = []
      movement_list = [x for x in self.getMovementList() if x.getUid() in
          movement_uid_list]
      if not movement_list: return

      deferred_simulation_movement_list = []
      # defer simulation movements
      if start_date is not None or stop_date is not None:
        for movement in movement_list:
          start_date = start_date or movement.getStartDate()
          stop_date = stop_date or movement.getStopDate()
          for s_m in movement.getDeliveryRelatedValueList():
            if s_m.getStartDate() != start_date or \
                s_m.getStopDate() != stop_date:
              s_m.edit(start_date=start_date, stop_date=stop_date)
              deferred_simulation_movement_list.append(s_m)

      solver_tag = '%s_splitAndDefer_solver' % self.getRelativeUrl()
      expand_tag = '%s_splitAndDefer_expand' % self.getRelativeUrl()
      detach_tag = '%s_splitAndDefer_detach' % self.getRelativeUrl()
      build_tag = '%s_splitAndDefer_build' % self.getRelativeUrl()
      # call solver and expand on deferrd movements
      for movement in movement_list:
        movement.activate(tag=solver_tag).Movement_solveMovement(
            delivery_solver, target_solver)
      tag_list.append(solver_tag)
      kw = {'after_tag': tag_list[:], 'tag': expand_tag}
      for s_m in deferred_simulation_movement_list:
        s_m.expand('deferred', activate_kw=kw)
      tag_list.append(expand_tag)

      detached_movement_url_list = []
      deleted_movement_uid_list = []
      #detach simulation movements
      for movement in movement_list:
        movement_url = movement.getRelativeUrl()
        movement_uid = getattr(movement,'uid',None)
        if movement_uid: deleted_movement_uid_list.append(movement_uid)
        for s_m in movement.getDeliveryRelatedValueList():
          delivery_list = \
              [x for x in s_m.getDeliveryList() if x != movement_url]
          s_m.activate(after_tag=tag_list[:], tag=detach_tag).setDeliveryList(
              delivery_list)
          detached_movement_url_list.append(s_m.getRelativeUrl())
      tag_list.append(detach_tag)

      #delete delivery movements
      # deleteContent uses the uid as a activity tag
      self.activate(after_tag=tag_list[:]).deleteContent([movement.getId() for
          movement in movement_list])
      tag_list.extend(deleted_movement_uid_list)

      # update causality state on self, after deletion
      self.activate(after_tag=tag_list[:],
          activity='SQLQueue').updateCausalityState()

      # call builder on detached movements
      builder = getattr(self.portal_deliveries, delivery_builder)
      builder.activate(after_tag=tag_list[:], tag=build_tag).build(
          movement_relative_url_list=detached_movement_url_list)


    #######################################################
    # Defer indexing process
    def reindexObject(self, *k, **kw):
      """
        Reindex children and simulation
      """
      self.recursiveReindexObject(*k, **kw)
      # do not reexpand simulation: this is a task for DSolver / TSolver

    #######################################################
    # Stock Management
    def _getMovementResourceList(self):
      resource_set = {m.getResource()
        for m in self.objectValues(portal_type=
          self.getPortalObject().getPortalMovementTypeList())}
      resource_set.discard(None)
      return list(resource_set)

    security.declareProtected(Permissions.AccessContentsInformation,
                              'getInventory')
    def getInventory(self, **kw):
      """
      Returns inventory
      """
      kw['resource'] = self._getMovementResourceList()
      return self.portal_simulation.getInventory(**kw)

    security.declareProtected(Permissions.AccessContentsInformation,
                              'getCurrentInventory')
    def getCurrentInventory(self, **kw):
      """
      Returns current inventory
      """
      kw['resource'] = self._getMovementResourceList()
      return self.portal_simulation.getCurrentInventory(**kw)

    security.declareProtected(Permissions.AccessContentsInformation,
                              'getAvailableInventory')
    def getAvailableInventory(self, **kw):
      """
      Returns available inventory
      (current inventory - deliverable)
      """
      kw['resource'] = self._getMovementResourceList()
      return self.portal_simulation.getAvailableInventory(**kw)

    security.declareProtected(Permissions.AccessContentsInformation,
                              'getFutureInventory')
    def getFutureInventory(self, **kw):
      """
      Returns inventory at infinite
      """
      kw['resource'] = self._getMovementResourceList()
      return self.portal_simulation.getFutureInventory(**kw)

    security.declareProtected(Permissions.AccessContentsInformation,
                              'getInventoryList')
    def getInventoryList(self, **kw):
      """
      Returns list of inventory grouped by section or site
      """
      kw['resource'] = self._getMovementResourceList()
      return self.portal_simulation.getInventoryList(**kw)

    security.declareProtected(Permissions.AccessContentsInformation,
                              'getCurrentInventoryList')
    def getCurrentInventoryList(self, **kw):
      """
      Returns list of inventory grouped by section or site
      """
      kw['resource'] = self._getMovementResourceList()
      return self.portal_simulation.getCurrentInventoryList(**kw)

    security.declareProtected(Permissions.AccessContentsInformation,
                              'getFutureInventoryList')
    def getFutureInventoryList(self, **kw):
      """
      Returns list of inventory grouped by section or site
      """
      kw['resource'] = self._getMovementResourceList()
      return self.portal_simulation.getFutureInventoryList(**kw)

    security.declareProtected(Permissions.AccessContentsInformation,
                              'getInventoryStat')
    def getInventoryStat(self, **kw):
      """
      Returns statistics of inventory grouped by section or site
      """
      kw['resource'] = self._getMovementResourceList()
      return self.portal_simulation.getInventoryStat(**kw)

    security.declareProtected(Permissions.AccessContentsInformation,
                              'getCurrentInventoryStat')
    def getCurrentInventoryStat(self, **kw):
      """
      Returns statistics of inventory grouped by section or site
      """
      kw['resource'] = self._getMovementResourceList()
      return self.portal_simulation.getCurrentInventoryStat(**kw)

    security.declareProtected(Permissions.AccessContentsInformation,
                              'getFutureInventoryStat')
    def getFutureInventoryStat(self, **kw):
      """
      Returns statistics of inventory grouped by section or site
      """
      kw['resource'] = self._getMovementResourceList()
      return self.portal_simulation.getFutureInventoryStat(**kw)

    security.declareProtected(Permissions.AccessContentsInformation,
                              'getInventoryChart')
    def getInventoryChart(self, **kw):
      """
      Returns list of inventory grouped by section or site
      """
      kw['resource'] = self._getMovementResourceList()
      return self.portal_simulation.getInventoryChart(**kw)

    security.declareProtected(Permissions.AccessContentsInformation,
                              'getCurrentInventoryChart')
    def getCurrentInventoryChart(self, **kw):
      """
      Returns list of inventory grouped by section or site
      """
      kw['resource'] = self._getMovementResourceList()
      return self.portal_simulation.getCurrentInventoryChart(**kw)

    security.declareProtected(Permissions.AccessContentsInformation,
                              'getFutureInventoryChart')
    def getFutureInventoryChart(self, **kw):
      """
      Returns list of inventory grouped by section or site
      """
      kw['resource'] = self._getMovementResourceList()
      return self.portal_simulation.getFutureInventoryChart(**kw)

    security.declareProtected(Permissions.AccessContentsInformation,
                              'getInventoryHistoryList')
    def getInventoryHistoryList(self, **kw):
      """
      Returns list of inventory grouped by section or site
      """
      kw['resource'] = self._getMovementResourceList()
      return self.portal_simulation.getInventoryHistoryList(**kw)

    security.declareProtected(Permissions.AccessContentsInformation,
                              'getInventoryHistoryChart')
    def getInventoryHistoryChart(self, **kw):
      """
      Returns list of inventory grouped by section or site
      """
      kw['resource'] = self._getMovementResourceList()
      return self.portal_simulation.getInventoryHistoryChart(**kw)

    security.declareProtected(Permissions.AccessContentsInformation,
                              'getMovementHistoryList')
    def getMovementHistoryList(self, **kw):
      """
      Returns list of inventory grouped by section or site
      """
      kw['resource'] = self._getMovementResourceList()
      return self.portal_simulation.getMovementHistoryList(**kw)

    security.declareProtected(Permissions.AccessContentsInformation,
                              'getMovementHistoryStat')
    def getMovementHistoryStat(self, **kw):
      """
      Returns list of inventory grouped by section or site
      """
      kw['resource'] = self._getMovementResourceList()
      return self.portal_simulation.getMovementHistoryStat(**kw)





# JPS: We must still decide if getInventoryAssetPrice is part of the Delivery API

#     security.declareProtected(Permissions.AccessContentsInformation, 'getInventoryAssetPrice')
#     def getInventoryAssetPrice(self, **kw):
#       """
#         Returns asset at infinite
#       """
#       kw['category'] = self._getMovementResourceList()
#       return self.portal_simulation.getInventoryAssetPrice(**kw)
#
#     security.declareProtected(Permissions.AccessContentsInformation, 'getFutureInventoryAssetPrice')
#     def getFutureInventoryAssetPrice(self, **kw):
#       """
#         Returns asset at infinite
#       """
#       kw['category'] = self._getMovementResourceList()
#       return self.portal_simulation.getFutureInventoryAssetPrice(**kw)
#
#     security.declareProtected(Permissions.AccessContentsInformation, 'getCurrentInventoryAssetPrice')
#     def getCurrentInventoryAssetPrice(self, **kw):
#       """
#         Returns asset at infinite
#       """
#       kw['category'] = self._getMovementResourceList()
#       return self.portal_simulation.getCurrentInventoryAssetPrice(**kw)
#
#     security.declareProtected(Permissions.AccessContentsInformation, 'getAvailableInventoryAssetPrice')
#     def getAvailableInventoryAssetPrice(self, **kw):
#       """
#         Returns asset at infinite
#       """
#       kw['category'] = self._getMovementResourceList()
#       return self.portal_simulation.getAvailableInventoryAssetPrice(**kw)

    ##########################################################################
    # Applied Rule stuff

    security.declareProtected(Permissions.AccessContentsInformation,
                              'localBuild')
    def localBuild(self, activity_kw=()):
      """Activate builders for this delivery

      The generated activity will find all buildable business links for this
      delivery, and call related builders, which will select all simulation
      movements part of the same explanation(s) as the delivery.

      XXX: Consider moving it to SimulableMixin if it's useful for
           Subscription Items.
      """
      # XXX: Previous implementation waited for expand activities of related
      #      documents and even suggested to look at explanation tree,
      #      instead of causalities. Is it required ?
      kw = {'priority': 3}
      kw.update(activity_kw)
      after_tag = kw.pop('after_tag', None)
      if isinstance(after_tag, basestring):
        after_tag = [after_tag]
      else:
        after_tag = list(after_tag) if after_tag else []
      after_tag.append('build:' + self.getPath())
      sm = getSecurityManager()
      newSecurityManager(None, nobody)
      try:
        unrestricted_apply(self.activate(after_tag=after_tag, **kw)._localBuild)
      finally:
        setSecurityManager(sm)

    def _localBuild(self):
      """Do an immediate local build for this delivery"""
      return self.asComposedDocument().build(explanation=self)

    def _createRootAppliedRule(self):
      # Only create RAR if we are not in a "too early" or "too late" state.
      state = self.getSimulationState()
      if (state != 'deleted' and
          state not in self.getPortalObject().getPortalDraftOrderStateList()):
        return super(Delivery, self)._createRootAppliedRule()

    security.declareProtected( Permissions.AccessContentsInformation,
                               'getRootCausalityValueList')
    def getRootCausalityValueList(self):
      """
        Returns the initial causality value for this movement.
        This method will look at the causality and check if the
        causality has already a causality
      """
      seen_set = set()
      def recursive(self):
        if self in seen_set:
          return []

        seen_set.add(self)
        causality_value_list = self.getCausalityValueList()
        if causality_value_list:
          initial_list = []
          for causality in causality_value_list:
            # The causality may be something which has not this method
            # (e.g. item)
            if getattr(causality, 'getRootCausalityValueList', None) is None:
                continue

            assert causality != self
            initial_list += [x for x in recursive(causality)
                             if x not in initial_list]
          return initial_list
        return [self]

      return recursive(self)

    # XXX Temp hack, should be removed has soon as the structure of
    # the order/delivery builder will be reviewed. It might
    # be reviewed if we plan to configure movement groups in the zmi
    security.declareProtected( Permissions.ModifyPortalContent,
                               'setRootCausalityValueList')
    def setRootCausalityValueList(self,value):
      """
      This is a hack
      """
      pass

    security.declareProtected( Permissions.AccessContentsInformation,
                               'getParentExplanationValue')
    def getParentExplanationValue(self):
      """
        This method should be removed as soon as movement groups
        will be rewritten. It is a temp hack
      """
      return self

    # XXX Temp hack, should be removed has soon as the structure of
    # the order/delivery builder will be reviewed. It might
    # be reviewed if we plan to configure movement groups in the zmi
    security.declareProtected( Permissions.ModifyPortalContent,
                               'setParentExplanationValue')
    def setParentExplanationValue(self,value):
      """
      This is a hack
      """
      pass

    security.declareProtected(Permissions.AccessContentsInformation,
                              'getBuilderList')
    def getBuilderList(self):
      """Returns appropriate builder list."""
      return self._getTypeBasedMethod('getBuilderList')()
      # XXX - quite a hack, since no way to know...
      #       propper implementation should use business path definition
      #       however, the real question is "is this really necessary"
      #       since the main purpose of this method is superceded
      #       by IDivergenceController

    security.declareProtected( Permissions.AccessContentsInformation,
                               'getRootSpecialiseValue')
    def getRootSpecialiseValue(self, portal_type_list):
      """Returns first specialise value matching portal type"""
      def findSpecialiseValue(context):
        if context.getPortalType() in portal_type_list:
          return context
        if getattr(context, 'getSpecialiseValueList', None) is not None:
          for specialise in context.getSpecialiseValueList():
            specialise_value = findSpecialiseValue(specialise)
            if specialise_value is not None:
              return specialise_value
        return None
      return findSpecialiseValue(self)

    security.declareProtected( Permissions.ModifyPortalContent,
                               'disconnectSimulationMovementList')
    def disconnectSimulationMovementList(self, movement_list=None):
      """Disconnects simulation movements from delivery's lines

      If movement_list is passed only those movements will be disconnected
      from simulation.

      If movements in movement_list do not belong to current
      delivery they are silently ignored.

      Returns list of disconnected Simulation Movements.

      Known issues and open questions:
       * how to protect disconnection from completed delivery?
       * what to do if movements from movement_list do not belong to delivery?
       * it is required to remove causality relation from delivery or delivery
         lines??
      """
      delivery_movement_value_list = self.getMovementList()
      if movement_list is not None:
        movement_value_list = [self.restrictedTraverse(movement) for movement
            in movement_list]
        # only those how are in this delivery
        movement_value_list = [movement_value for movement_value in
            movement_value_list if movement_value
            in delivery_movement_value_list]
      else:
        movement_value_list = delivery_movement_value_list

      disconnected_simulation_movement_list = []
      for movement_value in movement_value_list:
        # Note: Relies on fact that is invoked, when simulation movements are
        # indexed properly
        for simulation_movement in movement_value \
            .getDeliveryRelatedValueList(portal_type='Simulation Movement'):
          simulation_movement.edit(
            delivery = None,
            delivery_ratio = None
          )
          disconnected_simulation_movement_list.append(
              simulation_movement.getRelativeUrl())

      return disconnected_simulation_movement_list

    def _getAllRelatedSimulationMovementList(self):
      result = []
      for movement in self.getMovementList():
        result += movement.getDeliveryRelatedValueList()
      return result

    security.declareProtected(Permissions.AccessContentsInformation,
                              'getDivergentTesterAndSimulationMovementList')
    def getDivergentTesterAndSimulationMovementList(self):
      """
      This method returns a list of (tester, simulation_movement) for each divergence.
      """
      divergent_tester_list = []
      for simulation_movement in self._getAllRelatedSimulationMovementList():
        simulation_movement = simulation_movement.getObject()
        rule = simulation_movement.getParentValue().getSpecialiseValue()
        for tester in rule._getDivergenceTesterList(exclude_quantity=False):
          if tester.explain(simulation_movement) not in (None, []):
            divergent_tester_list.append((tester, simulation_movement))
      return divergent_tester_list

    # XXX: Dirty but required for erp5_banking_core
    getBaobabSourceUid = lambda x: x.getSourceUid()
    getBaobabSourceUid__roles__ = PermissionRole(Permissions.View)

    getBaobabDestinationUid = lambda x: x.getDestinationUid()
    getBaobabDestinationUid__roles__ = PermissionRole(Permissions.View)

    getBaobabSourceSectionUid = lambda x: x.getSourceSectionUid()
    getBaobabSourceSectionUid__roles__ = PermissionRole(Permissions.View)

    getBaobabDestinationSectionUid = lambda x: x.getDestinationSectionUid()
    getBaobabDestinationSectionUid__roles__ = PermissionRole(Permissions.View)

    getBaobabSourcePaymentUid = lambda x: x.getSourcePaymentUid()
    getBaobabSourcePaymentUid__roles__ = PermissionRole(Permissions.View)

    getBaobabDestinationPaymentUid = lambda x: x.getDestinationPaymentUid()
    getBaobabDestinationPaymentUid__roles__ = PermissionRole(Permissions.View)

    getBaobabSourceFunctionUid = lambda x: x.getSourceFunctionUid()
    getBaobabSourceFunctionUid__roles__ = PermissionRole(Permissions.View)

    getBaobabDestinationFunctionUid = lambda x: x.getDestinationFunctionUid()
    getBaobabDestinationFunctionUid__roles__ = PermissionRole(Permissions.View)

    getBaobabSourceProjectUid = lambda x: x.getSourceProjectUid()
    getBaobabSourceProjectUid__roles__ = PermissionRole(Permissions.View)

    getBaobabDestinationProjectUid = lambda x: x.getDestinationProjectUid()
    getBaobabDestinationProjectUid__roles__ = PermissionRole(Permissions.View)
Example #55
0
class DCWorkflowDefinition(WorkflowUIMixin, Folder):
    '''
    This class is the workflow engine and the container for the
    workflow definition.
    UI methods are in WorkflowUIMixin.
    '''

    implements(IDCWorkflowDefinition, IWorkflowDefinition)
    __implements__ = z2IWorkflowDefinition

    title = 'DC Workflow Definition'
    description = ''

    state_var = 'state'
    initial_state = None

    states = None
    transitions = None
    variables = None
    worklists = None
    scripts = None

    permissions = ()
    groups = ()  # Names of groups managed by this workflow.
    roles = None  # The role names managed by this workflow.
    # If roles is None, listRoles() provides a default.

    creation_guard = None  # The guard that can veto object creation.

    manager_bypass = 0  # Boolean: 'Manager' role bypasses guards

    manage_options = (
        {
            'label': 'Properties',
            'action': 'manage_properties'
        },
        {
            'label': 'States',
            'action': 'states/manage_main'
        },
        {
            'label': 'Transitions',
            'action': 'transitions/manage_main'
        },
        {
            'label': 'Variables',
            'action': 'variables/manage_main'
        },
        {
            'label': 'Worklists',
            'action': 'worklists/manage_main'
        },
        {
            'label': 'Scripts',
            'action': 'scripts/manage_main'
        },
        {
            'label': 'Permissions',
            'action': 'manage_permissions'
        },
        {
            'label': 'Groups',
            'action': 'manage_groups'
        },
    )

    security = ClassSecurityInfo()
    security.declareObjectProtected(ManagePortal)

    def __init__(self, id):
        self.id = id
        from States import States
        self._addObject(States('states'))
        from Transitions import Transitions
        self._addObject(Transitions('transitions'))
        from Variables import Variables
        self._addObject(Variables('variables'))
        from Worklists import Worklists
        self._addObject(Worklists('worklists'))
        from Scripts import Scripts
        self._addObject(Scripts('scripts'))

    def _addObject(self, ob):
        id = ob.getId()
        setattr(self, id, ob)
        self._objects = self._objects + ({
            'id': id,
            'meta_type': ob.meta_type
        }, )

    #
    # Workflow engine.
    #

    def _getStatusOf(self, ob):
        tool = aq_parent(aq_inner(self))
        status = tool.getStatusOf(self.id, ob)
        if status is None:
            return {}
        else:
            return status

    def _getWorkflowStateOf(self, ob, id_only=0):
        tool = aq_parent(aq_inner(self))
        status = tool.getStatusOf(self.id, ob)
        if status is None:
            state = self.initial_state
        else:
            state = status.get(self.state_var, None)
            if state is None:
                state = self.initial_state
        if id_only:
            return state
        else:
            return self.states.get(state, None)

    def _getPortalRoot(self):
        return aq_parent(aq_inner(aq_parent(aq_inner(self))))

    security.declarePrivate('getCatalogVariablesFor')

    def getCatalogVariablesFor(self, ob):
        '''
        Allows this workflow to make workflow-specific variables
        available to the catalog, making it possible to implement
        worklists in a simple way.
        Returns a mapping containing the catalog variables
        that apply to ob.
        '''
        res = {}
        status = self._getStatusOf(ob)
        for id, vdef in self.variables.items():
            if vdef.for_catalog:
                if status.has_key(id):
                    value = status[id]

                # Not set yet.  Use a default.
                elif vdef.default_expr is not None:
                    ec = createExprContext(StateChangeInfo(ob, self, status))
                    value = vdef.default_expr(ec)
                else:
                    value = vdef.default_value

                res[id] = value
        # Always provide the state variable.
        state_var = self.state_var
        res[state_var] = status.get(state_var, self.initial_state)
        return res

    security.declarePrivate('listObjectActions')

    def listObjectActions(self, info):
        '''
        Allows this workflow to
        include actions to be displayed in the actions box.
        Called only when this workflow is applicable to
        info.object.
        Returns the actions to be displayed to the user.
        '''
        ob = info.object
        sdef = self._getWorkflowStateOf(ob)
        if sdef is None:
            return None
        res = []
        for tid in sdef.transitions:
            tdef = self.transitions.get(tid, None)
            if tdef is not None and tdef.trigger_type == TRIGGER_USER_ACTION:
                if tdef.actbox_name:
                    if self._checkTransitionGuard(tdef, ob):
                        res.append((
                            tid,
                            {
                                'id': tid,
                                'name': tdef.actbox_name % info,
                                'url': tdef.actbox_url % info,
                                'permissions': (),  # Predetermined.
                                'category': tdef.actbox_category,
                                'transition': tdef
                            }))
        res.sort()
        return [result[1] for result in res]

    security.declarePrivate('listGlobalActions')

    def listGlobalActions(self, info):
        '''
        Allows this workflow to
        include actions to be displayed in the actions box.
        Called on every request.
        Returns the actions to be displayed to the user.
        '''
        if not self.worklists:
            return None  # Optimization
        sm = getSecurityManager()
        portal = self._getPortalRoot()
        res = []
        fmt_data = None
        for id, qdef in self.worklists.items():
            if qdef.actbox_name:
                guard = qdef.guard
                if guard is None or guard.check(sm, self, portal):
                    searchres = None
                    var_match_keys = qdef.getVarMatchKeys()
                    if var_match_keys:
                        # Check the catalog for items in the worklist.
                        catalog = getToolByName(self, 'portal_catalog')
                        kw = {}
                        for k in var_match_keys:
                            v = qdef.getVarMatch(k)
                            kw[k] = [x % info for x in v]
                        searchres = catalog.searchResults(**kw)
                        if not searchres:
                            continue
                    if fmt_data is None:
                        fmt_data = TemplateDict()
                        fmt_data._push(info)
                    fmt_data._push({'count': len(searchres)})
                    res.append((
                        id,
                        {
                            'id': id,
                            'name': qdef.actbox_name % fmt_data,
                            'url': qdef.actbox_url % fmt_data,
                            'permissions': (),  # Predetermined.
                            'category': qdef.actbox_category
                        }))
                    fmt_data._pop()
        res.sort()
        return [result[1] for result in res]

    security.declarePrivate('isActionSupported')

    def isActionSupported(self, ob, action, **kw):
        '''
        Returns a true value if the given action name
        is possible in the current state.
        '''
        sdef = self._getWorkflowStateOf(ob)
        if sdef is None:
            return 0
        if action in sdef.transitions:
            tdef = self.transitions.get(action, None)
            if (tdef is not None and tdef.trigger_type == TRIGGER_USER_ACTION
                    and self._checkTransitionGuard(tdef, ob, **kw)):
                return 1
        return 0

    security.declarePrivate('doActionFor')

    def doActionFor(self, ob, action, comment='', **kw):
        '''
        Allows the user to request a workflow action.  This method
        must perform its own security checks.
        '''
        kw['comment'] = comment
        sdef = self._getWorkflowStateOf(ob)
        if sdef is None:
            raise WorkflowException(_(u'Object is in an undefined state.'))
        if action not in sdef.transitions:
            raise Unauthorized(action)
        tdef = self.transitions.get(action, None)
        if tdef is None or tdef.trigger_type != TRIGGER_USER_ACTION:
            msg = _(
                u"Transition '${action_id}' is not triggered by a user "
                u"action.",
                mapping={'action_id': action})
            raise WorkflowException(msg)
        if not self._checkTransitionGuard(tdef, ob, **kw):
            raise Unauthorized(action)
        self._changeStateOf(ob, tdef, kw)

    security.declarePrivate('isInfoSupported')

    def isInfoSupported(self, ob, name):
        '''
        Returns a true value if the given info name is supported.
        '''
        if name == self.state_var:
            return 1
        vdef = self.variables.get(name, None)
        if vdef is None:
            return 0
        return 1

    security.declarePrivate('getInfoFor')

    def getInfoFor(self, ob, name, default):
        '''
        Allows the user to request information provided by the
        workflow.  This method must perform its own security checks.
        '''
        if name == self.state_var:
            return self._getWorkflowStateOf(ob, 1)
        vdef = self.variables[name]
        if vdef.info_guard is not None and not vdef.info_guard.check(
                getSecurityManager(), self, ob):
            return default
        status = self._getStatusOf(ob)
        if status is not None and status.has_key(name):
            value = status[name]

        # Not set yet.  Use a default.
        elif vdef.default_expr is not None:
            ec = createExprContext(StateChangeInfo(ob, self, status))
            value = vdef.default_expr(ec)
        else:
            value = vdef.default_value

        return value

    security.declarePrivate('allowCreate')

    def allowCreate(self, container, type_name):
        """Returns true if the user is allowed to create a workflow instance.

        The object passed to the guard is the prospective container.
        """
        if self.creation_guard is not None:
            return self.creation_guard.check(getSecurityManager(), self,
                                             container)
        return 1

    security.declarePrivate('notifyCreated')

    def notifyCreated(self, ob):
        """Notifies this workflow after an object has been created and added.
        """
        try:
            self._changeStateOf(ob, None)
        except (ObjectDeleted, ObjectMoved):
            # Swallow.
            pass

    security.declarePrivate('notifyBefore')

    def notifyBefore(self, ob, action):
        '''
        Notifies this workflow of an action before it happens,
        allowing veto by exception.  Unless an exception is thrown, either
        a notifySuccess() or notifyException() can be expected later on.
        The action usually corresponds to a method name.
        '''
        pass

    security.declarePrivate('notifySuccess')

    def notifySuccess(self, ob, action, result):
        '''
        Notifies this workflow that an action has taken place.
        '''
        pass

    security.declarePrivate('notifyException')

    def notifyException(self, ob, action, exc):
        '''
        Notifies this workflow that an action failed.
        '''
        pass

    security.declarePrivate('updateRoleMappingsFor')

    def updateRoleMappingsFor(self, ob):
        """Changes the object permissions according to the current state.
        """
        changed = 0
        sdef = self._getWorkflowStateOf(ob)
        if sdef is None:
            return 0
        # Update the role -> permission map.
        if self.permissions:
            for p in self.permissions:
                roles = []
                if sdef.permission_roles is not None:
                    roles = sdef.permission_roles.get(p, roles)
                if modifyRolesForPermission(ob, p, roles):
                    changed = 1
        # Update the group -> role map.
        groups = self.getGroups()
        managed_roles = self.getRoles()
        if groups and managed_roles:
            for group in groups:
                roles = ()
                if sdef.group_roles is not None:
                    roles = sdef.group_roles.get(group, ())
                if modifyRolesForGroup(ob, group, roles, managed_roles):
                    changed = 1
        return changed

    def _checkTransitionGuard(self, t, ob, **kw):
        guard = t.guard
        if guard is None:
            return 1
        if guard.check(getSecurityManager(), self, ob, **kw):
            return 1
        return 0

    def _findAutomaticTransition(self, ob, sdef):
        tdef = None
        for tid in sdef.transitions:
            t = self.transitions.get(tid, None)
            if t is not None and t.trigger_type == TRIGGER_AUTOMATIC:
                if self._checkTransitionGuard(t, ob):
                    tdef = t
                    break
        return tdef

    def _changeStateOf(self, ob, tdef=None, kwargs=None):
        '''
        Changes state.  Can execute multiple transitions if there are
        automatic transitions.  tdef set to None means the object
        was just created.
        '''
        moved_exc = None
        while 1:
            try:
                sdef = self._executeTransition(ob, tdef, kwargs)
            except ObjectMoved, moved_exc:
                ob = moved_exc.getNewObject()
                sdef = self._getWorkflowStateOf(ob)
                # Re-raise after all transitions.
            if sdef is None:
                break
            tdef = self._findAutomaticTransition(ob, sdef)
            if tdef is None:
                # No more automatic transitions.
                break
            # Else continue.
        if moved_exc is not None:
            # Re-raise.
            raise moved_exc
Example #56
0
class FSPythonScript(FSObject, Script):
    """FSPythonScripts act like Python Scripts but are not directly
    modifiable from the management interface."""

    meta_type = 'Filesystem Script (Python)'
    _params = _body = ''
    _v_f = None
    _proxy_roles = ()
    _owner = None  # Unowned

    manage_options = (
        {
            'label': 'Customize',
            'action': 'manage_main'
        },
        {
            'label': 'Test',
            'action': 'ZScriptHTML_tryForm',
            'help': ('PythonScripts', 'PythonScript_test.stx')
        },
    )

    security = ClassSecurityInfo()
    security.declareObjectProtected(View)

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

    security.declareProtected(
        View,
        'index_html',
    )
    # Prevent the bindings from being edited TTW
    security.declarePrivate('ZBindings_edit', 'ZBindingsHTML_editForm',
                            'ZBindingsHTML_editAction')

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

    def _readFile(self, reparse):
        """Read the data from the filesystem.
        """
        file = open(self._filepath, 'rU')
        try:
            data = file.read()
        finally:
            file.close()

        if reparse:
            self._write(data, reparse)

    def _validateProxy(self, roles=None):
        pass

    def __render_with_namespace__(self, namespace):
        '''Calls the script.'''
        self._updateFromFS()
        return Script.__render_with_namespace__(self, namespace)

    def __call__(self, *args, **kw):
        '''Calls the script.'''
        self._updateFromFS()
        return Script.__call__(self, *args, **kw)

    #### The following is mainly taken from PythonScript.py ###

    def _exec(self, bound_names, args, kw):
        """Call a Python Script

        Calling a Python Script is an actual function invocation.
        """
        # do caching
        keyset = None
        if self.ZCacheable_isCachingEnabled():
            # Prepare a cache key.
            keyset = kw.copy()
            asgns = self.getBindingAssignments()
            name_context = asgns.getAssignedName('name_context', None)
            if name_context:
                keyset[name_context] = self.aq_parent.getPhysicalPath()
            name_subpath = asgns.getAssignedName('name_subpath', None)
            if name_subpath:
                keyset[name_subpath] = self._getTraverseSubpath()
            # Note: perhaps we should cache based on name_ns also.
            keyset['*'] = args
            result = self.ZCacheable_get(keywords=keyset, default=_marker)
            if result is not _marker:
                # Got a cached value.
                return result

        # Prepare the function.
        f = self._v_f
        if f is None:
            # The script has errors.
            __traceback_supplement__ = (FSPythonScriptTracebackSupplement,
                                        self, 0)
            raise RuntimeError, '%s has errors.' % self._filepath

        # Updating func_globals directly is not thread safe here.
        # In normal PythonScripts, every thread has its own
        # copy of the function.  But in FSPythonScripts
        # there is only one copy.  So here's another way.
        new_globals = f.func_globals.copy()
        new_globals['__traceback_supplement__'] = (
            FSPythonScriptTracebackSupplement, self)
        new_globals['__file__'] = self._filepath
        if bound_names:
            new_globals.update(bound_names)
        if f.func_defaults:
            f = new.function(f.func_code, new_globals, f.func_name,
                             f.func_defaults)
        else:
            f = new.function(f.func_code, new_globals, f.func_name)

        # Execute the function in a new security context.
        security = getSecurityManager()
        security.addContext(self)
        try:
            result = f(*args, **kw)
            if keyset is not None:
                # Store the result in the cache.
                self.ZCacheable_set(result, keywords=keyset)
            return result
        finally:
            security.removeContext(self)

    security.declareProtected(ViewManagementScreens, 'getModTime')
    # getModTime defined in FSObject

    security.declareProtected(ViewManagementScreens, 'ZScriptHTML_tryForm')

    # ZScriptHTML_tryForm defined in Shared.DC.Scripts.Script.Script

    def ZScriptHTML_tryParams(self):
        """Parameters to test the script with."""
        param_names = []
        for name in self._params.split(','):
            name = name.strip()
            if name and name[0] != '*':
                param_names.append(name.split('=', 1)[0])
        return param_names

    security.declareProtected(ViewManagementScreens, 'read')

    def read(self):
        self._updateFromFS()
        return self._source

    security.declareProtected(ViewManagementScreens, '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._source

    security.declareProtected(ViewManagementScreens, 'PrincipiaSearchSource')

    def PrincipiaSearchSource(self):
        "Support for searching - the document's contents are searched."
        return "%s\n%s" % (self._params, self._body)

    security.declareProtected(ViewManagementScreens, 'params')

    def params(self):
        return self._params

    security.declareProtected(ViewManagementScreens, 'manage_haveProxy')
    manage_haveProxy = PythonScript.manage_haveProxy.im_func

    security.declareProtected(ViewManagementScreens, 'body')

    def body(self):
        return self._body

    security.declareProtected(ViewManagementScreens, 'get_size')

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

    security.declareProtected(FTPAccess, 'manage_FTPget')

    def manage_FTPget(self):
        "Get source for FTP download"
        self.REQUEST.RESPONSE.setHeader('Content-Type', 'text/plain')
        return self.read()

    def _write(self, text, compile):
        '''
        Parses the source, storing the body, params, title, bindings,
        and source in self.  If compile is set, compiles the
        function.
        '''
        ps = PythonScript(self.id)
        ps.write(text)
        if compile:
            ps._makeFunction(1)
            self._v_f = f = ps._v_f
            if f is not None:
                self.func_code = f.func_code
                self.func_defaults = f.func_defaults
            else:
                # There were errors in the compile.
                # No signature.
                self.func_code = bad_func_code()
                self.func_defaults = None
        self._body = ps._body
        self._params = ps._params
        self.title = ps.title
        self._setupBindings(ps.getBindingAssignments().getAssignedNames())
        self._source = ps.read()  # Find out what the script sees.

    def func_defaults(self):
        # This ensures func_code and func_defaults are
        # set when the code hasn't been compiled yet,
        # just in time for mapply().  Truly odd, but so is mapply(). :P
        self._updateFromFS()
        return self.__dict__.get('func_defaults', None)

    func_defaults = ComputedAttribute(func_defaults, 1)

    def func_code(self):
        # See func_defaults.
        self._updateFromFS()
        return self.__dict__.get('func_code', None)

    func_code = ComputedAttribute(func_code, 1)

    def title(self):
        # See func_defaults.
        self._updateFromFS()
        return self.__dict__.get('title', None)

    title = ComputedAttribute(title, 1)

    def getBindingAssignments(self):
        # Override of the version in Bindings.py.
        # This version ensures that bindings get loaded on demand.
        if not hasattr(self, '_bind_names'):
            # Set a default first to avoid recursion
            self._setupBindings()
            # Now do it for real
            self._updateFromFS()
        return self._bind_names
Example #57
0
from Products.DCWorkflow.utils import Message as _
from Products.DCWorkflow.Transitions import TRIGGER_USER_ACTION

from Products.CMFCore.utils import getToolByName
from Products.ZSQLCatalog.SQLCatalog import SimpleQuery, AutoQuery, ComplexQuery, NegatedQuery
from Products.CMFCore.utils import _getAuthenticatedUser
from Products.ERP5Type import Permissions
from Products.ERP5Type.Cache import CachingMethod
from sets import ImmutableSet
from Acquisition import aq_base
from Persistence import Persistent
from Products.ERP5Type.Globals import PersistentMapping
from MySQLdb import ProgrammingError, OperationalError
from DateTime import DateTime

security = ClassSecurityInfo()
WorkflowTool.security = security

def DCWorkflowDefinition_notifyWorkflowMethod(self, ob, transition_list, args=None, kw=None):
    '''
    Allows the system to request a workflow action.  This method
    must perform its own security checks.
    '''
    if type(transition_list) in StringTypes:
      method_id = transition_list
    elif len(transition_list) == 1:
      method_id = transition_list[0]
    else:
      raise ValueError('WorkflowMethod should be attached to exactly 1 transition per DCWorkflow instance.')
    sdef = self._getWorkflowStateOf(ob)
    if sdef is None:
Example #58
0
class CalendarTool(UniqueObject, SimpleItem):
    """ a calendar tool for encapsualting how calendars work and are displayed """
    id = 'portal_calendar'
    meta_type = 'CMF Calendar Tool'
    security = ClassSecurityInfo()
    plone_tool = 1

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

    #
    #   ZMI methods
    #
    security.declareProtected(ManagePortal, 'manage_overview')
    manage_overview = PageTemplateFile('www/explainCalendarTool',
                                       globals(),
                                       __name__='manage_overview')

    security.declareProtected(ManagePortal, 'manage_configure')
    manage_configure = PageTemplateFile('www/configureCalendarTool',
                                        globals(),
                                        __name__='manage_configure')

    def __init__(self):
        self.calendar_types = ['Event']
        self.use_session = ""

    security.declareProtected(ManagePortal, 'edit_configuration')

    def edit_configuration(self, show_types, use_session):
        """ Change the configuration of the calendar tool """
        self.calendar_types = show_types
        self.use_session = use_session
        if hasattr(self.REQUEST, 'RESPONSE'):
            self.REQUEST.RESPONSE.redirect('manage_configure')

    security.declarePublic('getCalendarTypes')

    def getCalendarTypes(self):
        """ Returns a list of type that will show in the calendar """
        return self.calendar_types

    security.declarePublic('getUseSession')

    def getUseSession(self):
        """ Returns the Use_Session option """
        return self.use_session

    security.declarePublic('getDays')

    def getDays(self):
        """ Returns a list of days with the correct start day first """
        return calendar.weekheader(2).split()

    security.declarePublic('getWeeksList')

    def getWeeksList(self, month='1', year='2002'):
        """Creates a series of weeks, each of which contains an integer day number.
           A day number of 0 means that day is in the previous or next month.
        """
        # daysByWeek is a list of days inside a list of weeks, like so:
        # [[0, 1, 2, 3, 4, 5, 6],
        #  [7, 8, 9, 10, 11, 12, 13],
        #  [14, 15, 16, 17, 18, 19, 20],
        #  [21, 22, 23, 24, 25, 26, 27],
        #  [28, 29, 30, 31, 0, 0, 0]]
        daysByWeek = calendar.monthcalendar(year, month)

        return daysByWeek

    security.declarePublic('getEventsForCalendar')

    def getEventsForCalendar(self, month='1', year='2002'):
        """ recreates a sequence of weeks, by days each day is a mapping.
            {'day': #, 'url': None}
        """
        year = int(year)
        month = int(month)
        # daysByWeek is a list of days inside a list of weeks, like so:
        # [[0, 1, 2, 3, 4, 5, 6],
        #  [7, 8, 9, 10, 11, 12, 13],
        #  [14, 15, 16, 17, 18, 19, 20],
        #  [21, 22, 23, 24, 25, 26, 27],
        #  [28, 29, 30, 31, 0, 0, 0]]
        daysByWeek = calendar.monthcalendar(year, month)
        weeks = []

        events = self.catalog_getevents(year, month)

        for week in daysByWeek:
            days = []
            for day in week:
                if events.has_key(day):
                    days.append(events[day])
                else:
                    days.append({'day': day, 'event': 0, 'eventslist': []})

            weeks.append(days)

        return weeks

    security.declarePublic('catalog_getevents')

    def catalog_getevents(self, year, month):
        """ given a year and month return a list of days that have events """
        first_date = DateTime(str(month) + '/1/' + str(year))
        last_day = calendar.monthrange(year, month)[1]
        ## This line was cropping the last day of the month out of the
        ## calendar when doing the query
        ## last_date=DateTime(str(month)+'/'+str(last_day)+'/'+str(year))
        last_date = first_date + last_day

        query = self.portal_catalog(portal_type=self.calendar_types,
                                    review_state='published',
                                    start={
                                        'query': last_date,
                                        'range': 'max'
                                    },
                                    end={
                                        'query': first_date,
                                        'range': 'min'
                                    },
                                    sort_on='start')

        # compile a list of the days that have events
        eventDays = {}
        for daynumber in range(1, 32):  # 1 to 31
            eventDays[daynumber] = {
                'eventslist': [],
                'event': 0,
                'day': daynumber
            }
        includedevents = []
        for result in query:
            if result.getRID() in includedevents:
                break
            else:
                includedevents.append(result.getRID())
            event = {}
            # we need to deal with events that end next month
            if result.end.month(
            ) != month:  # doesn't work for events that last ~12 months - fix it if it's a problem, otherwise ignore
                eventEndDay = last_day
                event['end'] = None
            else:
                eventEndDay = result.end.day()
                event['end'] = result.end.Time()
            # and events that started last month
            if result.start.month(
            ) != month:  # same as above re: 12 month thing
                eventStartDay = 1
                event['start'] = None
            else:
                eventStartDay = result.start.day()
                event['start'] = result.start.Time()
            event['title'] = result.Title or result.id
            if eventStartDay != eventEndDay:
                allEventDays = range(eventStartDay, eventEndDay + 1)
                eventDays[eventStartDay]['eventslist'].append({
                    'end':
                    None,
                    'start':
                    result.start.Time(),
                    'title':
                    result.Title
                })
                eventDays[eventStartDay]['event'] = 1
                for eventday in allEventDays[1:-1]:
                    eventDays[eventday]['eventslist'].append({
                        'end':
                        None,
                        'start':
                        None,
                        'title':
                        result.Title
                    })
                    eventDays[eventday]['event'] = 1
                eventDays[eventEndDay]['eventslist'].append({
                    'end':
                    result.end.Time(),
                    'start':
                    None,
                    'title':
                    result.Title
                })
                eventDays[eventEndDay]['event'] = 1
            else:
                eventDays[eventStartDay]['eventslist'].append(event)
                eventDays[eventStartDay]['event'] = 1
            # This list is not uniqued and isn't sorted
            # uniquing and sorting only wastes time
            # and in this example we don't need to because
            # later we are going to do an 'if 2 in eventDays'
            # so the order is not important.
            # example:  [23, 28, 29, 30, 31, 23]
        return eventDays

    security.declarePublic('getEventsForThisDay')

    def getEventsForThisDay(self, thisDay):
        """ given an exact day return ALL events that:
            A) Start on this day  OR
            B) End on this day  OR
            C) Start before this day  AND  end after this day"""

        catalog = self.portal_catalog

        first_date, last_date = self.getBeginAndEndTimes(
            thisDay.day(), thisDay.month(), thisDay.year())
        #first_date=DateTime(thisDay.Date()+" 00:00:00")
        #last_date=DateTime(thisDay.Date()+" 23:59:59")

        # Get all events that Start on this day
        query = self.portal_catalog(portal_type=self.calendar_types,
                                    review_state='published',
                                    start={
                                        'query': (first_date, last_date),
                                        'range': 'min:max'
                                    })

        # Get all events that End on this day
        query += self.portal_catalog(portal_type=self.calendar_types,
                                     review_state='published',
                                     end={
                                         'query': (first_date, last_date),
                                         'range': 'min:max'
                                     })

        # Get all events that Start before this day AND End after this day
        query += self.portal_catalog(portal_type=self.calendar_types,
                                     review_state='published',
                                     start={
                                         'query': first_date,
                                         'range': 'max'
                                     },
                                     end={
                                         'query': last_date,
                                         'range': 'min'
                                     })

        # Unique the results
        results = []
        rids = []
        for item in query:
            rid = item.getRID()
            if not rid in rids:
                results.append(item)
                rids.append(rid)

        def sort_function(x, y):
            z = cmp(x.start, y.start)
            if not z:
                return cmp(x.end, y.end)
            return z

        # Sort by start date
        results.sort(sort_function)

        return results

    security.declarePublic('getPreviousMonth')

    def getPreviousMonth(self, month, year):
        # given any particular year and month, this method will return a datetime object
        # for one month prior

        try:
            month = int(month)
        except:
            raise "Calendar Type Error", month
        try:
            year = int(year)
        except:
            raise "Calendar Type Error", year

        if month == 0 or month == 1:
            month, year = 12, year - 1
        else:
            month -= 1

        return DateTime(str(month) + '/1/' + str(year))

    security.declarePublic('getNextMonth')

    def getNextMonth(self, month, year):
        # given any particular year and month, this method will return a datetime object
        # for one month after

        try:
            month = int(month)
        except:
            raise "Calendar Type Error", month
        try:
            year = int(year)
        except:
            raise "Calendar Type Error", year

        if month == 12:
            month, year = 1, year + 1
        else:
            month += 1

        return DateTime(str(month) + '/1/' + str(year))

    security.declarePublic('getBeginAndEndTimes')

    def getBeginAndEndTimes(self, day, month, year):
        # Given any day, month and year this method returns 2 DateTime objects
        # That represent the exact start and the exact end of that particular day.

        day = str(day)
        month = str(month)
        year = str(year)

        begin = DateTime(month + '/' + day + '/' + year + ' 12:00:00AM')
        end = DateTime(month + '/' + day + '/' + year + ' 11:59:59PM')

        return (begin, end)
""" Patches to resource registries
"""
from AccessControl import ClassSecurityInfo
from Products.CMFCore.utils import getToolByName
from Products.ResourceRegistries import permissions
from zope.lifecycleevent import ObjectModifiedEvent
from zope.event import notify

security = ClassSecurityInfo()

def invalidateClientsCache(self, REQUEST=None):
    """ Invalidate client cache
    """
    notify(ObjectModifiedEvent(self))
    if REQUEST:
        portal_url = getToolByName(self, 'portal_url')()
        return REQUEST.RESPONSE.redirect(portal_url +
                '/@@invalidateClientsCache')

security.declareProtected(permissions.ManagePortal, 'manage_saveStylesheets')
def manage_saveStylesheets(self, REQUEST=None):
    """ Save stylesheets from the ZMI.
        Updates the whole sequence. For editing and reordering.
    """
    self._old_manage_saveStylesheets(REQUEST)
    invalidateClientsCache(self, REQUEST)

security.declareProtected(permissions.ManagePortal, 'manage_saveScripts')
def manage_saveScripts(self, REQUEST=None):
    """ Save scripts from the ZMI.
        Updates the whole sequence. For editing and reordering.
Example #60
0
class ARAnalysesField(ObjectField):
    """A field that stores Analyses instances
    """
    implements(IARAnalysesField)

    security = ClassSecurityInfo()
    _properties = Field._properties.copy()
    _properties.update({
        "type": "analyses",
        "default": None,
    })

    security.declarePrivate('get')

    def get(self, instance, **kwargs):
        """Returns a list of Analyses assigned to this AR

        Return a list of catalog brains unless `full_objects=True` is passed.
        Other keyword arguments are passed to bika_analysis_catalog

        :param instance: Analysis Request object
        :param kwargs: Keyword arguments to inject in the search query
        :returns: A list of Analysis Objects/Catalog Brains
        """
        catalog = getToolByName(instance, CATALOG_ANALYSIS_LISTING)
        query = dict([(k, v) for k, v in kwargs.items()
                      if k in catalog.indexes()])
        query["portal_type"] = "Analysis"
        query["getRequestUID"] = api.get_uid(instance)
        analyses = catalog(query)
        if not kwargs.get("full_objects", False):
            return analyses

        return map(api.get_object, analyses)

    security.declarePrivate('set')

    def set(self, instance, items, prices=None, specs=None, hidden=None, **kw):
        """Set/Assign Analyses to this AR

        :param items: List of Analysis objects/brains, AnalysisService
                      objects/brains and/or Analysis Service uids
        :type items: list
        :param prices: Mapping of AnalysisService UID -> price
        :type prices: dict
        :param specs: List of AnalysisService UID -> Result Range mappings
        :type specs: list
        :param hidden: List of AnalysisService UID -> Hidden mappings
        :type hidden: list
        :returns: list of new assigned Analyses
        """
        # This setter returns a list of new set Analyses
        new_analyses = []

        # Current assigned analyses
        analyses = instance.objectValues("Analysis")

        # Analyses which are in a non-open state must be retained, except those
        # that are in a registered state (the sample has not been received)
        non_open_analyses = filter(lambda an: not an.isOpen(), analyses)
        non_open_analyses = filter(
            lambda an: api.get_workflow_status_of(an) != "registered",
            non_open_analyses)

        # Prevent removing all analyses
        #
        # N.B.: Non-open analyses are rendered disabled in the HTML form.
        #       Therefore, their UIDs are not included in the submitted UIDs.
        if not items and not non_open_analyses:
            logger.warn("Not allowed to remove all Analyses from AR.")
            return new_analyses

        # Bail out if the items is not a list type
        if not isinstance(items, (list, tuple)):
            raise TypeError(
                "Items parameter must be a tuple or list, got '{}'".format(
                    type(items)))

        # Bail out if the AR is inactive
        if not api.is_active(instance):
            raise Unauthorized(
                "Inactive ARs can not be modified".format(AddAnalysis))

        # Bail out if the user has not the right permission
        if not check_permission(AddAnalysis, instance):
            raise Unauthorized(
                "You do not have the '{}' permission".format(AddAnalysis))

        # Convert the items to a valid list of AnalysisServices
        services = filter(None, map(self._to_service, items))

        # Calculate dependencies
        # FIXME Infinite recursion error possible here, if the formula includes
        #       the Keyword of the Service that includes the Calculation
        dependencies = map(lambda s: s.getServiceDependencies(), services)
        dependencies = list(itertools.chain.from_iterable(dependencies))

        # Merge dependencies and services
        services = set(services + dependencies)

        # Modify existing AR specs with new form values of selected analyses.
        self._update_specs(instance, specs)

        # Create a mapping of Service UID -> Hidden status
        if hidden is None:
            hidden = []
        hidden = dict(map(lambda d: (d.get("uid"), d.get("hidden")), hidden))

        # Ensure we have a prices dictionary
        if prices is None:
            prices = dict()

        # CREATE/MODIFY ANALYSES

        for service in services:
            service_uid = api.get_uid(service)
            keyword = service.getKeyword()

            # Create the Analysis if it doesn't exist
            if shasattr(instance, keyword):
                analysis = instance._getOb(keyword)
            else:
                analysis = create_analysis(instance, service)
                new_analyses.append(analysis)

            # set the hidden status
            analysis.setHidden(hidden.get(service_uid, False))

            # Set the price of the Analysis
            analysis.setPrice(prices.get(service_uid, service.getPrice()))

        # DELETE ANALYSES

        # Service UIDs
        service_uids = map(api.get_uid, services)

        # Analyses IDs to delete
        delete_ids = []

        # Assigned Attachments
        assigned_attachments = []

        for analysis in analyses:
            service_uid = analysis.getServiceUID()

            # Skip if the Service is selected
            if service_uid in service_uids:
                continue

            # Skip non-open Analyses
            if analysis in non_open_analyses:
                continue

            # Remember assigned attachments
            # https://github.com/senaite/senaite.core/issues/1025
            assigned_attachments.extend(analysis.getAttachment())
            analysis.setAttachment([])

            # If it is assigned to a worksheet, unassign it before deletion.
            worksheet = analysis.getWorksheet()
            if worksheet:
                worksheet.removeAnalysis(analysis)

            delete_ids.append(analysis.getId())

        if delete_ids:
            # Note: subscriber might promote the AR
            instance.manage_delObjects(ids=delete_ids)

        # Remove orphaned attachments
        for attachment in assigned_attachments:
            # only delete attachments which are no further linked
            if not attachment.getLinkedAnalyses():
                logger.info("Deleting attachment: {}".format(
                    attachment.getId()))
                attachment_id = api.get_id(attachment)
                api.get_parent(attachment).manage_delObjects(attachment_id)

        return new_analyses

    def _get_services(self, full_objects=False):
        """Fetch and return analysis service objects
        """
        bsc = api.get_tool("bika_setup_catalog")
        brains = bsc(portal_type="AnalysisService")
        if full_objects:
            return map(api.get_object, brains)
        return brains

    def _to_service(self, thing):
        """Convert to Analysis Service

        :param thing: UID/Catalog Brain/Object/Something
        :returns: Analysis Service object or None
        """

        # Convert UIDs to objects
        if api.is_uid(thing):
            thing = api.get_object_by_uid(thing, None)

        # Bail out if the thing is not a valid object
        if not api.is_object(thing):
            logger.warn("'{}' is not a valid object!".format(repr(thing)))
            return None

        # Ensure we have an object here and not a brain
        obj = api.get_object(thing)

        if IAnalysisService.providedBy(obj):
            return obj

        if IAnalysis.providedBy(obj):
            return obj.getAnalysisService()

        # An object, but neither an Analysis nor AnalysisService?
        # This should never happen.
        portal_type = api.get_portal_type(obj)
        logger.error("ARAnalysesField doesn't accept objects from {} type. "
                     "The object will be dismissed.".format(portal_type))
        return None

    def _update_specs(self, instance, specs):
        """Update AR specifications

        :param instance: Analysis Request
        :param specs: List of Specification Records
        """

        if specs is None:
            return

        # N.B. we copy the records here, otherwise the spec will be written to
        #      the attached specification of this AR
        rr = {
            item["keyword"]: item.copy()
            for item in instance.getResultsRange()
        }
        for spec in specs:
            keyword = spec.get("keyword")
            if keyword in rr:
                # overwrite the instance specification only, if the specific
                # analysis spec has min/max values set
                if all([spec.get("min"), spec.get("max")]):
                    rr[keyword].update(spec)
                else:
                    rr[keyword] = spec
            else:
                rr[keyword] = spec
        return instance.setResultsRange(rr.values())