-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
Hi,
This patch is against CMF-1.4.7, although one could equally argue it better suited elsewhere - there appear to me to be minor uncomfortable dependencies regardless of where it sits (unless it's made an independent product - which seems a little unwarranted given it's simplicity).
This patch includes the following: ~ FSPerlScript.py ~ images/fspl.gif (needs an artiste to draw a padlock!) ~ tests/test_FSPerlScript.py ~ tests/fake_skins/fake_skin/test1.pl ~ tests/fake_skins/fake_skin/test2.pl ~ __init__.py (FSPerlScript registration)
Unfortunately, FSPerlScript is not quite as useful as I'd anticipated, given that the 'use' statement is a restricted opcode.
I am more than willing to discuss with any interested party(s) how we may implement a security mechanism whereby we can specify 'safe' Perl modules, much as we do with the Python modules_allow stuff.
Cheers, Alan -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.2.4 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
iD8DBQFBhLGxCfroLk4EZpkRAtr6AKDCvDnf1gglfN7xrCW/eEZu0bvOowCfb3Wc BkRbevjQM1X20IbvgC6kCFw= =yHdw -----END PGP SIGNATURE-----
diff -Naur CMFCore/FSPerlScript.py CMFCore.fsperl/FSPerlScript.py --- CMFCore/FSPerlScript.py 1970-01-01 10:00:00.000000000 +1000 +++ CMFCore.fsperl/FSPerlScript.py 2004-10-31 19:59:21.396419752 +1100 @@ -0,0 +1,114 @@ +############################################################################## +# +# Copyright (c) 2004 Zope Corporation and Contributors. All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE +# +############################################################################## +""" Customizable Python scripts that come from the filesystem. + +$Id: FSPerlScript.py,v 1.21.4.3 2004/04/23 21:11:33 sidnei Exp $ +""" +import Globals, re +from AccessControl import ClassSecurityInfo, getSecurityManager +from Products.PerlMethod import PerlMethod, FuncCode +from Shared.DC.Scripts.Script import Script +from ComputedAttribute import ComputedAttribute + +from utils import _dtmldir +from CMFCorePermissions import ViewManagementScreens, View, FTPAccess +from DirectoryView import registerFileExtension, registerMetaType, expandpath +from FSObject import FSObject + +from OFS.Cache import Cacheable + +# +# Python regexps really f**k me off - this should parse multiline text in one hit! +# +#parameter_re = re.compile(r'''^##(title|parameters)=(.+)$''', re.MULTILINE | re.DOTALL) +parameter_re = re.compile(r'''^##(title|parameters)=(.+)$''') + +_marker = [] + +class FSPerlScript (FSObject, PerlMethod): + """FSPerlScripts act like Perl Scripts but are not directly + modifiable from the management interface.""" + + meta_type = 'Filesystem Script (Perl)' + + manage_options=( + {'label':'Customize', 'action':'manage_main'}, + {'label':'Test', 'action':'manage_try'}, + ) + Cacheable.manage_options + + __ac_permissions__ = FSObject.__ac_permissions__ + PerlMethod.__ac_permissions__ + + # Use declarative security + _security = ClassSecurityInfo() + _security.declareObjectProtected(View) + _security.declareProtected(View, 'index_html',) + + _security.declareProtected(ViewManagementScreens, 'manage_main') + manage_main = Globals.DTMLFile('custpy', _dtmldir) + + def _createZODBClone(self): + """Create a ZODB (editable) equivalent of this object.""" + obj = PerlMethod(self.getId(), self.title, self.args(), self.read()) + return obj + + def _readFile(self, reparse): + """Read the data from the filesystem. + + Read the file (indicated by exandpath(self._filepath), and parse the + data if necessary. + """ + fp = expandpath(self._filepath) + file = open(fp, 'r') + try: data = file.read() + finally: file.close() + # note we ignore reparse flag and ALWAYS reparse file ... + title = '' + args = '' + for line in data.split('\n'): + match = parameter_re.search(line) + if match: + k,v = match.groups() + if k == 'title': title = v + else: args = v + self.manage_edit(title, args, data) + + # force delegation to __call__ + index_html = None + + def __call__(self, *args, **kw): + '''Calls the script.''' + self._updateFromFS() + return PerlMethod.__call__(self, *args, **kw) + + _security.declareProtected(ViewManagementScreens, 'read') + def read(self): + self._updateFromFS() + return self.code + + _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.code + + _security.declareProtected(ViewManagementScreens, 'PrincipiaSearchSource') + def PrincipiaSearchSource(self): + "Support for searching - the document's contents are searched." + return self.document_src() + +Globals.InitializeClass(FSPerlScript) + +registerFileExtension('pl', FSPerlScript) +registerMetaType('Script (Perl)', FSPerlScript) diff -Naur CMFCore/images/fspl.gif CMFCore.fsperl/images/fspl.gif --- CMFCore/images/fspl.gif 1970-01-01 10:00:00.000000000 +1000 +++ CMFCore.fsperl/images/fspl.gif 2004-10-31 19:59:21.585391024 +1100 @@ -0,0 +1 @@ [EMAIL PROTECTED],[EMAIL PROTECTED]/[EMAIL PROTECTED]&/ ; \ No newline at end of file diff -Naur CMFCore/__init__.py CMFCore.fsperl/__init__.py --- CMFCore/__init__.py 2004-10-17 00:39:15.000000000 +1000 +++ CMFCore.fsperl/__init__.py 2004-10-31 19:59:21.545397104 +1100 @@ -21,7 +21,7 @@ import MemberDataTool, TypesTool import URLTool import DirectoryView, FSImage, FSFile, FSPropertiesObject -import FSDTMLMethod, FSPythonScript, FSSTXMethod +import FSDTMLMethod, FSPythonScript, FSSTXMethod, FSPerlScript import FSZSQLMethod import CookieCrumbler import ContentTypeRegistry @@ -115,6 +115,8 @@ 'images/fsdtml.gif', globals()) utils.registerIcon(FSPythonScript.FSPythonScript, 'images/fspy.gif', globals()) + utils.registerIcon(FSPerlScript.FSPerlScript, + 'images/fspl.gif', globals()) utils.registerIcon(FSImage.FSImage, 'images/fsimage.gif', globals()) utils.registerIcon(FSFile.FSFile, diff -Naur CMFCore/tests/fake_skins/fake_skin/test1.pl CMFCore.fsperl/tests/fake_skins/fake_skin/test1.pl --- CMFCore/tests/fake_skins/fake_skin/test1.pl 1970-01-01 10:00:00.000000000 +1000 +++ CMFCore.fsperl/tests/fake_skins/fake_skin/test1.pl 2004-10-31 19:59:21.682376280 +1100 @@ -0,0 +1,4 @@ +# +# this is a perl script ;) +# +return 'Hello World'; diff -Naur CMFCore/tests/fake_skins/fake_skin/test2.pl CMFCore.fsperl/tests/fake_skins/fake_skin/test2.pl --- CMFCore/tests/fake_skins/fake_skin/test2.pl 1970-01-01 10:00:00.000000000 +1000 +++ CMFCore.fsperl/tests/fake_skins/fake_skin/test2.pl 2004-10-31 19:59:21.682376280 +1100 @@ -0,0 +1,6 @@ +##title=Art or Porn +##parameters=name,author +# +# this test is to determine title/function parsing +# +return "$name - $author"; diff -Naur CMFCore/tests/test_FSPerlScript.py CMFCore.fsperl/tests/test_FSPerlScript.py --- CMFCore/tests/test_FSPerlScript.py 1970-01-01 10:00:00.000000000 +1000 +++ CMFCore.fsperl/tests/test_FSPerlScript.py 2004-10-31 19:59:21.683376128 +1100 @@ -0,0 +1,34 @@ +import Testing +import Zope +from OFS.Folder import Folder +from unittest import TestCase, TestSuite, makeSuite, main +from Products.CMFCore.FSPerlScript import FSPerlScript +from Products.CMFCore.tests.base.testcase import FSDVTest +from os.path import join +import sys, time + +class FSPerlScriptTests( FSDVTest ): + + def test_GetSize( self ): + """ Test get_size returns correct value """ + script = FSPerlScript('test1', join(self.skin_path_name,'test1.pl')) + self.assertEqual(len(script.read()),script.get_size()) + + def testSimpleExecute( self ): + script = FSPerlScript('test1', join(self.skin_path_name,'test1.pl')) + self.assertEqual(script(), 'Hello World') + + + def testBindings( self ): + script = FSPerlScript('test2', join(self.skin_path_name,'test2.pl')) + self.assertEqual(script.title, 'Art or Porn') + self.assertEqual(script.args(), "name, author") + self.assertEqual(script('Lolita','Vladimir Nabakov'), 'Lolita - Vladimir Nabakov') + +def test_suite(): + return TestSuite(( + makeSuite(FSPerlScriptTests), + )) + +if __name__ == '__main__': + main(defaultTest='test_suite')
_______________________________________________ Zope-Dev maillist - [EMAIL PROTECTED] http://mail.zope.org/mailman/listinfo/zope-dev ** No cross posts or HTML encoding! ** (Related lists - http://mail.zope.org/mailman/listinfo/zope-announce http://mail.zope.org/mailman/listinfo/zope )