Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Z
Zope
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
Zope
Commits
437d5131
Commit
437d5131
authored
Jul 10, 2010
by
Hanno Schlichting
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Factored out PythonScripts
parent
f44f4ddd
Changes
46
Show whitespace changes
Inline
Side-by-side
Showing
46 changed files
with
12 additions
and
2739 deletions
+12
-2739
buildout.cfg
buildout.cfg
+1
-0
doc/CHANGES.rst
doc/CHANGES.rst
+4
-2
setup.py
setup.py
+4
-2
sources.cfg
sources.cfg
+2
-0
src/Products/PythonScripts/CHANGES.txt
src/Products/PythonScripts/CHANGES.txt
+0
-83
src/Products/PythonScripts/Extensions/RemotePS.py
src/Products/PythonScripts/Extensions/RemotePS.py
+0
-20
src/Products/PythonScripts/PythonScript.py
src/Products/PythonScripts/PythonScript.py
+0
-545
src/Products/PythonScripts/README.txt
src/Products/PythonScripts/README.txt
+0
-75
src/Products/PythonScripts/Utility.py
src/Products/PythonScripts/Utility.py
+0
-20
src/Products/PythonScripts/__init__.py
src/Products/PythonScripts/__init__.py
+0
-62
src/Products/PythonScripts/configure.zcml
src/Products/PythonScripts/configure.zcml
+0
-7
src/Products/PythonScripts/help/ModuleAccess.stx
src/Products/PythonScripts/help/ModuleAccess.stx
+0
-56
src/Products/PythonScripts/help/PythonScript.py
src/Products/PythonScripts/help/PythonScript.py
+0
-232
src/Products/PythonScripts/help/PythonScript_edit.stx
src/Products/PythonScripts/help/PythonScript_edit.stx
+0
-115
src/Products/PythonScripts/help/PythonScript_test.stx
src/Products/PythonScripts/help/PythonScript_test.stx
+0
-18
src/Products/PythonScripts/help/Script.py
src/Products/PythonScripts/help/Script.py
+0
-28
src/Products/PythonScripts/help/standard.py
src/Products/PythonScripts/help/standard.py
+0
-160
src/Products/PythonScripts/module_access_examples.py
src/Products/PythonScripts/module_access_examples.py
+0
-83
src/Products/PythonScripts/patches.py
src/Products/PythonScripts/patches.py
+0
-101
src/Products/PythonScripts/standard.py
src/Products/PythonScripts/standard.py
+0
-108
src/Products/PythonScripts/tests/__init__.py
src/Products/PythonScripts/tests/__init__.py
+0
-3
src/Products/PythonScripts/tests/testBindings.py
src/Products/PythonScripts/tests/testBindings.py
+0
-319
src/Products/PythonScripts/tests/testPythonScript.py
src/Products/PythonScripts/tests/testPythonScript.py
+0
-338
src/Products/PythonScripts/tests/tscripts/big_boolean.ps
src/Products/PythonScripts/tests/tscripts/big_boolean.ps
+0
-4
src/Products/PythonScripts/tests/tscripts/boolean_map.ps
src/Products/PythonScripts/tests/tscripts/boolean_map.ps
+0
-12
src/Products/PythonScripts/tests/tscripts/class.__name__.ps
src/Products/PythonScripts/tests/tscripts/class.__name__.ps
+0
-6
src/Products/PythonScripts/tests/tscripts/complex_print.ps
src/Products/PythonScripts/tests/tscripts/complex_print.ps
+0
-9
src/Products/PythonScripts/tests/tscripts/fibonacci.ps
src/Products/PythonScripts/tests/tscripts/fibonacci.ps
+0
-6
src/Products/PythonScripts/tests/tscripts/filepath.ps
src/Products/PythonScripts/tests/tscripts/filepath.ps
+0
-2
src/Products/PythonScripts/tests/tscripts/for_loop.ps
src/Products/PythonScripts/tests/tscripts/for_loop.ps
+0
-4
src/Products/PythonScripts/tests/tscripts/global_is_declaration.ps
...cts/PythonScripts/tests/tscripts/global_is_declaration.ps
+0
-2
src/Products/PythonScripts/tests/tscripts/mutate_literals.ps
src/Products/PythonScripts/tests/tscripts/mutate_literals.ps
+0
-14
src/Products/PythonScripts/tests/tscripts/ns_bind.ps
src/Products/PythonScripts/tests/tscripts/ns_bind.ps
+0
-3
src/Products/PythonScripts/tests/tscripts/ns_bind_invalid.ps
src/Products/PythonScripts/tests/tscripts/ns_bind_invalid.ps
+0
-3
src/Products/PythonScripts/tests/tscripts/simple_print.ps
src/Products/PythonScripts/tests/tscripts/simple_print.ps
+0
-3
src/Products/PythonScripts/tests/tscripts/subversive_except.ps
...roducts/PythonScripts/tests/tscripts/subversive_except.ps
+0
-7
src/Products/PythonScripts/tests/tscripts/try_except.ps
src/Products/PythonScripts/tests/tscripts/try_except.ps
+0
-14
src/Products/PythonScripts/tests/tscripts/tuple_unpack_assignment.ps
...s/PythonScripts/tests/tscripts/tuple_unpack_assignment.ps
+0
-3
src/Products/PythonScripts/tests/tscripts/while_loop.ps
src/Products/PythonScripts/tests/tscripts/while_loop.ps
+0
-4
src/Products/PythonScripts/version.txt
src/Products/PythonScripts/version.txt
+0
-1
src/Products/PythonScripts/www/default_py
src/Products/PythonScripts/www/default_py
+0
-13
src/Products/PythonScripts/www/pyScriptAdd.dtml
src/Products/PythonScripts/www/pyScriptAdd.dtml
+0
-52
src/Products/PythonScripts/www/pyScriptEdit.dtml
src/Products/PythonScripts/www/pyScriptEdit.dtml
+0
-155
src/Products/PythonScripts/www/pyScriptProxy.dtml
src/Products/PythonScripts/www/pyScriptProxy.dtml
+0
-45
src/Products/PythonScripts/www/pyscript.gif
src/Products/PythonScripts/www/pyscript.gif
+0
-0
versions.cfg
versions.cfg
+1
-0
No files found.
buildout.cfg
View file @
437d5131
...
...
@@ -50,6 +50,7 @@ eggs =
MultiMapping
Persistence
Products.ExternalMethod
Products.PythonScripts
Products.ZCTextIndex
Record
RestrictedPython
...
...
doc/CHANGES.rst
View file @
437d5131
...
...
@@ -25,8 +25,10 @@ Restructuring
- Avoid using the ``Products.PythonScripts.standard`` module inside the
database manager ZMI.
- Factored out the `Products.MIMETools` and `Products.ExternalMethod` packages
into their own distributions.
- Factored out the `Products.MIMETools`, `Products.ExternalMethod` and
`Products.PythonScripts` packages into their own distributions. They will
no longer be included by default in Zope 2.14 but live on as independent
add-ons.
- Factored out the `Products.ZSQLMethods` into its own distribution. The
distribution also includes the `Shared.DC.ZRDB` code. The Zope2 distribution
...
...
setup.py
View file @
437d5131
...
...
@@ -47,8 +47,6 @@ setup(name='Zope2',
'Missing'
,
'MultiMapping'
,
'Persistence'
,
'Products.ExternalMethod'
,
'Products.MIMETools'
,
'Products.ZCTextIndex'
,
'Record'
,
'RestrictedPython'
,
...
...
@@ -99,6 +97,10 @@ setup(name='Zope2',
'zope.testing'
,
'zope.traversing'
,
'zope.viewlet'
,
# BBB optional dependencies to be removed in Zope 2.14
'Products.ExternalMethod'
,
'Products.MIMETools'
,
'Products.PythonScripts'
,
],
include_package_data
=
True
,
...
...
sources.cfg
View file @
437d5131
...
...
@@ -9,7 +9,9 @@ Missing = svn svn://svn.zope.org/repos/main/Missing/trunk
MultiMapping = svn svn://svn.zope.org/repos/main/MultiMapping/trunk
nt_svcutils = svn svn://svn.zope.org/repos/main/nt_svcutils/trunk
Persistence = svn svn://svn.zope.org/repos/main/Persistence/trunk
Products.ExternalMethod = svn svn://svn.zope.org/repos/main/Products.ExternalMethod/trunk
Products.MIMETools = svn svn://svn.zope.org/repos/main/Products.MIMETools/trunk
Products.PythonScripts = svn svn://svn.zope.org/repos/main/Products.PythonScripts/trunk
Products.ZCTextIndex = svn svn://svn.zope.org/repos/main/Products.ZCTextIndex/trunk
Record = svn svn://svn.zope.org/repos/main/Record/trunk
tempstorage = svn svn://svn.zope.org/repos/main/tempstorage/trunk
...
...
src/Products/PythonScripts/CHANGES.txt
deleted
100644 → 0
View file @
f44f4ddd
2001-04-26 Evan Simpson <evan@digicool.com>
* Version 2.0.0
* Totally replaced zbytecodhacks engine with Zope's new
RestrictedPython package, which it shares with DTML.
1999-12-13 Evan Simpson <evan@4-am.com>
* Version 0.1.7
* Nested functions and lambdas are now supported, with full safety.
* You can access all of the dtml-var format functions through a builtin
dictionary called special_formats (eg: special_formats['html-quote']).
* Handing off to Digital Creations for inclusion in CVS.
* Packaged with packProduct script, which excludes parent directories
and .pyc files. Makes for a smaller package, and doesn't step on
ownership/permissions of lib/python/Products path elements.
1999-12-01 Evan Simpson <evan@4-am.com>
* Added COPYRIGHT.txt, making Wide Open Source licence (BSD-style)
explicit. (Mike Goldman provided the text, I provided the silly name).
* Jeff Rush donated a PrincipiaSearchSource method, so that
PythonMethod objects can be zcataloged to the same degree
as DTML Methods.
* Also from Jeff Rush, a document_src method, so that the source of
PythonMethods can be viewed via a "View Source" link if desired.
* If a PM has a 'traverse_subpath' parameter, you can now directly
traverse it. The elements of the subpath will then be put into a list
in 'traverse_subpath'. (thanks to Anthony Baxter)
1999-11-11 Evan Simpson <evan@4-am.com>
* Version 0.1.6
* Fix to builtins messed up DTML Methods, so I re-fixed it.
1999-11-05 Evan Simpson <evan@4-am.com>
* Version 0.1.5
* Killed *%#&$@ weird bug in which having 'add' documents in 'www'
subdirectory prevented rename, paste, or import of existing
PythonMethods! See use of '_www'.
* Range, test, and several other Zope 'builtins' had an unbound 'self'
argument unless called on _, but that's fixed.
* Safe multiplication was utterly broken (thanks to the guard); now
it works. Is anyone using the safe version??
1999-10-18 Evan Simpson <evan@4-am.com>
* Eliminated bug which delayed stringification of printed values.
1999-10-08 Evan Simpson <evan@4-am.com>
* Version 0.1.4
* Fixed mis-design noticed by Michel Pelletier, and refactored
MakeFunction. Now both kinds of Python Method have the bugfix
from 0.1.3, and shouldn't provoke a transaction when called.
1999-10-07 Evan Simpson <evan@4-am.com>
* Version 0.1.3
* Fixed parameter bug with 'self' and no defaults
1999-09-24 Evan Simpson <evan@4-am.com>
* Version 0.1.2
* Added WebDAV/FTP access code donated by Michel Pelletier
* Made parameters part of WebDAV/FTP text
* Eliminated initialization of globals to None
* Added 'global_exists' global function instead
* Killed bug with unused parameters
* Put switch in Guarded.py to allow both regular and
dangerous (XXX) PythonMethods to live side-by-side.
This means that people who patched version 0.1.1
will have to re-create any unsafe PMs they use (Sorry).
1999-09-10 Evan Simpson <evan@4-am.com>
* Version 0.1.1
* Incorporated DT_Util builtins and guards
* Fixed direct access via URL
* Fixed methodAdd.dtml
* rstrip function body
* Major changes to zbytecodehacks
src/Products/PythonScripts/Extensions/RemotePS.py
deleted
100644 → 0
View file @
f44f4ddd
''' RemotePS.py
External Method that allows you to remotely (via XML-RPC, for instance)
execute restricted Python code.
For example, create an External Method 'restricted_exec' in your Zope
root, and you can remotely call:
foobarsize = s.foo.bar.restricted_exec('len(context.objectIds())')
'''
from
Products.PythonScripts.PythonScript
import
PythonScript
from
string
import
join
def
restricted_exec
(
self
,
body
,
varmap
=
None
):
ps
=
PythonScript
(
'temp'
)
if
varmap
is
None
:
varmap
=
{}
ps
.
ZPythonScript_edit
(
join
(
varmap
.
keys
(),
','
),
body
)
return
apply
(
ps
.
__of__
(
self
),
varmap
.
values
())
src/Products/PythonScripts/PythonScript.py
deleted
100644 → 0
View file @
f44f4ddd
##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (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.
#
##############################################################################
"""Python Scripts Product
This product provides support for Script objects containing restricted
Python code.
$Id$
"""
from
logging
import
getLogger
import
marshal
import
new
import
os
import
re
import
sys
import
traceback
from
urllib
import
quote
from
AccessControl.class_init
import
InitializeClass
from
AccessControl.requestmethod
import
requestmethod
from
AccessControl.SecurityInfo
import
ClassSecurityInfo
from
AccessControl.SecurityManagement
import
getSecurityManager
from
AccessControl.ZopeGuards
import
get_safe_globals
,
guarded_getattr
from
AccessControl.ZopeGuards
import
get_safe_globals
,
guarded_getattr
from
Acquisition
import
aq_parent
from
App.Common
import
package_home
from
App.Dialogs
import
MessageDialog
from
App.special_dtml
import
DTMLFile
from
DateTime.DateTime
import
DateTime
from
OFS.Cache
import
Cacheable
from
OFS.History
import
Historical
from
OFS.History
import
html_diff
from
OFS.SimpleItem
import
SimpleItem
from
RestrictedPython
import
compile_restricted_function
from
Shared.DC.Scripts.Script
import
BindingsUI
from
Shared.DC.Scripts.Script
import
defaultBindings
from
Shared.DC.Scripts.Script
import
Script
from
webdav.Lockable
import
ResourceLockedError
from
zExceptions
import
Forbidden
LOG
=
getLogger
(
'PythonScripts'
)
# Track the Python bytecode version
import
imp
Python_magic
=
imp
.
get_magic
()
del
imp
# This should only be incremented to force recompilation.
Script_magic
=
3
_log_complaint
=
(
'Some of your Scripts have stale code cached. Since Zope cannot'
' use this code, startup will be slightly slower until these Scripts'
' are edited. You can automatically recompile all Scripts that have'
' this problem by visiting /manage_addProduct/PythonScripts/recompile'
' of your server in a browser.'
)
manage_addPythonScriptForm
=
DTMLFile
(
'www/pyScriptAdd'
,
globals
())
_default_file
=
os
.
path
.
join
(
package_home
(
globals
()),
'www'
,
'default_py'
)
_marker
=
[]
# Create a new marker object
def
manage_addPythonScript
(
self
,
id
,
REQUEST
=
None
,
submit
=
None
):
"""Add a Python script to a folder.
"""
id
=
str
(
id
)
id
=
self
.
_setObject
(
id
,
PythonScript
(
id
))
if
REQUEST
is
not
None
:
file
=
REQUEST
.
form
.
get
(
'file'
,
''
)
if
type
(
file
)
is
not
type
(
''
):
file
=
file
.
read
()
if
not
file
:
file
=
open
(
_default_file
).
read
()
self
.
_getOb
(
id
).
write
(
file
)
try
:
u
=
self
.
DestinationURL
()
except
:
u
=
REQUEST
[
'URL1'
]
if
submit
==
" Add and Edit "
:
u
=
"%s/%s"
%
(
u
,
quote
(
id
))
REQUEST
.
RESPONSE
.
redirect
(
u
+
'/manage_main'
)
return
''
class
PythonScript
(
Script
,
Historical
,
Cacheable
):
"""Web-callable scripts written in a safe subset of Python.
The function may include standard python code, so long as it does
not attempt to use the "exec" statement or certain restricted builtins.
"""
meta_type
=
'Script (Python)'
_proxy_roles
=
()
_params
=
_body
=
''
errors
=
warnings
=
()
_v_change
=
0
manage_options
=
(
{
'label'
:
'Edit'
,
'action'
:
'ZPythonScriptHTML_editForm'
,
'help'
:
(
'PythonScripts'
,
'PythonScript_edit.stx'
)},
)
+
BindingsUI
.
manage_options
+
(
{
'label'
:
'Test'
,
'action'
:
'ZScriptHTML_tryForm'
,
'help'
:
(
'PythonScripts'
,
'PythonScript_test.stx'
)},
{
'label'
:
'Proxy'
,
'action'
:
'manage_proxyForm'
,
'help'
:
(
'OFSP'
,
'DTML-DocumentOrMethod_Proxy.stx'
)},
)
+
Historical
.
manage_options
+
SimpleItem
.
manage_options
+
\
Cacheable
.
manage_options
def
__init__
(
self
,
id
):
self
.
id
=
id
self
.
ZBindings_edit
(
defaultBindings
)
self
.
_makeFunction
()
security
=
ClassSecurityInfo
()
security
.
declareObjectProtected
(
'View'
)
security
.
declareProtected
(
'View'
,
'__call__'
)
security
.
declareProtected
(
'View management screens'
,
'ZPythonScriptHTML_editForm'
,
'manage_main'
,
'read'
,
'ZScriptHTML_tryForm'
,
'PrincipiaSearchSource'
,
'document_src'
,
'params'
,
'body'
,
'get_filepath'
)
ZPythonScriptHTML_editForm
=
DTMLFile
(
'www/pyScriptEdit'
,
globals
())
manage
=
manage_main
=
ZPythonScriptHTML_editForm
ZPythonScriptHTML_editForm
.
_setName
(
'ZPythonScriptHTML_editForm'
)
security
.
declareProtected
(
'Change Python Scripts'
,
'ZPythonScriptHTML_editAction'
,
'ZPythonScript_setTitle'
,
'ZPythonScript_edit'
,
'ZPythonScriptHTML_upload'
,
'ZPythonScriptHTML_changePrefs'
)
def
ZPythonScriptHTML_editAction
(
self
,
REQUEST
,
title
,
params
,
body
):
"""Change the script's main parameters."""
self
.
ZPythonScript_setTitle
(
title
)
self
.
ZPythonScript_edit
(
params
,
body
)
message
=
"Saved changes."
return
self
.
ZPythonScriptHTML_editForm
(
self
,
REQUEST
,
manage_tabs_message
=
message
)
def
ZPythonScript_setTitle
(
self
,
title
):
title
=
str
(
title
)
if
self
.
title
!=
title
:
self
.
title
=
title
self
.
ZCacheable_invalidate
()
def
ZPythonScript_edit
(
self
,
params
,
body
):
self
.
_validateProxy
()
if
self
.
wl_isLocked
():
raise
ResourceLockedError
,
"The script is locked via WebDAV."
if
type
(
body
)
is
not
type
(
''
):
body
=
body
.
read
()
if
self
.
_params
<>
params
or
self
.
_body
<>
body
or
self
.
_v_change
:
self
.
_params
=
str
(
params
)
self
.
write
(
body
)
def
ZPythonScriptHTML_upload
(
self
,
REQUEST
,
file
=
''
):
"""Replace the body of the script with the text in file."""
if
self
.
wl_isLocked
():
raise
ResourceLockedError
,
"The script is locked via WebDAV."
if
type
(
file
)
is
not
type
(
''
):
if
not
file
:
raise
ValueError
,
'File not specified'
file
=
file
.
read
()
self
.
write
(
file
)
message
=
'Saved changes.'
return
self
.
ZPythonScriptHTML_editForm
(
self
,
REQUEST
,
manage_tabs_message
=
message
)
def
ZPythonScriptHTML_changePrefs
(
self
,
REQUEST
,
height
=
None
,
width
=
None
,
dtpref_cols
=
"100%"
,
dtpref_rows
=
"20"
):
"""Change editing preferences."""
dr
=
{
"Taller"
:
5
,
"Shorter"
:
-
5
}.
get
(
height
,
0
)
dc
=
{
"Wider"
:
5
,
"Narrower"
:
-
5
}.
get
(
width
,
0
)
if
isinstance
(
height
,
int
):
dtpref_rows
=
height
if
isinstance
(
width
,
int
)
or
\
isinstance
(
width
,
str
)
and
width
.
endswith
(
'%'
):
dtpref_cols
=
width
rows
=
str
(
max
(
1
,
int
(
dtpref_rows
)
+
dr
))
cols
=
str
(
dtpref_cols
)
if
cols
.
endswith
(
'%'
):
cols
=
str
(
min
(
100
,
max
(
25
,
int
(
cols
[:
-
1
])
+
dc
)))
+
'%'
else
:
cols
=
str
(
max
(
35
,
int
(
cols
)
+
dc
))
e
=
(
DateTime
(
"GMT"
)
+
365
).
rfc822
()
setCookie
=
REQUEST
[
"RESPONSE"
].
setCookie
setCookie
(
"dtpref_rows"
,
rows
,
path
=
'/'
,
expires
=
e
)
setCookie
(
"dtpref_cols"
,
cols
,
path
=
'/'
,
expires
=
e
)
REQUEST
.
other
.
update
({
"dtpref_cols"
:
cols
,
"dtpref_rows"
:
rows
})
return
self
.
manage_main
(
self
,
REQUEST
)
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
]
!=
'*'
and
re
.
match
(
'
\
w
'
,name):
param_names.append(name.split('
=
', 1)[0].strip())
return param_names
def manage_historyCompare(self, rev1, rev2, REQUEST,
historyComparisonResults=''):
return PythonScript.inheritedAttribute('
manage_historyCompare
')(
self, rev1, rev2, REQUEST,
historyComparisonResults=html_diff(rev1.read(), rev2.read()) )
def __setstate__(self, state):
Script.__setstate__(self, state)
if (getattr(self, '
Python_magic
', None) != Python_magic or
getattr(self, '
Script_magic
', None) != Script_magic):
global _log_complaint
if _log_complaint:
LOG.info(_log_complaint)
_log_complaint = 0
# Changes here won'
t
get
saved
,
unless
this
Script
is
edited
.
body
=
self
.
_body
.
rstrip
()
if
body
:
self
.
_body
=
body
+
'
\
n
'
self
.
_compile
()
self
.
_v_change
=
1
elif
self
.
_code
is
None
:
self
.
_v_ft
=
None
else
:
self
.
_newfun
(
marshal
.
loads
(
self
.
_code
))
def
_compiler
(
self
,
*
args
,
**
kw
):
return
compile_restricted_function
(
*
args
,
**
kw
)
def
_compile
(
self
):
bind_names
=
self
.
getBindingAssignments
().
getAssignedNamesInOrder
()
r
=
self
.
_compiler
(
self
.
_params
,
self
.
_body
or
'pass'
,
self
.
id
,
self
.
meta_type
,
globalize
=
bind_names
)
code
=
r
[
0
]
errors
=
r
[
1
]
self
.
warnings
=
tuple
(
r
[
2
])
if
errors
:
self
.
_code
=
None
self
.
_v_ft
=
None
self
.
_setFuncSignature
((),
(),
0
)
# Fix up syntax errors.
filestring
=
' File "<string>",'
for
i
in
range
(
len
(
errors
)):
line
=
errors
[
i
]
if
line
.
startswith
(
filestring
):
errors
[
i
]
=
line
.
replace
(
filestring
,
' Script'
,
1
)
self
.
errors
=
errors
return
self
.
_code
=
marshal
.
dumps
(
code
)
self
.
errors
=
()
f
=
self
.
_newfun
(
code
)
fc
=
f
.
func_code
self
.
_setFuncSignature
(
f
.
func_defaults
,
fc
.
co_varnames
,
fc
.
co_argcount
)
self
.
Python_magic
=
Python_magic
self
.
Script_magic
=
Script_magic
self
.
_v_change
=
0
def
_newfun
(
self
,
code
):
g
=
get_safe_globals
()
g
[
'_getattr_'
]
=
guarded_getattr
g
[
'__debug__'
]
=
__debug__
# it doesn't really matter what __name__ is, *but*
# - we need a __name__
# (see testPythonScript.TestPythonScriptGlobals.test__name__)
# - it should not contain a period, so we can't use the id
# (see https://bugs.launchpad.net/zope2/+bug/142731/comments/4)
# - with Python 2.6 it should not be None
# (see testPythonScript.TestPythonScriptGlobals.test_filepath)
g
[
'__name__'
]
=
'script'
l
=
{}
exec
code
in
g
,
l
f
=
l
.
values
()[
0
]
self
.
_v_ft
=
(
f
.
func_code
,
g
,
f
.
func_defaults
or
())
return
f
def
_makeFunction
(
self
):
self
.
ZCacheable_invalidate
()
self
.
_compile
()
if
not
(
aq_parent
(
self
)
is
None
or
hasattr
(
self
,
'_filepath'
)):
# It needs a _filepath, and has an acquisition wrapper.
self
.
_filepath
=
self
.
get_filepath
()
def
_editedBindings
(
self
):
if
getattr
(
self
,
'_v_ft'
,
None
)
is
not
None
:
self
.
_makeFunction
()
def
_exec
(
self
,
bound_names
,
args
,
kw
):
"""Call a Python Script
Calling a Python Script is an actual function invocation.
"""
# Retrieve the value from the cache.
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
]
=
aq_parent
(
self
).
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
#__traceback_info__ = bound_names, args, kw, self.func_defaults
ft
=
self
.
_v_ft
if
ft
is
None
:
__traceback_supplement__
=
(
PythonScriptTracebackSupplement
,
self
)
raise
RuntimeError
,
'%s %s has errors.'
%
(
self
.
meta_type
,
self
.
id
)
fcode
,
g
,
fadefs
=
ft
g
=
g
.
copy
()
if
bound_names
is
not
None
:
g
.
update
(
bound_names
)
g
[
'__traceback_supplement__'
]
=
(
PythonScriptTracebackSupplement
,
self
,
-
1
)
g
[
'__file__'
]
=
getattr
(
self
,
'_filepath'
,
None
)
or
self
.
get_filepath
()
f
=
new
.
function
(
fcode
,
g
,
None
,
fadefs
)
try
:
result
=
f
(
*
args
,
**
kw
)
except
SystemExit
:
raise
ValueError
(
'SystemExit cannot be raised within a PythonScript'
)
if
keyset
is
not
None
:
# Store the result in the cache.
self
.
ZCacheable_set
(
result
,
keywords
=
keyset
)
return
result
def
manage_afterAdd
(
self
,
item
,
container
):
if
item
is
self
:
self
.
_filepath
=
self
.
get_filepath
()
def
manage_beforeDelete
(
self
,
item
,
container
):
# shut up deprecation warnings
pass
def
manage_afterClone
(
self
,
item
):
# shut up deprecation warnings
pass
def
get_filepath
(
self
):
return
self
.
meta_type
+
':'
+
'/'
.
join
(
self
.
getPhysicalPath
())
def
manage_haveProxy
(
self
,
r
):
return
r
in
self
.
_proxy_roles
def
_validateProxy
(
self
,
roles
=
None
):
if
roles
is
None
:
roles
=
self
.
_proxy_roles
if
not
roles
:
return
user
=
getSecurityManager
().
getUser
()
if
user
is
not
None
and
user
.
allowed
(
self
,
roles
):
return
raise
Forbidden
,
(
'You are not authorized to change <em>%s</em> '
'because you do not have proxy roles.
\
n
<!--%s, %s-->'
%
(
self
.
id
,
user
,
roles
))
security
.
declareProtected
(
'Change proxy roles'
,
'manage_proxyForm'
,
'manage_proxy'
)
manage_proxyForm
=
DTMLFile
(
'www/pyScriptProxy'
,
globals
())
@
requestmethod
(
'POST'
)
def
manage_proxy
(
self
,
roles
=
(),
REQUEST
=
None
):
"Change Proxy Roles"
self
.
_validateProxy
(
roles
)
self
.
_validateProxy
()
self
.
ZCacheable_invalidate
()
self
.
_proxy_roles
=
tuple
(
roles
)
if
REQUEST
:
return
MessageDialog
(
title
=
'Success!'
,
message
=
'Your changes have been saved'
,
action
=
'manage_main'
)
security
.
declareProtected
(
'Change Python Scripts'
,
'PUT'
,
'manage_FTPput'
,
'write'
,
'manage_historyCopy'
,
'manage_beforeHistoryCopy'
,
'manage_afterHistoryCopy'
)
def
PUT
(
self
,
REQUEST
,
RESPONSE
):
""" Handle HTTP PUT requests """
self
.
dav__init
(
REQUEST
,
RESPONSE
)
self
.
dav__simpleifhandler
(
REQUEST
,
RESPONSE
,
refresh
=
1
)
self
.
write
(
REQUEST
.
get
(
'BODY'
,
''
))
RESPONSE
.
setStatus
(
204
)
return
RESPONSE
manage_FTPput
=
PUT
def
write
(
self
,
text
):
""" Change the Script by parsing a read()-style source text. """
self
.
_validateProxy
()
mdata
=
self
.
_metadata_map
()
bindmap
=
self
.
getBindingAssignments
().
getAssignedNames
()
bup
=
0
st
=
0
try
:
while
1
:
# Find the next non-empty line
m
=
_nonempty_line
.
search
(
text
,
st
)
if
not
m
:
# There were no non-empty body lines
body
=
''
break
line
=
m
.
group
(
0
).
strip
()
if
line
[:
2
]
!=
'##'
:
# We have found the first line of the body
body
=
text
[
m
.
start
(
0
):]
break
st
=
m
.
end
(
0
)
# Parse this header line
if
len
(
line
)
==
2
or
line
[
2
]
==
' '
or
'='
not
in
line
:
# Null header line
continue
k
,
v
=
line
[
2
:].
split
(
'='
,
1
)
k
=
k
.
strip
().
lower
()
v
=
v
.
strip
()
if
not
mdata
.
has_key
(
k
):
raise
SyntaxError
,
'Unrecognized header line "%s"'
%
line
if
v
==
mdata
[
k
]:
# Unchanged value
continue
# Set metadata value
if
k
==
'title'
:
self
.
title
=
v
elif
k
==
'parameters'
:
self
.
_params
=
v
elif
k
[:
5
]
==
'bind '
:
bindmap
[
_nice_bind_names
[
k
[
5
:]]]
=
v
bup
=
1
body
=
body
.
rstrip
()
if
body
:
body
=
body
+
'
\
n
'
if
body
!=
self
.
_body
:
self
.
_body
=
body
if
bup
:
self
.
ZBindings_edit
(
bindmap
)
else
:
self
.
_makeFunction
()
except
:
LOG
.
error
(
'write failed'
,
exc_info
=
sys
.
exc_info
())
raise
def
manage_FTPget
(
self
):
"Get source for FTP download"
self
.
REQUEST
.
RESPONSE
.
setHeader
(
'Content-Type'
,
'text/plain'
)
return
self
.
read
()
def
_metadata_map
(
self
):
m
=
{
'title'
:
self
.
title
,
'parameters'
:
self
.
_params
,
}
bindmap
=
self
.
getBindingAssignments
().
getAssignedNames
()
for
k
,
v
in
_nice_bind_names
.
items
():
m
[
'bind '
+
k
]
=
bindmap
.
get
(
v
,
''
)
return
m
def
read
(
self
):
""" Generate a text representation of the Script source.
Includes specially formatted comment lines for parameters,
bindings, and the title.
"""
# Construct metadata header lines, indented the same as the body.
m
=
_first_indent
.
search
(
self
.
_body
)
if
m
:
prefix
=
m
.
group
(
0
)
+
'##'
else
:
prefix
=
'##'
hlines
=
[
'%s %s "%s"'
%
(
prefix
,
self
.
meta_type
,
self
.
id
)]
mm
=
self
.
_metadata_map
().
items
()
mm
.
sort
()
for
kv
in
mm
:
hlines
.
append
(
'%s=%s'
%
kv
)
if
self
.
errors
:
hlines
.
append
(
''
)
hlines
.
append
(
' Errors:'
)
for
line
in
self
.
errors
:
hlines
.
append
(
' '
+
line
)
if
self
.
warnings
:
hlines
.
append
(
''
)
hlines
.
append
(
' Warnings:'
)
for
line
in
self
.
warnings
:
hlines
.
append
(
' '
+
line
)
hlines
.
append
(
''
)
return
(
'
\
n
'
+
prefix
).
join
(
hlines
)
+
'
\
n
'
+
self
.
_body
def
params
(
self
):
return
self
.
_params
def
body
(
self
):
return
self
.
_body
def
get_size
(
self
):
return
len
(
self
.
read
())
getSize
=
get_size
def
PrincipiaSearchSource
(
self
):
"Support for searching - the document's contents are searched."
return
"%s
\
n
%s"
%
(
self
.
_params
,
self
.
_body
)
def
document_src
(
self
,
REQUEST
=
None
,
RESPONSE
=
None
):
"""Return unprocessed document source."""
if
RESPONSE
is
not
None
:
RESPONSE
.
setHeader
(
'Content-Type'
,
'text/plain'
)
return
self
.
read
()
InitializeClass
(
PythonScript
)
class
PythonScriptTracebackSupplement
:
"""Implementation of ITracebackSupplement"""
def
__init__
(
self
,
script
,
line
=
0
):
self
.
object
=
script
# If line is set to -1, it means to use tb_lineno.
self
.
line
=
line
_first_indent
=
re
.
compile
(
'(?m)^ *(?! |$)'
)
_nonempty_line
=
re
.
compile
(
'(?m)^(.*
\
S.*)$
'
)
_nice_bind_names = {'
context
': '
name_context
', '
container
': '
name_container
',
'
script
': '
name_m_self
', '
namespace
': '
name_ns
',
'
subpath
': '
name_subpath
'}
src/Products/PythonScripts/README.txt
deleted
100644 → 0
View file @
f44f4ddd
Python Scripts
The Python Scripts product provides support for restricted execution of
Python scripts, exposing them as callable objects within the Zope
environment.
Providing access to extra modules
Python script objects have a limited number of "safe" modules
available to them by default. In the course of working with Zope,
you will probably wish to make other modules available to script
objects.
The Utility.py module in the PythonScripts products provides a
simple way to make modules available for use by script objects
on a site-wide basis. Before making a module available to Python
scripts, you should carefully consider the potential for abuse
or misuse of the module, since all users with permission to
create and edit Python scripts will be able to use any functions
and classes defined in the module. In some cases, you may want to
create a custom module that just imports a subset of names from
another module and make that custom module available to reduce
the risk of abuse.
The easiest way to make modules available to Python scripts on
your site is to create a new directory in your Products directory
containing an "__init__.py" file. At Zope startup time, this
"product" will be imported, and any module assertions you make
in the __init__.py will take effect. Here's how to do it:
o In your Products directory (either in lib/python of your
Zope installation or in the root of your Zope install,
depending on your deployment model), create a new directory
with a name like "GlobalModules".
o In the new directory, create a file named "__init__.py".
o Edit the __init__.py file, and add calls to the 'allow_module'
function (located in the Products.PythonScripts.Utility module),
passing the names of modules to be enabled for use by scripts.
For example:
# Global module assertions for Python scripts
from Products.PythonScripts.Utility import allow_module
allow_module('base64')
allow_module('re')
allow_module('DateTime.DateTime')
This example adds the modules 'base64', 're' and the 'DateTime'
module in the 'DateTime' package for use by Python scripts. Note
that for packages (dotted names), each module in the package path
will become available to script objects.
o Restart your Zope server. After restarting, the modules you enabled
in your custom product will be available to Python scripts.
NB -- Placing security assestions within the package/module you are trying
to import will not work unless that package/module is located in
your Products directory.
This is because that package/module would have to be imported for its
included security assertions to take effect, but to do
that would require importing a module without any security
declarations, which defeats the point of the restricted
python environment.
Products work differently as they are imported at Zope startup.
By placing a package/module in your Products directory, you are
asserting, among other things, that it is safe for Zope to check
that package/module for security assertions. As a result, please
be careful when place packages or modules that are not Zope Products
in the Products directory.
src/Products/PythonScripts/Utility.py
deleted
100644 → 0
View file @
f44f4ddd
##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (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
#
##############################################################################
"""Utility module for making simple security assertions for
Python scripts."""
__version__
=
'$Revision: 1.6 $'
[
11
:
-
2
]
# These have been relocated, and should be imported from AccessControl
from
AccessControl
import
allow_module
,
allow_class
src/Products/PythonScripts/__init__.py
deleted
100644 → 0
View file @
f44f4ddd
##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (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
#
##############################################################################
__doc__
=
'''Python Scripts Product Initialization
$Id$'''
import
PythonScript
import
standard
# Temporary
from
Shared.DC
import
Scripts
__module_aliases__
=
(
(
'Products.PythonScripts.Script'
,
Scripts
.
Script
),
(
'Products.PythonScripts.Bindings'
,
Scripts
.
Bindings
),
(
'Products.PythonScripts.BindingsUI'
,
Scripts
.
BindingsUI
),)
__roles__
=
None
__allow_access_to_unprotected_subobjects__
=
1
def
initialize
(
context
):
context
.
registerClass
(
PythonScript
.
PythonScript
,
permission
=
'Add Python Scripts'
,
constructors
=
(
PythonScript
.
manage_addPythonScriptForm
,
PythonScript
.
manage_addPythonScript
),
icon
=
'www/pyscript.gif'
)
context
.
registerHelp
()
context
.
registerHelpTitle
(
'Script (Python)'
)
global
_m
_m
[
'recompile'
]
=
recompile
_m
[
'recompile__roles__'
]
=
(
'Manager'
,)
# utility stuff
def
recompile
(
self
):
'''Recompile all Python Scripts'''
base
=
self
.
this
()
scripts
=
base
.
ZopeFind
(
base
,
obj_metatypes
=
(
'Script (Python)'
,),
search_sub
=
1
)
names
=
[]
for
name
,
ob
in
scripts
:
if
ob
.
_v_change
:
names
.
append
(
name
)
ob
.
_compile
()
ob
.
_p_changed
=
1
if
names
:
return
'The following Scripts were recompiled:
\
n
'
+
'
\
n
'
.
join
(
names
)
return
'No Scripts were found that required recompilation.'
import
patches
src/Products/PythonScripts/configure.zcml
deleted
100644 → 0
View file @
f44f4ddd
<configure xmlns="http://namespaces.zope.org/zope"
xmlns:five="http://namespaces.zope.org/five">
<five:deprecatedManageAddDelete
class="Products.PythonScripts.PythonScript.PythonScript"/>
</configure>
src/Products/PythonScripts/help/ModuleAccess.stx
deleted
100644 → 0
View file @
f44f4ddd
Allowing Import of Modules
Scripts are able to import a small number of Python modules for
which there are security declarations. These include 'string',
'math', and 'random'. The only way to make other Python modules
available for import is to add security declarations to them in the
filesystem.
MyScriptModules
The simplest way to allow import of a module is to create your own
simple custom Product. To make this Product:
1. Create a subdirectory of your Zope installation's "Products"
directory. The name of the directory doesn't really matter; Let's
call it 'MyScriptModules'.
2. Create a file in this subdirectory called '__init__.py'.
3. Add the following lines to your '__init__.py'::
from Products.PythonScripts.Utility import allow_module, allow_class
from AccessControl import ModuleSecurityInfo, ClassSecurityInfo
from AccessControl.class_init import InitializeClass
4. For each module to which you want to allow access, add
security declarations in '__init__.py'.
Security Declarations
You will need to write different security declarations depending
on how much of a module you want to expose. You should import the
module at the Python command line, and use 'dir(<module_name>)' to
examine its contents. Names starting with underscore ('_') may be
safely ignored. Be wary of dangerous modules, such as 'sys' and
'os', which may be exposed by the module.
You can handle a module, such as 'base64', that contains only safe
functions by writing 'allow_module("module_name")'.
To allow access to only some names, in a module with dangerous
contents, you can write::
ModuleSecurityInfo('module_name').declarePublic('name1',
'name2', ...)
If the module contains a class that you want to use, you will need
to add the following::
from <module_name> import <class>
allow_class(<class>)
Certain modules, such as 'sha', provide extension types instead of
classes. Security declarations typically cannot be added to
extension types, so the only way to use this sort of module is to
write a Python wrapper class, or use External Methods.
src/Products/PythonScripts/help/PythonScript.py
deleted
100644 → 0
View file @
f44f4ddd
##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (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
#
##############################################################################
def
manage_addPythonScript
(
id
,
REQUEST
=
None
):
"""Add a Python script to a folder.
"""
class
PythonScript
:
"""
Python Scripts contain python code that gets executed when you call the
script by:
o Calling the script through the web by going to its location with a
web browser.
o Calling the script from another script object.
o Calling the script from a method object, such as a DTML Method.
Python Scripts can contain a "safe" subset of the python language.
Python Scripts must be safe because they can be potentially edited by
many different users through an insecure medium like the web. The
following safety issues drive the need for secure Python Scripts:
o Because many users can use Zope, a Python Script must make sure it
does not allow a user to do something they are not allowed to do,
like deleting an object they do not have permission to delete.
Because of this requirement, Python Scripts do many security checks
in the course of their execution.
o Because Python Scripts can be edited through the insecure medium of
the web, they are not allowed access to the Zope server's
file-system. Normal Python builtins like 'open' are, therefore,
not allowed.
o Because many standard Python modules break the above two security
restrictions, only a small subset of Python modules may be imported
into a Python Scripts with the "import" statement unless they have
been validated by Zope's security policy. Currently, the following
standard python modules have been validated:
o string
o math
o random
o Products.PythonScripts.standard
o Because it allows you to execute arbitrary python code, the python
"exec" statement is not allowed in Python methods.
o Because they may represent or cause security violations, some
Python builtin functions are not allowed. The following
Python builtins are not allowed:
o open
o input
o raw_input
o eval
o execfile
o compile
o type
o coerce
o intern
o dir
o globals
o locals
o vars
o buffer
o reduce
o Other builtins are restricted in nature. The following builtins
are restricted:
range -- Due to possible memory denial of service attacks, the
range builtin is restricted to creating ranges less than 10,000
elements long.
filter, map, tuple, list -- For the same reason, builtins
that construct lists from sequences do not operate on strings.
getattr, setattr, delattr -- Because these may enable Python
code to circumvent Zope's security system, they are replaced with
custom, security constrained versions.
o In order to be consistent with the Python expressions
available to DTML, the builtin functions are augmented with a
small number of functions and a class:
o test
o namespace
o render
o same_type
o DateTime
o Because the "print" statement cannot operate normally in Zope,
its effect has been changed. Rather than sending text to
stdout, "print" appends to an internal variable. The special
builtin name "printed" evaluates to the concatenation of all
text printed so far during the current execution of the
script.
"""
__constructor__
=
manage_addPythonScript
__extends__
=
(
'PythonScripts.Script.Script'
,
)
def
ZPythonScriptHTML_editAction
(
REQUEST
,
title
,
params
,
body
):
"""
Change the script's main parameters. This method accepts the
following arguments:
REQUEST -- The current request.
title -- The new value of the Python Script's title. This must
be a string.
params -- The new value of the Python Script's parameters. Must
be a comma seperated list of values in valid python function
signature syntax. If it does not contain a valid signature
string, a SyntaxError is raised.
body -- The new value of the Python Script's body. Must contain
valid Python syntax. If it does not contain valid Python syntax,
a SyntaxError is raised.
"""
def
ZPythonScript_setTitle
(
title
):
"""
Change the script's title. This method accepts one argument,
'title' which is the new value for the script's title and must be a
string.
"""
def
ZPythonScript_edit
(
params
,
body
):
"""
Change the parameters and body of the script. This method accepts
two arguments:
params -- The new value of the Python Script's parameters. Must
be a comma seperated list of values in valid python function
signature syntax. If it does not contain a valid signature
string, a SyntaxError is raised.
body -- The new value of the Python Script's body. Must contain
valid Python syntax. If it does not contain valid Python syntax,
a SyntaxError is raised.
"""
def
ZPythonScriptHTML_upload
(
REQUEST
,
file
=
''
):
"""
Pass the text in file to the 'write' method.
"""
def
ZScriptHTML_tryParams
():
"""
Return a list of the required parameters with which to
test the script.
"""
def
read
():
"""
Return the body of the Python Script, with a special comment
block prepended. This block contains meta-data in the form of
comment lines as expected by the 'write' method.
"""
def
write
(
text
):
"""
Change the script by parsing the text argument into parts.
Leading lines that begin with '##' are stripped off, and if
they are of the form '##name=value', they are used to set
meta-data such as the title and parameters. The remainder of
the text is set as the body of the Python Script.
"""
def
document_src
(
REQUEST
=
None
,
RESPONSE
=
None
):
"""
Return the text of the 'read' method, with content type
'text/plain' set on the RESPONSE.
"""
src/Products/PythonScripts/help/PythonScript_edit.stx
deleted
100644 → 0
View file @
f44f4ddd
Edit View: Edit A Script (Python)
Description
This view allows you to edit the logic which composes a script
in Python. Script instances execute in a restricted
context, bounded by your user's privilege level in Zope, and
certain global restrictions of all through-the-web code. For
information about what you "can" and "cannot" do in a Script
instance as opposed to non-through-the-web Python,
see the API Reference documentation for "Script (Python)" in
this help system.
Controls
'Title' -- Allows you to specify the Zope title of the script.
'Id' -- Allows you to specify the id of the script.
'Parameter List' -- Enter function parameters for this script
separated by commas. For example: *foo, bar, baz*
Status Elements
'Bound Names' -- the names used by this script for bindings.
You may use these names in the body of the script to refer to
bound elements. The defaults are::
context -- the script's "parent" respective to acquisition.
container -- the script's "parent" respective to containment.
script -- the script object itself.
traverse_subpath -- if the script is called directly from a URL,
this is the portion of the URL path after the script's name,
split at slash separators, into a list of strings. If the script
was not called directly from a URL, this will be an empty list.
Another possible name binding, to the "namespace" object, is
not set by default. If this was set, if the Script was
called from DTML, it would represent the namespace of the
calling DTML object.
More information about bindings can be found by visiting the
help screens of the "Bindings" tab of a Script (Python)
instance.
Buttons and Other Form Elements
'Save Changes' -- saves changes you make to the body, title, or
parameter list.
'Taller'/'Shorter'/'Wider'/'Narrower' -- make the body textarea
taller, shorter, wider, or narrower.
'File' -- upload a file into this Script (Python) instance.
File Upload Details
Files uploaded into a Script (Python) instance may either
consist only of the actual body of the function, or the file
containing the function body may contain at its head a set of
lines starting with "##" which describe bindings, parameters,
and the title. For example, a file uploaded into a Script
(Python) instance might be simply::
return "Hello"
If you upload this file into a Script (Python) instance, the
existing settings (or default settings) for bindings,
parameters, and title will remain.
However, if you wished to, you could develop a Script (Python)
on disk which looked like::
## Script (Python) "foo"
##bind container=container
##bind context=context
##bind namespace=
##bind script=script
##bind subpath=traverse_subpath
##parameters=goop, fudge
##title=
##
return "Fudge was %s, goop was %s" % (fudge, goop)
The lines preceded by "##" are metadata about the Script
(Python) instance which can survive a round trip via FTP or
through the web interface. When these lines are encountered
by the parser after an upload (or webform save), they serve to
*modify* the settings of the Script (Python) instance with the
metadata contained within the blocked area.
Lines beginning with "##" without any spaces after the "##"
are contextually meaningful to the file upload parser. There
are three keywords which can directly follow a "##": "bind",
"parameters", and "title".
The "bind" keyword following a "##" binds a name to a object
in the context this Script (Python) instance's body. For
example, the line "##bind container=goober" binds the name
"goober" to the acquisition parent of the script, allowing you
to refer to "goober" in the script body. Legal objects to
which to bind are: container, context, namespace, script, and
subpath. See the help available from the "bindings" tab of
Script (Python) instances for more details about what bindings
mean.
The "title" keyword following a "##" provides a title to the
script. E.g. "title=A Really Neat Script"
The "parameters" keyword following a "##" provides parameters
to the Script (Python) instance. E.g. "parameters=foo,bar,baz".
src/Products/PythonScripts/help/PythonScript_test.stx
deleted
100644 → 0
View file @
f44f4ddd
Test View: Test a Script (Python)
Description
This view allows you to test a Script (Python) instance.
Controls
If a Script has no parameters, when the "Test" tab is
visited the return value of the script will be presented in
the manage_main frame.
However, if a Script instance has parameters, a form
will be presented with fields for "Parameter" and "Value",
changeable on a per-parameter basis. These accept string
values. The 'Run Script' button runs the script after the
'Parameter' and 'Value' fields have been filled in, and
returns the results in the manage_main frame.
src/Products/PythonScripts/help/Script.py
deleted
100644 → 0
View file @
f44f4ddd
##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (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
#
##############################################################################
class
Script
:
"""
Web-callable script base interface.
"""
def
ZScriptHTML_tryAction
(
REQUEST
,
argvars
):
"""
Apply the test parameters provided by the dictionary 'argvars'.
This will call the current script with the given arguments and
return the result.
"""
src/Products/PythonScripts/help/standard.py
deleted
100644 → 0
View file @
f44f4ddd
"""
Products.PythonScripts.standard: Utility functions and classes
The functions and classes in this module are available from
Python-based scripts, DTML, and Page Templates.
"""
def
whole_dollars
(
number
):
"""
Show a numeric value with a dollar symbol.
"""
def
dollars_and_cents
(
number
):
"""
Show a numeric value with a dollar symbol and two decimal places.
"""
def
structured_text
(
s
):
"""
Convert a string in structured-text format to HTML.
See Also
"Structured-Text Rules":http://dev.zope.org/Members/jim/StructuredTextWiki/StructuredTextNGRules
"""
def
sql_quote
(
s
):
"""
Convert single quotes to pairs of single quotes. This is needed to
safely include values in Standard Query Language (SQL) strings.
"""
def
html_quote
(
s
):
"""
Convert characters that have special meaning in HTML to HTML
character entities.
See Also
"Python 'cgi' module":http://www.python.org/doc/current/lib/Functions_in_cgi_module.html
'escape' function.
"""
def
url_quote
(
s
):
"""
Convert characters that have special meaning in URLS to HTML
character entities using decimal values.
See Also
"Python 'urllib' module":http://www.python.org/doc/current/lib/module-urllib.html
'quote' function.
"""
def
url_quote_plus
(
s
):
"""
Like url_quote but also replace blank space characters with
'+'. This is needed for building query strings in some cases.
See Also
"Python 'urllib' module":http://www.python.org/doc/current/lib/module-urllib.html
'quote_plus' function.
"""
def
url_unquote
(
s
):
"""
Convert HTML %xx character entities into the characters they
represent. (Undoes the affects of url_quote).
See Also
"Python 'urllib' module":http://www.python.org/doc/current/lib/module-urllib.html
'unquote' function.
"""
def
url_unquote_plus
(
s
):
"""
Like url_unquote but also replace '+' characters with blank spaces.
See Also
"Python 'urllib' module":http://www.python.org/doc/current/lib/module-urllib.html
'unquote_plus' function.
"""
def
urlencode
(
query
,
doseq
=
0
):
"""
Convert a mapping object (such as a dictionary) or a sequence of
two-element tuples to a URL encoded query string. Useful for generating
query strings programmatically.
See Also
"Python 'urllib' module":http://www.python.org/doc/current/lib/module-urllib.html
'urlencode' function.
"""
def
newline_to_br
(
s
):
"""
Convert newlines and carriage-return and newline combinations to
break tags.
"""
def
thousand_commas
(
number
):
"""
Insert commas every three digits to the left of a decimal point in
values containing numbers. For example, the value, "12000
widgets" becomes "12,000 widgets".
"""
class
DTML
:
"""
DTML - temporary, security-restricted DTML objects
"""
def
__init__
(
source
,
**
kw
):
"""
Create a DTML object with source text and keyword
variables. The source text defines the DTML source
content. The optinal keyword arguments define variables.
"""
def
call
(
client
=
None
,
REQUEST
=
{},
**
kw
):
"""
Render the DTML.
To accomplish its task, DTML often needs to resolve various
names into objects. For example, when the code <dtml-var
spam> is executed, the DTML engine tries to resolve the
name 'spam'.
In order to resolve names, you must be pass a namespace to the
DTML. This can be done several ways:
* By passing a 'client' object - If the argument 'client' is
passed, then names are looked up as attributes on the
argument.
* By passing a 'REQUEST' mapping - If the argument 'REQUEST'
is passed, then names are looked up as items on the
argument. If the object is not a mapping, an TypeError
will be raised when a name lookup is attempted.
* By passing keyword arguments -- names and their values can
be passed as keyword arguments to the Method.
The namespace given to a DTML object is the composite of these
three methods. You can pass any number of them or none at
all. Names will be looked up first in the keyword argument,
next in the client and finally in the mapping.
"""
src/Products/PythonScripts/module_access_examples.py
deleted
100644 → 0
View file @
f44f4ddd
'''Examples for enabling Script import
This file contains example code that can be used to make various
standard Python modules available to Scripts.
In order to use the example code, create a directory called
"MyScriptModules", or something equally descriptive, in your
Zope's "Products" directory. Copy this file to a file called
"__init__.py" in the new directory. Edit the new file,
uncommenting the block of code for each module that you want to
make available for import by Scripts.
You can, of course, add your own code to your "__init__.py" for
modules that are not listed below. The list is not comprehensive,
but is provided as a decent cross-section of modules.
NB: Placing security assestions within the package/module you are trying
to import will not work unless that package/module is located in
your Products directory.
This is because that package/module would have to be imported for its
included security assertions to take effect, but to do
that would require importing a module without any security
declarations, which defeats the point of the restricted
python environment.
Products work differently as they are imported at Zope startup.
By placing a package/module in your Products directory, you are
asserting, among other things, that it is safe for Zope to check
that package/module for security assertions. As a result, please
be careful when place packages or modules that are not Zope Products
in the Products directory.
'''
from
AccessControl
import
allow_module
,
allow_class
,
allow_type
from
AccessControl
import
ModuleSecurityInfo
# These modules are pretty safe
# allow_module('base64')
# allow_module('binascii')
# allow_module('bisect')
# allow_module('colorsys')
# allow_module('crypt')
# Only parts of these modules should be exposed
# ModuleSecurityInfo('fnmatch').declarePublic('fnmatch', 'fnmatchcase')
# ModuleSecurityInfo('re').declarePublic('compile', 'findall',
# 'match', 'search', 'split', 'sub', 'subn', 'error',
# 'I', 'L', 'M', 'S', 'X')
# import re
# allow_type(type(re.compile('')))
# allow_type(type(re.match('x','x')))
# ModuleSecurityInfo('StringIO').declarePublic('StringIO')
# These modules allow access to other servers
# ModuleSecurityInfo('ftplib').declarePublic('FTP', 'all_errors',
# 'error_reply', 'error_temp', 'error_perm', 'error_proto')
# from ftplib import FTP
# allow_class(FTP)
# ModuleSecurityInfo('httplib').declarePublic('HTTP')
# from httplib import HTTP
# allow_class(HTTP)
# ModuleSecurityInfo('nntplib').declarePublic('NNTP',
# 'error_reply', 'error_temp', 'error_perm', 'error_proto')
# from httplib import NNTP
# allow_class(NNTP)
src/Products/PythonScripts/patches.py
deleted
100644 → 0
View file @
f44f4ddd
################################################################
# Monkey patch for LP #257276 (Hotfix-2008-08-12)
#
# This code is taken from the encodings module of Python 2.4.
# Note that this code is originally (C) CNRI and it is possibly not compatible
# with the ZPL and therefore should not live within svn.zope.org. However this
# checkin is blessed by Jim Fulton for now. The fix is no longer required with
# Python 2.5 and hopefully fixed in Python 2.4.6 release.
################################################################
# Written by Marc-Andre Lemburg (mal@lemburg.com).
# (c) Copyright CNRI, All Rights Reserved. NO WARRANTY.
import
sys
def
search_function
(
encoding
):
# Cache lookup
entry
=
_cache
.
get
(
encoding
,
_unknown
)
if
entry
is
not
_unknown
:
return
entry
# Import the module:
#
# First try to find an alias for the normalized encoding
# name and lookup the module using the aliased name, then try to
# lookup the module using the standard import scheme, i.e. first
# try in the encodings package, then at top-level.
#
norm_encoding
=
normalize_encoding
(
encoding
)
aliased_encoding
=
_aliases
.
get
(
norm_encoding
)
or
\
_aliases
.
get
(
norm_encoding
.
replace
(
'.'
,
'_'
))
if
aliased_encoding
is
not
None
:
modnames
=
[
aliased_encoding
,
norm_encoding
]
else
:
modnames
=
[
norm_encoding
]
for
modname
in
modnames
:
if
not
modname
or
'.'
in
modname
:
continue
try
:
mod
=
__import__
(
modname
,
globals
(),
locals
(),
_import_tail
)
if
not
mod
.
__name__
.
startswith
(
'encodings.'
):
continue
except
ImportError
:
pass
else
:
break
else
:
mod
=
None
try
:
getregentry
=
mod
.
getregentry
except
AttributeError
:
# Not a codec module
mod
=
None
if
mod
is
None
:
# Cache misses
_cache
[
encoding
]
=
None
return
None
# Now ask the module for the registry entry
entry
=
tuple
(
getregentry
())
if
len
(
entry
)
!=
4
:
raise
CodecRegistryError
,
\
'module "%s" (%s) failed to register'
%
\
(
mod
.
__name__
,
mod
.
__file__
)
for
obj
in
entry
:
if
not
callable
(
obj
):
raise
CodecRegistryError
,
\
'incompatible codecs in module "%s" (%s)'
%
\
(
mod
.
__name__
,
mod
.
__file__
)
# Cache the codec registry entry
_cache
[
encoding
]
=
entry
# Register its aliases (without overwriting previously registered
# aliases)
try
:
codecaliases
=
mod
.
getaliases
()
except
AttributeError
:
pass
else
:
for
alias
in
codecaliases
:
if
not
_aliases
.
has_key
(
alias
):
_aliases
[
alias
]
=
modname
# Return the registry entry
return
entry
if
sys
.
version_info
[:
2
]
<
(
2
,
5
):
import
encodings
encodings
.
search_function
.
func_code
=
search_function
.
func_code
src/Products/PythonScripts/standard.py
deleted
100644 → 0
View file @
f44f4ddd
##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (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
#
##############################################################################
"""Python Scripts standard utility module
This module provides helpful functions and classes for use in Python
Scripts. It can be accessed from Python with the statement
"import Products.PythonScripts.standard"
"""
__version__
=
'$Revision: 1.14 $'
[
11
:
-
2
]
from
urllib
import
urlencode
from
AccessControl.SecurityInfo
import
ModuleSecurityInfo
from
AccessControl.SecurityManagement
import
getSecurityManager
from
App.special_dtml
import
HTML
from
DocumentTemplate.DT_Var
import
special_formats
from
DocumentTemplate.DT_Var
import
whole_dollars
from
DocumentTemplate.DT_Var
import
dollars_and_cents
from
DocumentTemplate.DT_Var
import
structured_text
from
DocumentTemplate.DT_Var
import
sql_quote
from
DocumentTemplate.DT_Var
import
html_quote
from
DocumentTemplate.DT_Var
import
url_quote
from
DocumentTemplate.DT_Var
import
url_quote_plus
from
DocumentTemplate.DT_Var
import
newline_to_br
from
DocumentTemplate.DT_Var
import
thousands_commas
from
DocumentTemplate.DT_Var
import
url_unquote
from
DocumentTemplate.DT_Var
import
url_unquote_plus
from
DocumentTemplate.DT_Var
import
restructured_text
from
DocumentTemplate.security
import
RestrictedDTML
from
ZPublisher.HTTPRequest
import
record
security
=
ModuleSecurityInfo
()
security
.
declarePublic
(
'special_formats'
,
'whole_dollars'
,
'dollars_and_cents'
,
'structured_text'
,
'restructured_text'
,
'sql_quote'
,
'html_quote'
,
'url_quote'
,
'url_quote_plus'
,
'newline_to_br'
,
'thousands_commas'
,
'url_unquote'
,
'url_unquote_plus'
,
'urlencode'
,
)
security
.
declarePublic
(
'DTML'
)
class
DTML
(
RestrictedDTML
,
HTML
):
"""DTML objects are DocumentTemplate.HTML objects that allow
dynamic, temporary creation of restricted DTML."""
def
__call__
(
self
,
client
=
None
,
REQUEST
=
{},
RESPONSE
=
None
,
**
kw
):
"""Render the DTML given a client object, REQUEST mapping,
Response, and key word arguments."""
security
=
getSecurityManager
()
security
.
addContext
(
self
)
try
:
return
HTML
.
__call__
(
self
,
client
,
REQUEST
,
**
kw
)
finally
:
security
.
removeContext
(
self
)
# We don't expose classes directly to restricted code
class
_Object
(
record
):
_guarded_writes
=
1
def
__init__
(
self
,
**
kw
):
self
.
update
(
kw
)
def
__setitem__
(
self
,
key
,
value
):
key
=
str
(
key
)
if
key
.
startswith
(
'_'
):
raise
ValueError
,
(
'Object key %s is invalid. '
'Keys may not begin with an underscore.'
%
`key`
)
self
.
__dict__
[
key
]
=
value
def
update
(
self
,
d
):
for
key
in
d
.
keys
():
# Ignore invalid keys, rather than raising an exception.
try
:
skey
=
str
(
key
)
except
:
continue
if
skey
==
key
and
not
skey
.
startswith
(
'_'
):
self
.
__dict__
[
skey
]
=
d
[
key
]
def
__hash__
(
self
):
return
id
(
self
)
security
.
declarePublic
(
'Object'
)
def
Object
(
**
kw
):
return
_Object
(
**
kw
)
security
.
apply
(
globals
())
src/Products/PythonScripts/tests/__init__.py
deleted
100644 → 0
View file @
f44f4ddd
"""
Python package.
"""
src/Products/PythonScripts/tests/testBindings.py
deleted
100644 → 0
View file @
f44f4ddd
##############################################################################
#
# Copyright (c) 2003 Zope Foundation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (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.
#
##############################################################################
"""Test Bindings
$Id$
"""
import
unittest
import
ZODB
import
transaction
from
Acquisition
import
Implicit
from
AccessControl
import
ClassSecurityInfo
from
AccessControl.class_init
import
InitializeClass
from
OFS.ObjectManager
import
ObjectManager
from
OFS.Folder
import
Folder
class
SecurityManager
:
def
__init__
(
self
,
reject
=
0
):
self
.
calls
=
[]
self
.
reject
=
reject
def
validate
(
self
,
*
args
):
from
AccessControl
import
Unauthorized
self
.
calls
.
append
((
'validate'
,
args
))
if
self
.
reject
:
raise
Unauthorized
return
1
def
validateValue
(
self
,
*
args
):
from
AccessControl
import
Unauthorized
self
.
calls
.
append
((
'validateValue'
,
args
))
if
self
.
reject
:
raise
Unauthorized
return
1
def
checkPermission
(
self
,
*
args
):
self
.
calls
.
append
((
'checkPermission'
,
args
))
return
not
self
.
reject
def
addContext
(
self
,
*
args
):
self
.
calls
.
append
((
'addContext'
,
args
))
return
1
def
removeContext
(
self
,
*
args
):
self
.
calls
.
append
((
'removeContext'
,
args
))
return
1
class
UnderprivilegedUser
:
def
getId
(
self
):
return
'underprivileged'
def
allowed
(
self
,
object
,
object_roles
=
None
):
return
0
class
RivilegedUser
:
def
getId
(
self
):
return
'privileged'
def
allowed
(
self
,
object
,
object_roles
=
None
):
return
1
class
FauxRoot
(
ObjectManager
):
def
getPhysicalPath
(
self
):
return
(
''
,)
def
__repr__
(
self
):
return
'<FauxRoot>'
class
FauxFolder
(
Folder
):
security
=
ClassSecurityInfo
()
security
.
declareObjectPrivate
()
security
.
declarePrivate
(
'__repr__'
)
def
__repr__
(
self
):
return
'<FauxFolder: %s>'
%
self
.
getId
()
security
.
declarePublic
(
'methodWithRoles'
)
def
methodWithRoles
(
self
):
return
'method called'
InitializeClass
(
FauxFolder
)
class
TestBindings
(
unittest
.
TestCase
):
def
setUp
(
self
):
from
Testing.ZODButil
import
makeDB
transaction
.
begin
()
self
.
db
=
makeDB
()
self
.
connection
=
self
.
db
.
open
()
def
tearDown
(
self
):
from
Testing.ZODButil
import
cleanDB
from
AccessControl.SecurityManagement
import
noSecurityManager
noSecurityManager
()
transaction
.
abort
()
self
.
connection
.
close
()
self
.
db
.
close
()
cleanDB
()
def
_getRoot
(
self
):
from
Testing.makerequest
import
makerequest
#true_root = self.connection.root()[ 'Application' ]
#true_root = self.connection.root()
#return makerequest(true_root)
return
makerequest
(
FauxRoot
())
def
_makeTree
(
self
):
root
=
self
.
_getRoot
()
guarded
=
FauxFolder
()
guarded
.
_setId
(
'guarded'
)
guarded
.
__roles__
=
(
'Manager'
,
)
root
.
_setOb
(
'guarded'
,
guarded
)
guarded
=
root
.
_getOb
(
'guarded'
)
open
=
FauxFolder
()
open
.
_setId
(
'open'
)
open
.
__roles__
=
(
'Anonymous'
,
)
guarded
.
_setOb
(
'open'
,
open
)
bound_unused_container_ps
=
self
.
_newPS
(
'return 1'
)
guarded
.
_setOb
(
'bound_unused_container_ps'
,
bound_unused_container_ps
)
bound_used_container_ps
=
self
.
_newPS
(
'return container.id'
)
guarded
.
_setOb
(
'bound_used_container_ps'
,
bound_used_container_ps
)
bound_used_container_ok_ps
=
self
.
_newPS
(
'return container.id'
)
open
.
_setOb
(
'bound_used_container_ok_ps'
,
bound_used_container_ok_ps
)
bound_unused_context_ps
=
self
.
_newPS
(
'return 1'
)
guarded
.
_setOb
(
'bound_unused_context_ps'
,
bound_unused_context_ps
)
bound_used_context_ps
=
self
.
_newPS
(
'return context.id'
)
guarded
.
_setOb
(
'bound_used_context_ps'
,
bound_used_context_ps
)
bound_used_context_methodWithRoles_ps
=
self
.
_newPS
(
'return context.methodWithRoles()'
)
guarded
.
_setOb
(
'bound_used_context_methodWithRoles_ps'
,
bound_used_context_methodWithRoles_ps
)
container_ps
=
self
.
_newPS
(
'return container'
)
guarded
.
_setOb
(
'container_ps'
,
container_ps
)
container_str_ps
=
self
.
_newPS
(
'return str(container)'
)
guarded
.
_setOb
(
'container_str_ps'
,
container_str_ps
)
context_ps
=
self
.
_newPS
(
'return context'
)
guarded
.
_setOb
(
'context_ps'
,
context_ps
)
context_str_ps
=
self
.
_newPS
(
'return str(context)'
)
guarded
.
_setOb
(
'context_str_ps'
,
context_str_ps
)
return
root
def
_newPS
(
self
,
txt
,
bind
=
None
):
from
Products.PythonScripts.PythonScript
import
PythonScript
ps
=
PythonScript
(
'ps'
)
#ps.ZBindings_edit(bind or {})
ps
.
write
(
txt
)
ps
.
_makeFunction
()
return
ps
# These test that the mere binding of context or container, when the
# user doesn't have access to them, doesn't raise an unauthorized. An
# exception *will* be raised if the script attempts to use them. This
# is a b/w compatibility hack: see Bindings.py for details.
def
test_bound_unused_container
(
self
):
from
AccessControl.SecurityManagement
import
newSecurityManager
newSecurityManager
(
None
,
UnderprivilegedUser
())
root
=
self
.
_makeTree
()
guarded
=
root
.
_getOb
(
'guarded'
)
ps
=
guarded
.
_getOb
(
'bound_unused_container_ps'
)
self
.
assertEqual
(
ps
(),
1
)
def
test_bound_used_container
(
self
):
from
AccessControl.SecurityManagement
import
newSecurityManager
from
AccessControl
import
Unauthorized
newSecurityManager
(
None
,
UnderprivilegedUser
())
root
=
self
.
_makeTree
()
guarded
=
root
.
_getOb
(
'guarded'
)
ps
=
guarded
.
_getOb
(
'bound_used_container_ps'
)
self
.
assertRaises
(
Unauthorized
,
ps
)
ps
=
guarded
.
_getOb
(
'container_str_ps'
)
self
.
assertRaises
(
Unauthorized
,
ps
)
ps
=
guarded
.
_getOb
(
'container_ps'
)
container
=
ps
()
self
.
assertRaises
(
Unauthorized
,
container
)
self
.
assertRaises
(
Unauthorized
,
container
.
index_html
)
try
:
str
(
container
)
except
Unauthorized
:
pass
else
:
self
.
fail
(
"str(container) didn't raise Unauthorized!"
)
ps
=
guarded
.
_getOb
(
'bound_used_container_ps'
)
ps
.
_proxy_roles
=
(
'Manager'
,
)
ps
()
ps
=
guarded
.
_getOb
(
'container_str_ps'
)
ps
.
_proxy_roles
=
(
'Manager'
,
)
ps
()
def
test_bound_used_container_allowed
(
self
):
from
AccessControl.SecurityManagement
import
newSecurityManager
newSecurityManager
(
None
,
UnderprivilegedUser
())
root
=
self
.
_makeTree
()
guarded
=
root
.
_getOb
(
'guarded'
)
open
=
guarded
.
_getOb
(
'open'
)
ps
=
open
.
unrestrictedTraverse
(
'bound_used_container_ok_ps'
)
self
.
assertEqual
(
ps
(),
'open'
)
def
test_bound_unused_context
(
self
):
from
AccessControl.SecurityManagement
import
newSecurityManager
newSecurityManager
(
None
,
UnderprivilegedUser
())
root
=
self
.
_makeTree
()
guarded
=
root
.
_getOb
(
'guarded'
)
ps
=
guarded
.
_getOb
(
'bound_unused_context_ps'
)
self
.
assertEqual
(
ps
(),
1
)
def
test_bound_used_context
(
self
):
from
AccessControl.SecurityManagement
import
newSecurityManager
from
AccessControl
import
Unauthorized
newSecurityManager
(
None
,
UnderprivilegedUser
())
root
=
self
.
_makeTree
()
guarded
=
root
.
_getOb
(
'guarded'
)
ps
=
guarded
.
_getOb
(
'bound_used_context_ps'
)
self
.
assertRaises
(
Unauthorized
,
ps
)
ps
=
guarded
.
_getOb
(
'context_str_ps'
)
self
.
assertRaises
(
Unauthorized
,
ps
)
ps
=
guarded
.
_getOb
(
'context_ps'
)
context
=
ps
()
self
.
assertRaises
(
Unauthorized
,
context
)
self
.
assertRaises
(
Unauthorized
,
context
.
index_html
)
try
:
str
(
context
)
except
Unauthorized
:
pass
else
:
self
.
fail
(
"str(context) didn't raise Unauthorized!"
)
ps
=
guarded
.
_getOb
(
'bound_used_context_ps'
)
ps
.
_proxy_roles
=
(
'Manager'
,
)
ps
()
ps
=
guarded
.
_getOb
(
'context_str_ps'
)
ps
.
_proxy_roles
=
(
'Manager'
,
)
ps
()
def
test_bound_used_context_allowed
(
self
):
from
AccessControl.SecurityManagement
import
newSecurityManager
newSecurityManager
(
None
,
UnderprivilegedUser
())
root
=
self
.
_makeTree
()
guarded
=
root
.
_getOb
(
'guarded'
)
open
=
guarded
.
_getOb
(
'open'
)
ps
=
open
.
unrestrictedTraverse
(
'bound_used_context_ps'
)
self
.
assertEqual
(
ps
(),
'open'
)
def
test_ok_no_bindings
(
self
):
from
AccessControl.SecurityManagement
import
newSecurityManager
newSecurityManager
(
None
,
UnderprivilegedUser
())
root
=
self
.
_makeTree
()
guarded
=
root
.
_getOb
(
'guarded'
)
boundless_ps
=
self
.
_newPS
(
'return 42'
)
guarded
.
_setOb
(
'boundless_ps'
,
boundless_ps
)
boundless_ps
=
guarded
.
_getOb
(
'boundless_ps'
)
#
# Clear the bindings, so that the script may execute.
#
boundless_ps
.
ZBindings_edit
(
{
'name_context'
:
''
,
'name_container'
:
''
,
'name_m_self'
:
''
,
'name_ns'
:
''
,
'name_subpath'
:
''
})
self
.
assertEqual
(
boundless_ps
(),
42
)
def
test_bound_used_context_method_w_roles
(
self
):
from
AccessControl.SecurityManagement
import
newSecurityManager
from
AccessControl
import
Unauthorized
newSecurityManager
(
None
,
UnderprivilegedUser
())
root
=
self
.
_makeTree
()
guarded
=
root
.
_getOb
(
'guarded'
)
# Assert that we can call a protected method, even though we have
# no access to the context directly.
ps
=
guarded
.
_getOb
(
'bound_used_context_ps'
)
self
.
assertRaises
(
Unauthorized
,
ps
)
ps
=
guarded
.
_getOb
(
'bound_used_context_methodWithRoles_ps'
)
self
.
assertEqual
(
ps
(),
'method called'
)
def
test_suite
():
suite
=
unittest
.
TestSuite
()
suite
.
addTest
(
unittest
.
makeSuite
(
TestBindings
))
return
suite
if
__name__
==
'__main__'
:
unittest
.
main
()
src/Products/PythonScripts/tests/testPythonScript.py
deleted
100644 → 0
View file @
f44f4ddd
##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (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
#
##############################################################################
import
os
,
unittest
,
warnings
from
Products.PythonScripts.PythonScript
import
PythonScript
from
AccessControl.SecurityManagement
import
newSecurityManager
from
AccessControl.SecurityManagement
import
noSecurityManager
from
RestrictedPython.tests.verify
import
verify
if
__name__
==
'__main__'
:
here
=
os
.
getcwd
()
else
:
here
=
os
.
path
.
dirname
(
__file__
)
if
not
here
:
here
=
os
.
getcwd
()
class
WarningInterceptor
:
_old_stderr
=
None
_our_stderr_stream
=
None
def
_trap_warning_output
(
self
):
if
self
.
_old_stderr
is
not
None
:
return
import
sys
from
StringIO
import
StringIO
self
.
_old_stderr
=
sys
.
stderr
self
.
_our_stderr_stream
=
sys
.
stderr
=
StringIO
()
def
_free_warning_output
(
self
):
if
self
.
_old_stderr
is
None
:
return
import
sys
sys
.
stderr
=
self
.
_old_stderr
# Test Classes
def
readf
(
name
):
path
=
os
.
path
.
join
(
here
,
'tscripts'
,
'%s.ps'
%
name
)
return
open
(
path
,
'r'
).
read
()
class
VerifiedPythonScript
(
PythonScript
):
def
_newfun
(
self
,
code
):
verify
(
code
)
return
PythonScript
.
_newfun
(
self
,
code
)
class
PythonScriptTestBase
(
unittest
.
TestCase
):
def
setUp
(
self
):
newSecurityManager
(
None
,
None
)
def
tearDown
(
self
):
noSecurityManager
()
def
_newPS
(
self
,
txt
,
bind
=
None
):
ps
=
VerifiedPythonScript
(
'ps'
)
ps
.
ZBindings_edit
(
bind
or
{})
ps
.
write
(
txt
)
ps
.
_makeFunction
()
if
ps
.
errors
:
raise
SyntaxError
,
ps
.
errors
[
0
]
return
ps
def
_filePS
(
self
,
fname
,
bind
=
None
):
ps
=
VerifiedPythonScript
(
fname
)
ps
.
ZBindings_edit
(
bind
or
{})
ps
.
write
(
readf
(
fname
))
ps
.
_makeFunction
()
if
ps
.
errors
:
raise
SyntaxError
,
ps
.
errors
[
0
]
return
ps
class
TestPythonScriptNoAq
(
PythonScriptTestBase
):
def
testEmpty
(
self
):
empty
=
self
.
_newPS
(
''
)()
self
.
failUnless
(
empty
is
None
)
def
testIndented
(
self
):
# This failed to compile in Zope 2.4.0b2.
res
=
self
.
_newPS
(
'if 1:
\
n
return 2'
)()
self
.
assertEqual
(
res
,
2
)
def
testReturn
(
self
):
res
=
self
.
_newPS
(
'return 1'
)()
self
.
assertEqual
(
res
,
1
)
def
testReturnNone
(
self
):
res
=
self
.
_newPS
(
'return'
)()
self
.
failUnless
(
res
is
None
)
def
testParam1
(
self
):
res
=
self
.
_newPS
(
'##parameters=x
\
n
return x'
)(
'txt'
)
self
.
assertEqual
(
res
,
'txt'
)
def
testParam2
(
self
):
eq
=
self
.
assertEqual
one
,
two
=
self
.
_newPS
(
'##parameters=x,y
\
n
return x,y'
)(
'one'
,
'two'
)
eq
(
one
,
'one'
)
eq
(
two
,
'two'
)
def
testParam26
(
self
):
import
string
params
=
string
.
letters
[:
26
]
sparams
=
','
.
join
(
params
)
ps
=
self
.
_newPS
(
'##parameters=%s
\
n
return %s'
%
(
sparams
,
sparams
))
res
=
ps
(
*
params
)
self
.
assertEqual
(
res
,
tuple
(
params
))
def
testArithmetic
(
self
):
res
=
self
.
_newPS
(
'return 1 * 5 + 4 / 2 - 6'
)()
self
.
assertEqual
(
res
,
1
)
def
testCollector2295
(
self
):
res
=
self
.
_newPS
(
'if False:
\
n
pass
\
n
#hi'
)
def
testCollector2295
(
self
):
res
=
self
.
_newPS
(
'if False:
\
n
pass
\
n
#hi'
)
def
testReduce
(
self
):
res
=
self
.
_newPS
(
'return reduce(lambda x, y: x + y, [1,3,5,7])'
)()
self
.
assertEqual
(
res
,
16
)
res
=
self
.
_newPS
(
'return reduce(lambda x, y: x + y, [1,3,5,7], 1)'
)()
self
.
assertEqual
(
res
,
17
)
def
testImport
(
self
):
eq
=
self
.
assertEqual
a
,
b
,
c
=
self
.
_newPS
(
'import string; return string.split("a b c")'
)()
eq
(
a
,
'a'
)
eq
(
b
,
'b'
)
eq
(
c
,
'c'
)
def
testWhileLoop
(
self
):
res
=
self
.
_filePS
(
'while_loop'
)()
self
.
assertEqual
(
res
,
1
)
def
testForLoop
(
self
):
res
=
self
.
_filePS
(
'for_loop'
)()
self
.
assertEqual
(
res
,
10
)
def
testMutateLiterals
(
self
):
eq
=
self
.
assertEqual
l
,
d
=
self
.
_filePS
(
'mutate_literals'
)()
eq
(
l
,
[
2
])
eq
(
d
,
{
'b'
:
2
})
def
testTupleUnpackAssignment
(
self
):
eq
=
self
.
assertEqual
d
,
x
=
self
.
_filePS
(
'tuple_unpack_assignment'
)()
eq
(
d
,
{
'a'
:
0
,
'b'
:
1
,
'c'
:
2
})
eq
(
x
,
3
)
def
testDoubleNegation
(
self
):
res
=
self
.
_newPS
(
'return not not "this"'
)()
self
.
assertEqual
(
res
,
1
)
def
testTryExcept
(
self
):
eq
=
self
.
assertEqual
a
,
b
=
self
.
_filePS
(
'try_except'
)()
eq
(
a
,
1
)
eq
(
b
,
1
)
def
testBigBoolean
(
self
):
res
=
self
.
_filePS
(
'big_boolean'
)()
self
.
failUnless
(
res
)
def
testFibonacci
(
self
):
res
=
self
.
_filePS
(
'fibonacci'
)()
self
.
assertEqual
(
res
,
[
1
,
1
,
2
,
3
,
5
,
8
,
13
,
21
,
34
,
55
,
89
,
144
,
233
,
377
,
610
,
987
,
1597
,
2584
,
4181
,
6765
,
10946
,
17711
,
28657
,
46368
,
75025
,
121393
,
196418
,
317811
,
514229
,
832040
,
1346269
,
2178309
,
3524578
,
5702887
,
9227465
,
14930352
,
24157817
,
39088169
,
63245986
])
def
testSimplePrint
(
self
):
res
=
self
.
_filePS
(
'simple_print'
)()
self
.
assertEqual
(
res
,
'a 1 []
\
n
'
)
def
testComplexPrint
(
self
):
res
=
self
.
_filePS
(
'complex_print'
)()
self
.
assertEqual
(
res
,
'double
\
n
double
\
n
x: 1
\
n
y: 0 1 2
\
n
\
n
'
)
def
testNSBind
(
self
):
f
=
self
.
_filePS
(
'ns_bind'
,
bind
=
{
'name_ns'
:
'_'
})
bound
=
f
.
__render_with_namespace__
({
'yes'
:
1
,
'no'
:
self
.
fail
})
self
.
assertEqual
(
bound
,
1
)
def
testNSBindInvalidHeader
(
self
):
self
.
assertRaises
(
SyntaxError
,
self
.
_filePS
,
'ns_bind_invalid'
)
def
testBooleanMap
(
self
):
res
=
self
.
_filePS
(
'boolean_map'
)()
self
.
failUnless
(
res
)
def
testGetSize
(
self
):
f
=
self
.
_filePS
(
'complex_print'
)
self
.
assertEqual
(
f
.
get_size
(),
len
(
f
.
read
()))
def
testSet
(
self
):
res
=
self
.
_newPS
(
'from sets import Set; return len(Set([1,2,3]))'
)()
self
.
assertEqual
(
res
,
3
)
def
testDateTime
(
self
):
res
=
self
.
_newPS
(
"return DateTime('2007/12/10').strftime('%d.%m.%Y')"
)()
self
.
assertEqual
(
res
,
'10.12.2007'
)
def
testRaiseSystemExitLaunchpad257269
(
self
):
ps
=
self
.
_newPS
(
"raise SystemExit"
)
self
.
assertRaises
(
ValueError
,
ps
)
def
testEncodingTestDotTestAllLaunchpad257276
(
self
):
ps
=
self
.
_newPS
(
"return 'foo'.encode('test.testall')"
)
self
.
assertRaises
(
LookupError
,
ps
)
class
TestPythonScriptErrors
(
PythonScriptTestBase
):
def
assertPSRaises
(
self
,
error
,
path
=
None
,
body
=
None
):
assert
not
(
path
and
body
)
and
(
path
or
body
)
if
body
is
None
:
body
=
readf
(
path
)
if
error
is
SyntaxError
:
self
.
assertRaises
(
SyntaxError
,
self
.
_newPS
,
body
)
else
:
ps
=
self
.
_newPS
(
body
)
self
.
assertRaises
(
error
,
ps
)
def
testSubversiveExcept
(
self
):
self
.
assertPSRaises
(
SyntaxError
,
path
=
'subversive_except'
)
def
testBadImports
(
self
):
from
zExceptions
import
Unauthorized
self
.
assertPSRaises
(
Unauthorized
,
body
=
"from string import *"
)
self
.
assertPSRaises
(
Unauthorized
,
body
=
"from datetime import datetime"
)
self
.
assertPSRaises
(
Unauthorized
,
body
=
"import mmap"
)
def
testAttributeAssignment
(
self
):
# It's illegal to assign to attributes of anything that
# doesn't has enabling security declared.
# Classes (and their instances) defined by restricted code
# are an exception -- they are fully readable and writable.
cases
=
[(
"import string"
,
"string"
),
(
"def f(): pass"
,
"f"
),
]
assigns
=
[
"%s.splat = 'spam'"
,
"setattr(%s, '_getattr_', lambda x, y: True)"
,
"del %s.splat"
,
]
for
defn
,
name
in
cases
:
for
asn
in
assigns
:
f
=
self
.
_newPS
(
defn
+
"
\
n
"
+
asn
%
name
)
self
.
assertRaises
(
TypeError
,
f
)
class
TestPythonScriptGlobals
(
PythonScriptTestBase
,
WarningInterceptor
):
def
setUp
(
self
):
PythonScriptTestBase
.
setUp
(
self
)
def
tearDown
(
self
):
self
.
_free_warning_output
()
PythonScriptTestBase
.
tearDown
(
self
)
def
_exec
(
self
,
script
,
bound_names
=
None
,
args
=
None
,
kws
=
None
):
if
args
is
None
:
args
=
()
if
kws
is
None
:
kws
=
{}
bindings
=
{
'name_container'
:
'container'
}
f
=
self
.
_filePS
(
script
,
bindings
)
return
f
.
_exec
(
bound_names
,
args
,
kws
)
def
testGlobalIsDeclaration
(
self
):
bindings
=
{
'container'
:
7
}
results
=
self
.
_exec
(
'global_is_declaration'
,
bindings
)
self
.
assertEqual
(
results
,
8
)
def
test__name__
(
self
):
f
=
self
.
_filePS
(
'class.__name__'
)
self
.
assertEqual
(
f
(),
(
"'script.foo'>"
,
"'string'"
))
def
test_filepath
(
self
):
# This test is meant to raise a deprecation warning.
# It used to fail mysteriously instead.
def
warnMe
(
message
):
warnings
.
warn
(
message
,
stacklevel
=
2
)
try
:
f
=
self
.
_filePS
(
'filepath'
)
self
.
_trap_warning_output
()
results
=
f
.
_exec
({
'container'
:
warnMe
},
(),
{})
self
.
_free_warning_output
()
warning
=
self
.
_our_stderr_stream
.
getvalue
()
self
.
failUnless
(
'UserWarning: foo'
in
warning
)
except
TypeError
,
e
:
self
.
fail
(
e
)
class
PythonScriptInterfaceConformanceTests
(
unittest
.
TestCase
):
def
test_class_conforms_to_IWriteLock
(
self
):
from
zope.interface.verify
import
verifyClass
from
webdav.interfaces
import
IWriteLock
verifyClass
(
IWriteLock
,
PythonScript
)
def
test_suite
():
suite
=
unittest
.
TestSuite
()
suite
.
addTest
(
unittest
.
makeSuite
(
TestPythonScriptNoAq
))
suite
.
addTest
(
unittest
.
makeSuite
(
TestPythonScriptErrors
))
suite
.
addTest
(
unittest
.
makeSuite
(
TestPythonScriptGlobals
))
suite
.
addTest
(
unittest
.
makeSuite
(
PythonScriptInterfaceConformanceTests
))
return
suite
def
main
():
unittest
.
TextTestRunner
().
run
(
test_suite
())
if
__name__
==
'__main__'
:
main
()
src/Products/PythonScripts/tests/tscripts/big_boolean.ps
deleted
100644 → 0
View file @
f44f4ddd
'ab'[1]
mab = {'a': 1, 'b': 2}
r10 = range(10)
return r10[3:5][1] == 4 and r10[mab['b']] and 1 < mab['ab'[r10[1]]] < 3
src/Products/PythonScripts/tests/tscripts/boolean_map.ps
deleted
100644 → 0
View file @
f44f4ddd
result = []
for c in 'abcdef':
result.append({'a-c': (c <= 'c') or None,
'd-f': (c >= 'd') and 2})
return result == [
{'a-c': 1, 'd-f': 0},
{'a-c': 1, 'd-f': 0},
{'a-c': 1, 'd-f': 0},
{'a-c': None, 'd-f': 2},
{'a-c': None, 'd-f': 2},
{'a-c': None, 'd-f': 2},
]
src/Products/PythonScripts/tests/tscripts/class.__name__.ps
deleted
100644 → 0
View file @
f44f4ddd
import string
class foo:
pass
return repr(foo).split()[1], repr(string).split()[1]
src/Products/PythonScripts/tests/tscripts/complex_print.ps
deleted
100644 → 0
View file @
f44f4ddd
x = {'x': 1}
y = range(3)
print 'double'
print printed,
print 'x:', x['x']
print 'y:', y[0], y[1], y[2]
print
return printed
src/Products/PythonScripts/tests/tscripts/fibonacci.ps
deleted
100644 → 0
View file @
f44f4ddd
l = []
a, b = 0, 1
while b < 100000000:
l.append(b)
a, b = b, a+b
return l
src/Products/PythonScripts/tests/tscripts/filepath.ps
deleted
100644 → 0
View file @
f44f4ddd
return container('foo')
# This test is meant to raise a deprecation warning.
src/Products/PythonScripts/tests/tscripts/for_loop.ps
deleted
100644 → 0
View file @
f44f4ddd
a = 0
for x in range(10):
a = a + 1
return a
src/Products/PythonScripts/tests/tscripts/global_is_declaration.ps
deleted
100644 → 0
View file @
f44f4ddd
container = container + 1
return container
src/Products/PythonScripts/tests/tscripts/mutate_literals.ps
deleted
100644 → 0
View file @
f44f4ddd
l1 = [1, 2, 3]
l2 = [l1[0], l1[1]]
l2.extend(l1)
l2.append(4)
del l2[:2]
del l2[0]
l2[-2:] = []
d = {'a': 1, 'b': l2[0]}
d['a'] = 0
del d['a']
return l2, d
src/Products/PythonScripts/tests/tscripts/ns_bind.ps
deleted
100644 → 0
View file @
f44f4ddd
##parameters=yes
no = 0
return yes
src/Products/PythonScripts/tests/tscripts/ns_bind_invalid.ps
deleted
100644 → 0
View file @
f44f4ddd
##parameters=yes
##unknownheader='foo'
return
src/Products/PythonScripts/tests/tscripts/simple_print.ps
deleted
100644 → 0
View file @
f44f4ddd
print 'a', 1, []
return printed
src/Products/PythonScripts/tests/tscripts/subversive_except.ps
deleted
100644 → 0
View file @
f44f4ddd
# -*- python -*-
# An attempt to bind an illegal name in an except clause
try
:
1
/
0
except
ZeroDivisionError
,
__getattr__
:
pass
src/Products/PythonScripts/tests/tscripts/try_except.ps
deleted
100644 → 0
View file @
f44f4ddd
a = 0
b = 1
try:
int('$')
except ValueError:
a = 1
try:
int('1')
except:
b = 0
return a, b
src/Products/PythonScripts/tests/tscripts/tuple_unpack_assignment.ps
deleted
100644 → 0
View file @
f44f4ddd
d = {}
(d['a'], d['b'], d['c'], x) = range(4)
return d, x
src/Products/PythonScripts/tests/tscripts/while_loop.ps
deleted
100644 → 0
View file @
f44f4ddd
a = 0
while a < 10:
a = a + 1
return 1
src/Products/PythonScripts/version.txt
deleted
100644 → 0
View file @
f44f4ddd
PythonScripts-2-0-0
src/Products/PythonScripts/www/default_py
deleted
100644 → 0
View file @
f44f4ddd
# Example code:
# Import a standard function, and get the HTML request and response objects.
from Products.PythonScripts.standard import html_quote
request = container.REQUEST
response = request.response
# Return a string identifying this script.
print "This is the", script.meta_type, '"%s"' % script.getId(),
if script.title:
print "(%s)" % html_quote(script.title),
print "in", container.absolute_url()
return printed
src/Products/PythonScripts/www/pyScriptAdd.dtml
deleted
100644 → 0
View file @
f44f4ddd
<dtml-var manage_page_header>
<dtml-var "manage_form_title(this(), _,
form_title='Add Python Script',
)">
<p class="form-help">
Python Scripts allow you to add functionality to Zope by writing
scripts in the Python programming language
that are exposed as callable Zope objects. You may choose to upload
the script from a local file by typing the file name or using the
<em>browse</em> button.
</p>
<form action="manage_addPythonScript" method="post"
enctype="multipart/form-data">
<table cellspacing="0" cellpadding="2" border="0">
<tr>
<td align="left" valign="top">
<div class="form-label">
Id
</div>
</td>
<td align="left" valign="top">
<input type="text" name="id" size="40" />
</td>
</tr>
<tr>
<td align="left" valign="top">
<div class="form-optional">
File
</div>
</td>
<td align="left" valign="top">
<input type="file" name="file" size="25" value="" />
</td>
</tr>
<tr>
<td align="left" valign="top">
</td>
<td align="left" valign="top">
<div class="form-element">
<input class="form-element" type="submit" name="submit"
value=" Add " />
<input class="form-element" type="submit" name="submit"
value=" Add and Edit " />
</div>
</td>
</tr>
</table>
</form>
<dtml-var manage_page_footer>
src/Products/PythonScripts/www/pyScriptEdit.dtml
deleted
100644 → 0
View file @
f44f4ddd
<dtml-var manage_page_header>
<dtml-var manage_tabs>
<form action="&dtml-URL1;" method="post">
<input type="hidden" name=":default_method" value="ZPythonScriptHTML_changePrefs">
<table width="100%" cellspacing="0" cellpadding="2" border="0">
<dtml-with keyword_args mapping>
<tr>
<td align="left" valign="top">
<div class="form-optional">
Title
</div>
</td>
<td align="left" valign="top" width="99%">
<input type="text" name="title" size="40"
value="&dtml-title;" />
</td>
</tr>
<tr>
<td align="left" valign="top" nowrap>
<div class="form-optional">
Parameter List
</div>
</td>
<td align="left" valign="top">
<input type="text" name="params" size="40"
value="&dtml-params;" />
</td>
</tr>
</dtml-with>
<dtml-with getBindingAssignments>
<dtml-if getAssignedNamesInOrder>
<tr>
<td align="left" valign="top">
<div class="form-label">
Bound Names
</div>
</td>
<td align="left" valign="top">
<div class="form-text">
<dtml-in getAssignedNamesInOrder>
&dtml-sequence-item;<dtml-unless sequence-end>, </dtml-unless>
</dtml-in>
</div>
</td>
</tr>
</dtml-if>
</dtml-with>
<tr>
<td align="left" valign="top">
<div class="form-label">
Last Modified
</div>
</td>
<td align="left" valign="top">
<div class="form-text">
<dtml-var bobobase_modification_time fmt="%Y-%m-%d %H:%M">
</div>
</td>
</tr>
<dtml-if errors>
<tr>
<td align="left" valign="middle" class="form-label">Errors</td>
<td align="left" valign="middle" style="background-color: #FFDDDD">
<pre><dtml-var expr="'\n'.join(errors)" html_quote></pre>
</td>
</tr>
</dtml-if>
<dtml-if warnings>
<tr>
<td align="left" valign="middle" class="form-label">Warnings</td>
<td align="left" valign="middle" style="background-color: #FFEEDD">
<pre><dtml-var expr="'\n'.join(warnings)" html_quote></pre>
</td>
</tr>
</dtml-if>
<dtml-with keyword_args mapping>
<tr>
<td align="left" valign="top" colspan="2">
<div style="width: 100%;">
<dtml-let cols="REQUEST.get('dtpref_cols', '100%')"
rows="REQUEST.get('dtpref_rows', '20')">
<dtml-if "cols[-1]=='%'">
<textarea name="body:text" wrap="off" style="width: &dtml-cols;;"
<dtml-else>
<textarea name="body:text" wrap="off" cols="&dtml-cols;"
</dtml-if>
rows="&dtml-rows;">&dtml-body;</textarea>
</dtml-let>
</div>
</td>
</tr>
</dtml-with>
<tr>
<td align="left" valign="top" colspan="2">
<div class="form-element">
<dtml-if wl_isLocked>
<em>Locked by WebDAV</em>
<dtml-else>
<input class="form-element" type="submit"
name="ZPythonScriptHTML_editAction:method" value="Save Changes">
</dtml-if>
<input class="form-element" type="submit" name="height" value="Taller">
<input class="form-element" type="submit" name="height" value="Shorter">
<input class="form-element" type="submit" name="width" value="Wider">
<input class="form-element" type="submit" name="width" value="Narrower">
</div>
</td>
</tr>
</table>
</form>
<p class="form-help">
You may upload the source for &dtml-title_and_id; using the form below.
Choose an existing file from your local computer by clicking <em>browse</em>
The contents of the file should be a valid script with an optional
"##data" block at the start. You may click the following link
to <a href="document_src">view or download</a> the current source.
</p>
<form action="ZPythonScriptHTML_upload" method="post"
enctype="multipart/form-data">
<table cellpadding="2" cellspacing="0" border="0">
<tr>
<td align="left" valign="top">
<div class="form-label">
File
</div>
</td>
<td align="left" valign="top">
<input type="file" name="file" size="25" value="">
</td>
</tr>
<tr>
<td></td>
<td align="left" valign="top">
<div class="form-element">
<dtml-if wl_isLocked>
<em>Locked by WebDAV</em>
<dtml-else>
<input class="form-element" type="submit" value="Upload File">
</dtml-if>
</div>
</td>
</tr>
</table>
</form>
<dtml-var manage_page_footer>
src/Products/PythonScripts/www/pyScriptProxy.dtml
deleted
100644 → 0
View file @
f44f4ddd
<dtml-var manage_page_header>
<dtml-var manage_tabs>
<p class="form-help">
Proxy roles allow you to control the access that a script has. Proxy roles
replace the roles of the user who is executing the script. This can be used
to both expand and limit access to resources. Select the proxy roles for
this object from the list below.
</p>
<form action="manage_proxy" method="post">
<table cellpadding="2" cellspacing="0" border="0">
<tr>
<tr>
<td align="left" valign="top">
<div class="form-label">
Proxy Roles
</div>
</td>
<td align="left" valign="top">
<div class="form-element">
<select name="roles:list" size="7" multiple>
<dtml-in valid_roles>
<dtml-if expr="_vars['sequence-item'] != 'Shared'">
<option <dtml-if
expr="manage_haveProxy(_vars['sequence-item'])">selected</dtml-if
>>&dtml-sequence-item;</option>
</dtml-if>
</dtml-in valid_roles>
</select>
</div>
</td>
</tr>
<tr>
<td align="left" valign="top" colspan="2">
<div class="form-element">
<input class="form-element" type="submit" name="SUBMIT" value="Save Changes">
</div>
</td>
</tr>
</table>
</form>
<dtml-var manage_page_footer>
src/Products/PythonScripts/www/pyscript.gif
deleted
100644 → 0
View file @
f44f4ddd
184 Bytes
versions.cfg
View file @
437d5131
...
...
@@ -17,6 +17,7 @@ nt-svcutils = 2.13.0
Persistence = 2.13.2
Products.ExternalMethod = 2.13.0
Products.MIMETools = 2.13.0
Products.PythonScripts = 2.13.0
Products.ZCTextIndex = 2.13.0
Record = 2.13.0
tempstorage = 2.11.3
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment