Ejemplo n.º 1
0
 def handleSave(self, action):
     """
     """
     data, errors = self.extractData()
     config = IConfig(self.context)
     assert config.is_update_realms_possible()
     if len(errors)==0:
         # get realm
         currentRealm = self.getRealmById(data['id'])
         if not currentRealm:
             raise Exception('Could not find realm')
         # no other realm should have same url+username
         for realm in config.getRealms():
             if realm!=currentRealm:
                 if realm.username==data['username'] and\
                    realm.url==data['url']:
                     self.statusMessage(
                         'This URL / Username combination already exists!',
                         )
                     return
         # update realm
         currentRealm.active = data['active'] and 1 or 0
         currentRealm.url = data['url']
         currentRealm.username = data['username']
         if data['password'] and len(data['password'])>0:
             currentRealm.password = data['password']
         self.statusMessage('Updated realm successfully')
         return self.request.RESPONSE.redirect('./@@publisher-config')
Ejemplo n.º 2
0
 def handleAdd(self, action):
     """
     This handler handles a click on the "Add Realm"-Button.
     If no errors occured, it adds a new Realm to the Config.
     @param action:      ActionInfo object provided by z3c.form
     @return:            None (form is shown) or Response-redirect
     """
     data, errors = self.extractData()
     config = IConfig(self.context)
     if len(errors)==0:
         assert config.is_update_realms_possible()
         # url + username has to be unique
         for realm in config.getRealms():
             if realm.url==data['url'] and realm.username==data['username']:
                 self.statusMessage(
                     'This URL / Username combination already exists!',
                     'error')
                 return
         kwargs = {
             'active': data['active'] and 1 or 0,
             'url': data['url'],
             'username': data['username'],
             'password': data['password'],
             }
         realm = Realm(**kwargs)
         config.appendRealm(realm)
         self.statusMessage('Added realm successfully')
         return self.request.RESPONSE.redirect('./@@publisher-config')
Ejemplo n.º 3
0
    def test_overridden_realms_config(self):
        self.layer.load_zcml_string(
            '\n'.join((
                    '<configure xmlns:publisher="http://namespaces.' + \
                        'zope.org/ftw.publisher">',

                    '    <publisher:override-realm',
                    '        url="http://localhost:9090/site"',
                    '        username="******"',
                    '        password="******" />',

                    '</configure>'
                    )))

        portal = self.providing_stub([IPloneSiteRoot, IAttributeAnnotatable])
        portal.portal_url.getPortalObject.return_value = portal

        config = IConfig(portal)
        self.assertTrue(config)
        self.assertFalse(config.is_update_realms_possible())

        self.assertEquals(len(config.getRealms()), 1)

        with self.assertRaises(AttributeError):
            config.appendRealm(Realm(1, 'http://site', 'foo', 'pw'))
    def test_sender(self, browser):
        intercepted_data = {}

        class MockedReceiverView(BrowserView):
            def __call__(self):
                intercepted_data['jsondata'] = self.request.form.get(
                    'jsondata')
                return createResponse(SuccessState())

        config = IConfig(self.portal)
        config.appendRealm(
            Realm(1, self.portal.absolute_url(), SITE_OWNER_NAME,
                  SITE_OWNER_PASSWORD))
        transaction.commit()

        with view_registered(MockedReceiverView,
                             'global_statusmessage_config_receiver',
                             required=(IPloneSiteRoot, Interface)):
            browser.login(SITE_OWNER_NAME).open(
                view='@@global_statusmessage_config')
            browser.fill(self.form_data)
            browser.click_on('Save and publish')

        self.assertDictEqual(
            self.expected_settings,
            encode_after_json(json.loads(intercepted_data['jsondata'])))

        self.assertEqual(['Changes saved and published.'], info_messages())
    def test_blacklisting_intermediate_wildcards_does_not_affect_parents(self):
        config = IConfig(self.portal)
        config.setPathBlacklist(PersistentList())
        config.appendPathToBlacklist('/demo/one*two')
        blacklist = IPathBlacklist(self.portal)

        self.assertFalse(blacklist.is_blacklisted('/demo/one'))
        self.assertFalse(blacklist.is_blacklisted('/demo/oneXtwo'))
        self.assertFalse(blacklist.is_blacklisted('/demo/one/two'))
    def test_blacklist_does_not_affect_parents(self):
        config = IConfig(self.portal)
        config.setPathBlacklist(PersistentList())
        config.appendPathToBlacklist('/foo/bar/one/two/three')
        blacklist = IPathBlacklist(self.portal)

        self.assertFalse(blacklist.is_blacklisted('/foo/bar'))
        self.assertFalse(blacklist.is_blacklisted('/foo/bar/one/two'))
        self.assertTrue(blacklist.is_blacklisted('/foo/bar/one/two/three'))
Ejemplo n.º 7
0
    def __call__(self):
        """
        Handles logging purposes and calls execute() method.
        """

        # get config and queue
        self.config = IConfig(self.context)
        portal = self.context.portal_url.getPortalObject()
        self.queue = IQueue(portal)
        event.notify(BeforeQueueExecutionEvent(portal, self.queue))
        # prepare logger
        self.logger = getLogger()
        self.error_logger = getErrorLogger()
        # is it allowed to publish?
        if not self.config.publishing_enabled():
            self.logger.warning('PUBLISHING IS DISABLED')
            return 'PUBLISHING IS DISABLED'

        if self.config.locking_enabled():
            self.logger.info('LOCKING IS ENABLED')
        else:
            self.logger.info('LOCKING IS DISABLED')

        # lock - check for locking flag
        if self.config.locking_enabled(
        ) and not self.get_lock_object().acquire(0):
            self.logger.warning('Already publishing')
            return 'Already publishing'

        # register our own logging handler for returning logs afterwards
        logStream = StringIO()
        logHandler = logging.StreamHandler(logStream)
        self.logger.addHandler(logHandler)
        # be sure to remove the handler!
        try:
            # execute queue
            self.execute()
        except Exception:
            self.logger.removeHandler(logHandler)
            if self.config.locking_enabled():
                self.get_lock_object().release()
            # re-raise exception
            raise
        # get logs
        self.logger.removeHandler(logHandler)
        logStream.seek(0)
        log = logStream.read()
        del logStream
        del logHandler

        # unlock
        if self.config.locking_enabled():
            self.get_lock_object().release()

        event.notify(QueueExecutedEvent(portal, log))
        return log
Ejemplo n.º 8
0
    def test_default_realms_config(self):
        portal = self.providing_stub([IPloneSiteRoot, IAttributeAnnotatable])
        portal.portal_url.getPortalObject.return_value = portal
        config = IConfig(portal)
        self.assertTrue(config)
        self.assertTrue(config.is_update_realms_possible())

        self.assertEquals(len(config.getRealms()), 0)
        config.appendRealm(Realm(1, 'http://site', 'foo', 'pw'))
        self.assertEquals(len(config.getRealms()), 1)
Ejemplo n.º 9
0
    def test_ignoring_fields_of_field_data_adapter_plone_4(self):
        self.grant('Manager')
        folder = create(Builder('folder').titled(u'Foo'))
        data = encode_after_json(json.loads(Extractor()(folder, 'push', {})))
        self.assertIn('field_data_adapter', data)
        self.assertIn('description', data['field_data_adapter'])

        IConfig(self.portal).set_ignored_fields({'Folder': ['description']})
        data = encode_after_json(json.loads(Extractor()(folder, 'push', {})))
        self.assertNotIn('description', data['field_data_adapter'])
    def test_item_can_be_added_to_blacklist(self):
        config = IConfig(self.portal)
        config.setPathBlacklist(PersistentList())

        # The blacklist is empty by default.
        self.assertEqual(0, len(config.getPathBlacklist()))

        # Items can be added to the blacklist.
        config.appendPathToBlacklist('hans')
        self.assertIn('hans', config.getPathBlacklist())
        self.assertEqual(1, len(config.getPathBlacklist()))
    def test_portal_can_be_blacklisted(self):
        config = IConfig(self.portal)
        config.setPathBlacklist(PersistentList())
        blacklist = IPathBlacklist(self.portal)

        # The portal is not blacklisted by default.
        self.assertFalse(blacklist.is_blacklisted(self.portal))

        # Blacklist the portal.
        config.appendPathToBlacklist('/'.join(self.portal.getPhysicalPath()))
        self.assertTrue(blacklist.is_blacklisted(self.portal))
Ejemplo n.º 12
0
    def send_to_receiver(self):
        data = json.dumps(
            decode_for_json(self.get_settings_data())
        )

        realms = IConfig(api.portal.get()).getRealms()
        for realm in realms:
            sendJsonToRealm(
                data,
                realm,
                'global_statusmessage_config_receiver'
            )
Ejemplo n.º 13
0
def add_saved_input_to_ignored_fields(site):
    config = IConfig(site)
    ignored_fields = config.get_ignored_fields()
    if 'FormSaveDataAdapter' in ignored_fields.keys():
        if 'SavedFormInput' not in ignored_fields['FormSaveDataAdapter']:
            ignored_fields['FormSaveDataAdapter'].append('SavedFormInput')
    else:
        ignored_fields['FormSaveDataAdapter'] = [
            'SavedFormInput',
        ]

    config.set_ignored_fields(ignored_fields)
Ejemplo n.º 14
0
 def handleAdd(self, action):
     portal = self.context.portal_url.getPortalObject()
     config = IConfig(portal)
     data, errors = self.extractData()
     if not len(errors):
         path = data.get('path').strip()
         if not path.startswith('/'):
             raise Exception('Path does not start with /')
         config.appendPathToBlacklist(path)
         message = _(u'info_path_added', default=u'Path added')
         IStatusMessage(self.request).addStatusMessage(message, type='info')
         return self.request.RESPONSE.redirect(
             './@@publisher-config-blacklist')
Ejemplo n.º 15
0
 def execute_single_job(self, job):
     """ Executes a single job without calling the view
     """
     self.logger = getLogger()
     self.error_logger = getErrorLogger()
     portal = self.context.portal_url.getPortalObject()
     self.config = IConfig(portal)
     self.queue = IQueue(portal)
     # remove job from queue
     if job in self.queue.getJobs():
         self.queue.removeJob(job)
     elif job in self.queue.get_executed_jobs():
         self.queue.remove_executed_job(job)
     # execute it
     self.executeJob(job)
     # move json file
     job.move_jsonfile_to(self.config.get_executed_folder())
     # add to executed list
     return self.queue.append_executed_job(job)
Ejemplo n.º 16
0
def download(self, REQUEST=None, RESPONSE=None):
    """Download the saved data
    """
    url_tool = getToolByName(self, 'portal_url')
    config = IConfig(url_tool.getPortalObject())
    pub_state = getMultiAdapter((self, REQUEST), IPublisherContextState)
    realms = config.getRealms()
    download_format = getattr(self, 'DownloadFormat', 'csv')

    if len(realms) == 0 or not pub_state.is_parent_published():
        if download_format == 'tsv':
            return self.download_tsv(REQUEST, RESPONSE)
        else:
            assert download_format == 'csv', 'Unknown download format'
            return self.download_csv(REQUEST, RESPONSE)

    elif len(realms) == 1:
        data = {'uid': self.UID(), 'download_format': download_format}
        return_data_realm = sendRequestToRealm(data,
                                               realms[0],
                                               'formgen_get_saved_data')
        return_data_this = self.getSavedFormInputForEdit()
        return_data = '{}{}'.format(return_data_realm, return_data_this)

        filename = self.id
        if filename.find('.') < 0:
            filename = '%s.%s' % (filename, download_format)
        header_value = contentDispositionHeader('attachment',
                                                self.getCharset(),
                                                filename=filename)
        RESPONSE.setHeader("Content-Disposition", header_value)
        sep_type = download_format == 'csv' and 'comma' or 'tab'
        RESPONSE.setHeader("Content-Type",
                           'text/%s-separated-values;'
                           'charset=%s' % (sep_type, self.getCharset()))

        return return_data

    else:
        messages = IStatusMessage(self.request)
        messages.add(_(u"couldn't determine correct realm to fetch from."),
                     type=u"error")
        return RESPONSE.redirect(self.context.absolute_url())
Ejemplo n.º 17
0
    def setUp(self):
        super(TestFormGenIntegration, self).setUp()

        self.portal = self.layer['portal']
        setRoles(self.portal, TEST_USER_ID, ['Manager'])

        self.wftool = getToolByName(self.portal, 'portal_workflow')
        self.wftool.setChainForPortalTypes(['FormFolder', 'Form Folder'],
                                           'publisher-example-workflow')

        self.formfolder = create(Builder('form folder'))
        self.save_data_adapter = create(
            Builder('save data adapter').within(self.formfolder))

        self.data_string = "[email protected], Test, only a Test \n \
                           [email protected], another Test, Still a Test"

        self.save_data_adapter.setSavedFormInput(self.data_string)
        config = IConfig(self.portal)
        config.appendRealm(Realm(1, 'http://site', 'foo', 'pw'))
Ejemplo n.º 18
0
    def __call__(self, object, action, additional_data):
        """
        Extracts the required data (action dependent) from a object for
        creating a Job.
        @param object:      Plone Object to export data from
        @param action:      Action to perform [push|delete]
        @type action:       string
        @param additional_data: Additional infos.
        @type additional_data: dict
        @return:            data (json "encoded")
        @rtype:             string
        """
        self.object = object
        self.is_root = IPloneSiteRoot.providedBy(self.object)
        data = {}

        if action not in ['delete', 'move']:
            adapters = sorted(getAdapters((self.object, ), IDataCollector))
            for name, adapter in adapters:
                data[name] = adapter.getData()
        # gets the metadata, we dont use an adapter in this case,
        # cause metdata is the most important data-set we need
        data['metadata'] = self.getMetadata(action)

        # remove ignored fields
        portal = self.object.portal_url.getPortalObject()
        config = IConfig(portal)
        ignore = config.get_ignored_fields()
        for field_to_ignore in ignore.get(data['metadata']['portal_type'], ()):
            # AT:
            data.get('field_data_adapter', {}).pop(field_to_ignore, None)
            # DX:
            for schemata in data.get('dx_field_data_adapter', {}).values():
                schemata.pop(field_to_ignore, None)

        if action == 'move':
            data['move'] = additional_data['move_data']

        # convert to json
        jsondata = self.convertToJson(data)
        return jsondata
Ejemplo n.º 19
0
    def is_blacklisted(self, context=None, path=None):
        """ Checks if the adapter the context, the given
        `context` or the given `path` is blacklisted.
        """
        if context and path:
            raise ValueError(
                'Only one of `context` and `path` can be checked at once.')
        elif not context and not path:
            context = self.context
        elif not path and type(context) in (str, unicode):
            path = context
            context = None
        if not path and isinstance(context,
                                   CatalogBrains.AbstractCatalogBrain):
            # context is a brain
            path = context.getPath()
        if not path:
            path = '/'.join(context.getPhysicalPath())

        path = path.strip()
        if path.endswith('/'):
            path = path[:-1]

        # check the path
        config = IConfig(self.portal)

        for blocked_path in config.getPathBlacklist():
            blocked_path = blocked_path.strip()
            if path == blocked_path:
                return True
            if blocked_path.endswith('*') and \
                    path.startswith(blocked_path[:-1]):
                if path == blocked_path[:-1]:
                    return True
                elif blocked_path[-2] != '/' and \
                        path[len(blocked_path) - 1] == '/':
                    return False
                else:
                    return True
        return False
Ejemplo n.º 20
0
 def __init__(self, *args, **kwargs):
     super(PathBlacklistView, self).__init__(*args, **kwargs)
     self.portal = self.context.portal_url.getPortalObject()
     self.config = IConfig(self.portal)
Ejemplo n.º 21
0
def download(self, response, delimiter=""):
    """This patch combines the data from the sender installation and the receiver
    installation to one csv / tsv.
    We assume that the form config is the same on both sides.

    The concept is to first execute the standard implementation, which sets the
    response headers and streams the local data.

    If the context is considered public, the second step is to get the data from
    the remote realms and append it to the response body (with response.write).

    This will combine the data of the all sites in a streamed http response.

    This implementation also works in local development with two plone sites,
    assuming that the receiver side does not have any realms configured.
    """

    site = getSite()
    realms = IConfig(site).getRealms()
    if not realms:
        return

    if site.REQUEST.get('is_publisher', None):
        # Prevent endless loop if sender and receiver are running on the same machine
        self._old_download(response, delimiter)
        return

    pub_state = getMultiAdapter((get_context(self), response),
                                IPublisherContextState)
    if not pub_state.is_parent_published():
        return

    site_path = '/'.join(site.getPhysicalPath())
    context_path = '/'.join(get_context(self).getPhysicalPath())
    relative_path = os.path.relpath(context_path, site_path)
    view_path = '/'.join((relative_path, '@@actions', self.__name__, '@@data'))

    is_xlsx = getattr(self, 'DownloadFormat', 'tsv') == 'xlsx'
    is_csv = getattr(self, 'DownloadFormat', 'tsv') == 'csv'

    if is_csv and len(delimiter) == 0:
        delimiter = ','

    if not is_xlsx:
        self._old_download(response, delimiter)

    for realm in realms:
        try:
            remote_response = sendRequestToRealm(getSite().REQUEST.form.copy(),
                                                 realm,
                                                 view_path.lstrip('/') +
                                                 '?is_publisher=1',
                                                 return_response=True)

        except HTTPError:
            remote_response = False  # Nothing to combine

        if remote_response and remote_response.code != 200:
            raise ValueError(
                'Bad response from remote realm ({} {}): {!r}..'.format(
                    remote_response.code,
                    remote_response.msg,
                    remote_response.read(100),
                ))

        try:
            if is_xlsx:
                use_title_row = getattr(self, "UseColumnNames", False)
                local_excel = self.get_saved_form_input_as_xlsx(use_title_row)
                combine_excel(response, local_excel, remote_response,
                              use_title_row)
            else:
                response.write(remote_response.read())
        except ImportError:
            raise Exception(
                'Was not able to combine excel, since openpyxl is missing')
        finally:
            if remote_response:
                remote_response.close()
Ejemplo n.º 22
0
 def getRealmById(self, id):
     for realm in IConfig(self.context).getRealms():
         if self.makeRealmId(realm)==id:
             return realm
     return None
Ejemplo n.º 23
0
 def __init__(self, *args, **kwargs):
     super(PublisherConfigletView, self).__init__(*args, **kwargs)
     self.config = IConfig(self.context)
     self.queue = IQueue(self.context)