annotate roundup/cgi/PageTemplates/Expressions.py @ 4531:ddff9669361b

Fix matching of incoming email addresses to the alternate_addresses field... ...of a user -- this would match substrings, e.g. if the user has discuss-support@example.com as an alternate email and an incoming mail is addressed to support@example.com this would (wrongly) match. Note: I *think* I've seen this discussed somewhere but couldn't find it, neither in the tracker nor in recent discussions on the mailinglists. So if someone remembers an issue which now should be closed, please tell me :-)
author Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
date Wed, 24 Aug 2011 14:43:52 +0000
parents 445e1bc8b1df
children 6e3e4f24c753
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
1 ##############################################################################
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
2 #
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
3 # Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
4 #
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
5 # This software is subject to the provisions of the Zope Public License,
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
6 # Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
7 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
8 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
9 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
10 # FOR A PARTICULAR PURPOSE
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
11 #
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
12 ##############################################################################
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
13 # Modified for Roundup:
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
14 #
2663
5f9e00836006 update comment
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
15 # 1. removed all Zope-specific code (doesn't even try to import that stuff now)
5f9e00836006 update comment
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
16 # 2. removed all Acquisition
5f9e00836006 update comment
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
17 # 3. removed blocking of leading-underscore URL components
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
18
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
19 """Page Template Expression Engine
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
20
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
21 Page Template-specific implementation of TALES, with handlers
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
22 for Python expressions, string literals, and paths.
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
23 """
1071
c08b3820edd1 Adhering to ZPL
Richard Jones <richard@users.sourceforge.net>
parents: 1065
diff changeset
24
2663
5f9e00836006 update comment
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
25 __version__='$Revision: 1.12 $'[11:-2]
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
26
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
27 import re, sys
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
28 from TALES import Engine, CompilerError, _valid_name, NAME_RE, \
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
29 Undefined, Default, _parse_expr
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
30
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
31
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
32 _engine = None
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
33 def getEngine():
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
34 global _engine
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
35 if _engine is None:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
36 from PathIterator import Iterator
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
37 _engine = Engine(Iterator)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
38 installHandlers(_engine)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
39 return _engine
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
40
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
41 def installHandlers(engine):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
42 reg = engine.registerType
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
43 pe = PathExpr
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
44 for pt in ('standard', 'path', 'exists', 'nocall'):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
45 reg(pt, pe)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
46 reg('string', StringExpr)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
47 reg('python', PythonExpr)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
48 reg('not', NotExpr)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
49 reg('defer', DeferExpr)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
50
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
51 from PythonExpr import getSecurityManager, PythonExpr
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
52 guarded_getattr = getattr
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
53 try:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
54 from zExceptions import Unauthorized
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
55 except ImportError:
4238
445e1bc8b1df remove use of string exception
Richard Jones <richard@users.sourceforge.net>
parents: 2663
diff changeset
56 class Unauthorized(Exception):
445e1bc8b1df remove use of string exception
Richard Jones <richard@users.sourceforge.net>
parents: 2663
diff changeset
57 pass
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
58
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
59 def acquisition_security_filter(orig, inst, name, v, real_validate):
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
60 if real_validate(orig, inst, name, v):
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
61 return 1
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
62 raise Unauthorized, name
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
63
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
64 def call_with_ns(f, ns, arg=1):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
65 if arg==2:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
66 return f(None, ns)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
67 else:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
68 return f(ns)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
69
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
70 class _SecureModuleImporter:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
71 """Simple version of the importer for use with trusted code."""
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
72 __allow_access_to_unprotected_subobjects__ = 1
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
73 def __getitem__(self, module):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
74 __import__(module)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
75 return sys.modules[module]
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
76
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
77 SecureModuleImporter = _SecureModuleImporter()
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
78
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
79 Undefs = (Undefined, AttributeError, KeyError,
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
80 TypeError, IndexError, Unauthorized)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
81
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
82 def render(ob, ns):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
83 """
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
84 Calls the object, possibly a document template, or just returns it if
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
85 not callable. (From DT_Util.py)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
86 """
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
87 if hasattr(ob, '__render_with_namespace__'):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
88 ob = call_with_ns(ob.__render_with_namespace__, ns)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
89 else:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
90 base = ob
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
91 if callable(base):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
92 try:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
93 if getattr(base, 'isDocTemp', 0):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
94 ob = call_with_ns(ob, ns, 2)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
95 else:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
96 ob = ob()
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
97 except AttributeError, n:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
98 if str(n) != '__call__':
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
99 raise
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
100 return ob
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
101
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
102 class SubPathExpr:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
103 def __init__(self, path):
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
104 self._path = path = path.strip().split('/')
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
105 self._base = base = path.pop(0)
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
106 if base and not _valid_name(base):
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
107 raise CompilerError, 'Invalid variable name "%s"' % base
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
108 # Parse path
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
109 self._dp = dp = []
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
110 for i in range(len(path)):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
111 e = path[i]
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
112 if e[:1] == '?' and _valid_name(e[1:]):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
113 dp.append((i, e[1:]))
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
114 dp.reverse()
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
115
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
116 def _eval(self, econtext,
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
117 list=list, isinstance=isinstance, StringType=type('')):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
118 vars = econtext.vars
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
119 path = self._path
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
120 if self._dp:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
121 path = list(path) # Copy!
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
122 for i, varname in self._dp:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
123 val = vars[varname]
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
124 if isinstance(val, StringType):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
125 path[i] = val
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
126 else:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
127 # If the value isn't a string, assume it's a sequence
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
128 # of path names.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
129 path[i:i+1] = list(val)
1065
0f9aa62917bd much nicer error messages when there's a templating error
Richard Jones <richard@users.sourceforge.net>
parents: 1049
diff changeset
130 base = self._base
1136
7e193bbda38e added generic item editing
Richard Jones <richard@users.sourceforge.net>
parents: 1101
diff changeset
131 __traceback_info__ = 'path expression "%s"'%('/'.join(self._path))
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
132 if base == 'CONTEXTS' or not base:
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
133 ob = econtext.contexts
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
134 else:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
135 ob = vars[base]
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
136 if isinstance(ob, DeferWrapper):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
137 ob = ob()
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
138 if path:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
139 ob = restrictedTraverse(ob, path, getSecurityManager())
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
140 return ob
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
141
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
142 class PathExpr:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
143 def __init__(self, name, expr, engine):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
144 self._s = expr
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
145 self._name = name
1233
69bf0d381fd7 Zope Collector fixes.
Richard Jones <richard@users.sourceforge.net>
parents: 1181
diff changeset
146 self._hybrid = 0
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
147 paths = expr.split('|')
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
148 self._subexprs = []
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
149 add = self._subexprs.append
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
150 for i in range(len(paths)):
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
151 path = paths[i].lstrip()
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
152 if _parse_expr(path):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
153 # This part is the start of another expression type,
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
154 # so glue it back together and compile it.
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
155 add(engine.compile(('|'.join(paths[i:]).lstrip())))
1233
69bf0d381fd7 Zope Collector fixes.
Richard Jones <richard@users.sourceforge.net>
parents: 1181
diff changeset
156 self._hybrid = 1
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
157 break
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
158 add(SubPathExpr(path)._eval)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
159
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
160 def _exists(self, econtext):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
161 for expr in self._subexprs:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
162 try:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
163 expr(econtext)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
164 except Undefs:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
165 pass
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
166 else:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
167 return 1
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
168 return 0
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
169
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
170 def _eval(self, econtext,
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
171 isinstance=isinstance, StringType=type(''), render=render):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
172 for expr in self._subexprs[:-1]:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
173 # Try all but the last subexpression, skipping undefined ones.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
174 try:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
175 ob = expr(econtext)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
176 except Undefs:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
177 pass
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
178 else:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
179 break
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
180 else:
1233
69bf0d381fd7 Zope Collector fixes.
Richard Jones <richard@users.sourceforge.net>
parents: 1181
diff changeset
181 # On the last subexpression allow exceptions through, and
69bf0d381fd7 Zope Collector fixes.
Richard Jones <richard@users.sourceforge.net>
parents: 1181
diff changeset
182 # don't autocall if the expression was not a subpath.
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
183 ob = self._subexprs[-1](econtext)
1233
69bf0d381fd7 Zope Collector fixes.
Richard Jones <richard@users.sourceforge.net>
parents: 1181
diff changeset
184 if self._hybrid:
69bf0d381fd7 Zope Collector fixes.
Richard Jones <richard@users.sourceforge.net>
parents: 1181
diff changeset
185 return ob
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
186
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
187 if self._name == 'nocall' or isinstance(ob, StringType):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
188 return ob
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
189 # Return the rendered object
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
190 return render(ob, econtext.vars)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
191
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
192 def __call__(self, econtext):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
193 if self._name == 'exists':
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
194 return self._exists(econtext)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
195 return self._eval(econtext)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
196
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
197 def __str__(self):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
198 return '%s expression %s' % (self._name, `self._s`)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
199
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
200 def __repr__(self):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
201 return '%s:%s' % (self._name, `self._s`)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
202
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
203
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
204 _interp = re.compile(r'\$(%(n)s)|\${(%(n)s(?:/[^}]*)*)}' % {'n': NAME_RE})
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
205
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
206 class StringExpr:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
207 def __init__(self, name, expr, engine):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
208 self._s = expr
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
209 if '%' in expr:
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
210 expr = expr.replace('%', '%%')
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
211 self._vars = vars = []
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
212 if '$' in expr:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
213 parts = []
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
214 for exp in expr.split('$$'):
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
215 if parts: parts.append('$')
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
216 m = _interp.search(exp)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
217 while m is not None:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
218 parts.append(exp[:m.start()])
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
219 parts.append('%s')
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
220 vars.append(PathExpr('path', m.group(1) or m.group(2),
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
221 engine))
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
222 exp = exp[m.end():]
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
223 m = _interp.search(exp)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
224 if '$' in exp:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
225 raise CompilerError, (
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
226 '$ must be doubled or followed by a simple path')
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
227 parts.append(exp)
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
228 expr = ''.join(parts)
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
229 self._expr = expr
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
230
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
231 def __call__(self, econtext):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
232 vvals = []
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
233 for var in self._vars:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
234 v = var(econtext)
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
235 # I hope this isn't in use anymore.
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
236 ## if isinstance(v, Exception):
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
237 ## raise v
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
238 vvals.append(v)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
239 return self._expr % tuple(vvals)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
240
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
241 def __str__(self):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
242 return 'string expression %s' % `self._s`
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
243
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
244 def __repr__(self):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
245 return 'string:%s' % `self._s`
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
246
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
247 class NotExpr:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
248 def __init__(self, name, expr, compiler):
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
249 self._s = expr = expr.lstrip()
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
250 self._c = compiler.compile(expr)
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
251
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
252 def __call__(self, econtext):
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
253 # We use the (not x) and 1 or 0 formulation to avoid changing
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
254 # the representation of the result in Python 2.3, where the
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
255 # result of "not" becomes an instance of bool.
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
256 return (not econtext.evaluateBoolean(self._c)) and 1 or 0
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
257
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
258 def __repr__(self):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
259 return 'not:%s' % `self._s`
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
260
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
261 class DeferWrapper:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
262 def __init__(self, expr, econtext):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
263 self._expr = expr
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
264 self._econtext = econtext
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
265
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
266 def __str__(self):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
267 return str(self())
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
268
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
269 def __call__(self):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
270 return self._expr(self._econtext)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
271
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
272 class DeferExpr:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
273 def __init__(self, name, expr, compiler):
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
274 self._s = expr = expr.lstrip()
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
275 self._c = compiler.compile(expr)
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
276
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
277 def __call__(self, econtext):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
278 return DeferWrapper(self._c, econtext)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
279
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
280 def __repr__(self):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
281 return 'defer:%s' % `self._s`
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
282
2351
97fae0466d97 more ZPT porting tweaks
Richard Jones <richard@users.sourceforge.net>
parents: 2349
diff changeset
283 class TraversalError:
97fae0466d97 more ZPT porting tweaks
Richard Jones <richard@users.sourceforge.net>
parents: 2349
diff changeset
284 def __init__(self, path, name):
97fae0466d97 more ZPT porting tweaks
Richard Jones <richard@users.sourceforge.net>
parents: 2349
diff changeset
285 self.path = path
97fae0466d97 more ZPT porting tweaks
Richard Jones <richard@users.sourceforge.net>
parents: 2349
diff changeset
286 self.name = name
97fae0466d97 more ZPT porting tweaks
Richard Jones <richard@users.sourceforge.net>
parents: 2349
diff changeset
287
97fae0466d97 more ZPT porting tweaks
Richard Jones <richard@users.sourceforge.net>
parents: 2349
diff changeset
288
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
289
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
290 def restrictedTraverse(object, path, securityManager,
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
291 get=getattr, has=hasattr, N=None, M=[],
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
292 TupleType=type(()) ):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
293
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
294 REQUEST = {'path': path}
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
295 REQUEST['TraversalRequestNameStack'] = path = path[:] # Copy!
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
296 path.reverse()
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
297 validate = securityManager.validate
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
298 __traceback_info__ = REQUEST
2351
97fae0466d97 more ZPT porting tweaks
Richard Jones <richard@users.sourceforge.net>
parents: 2349
diff changeset
299 done = []
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
300 while path:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
301 name = path.pop()
2351
97fae0466d97 more ZPT porting tweaks
Richard Jones <richard@users.sourceforge.net>
parents: 2349
diff changeset
302 __traceback_info__ = TraversalError(done, name)
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
303
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
304 if isinstance(name, TupleType):
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
305 object = object(*name)
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
306 continue
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
307
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
308 if not name:
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
309 # Skip directly to item access
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
310 o = object[name]
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
311 # Check access to the item.
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
312 if not validate(object, object, name, o):
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
313 raise Unauthorized, name
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
314 object = o
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
315 continue
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
316
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
317 # Try an attribute.
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
318 o = guarded_getattr(object, name, M)
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
319 if o is M:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
320 # Try an item.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
321 try:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
322 # XXX maybe in Python 2.2 we can just check whether
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
323 # the object has the attribute "__getitem__"
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
324 # instead of blindly catching exceptions.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
325 o = object[name]
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
326 except AttributeError, exc:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
327 if str(exc).find('__getitem__') >= 0:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
328 # The object does not support the item interface.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
329 # Try to re-raise the original attribute error.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
330 # XXX I think this only happens with
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
331 # ExtensionClass instances.
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
332 guarded_getattr(object, name)
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
333 raise
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
334 except TypeError, exc:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
335 if str(exc).find('unsubscriptable') >= 0:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
336 # The object does not support the item interface.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
337 # Try to re-raise the original attribute error.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
338 # XXX This is sooooo ugly.
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
339 guarded_getattr(object, name)
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
340 raise
2351
97fae0466d97 more ZPT porting tweaks
Richard Jones <richard@users.sourceforge.net>
parents: 2349
diff changeset
341 done.append((name, o))
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
342 object = o
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
343
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
344 return object

Roundup Issue Tracker: http://roundup-tracker.org/