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
505a61ac
Commit
505a61ac
authored
Sep 02, 1997
by
Jim Fulton
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implemented new authorization model.
No longer use Realm module.
parent
9568a570
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
339 additions
and
559 deletions
+339
-559
lib/python/ZPublisher/Publish.py
lib/python/ZPublisher/Publish.py
+339
-559
No files found.
lib/python/ZPublisher/Publish.py
View file @
505a61ac
...
...
@@ -102,9 +102,9 @@ Published objects
concatinating the sub-object name with the special attribute
name. For example, let 'foo.bar' be a dictionary, and foo.bar.spam
an item in the dictionary. When attempting to obtain the special
attribute '__r
ealm
__', the object publisher will first try to
evaluate 'foo.bar.spam.__r
ealm
__', and then try to evaluate:
'foo.bar["spam"+"__r
ealm
__"]'.
attribute '__r
oles
__', the object publisher will first try to
evaluate 'foo.bar.spam.__r
oles
__', and then try to evaluate:
'foo.bar["spam"+"__r
oles
__"]'.
Access Control
...
...
@@ -117,11 +117,7 @@ Access Control
a collection of named groups. Each group must be a dictionary that
use names as keys (i.e. sets of names). The values in these
dictionaries may contain passwords for authenticating each of the
names. Alternatively, passwords may be provided in separate "realm"
objects. If no realm is provided, then basic authentication will be
used and the object publisher will attempt to authenticate the
access to the object using one of the supplied name and password
pairs. The basic authentication realm name used is
names. The basic authentication realm name used is
'module_name.server_name', where 'module_name' is the name of the
module containing the published objects, and server_name is the name
of the web server.
...
...
@@ -154,41 +150,23 @@ Access Control
set to None, in which case the object will be public, even if
containing objects are not.
R
ealm
s
R
ole
s
Realms provide a mechanism for separating authentication and
authorization.
Meaning of __roles__:
An object may have an attribute '__realm__', which should be
either a realm object, or a mapping object mapping names to
passwords.
If a mapping object is provided, then it will be used for
basic authentication using a realm name of
"module_name.server_name", where "module_name" is the name of
the module containing the published objects, and server_name
is the name of the web server.
If a realm object is used, then it will use an application
supplied realm name and password mapping object, and may use
other than basic authentication. If a realm is provided that
does not include it's own name to password mapping, then the
name to password mappings contained in an object's
'__allow_groups__' attribute will be used.
An object may "acquir" a realm from one of it's parent
objects in the URI path to the object, including the module
used to publish the object.
None -- Public
False and not None -- private
A sequence of role names.
Fixed-attribute objects
For some interesting objects, such as functions, and methods,
it may not be possible for applications to set
'__
allow_groups__' or '__realm
__' attributes. In these cases, the
object's parent object may contain attribute
s
'object_name__
allow_groups__' or 'object_name__realm
__', which
will be used as surrogates for the object's
'__allow_groups__'
and '__realm__' attributes
.
'__
roles
__' attributes. In these cases, the
object's parent object may contain attribute
'object_name__
roles
__', which
will be used as surrogates for the object's
'__role__' attribute
.
Determining the authenticated user name
...
...
@@ -479,18 +457,13 @@ Examples
# web_objects={'greet':hi, 'addxy':add}
# Here's out "password" database.
from Realm import Realm
__realm__=Realm('spam.digicool.com',
{'jim':'spam', 'paul':'eggs'})
Publishing a module using CGI
o Do not copy the module to be published to the cgi-bin
directory.
o Copy the files: cgi_module_publisher.pyc and CGIResponse.pyc,
Realm.pyc,
and newcgi.pyc, to the directory containing the
and newcgi.pyc, to the directory containing the
module to be published, or to a directory in the standard
(compiled in) Python search path.
...
...
@@ -504,7 +477,7 @@ Publishing a module using CGI
Publishing a module using Fast CGI
o Copy the files: cgi_module_publisher.pyc and CGIResponse.pyc,
Realm.pyc,
and newcgi.pyc, to the directory containing the
and newcgi.pyc, to the directory containing the
module to be published, or to a directory in the standard
(compiled in) Python search path.
...
...
@@ -518,7 +491,7 @@ Publishing a module using Fast CGI
o Configure the Fast CGI-enabled web server to execute this
file.
$Id: Publish.py,v 1.4
6 1997/07/28 22:01:58
jim Exp $"""
$Id: Publish.py,v 1.4
7 1997/09/02 21:18:53
jim Exp $"""
#'
# Copyright
#
...
...
@@ -572,7 +545,8 @@ $Id: Publish.py,v 1.46 1997/07/28 22:01:58 jim Exp $"""
#
# See end of file for change log.
#
__version__
=
'$Revision: 1.46 $'
[
11
:
-
2
]
##########################################################################
__version__
=
'$Revision: 1.47 $'
[
11
:
-
2
]
def
main
():
...
...
@@ -582,12 +556,13 @@ def main():
if
__name__
==
"__main__"
:
main
()
import
sys
,
os
,
string
,
types
,
cgi
,
regex
,
regsub
import
sys
,
os
,
string
,
types
,
cgi
,
regex
,
regsub
,
base64
from
string
import
*
from
CGIResponse
import
Response
from
Realm
import
Realm
,
allow_group_composition
from
urllib
import
quote
from
cgi
import
FieldStorage
,
MiniFieldStorage
from
string
import
upper
,
lower
,
strip
UNSPECIFIED_ROLES
=
''
try
:
from
ExtensionClass
import
Base
...
...
@@ -606,6 +581,93 @@ except:
class
ModulePublisher
:
def
__init__
(
self
,
stdin
=
sys
.
stdin
,
stdout
=
sys
.
stdout
,
stderr
=
sys
.
stderr
,
environ
=
os
.
environ
):
self
.
environ
=
environ
fp
=
None
try
:
if
environ
[
'REQUEST_METHOD'
]
!=
'GET'
:
fp
=
stdin
except
:
pass
try
:
self
.
HTTP_AUTHORIZATION
=
environ
[
'HTTP_AUTHORIZATION'
]
del
environ
[
'HTTP_AUTHORIZATION'
]
except
:
try
:
self
.
HTTP_AUTHORIZATION
=
environ
[
'HTTP_CGI_AUTHORIZATION'
]
del
environ
[
'HTTP_CGI_AUTHORIZATION'
]
except
:
pass
form
=
{}
if
environ
.
has_key
(
'HTTP_COOKIE'
):
parse_cookie
(
self
.
environ
[
'HTTP_COOKIE'
],
form
)
fs
=
FieldStorage
(
fp
=
fp
,
environ
=
environ
,
keep_blank_values
=
1
)
try
:
fslist
=
fs
.
list
except
:
fslist
=
None
if
fslist
is
None
:
form
=
{
'BODY'
:
fs
}
else
:
tuple_items
=
{}
type_re
=
regex
.
compile
(
'
\
(:
\
|%3[aA]
\
)
\
([a-zA-Z][a-zA-Z0-9_]+
\
)
'
)
type_search=type_re.search
lt=type([])
CGI_name=isCGI_NAME
for item in fslist:
key=item.name
try:
if (item.file and
(item.filename is not None or
'
content
-
type
' in map(lower,
item.headers.keys()))):
item=FileUpload(item)
else:
item=item.value
except: pass
seqf=None
l=type_search(key)
while l >= 0:
type_name=type_re.group(2)
key=key[:l]+key[l+len(type_re.group(0)):]
if type_name == '
list
':
seqf=list
elif type_name == '
tuple
':
seqf=tuple
tuple_items[key]=1
else:
item=type_converters[type_name](item)
l=type_search(key)
# Filter out special names from form:
if CGI_name(key) or key[:5]=='
HTTP_
': continue
try:
found=form[key]
if type(found) is lt: found.append(item)
else:
found=[found,item]
form[key]=found
except:
if seqf: item=[item]
form[key]=item
for key in tuple_items.keys(): form[key]=tuple(form[key])
request=self.request=Request(environ,form,stdin)
self.response=Response(stdout=stdout, stderr=stderr)
self.stdin=stdin
self.stdout=stdout
self.stderr=stderr
self.base=request.base
self.script=request.script
def html(self,title,body):
return ("<html>
\
n
"
"<head>
\
n
<title>%s</title>
\
n
</head>
\
n
"
...
...
@@ -633,44 +695,20 @@ class ModulePublisher:
"<!--%s-->"
% (name,self.request))
def unauthorized(self, realm):
self.response['
WWW
-
authenticate
']='
basic
realm
=
"%s"' % realm
raise '
Unauthorized
', (
"""<strong>You are not authorized to access this resource.
</strong>
"""
)
def forbiddenError(self,object=None):
raise '
NotFound
',self.html(
"Resource not found",
"Sorry, the requested document does not exist.
\
n
"
"<!--%s-->" % object)
def
env
(
self
,
key
):
try
:
return
self
.
environ
[
key
]
except
:
if
key
==
'HTTP_AUTHORIZATION'
:
try
:
return
self
.
environ
[
'HTTP_CGI_AUTHORIZATION'
]
except
:
return
''
return
''
def
validate
(
self
,
groups
,
realm
=
None
):
sys
.
stdout
=
self
.
stdout
if
not
realm
:
try
:
realm
=
self
.
realm
except
:
realm
=
Realm
(
"%s.%s"
%
(
self
.
module_name
,
self
.
request
.
SERVER_NAME
))
self
.
realm
=
realm
try
:
user
=
realm
.
validate
(
self
.
env
(
"HTTP_AUTHORIZATION"
),
groups
)
self
.
request
[
'AUTHENTICATED_USER'
]
=
user
get_transaction
().
note
(
"%s
\
t
%s"
%
(
user
,
self
.
env
(
'PATH_INFO'
)))
return
user
except
realm
.
Unauthorized
,
v
:
auth
,
v
=
v
self
.
response
[
'WWW-authenticate'
]
=
auth
raise
'Unauthorized'
,
v
except
:
self
.
forbiddenError
()
def get_request_data(self,request_params):
try: request_params=request_params()
except: pass
...
...
@@ -680,7 +718,7 @@ class ModulePublisher:
def get_module_info(self, server_name, module_name, module):
realm
_name
=
"%s.%s"
%
(
module_name
,
server_name
)
realm="%s.%s" % (module_name,server_name)
try: bobo_before=module.__bobo_before__
except: bobo_before=None
...
...
@@ -688,14 +726,6 @@ class ModulePublisher:
try: bobo_after=module.__bobo_after__
except: bobo_after=None
# Try to get realm from module
try
:
realm
=
module
.
__realm__
if
type
(
realm
)
is
type
(
''
):
realm_name
=
realm
realm
=
None
except
:
realm
=
None
# Get request data from outermost environment:
try: request_params=module.__request_data__
except: request_params=None
...
...
@@ -708,14 +738,14 @@ class ModulePublisher:
except: groups=None
web_objects=None
find_object
=
old_find_object
try:
object=module.bobo_application
find_object
=
new_find_object
try:
groups=object.__allow_groups__
inherited_groups.append(groups)
except: groups=None
try: roles=object.__roles__
except: roles=UNSPECIFIED_ROLES
except:
try:
web_objects=module.web_objects
...
...
@@ -728,9 +758,9 @@ class ModulePublisher:
if web_objects is not None: doc='
'
else: doc=None
return
(
bobo_before
,
bobo_after
,
re
alm
,
realm_name
,
re
quest_params
,
inherited_groups
,
groups
,
object
,
doc
,
published
,
find_object
)
return (bobo_before, bobo_after, request_params,
inherited_groups, groups,
roles,
object, doc, published,
realm
)
def publish(self, module_name, after_list, published='
web_objects
',
...
...
@@ -739,7 +769,7 @@ class ModulePublisher:
# First check for "cancel" redirect:
cancel=''
try:
if
string
.
lower
(
self
.
request
[
'SUBMIT'
])
==
'cancel'
:
if lower(self.request['
SUBMIT
'])=='
cancel
':
cancel=self.request['
CANCEL_ACTION
']
except: pass
if cancel:
...
...
@@ -747,13 +777,14 @@ class ModulePublisher:
if module_name[-4:]=='
.
cgi
': module_name=module_name[:-4]
self.module_name=module_name
request=self.request
response=self.response
server_name
=
self
.
request
.
SERVER_NAME
server_name=request.SERVER_NAME
try:
(
bobo_before
,
bobo_after
,
re
alm
,
realm_name
,
re
quest_params
,
inherited_groups
,
groups
,
object
,
doc
,
published
,
find_object
(bobo_before, bobo_after, request_params,
inherited_groups, groups,
roles,
object, doc, published,
realm
) = info = module_dicts[server_name, module_name]
except:
info={}
...
...
@@ -762,16 +793,13 @@ class ModulePublisher:
info=self.get_module_info(server_name, module_name,
info[module_name])
module_dicts[server_name, module_name]=info
(
bobo_before
,
bobo_after
,
re
alm
,
realm_name
,
re
quest_params
,
inherited_groups
,
groups
,
object
,
doc
,
published
,
find_object
(bobo_before, bobo_after, request_params,
inherited_groups, groups,
roles,
object, doc, published,
realm
) = info
except: raise ImportError, (
sys.exc_type, sys.exc_value, sys.exc_traceback)
if
find_object
is
old_find_object
:
response
.
setBase
(
self
.
base
,
''
)
after_list[0]=bobo_after
if bobo_before is not None: bobo_before();
...
...
@@ -779,13 +807,13 @@ class ModulePublisher:
if request_params: self.get_request_data(request_params)
# Get a nice clean path list:
path
=
(
string
.
strip
(
self
.
env
(
'PATH_INFO'
))
)
path=
strip(request['
PATH_INFO
']
)
if path[:1]=='
/
': path=path[1:]
if path[-1:]=='
/
': path=path[:-1]
path
=
s
tring
.
splitfields
(
path
,
'/'
)
path=s
plit
(path,'
/
')
while path and not path[0]: path = path[1:]
method
=
upper
(
self
.
request
[
'REQUEST_METHOD'
])
method=upper(request['
REQUEST_METHOD
'])
if method=='
GET
' or method=='
POST
': method='
index_html
'
# Get default object if no path was specified:
...
...
@@ -803,56 +831,124 @@ class ModulePublisher:
if not path: path = ['
help
']
# Traverse the URL to find the object:
(
object
,
parents
,
URL
,
groups
,
realm
,
inherited_groups
,
realm_name
,
roles
)
=
find_object
(
self
,
info
,
path
,
method
)
URL=self.script
parents=[]
# Do authorization checks
if
groups
is
not
None
:
try: # Try to bind the top-level object to the request
object=object.__of__(RequestContainer(REQUEST=self.request))
except: pass
# Do composition, if we've got a named group:
try
:
try
:
groups
.
keys
# See if we've got a mapping
except
:
groups
=
groups
()
groups
.
keys
g
=
{
None
:
None
}
for
i
in
inherited_groups
[:
-
1
]:
g
=
allow_group_composition
(
g
,
i
)
if
roles
:
groups
=
allow_group_composition
(
g
,
inherited_groups
[
-
1
])
if
type
(
roles
)
is
type
(
''
):
groups
=
(
g
[
roles
],)
else
:
groups
=
map
(
lambda
role
:
g
[
role
],
roles
)
while path:
entry_name,path=path[0], path[1:]
URL="%s/%s" % (URL,quote(entry_name))
got=0
if entry_name:
if entry_name[:1]=='
_
': self.forbiddenError(entry_name)
try: traverse=object.__bobo_traverse__
except: traverse=None
if traverse is not None:
request['
URL
']=URL
subobject=traverse(request,entry_name)
else:
groups
=
allow_group_composition
(
groups
,
g
)
try:
subobject=getattr(object,entry_name)
except AttributeError:
try:
subobject=object[entry_name]
got=1
except:
# groups was not a mapping (or a function returning a
# mapping), so no point in composing.
pass
if
groups
is
not
None
:
self.notFoundError("%s" % (entry_name))
if
not
groups
:
self
.
forbiddenError
()
try:
if
realm
.
name
is
None
:
realm
.
name
=
realm_name
try: doc=subobject.__doc__
except: doc=getattr(subobject, entry_name+'
__doc__
')
if not doc: raise AttributeError, entry_name
except: self.notFoundError("%s" % (entry_name))
try: roles=subobject.__roles__
except:
try
:
len
(
realm
)
realm
=
Realm
(
realm_name
,
realm
)
if not got:
try: roles=getattr(object,entry_name+'
__roles__
')
except:
if (entry_name=='
manage
' or
entry_name[:7]=='
manage_
'):
roles='
manage
',
# Promote subobject to object
parents.append(object)
object=subobject
# Check for method:
if (not path and hasattr(object,method) and
entry_name != method):
response.setBase(URL+'
/
','')
path=[method]
if entry_name != method and method != '
index_html
':
self.notFoundError(method)
parents.append(object)
parents.reverse()
# Do authorization checks
user=None
if roles is not None:
last_parent_index=len(parents)
for i in range(last_parent_index):
try: groups=parents[i].__allow_groups__
except: groups=-1
if groups == -1: continue
try: v=groups.validate
except: v=old_validation
if v is old_validation and roles is UNSPECIFIED_ROLES:
# No roles, so if we have a named group, get roles from
# group keys
try: roles=groups.keys()
except AttributeError:
try: groups=groups()
except: pass
try: roles=groups.keys()
except: pass
self
.
validate
(
groups
,
realm
)
if groups is None: break # Public group
try: auth=self.HTTP_AUTHORIZATION
except: self.unauthorized(realm)
if v is old_validation:
user=old_validation(groups, auth, roles)
elif roles is UNSPECIFIED_ROLES: user=v(request, auth)
else: user=v(request, auth, roles)
while user is None and i < last_parent_index:
try: groups=parents[i].__allow_groups__
except: groups=-1
i=i+1
if groups == -1: continue
try: v=groups.validate
except: v=old_validation
if v is old_validation:
user=old_validation(groups, auth, roles)
elif roles is UNSPECIFIED_ROLES: user=v(request, auth)
else: user=v(request, auth, roles)
if user is None: self.unauthorized(realm)
break
if user is not None: request['
AUTHENTICATED_USER
']=user
del parents[0]
# Attempt to start a transaction:
try: transaction=get_transaction()
except: transaction=None
if transaction is not None:
info
=
"
\
t
"
+
self
.
env
(
'PATH_INFO'
)
info="
\
t
" +
request['
PATH_INFO
']
try:
u
=
self
.
request
[
'AUTHENTICATED_USER'
]
try
:
u
=
"%s.%s"
%
(
u
,
self
.
request
[
'session__domain'
])
except
:
pass
u=request['
AUTHENTICATED_USER
']
try: info=u+info
except: pass
except: pass
...
...
@@ -885,26 +981,24 @@ class ModulePublisher:
except:
return response.setBody(object)
query
=
self
.
request
query
[
'RESPONSE'
]
=
response
query
[
'URL'
]
=
URL
query
[
'PARENT_URL'
]
=
URL
[:
string
.
rfind
(
URL
,
'/'
)]
request['
RESPONSE
']=response
request['
URL
']=URL
request['
PARENT_URL
']=URL[:rfind(URL,'
/
')]
if parents:
parents
.
reverse
()
selfarg=parents[0]
for i in range(len(parents)):
try:
p=parents[i].aq_self
parents[i]=p
except: pass
query
[
'PARENTS'
]
=
parents
request
['
PARENTS
']=parents
args=[]
nrequired=len(argument_names) - (len(defaults or []))
for name_index in range(len(argument_names)):
argument_name=argument_names[name_index]
try:
v
=
query
[
argument_name
]
v=
request
[argument_name]
args.append(v)
except (KeyError,AttributeError,IndexError):
if argument_name=='
self
': args.append(selfarg)
...
...
@@ -944,255 +1038,6 @@ def str_field(v):
except: pass
return v
def
attr_meta_data
(
object
,
subobject
,
entry_name
,
inherited_groups
,
groups
,
realm
,
realm_name
,
default_realm_name
,
roles
):
try
:
groups
=
subobject
.
__allow_groups__
inherited_groups
.
append
(
groups
)
except
:
try
:
groups
=
getattr
(
object
,
entry_name
+
'__allow_groups__'
)
inherited_groups
.
append
(
groups
)
except
:
pass
try
:
roles
=
subobject
.
__roles__
except
:
try
:
roles
=
getattr
(
object
,
entry_name
+
'__roles__'
)
except
:
pass
try
:
doc
=
subobject
.
__doc__
except
:
try
:
doc
=
getattr
(
object
,
entry_name
+
'__doc__'
)
except
:
doc
=
None
try
:
realm
=
subobject
.
__realm__
realm_name
=
default_realm_name
except
:
try
:
realm
=
getattr
(
object
,
entry_name
+
'__realm__'
)
realm_name
=
default_realm_name
except
:
pass
return
inherited_groups
,
groups
,
realm
,
realm_name
,
doc
,
roles
def
item_meta_data
(
subobject
,
inherited_groups
,
groups
,
realm
,
realm_name
,
default_realm_name
,
roles
):
try
:
groups
=
subobject
.
__allow_groups__
inherited_groups
.
append
(
groups
)
except
:
pass
try
:
doc
=
subobject
.
__doc__
except
:
doc
=
None
try
:
roles
=
subobject
.
__roles__
except
:
roles
=
None
try
:
realm
=
subobject
.
__realm__
realm_name
=
default_realm_name
except
:
pass
return
inherited_groups
,
groups
,
realm
,
realm_name
,
doc
,
roles
def
new_find_object
(
self
,
info
,
path
,
method
):
(
bobo_before
,
bobo_after
,
realm
,
realm_name
,
request_params
,
inherited_groups
,
groups
,
object
,
doc
,
published
,
ignore
)
=
info
default_realm_name
=
realm_name
inherited_groups
=
inherited_groups
[:]
request
=
self
.
request
URL
=
self
.
script
parents
=
[]
try
:
# Try to bind the top-level object to the request
object
=
object
.
__of__
(
RequestContainer
(
REQUEST
=
self
.
request
,
RESPONSE
=
self
.
response
))
except
:
pass
roles
=
()
while
path
:
entry_name
,
path
=
path
[
0
],
path
[
1
:]
URL
=
"%s/%s"
%
(
URL
,
quote
(
entry_name
))
default_realm_name
=
"%s.%s"
%
(
entry_name
,
default_realm_name
)
if
entry_name
:
try
:
traverse
=
object
.
__bobo_traverse__
except
:
traverse
=
None
if
traverse
is
not
None
:
request
[
'URL'
]
=
URL
subobject
=
traverse
(
request
,
entry_name
)
(
inherited_groups
,
groups
,
realm
,
realm_name
,
doc
,
roles
)
=
attr_meta_data
(
object
,
subobject
,
entry_name
,
inherited_groups
,
groups
,
realm
,
realm_name
,
default_realm_name
,
roles
)
else
:
try
:
subobject
=
getattr
(
object
,
entry_name
)
(
inherited_groups
,
groups
,
realm
,
realm_name
,
doc
,
roles
)
=
attr_meta_data
(
object
,
subobject
,
entry_name
,
inherited_groups
,
groups
,
realm
,
realm_name
,
default_realm_name
,
roles
)
except
AttributeError
:
try
:
subobject
=
object
[
entry_name
]
(
inherited_groups
,
groups
,
realm
,
realm_name
,
doc
,
roles
)
=
item_meta_data
(
subobject
,
inherited_groups
,
groups
,
realm
,
realm_name
,
default_realm_name
,
roles
)
except
(
TypeError
,
AttributeError
,
KeyError
),
mess
:
if
not
path
and
entry_name
==
'help'
and
doc
:
object
=
doc
entry_name
,
subobject
=
(
'__doc__'
,
self
.
html
(
'Documentation for '
+
((
self
.
env
(
'PATH_INFO'
)
or
(
'/'
+
self
.
module_name
))[
1
:]),
'<pre>
\
n
%s
\
n
</pre>'
%
doc
)
)
else
:
self
.
notFoundError
(
"%s: %s"
%
(
entry_name
,
mess
))
# Perform simple checks
if
(
entry_name
!=
'__doc__'
and
(
not
doc
or
entry_name
[
0
]
==
'_'
)
):
if
not
doc
:
entry_name
=
str
(
subobject
)
self
.
forbiddenError
(
entry_name
)
# Promote subobject to object
parents
.
append
(
object
)
object
=
subobject
# Check for method:
if
(
not
path
and
hasattr
(
object
,
method
)
and
entry_name
!=
method
):
path
=
[
method
]
if
entry_name
!=
method
and
method
!=
'index_html'
:
self
.
notFoundError
(
method
)
return
(
object
,
parents
,
URL
,
groups
,
realm
,
inherited_groups
,
realm_name
,
roles
)
def
old_find_object
(
self
,
info
,
path
,
method
):
(
bobo_before
,
bobo_after
,
realm
,
realm_name
,
request_params
,
inherited_groups
,
groups
,
object
,
doc
,
published
,
ignore
)
=
info
default_realm_name
=
realm_name
inherited_groups
=
inherited_groups
[:]
URL
=
self
.
script
parents
=
[]
# sad_pathetic_persistence_hack:
try
:
setstate
=
object
.
__dict__
[
'_p_setstate'
]
except
:
setstate
=
None
if
setstate
:
setstate
(
object
)
topobject
=
object
while
path
:
if
object
is
not
topobject
and
topobject
is
not
None
:
topobject
=
None
try
:
# Try to bind the top-level object to the request
object
=
object
.
__of__
(
RequestContainer
(
REQUEST
=
self
.
request
,
RESPONSE
=
self
.
response
))
except
:
pass
entry_name
,
path
=
path
[
0
],
path
[
1
:]
URL
=
"%s/%s"
%
(
URL
,
quote
(
entry_name
))
default_realm_name
=
"%s.%s"
%
(
entry_name
,
default_realm_name
)
if
entry_name
:
try
:
subobject
=
getattr
(
object
,
entry_name
)
# sad_pathetic_persistence_hack:
try
:
setstate
=
subobject
.
__dict__
[
'_p_setstate'
]
except
:
setstate
=
None
if
setstate
:
setstate
(
subobject
)
(
inherited_groups
,
groups
,
realm
,
realm_name
,
doc
)
=
attr_meta_data
(
object
,
subobject
,
entry_name
,
inherited_groups
,
groups
,
realm
,
realm_name
,
default_realm_name
)
try
:
request_params
=
getattr
(
subobject
,
'__request_data__'
)
self
.
get_request_data
(
request_params
)
except
:
pass
except
AttributeError
:
try
:
subobject
=
object
[
entry_name
]
# sad_pathetic_persistence_hack:
try
:
setstate
=
subobject
.
__dict__
[
'_p_setstate'
]
except
:
setstate
=
None
if
setstate
:
setstate
(
subobject
)
(
inherited_groups
,
groups
,
realm
,
realm_name
,
doc
)
=
item_meta_data
(
subobject
,
inherited_groups
,
groups
,
realm
,
realm_name
,
default_realm_name
)
try
:
request_params
=
getattr
(
subobject
,
'__request_data__'
)
self
.
get_request_data
(
request_params
)
except
:
pass
except
(
TypeError
,
AttributeError
,
KeyError
),
mess
:
if
not
path
and
entry_name
==
'help'
and
doc
:
object
=
doc
entry_name
,
subobject
=
(
'__doc__'
,
self
.
html
(
'Documentation for '
+
((
self
.
env
(
'PATH_INFO'
)
or
(
'/'
+
self
.
module_name
))[
1
:]),
'<pre>
\
n
%s
\
n
</pre>'
%
doc
)
)
else
:
self
.
notFoundError
(
"%s: %s"
%
(
entry_name
,
mess
))
if
published
:
# Bypass simple checks the first time
published
=
None
else
:
# Perform simple checks
if
(
type
(
subobject
)
==
types
.
ModuleType
or
entry_name
!=
'__doc__'
and
(
not
doc
or
entry_name
[
0
]
==
'_'
)
):
if
not
doc
:
entry_name
=
str
(
subobject
)
self
.
forbiddenError
(
entry_name
)
# Promote subobject to object
parents
.
append
(
object
)
object
=
subobject
# Check for method:
if
(
not
path
and
hasattr
(
object
,
method
)
and
entry_name
!=
method
):
path
=
[
method
]
if
entry_name
!=
method
and
method
!=
'index_html'
:
self
.
notFoundError
(
method
)
return
(
object
,
parents
,
URL
,
groups
,
realm
,
inherited_groups
,
realm_name
,
None
)
class FileUpload:
'''
\
...
...
@@ -1222,23 +1067,6 @@ class FileUpload:
self.filename=aFieldStorage.filename
def
flatten_field
(
v
,
converter
=
None
):
if
type
(
v
)
is
types
.
ListType
:
if
len
(
v
)
>
1
:
return
map
(
flatten_field
,
v
)
v
=
v
[
0
]
try
:
if
v
.
file
and
(
v
.
filename
is
not
None
or
'content-type'
in
map
(
string
.
lower
,
v
.
headers
.
keys
())):
v
=
FileUpload
(
v
)
else
:
v
=
v
.
value
except
:
pass
if
converter
:
v
=
converter
(
v
)
return
v
def field2string(v):
try: v=v.read()
except: v=str(v)
...
...
@@ -1253,28 +1081,28 @@ def field2text(v, nl=regex.compile('\r\n\|\n\r'), sub=regsub.gsub):
def field2required(v):
try: v=v.read()
except: v=str(v)
if
stri
ng
.
stri
p
(
v
):
return
v
if strip(v): return v
raise ValueError, '
No
input
for
required
field
'
def field2int(v):
try: v=v.read()
except: v=str(v)
# we can remove the check for an empty string when we go to python 1.4
if
v
:
return
string
.
atoi
(
v
)
if v: return atoi(v)
raise ValueError, '
Empty
entry
when
integer
expected
'
def field2float(v):
try: v=v.read()
except: v=str(v)
# we can remove the check for an empty string when we go to python 1.4
if
v
:
return
string
.
atof
(
v
)
if v: return atof(v)
raise ValueError, '
Empty
entry
when
floating
-
point
number
expected
'
def field2long(v):
try: v=v.read()
except: v=str(v)
# we can remove the check for an empty string when we go to python 1.4
if
v
:
return
string
.
atol
(
v
)
if v: return atol(v)
raise ValueError, '
Empty
entry
when
integer
expected
'
def field2Regex(v):
...
...
@@ -1290,25 +1118,25 @@ def field2regex(v):
def field2Regexs(v):
try: v=v.read()
except: v=str(v)
v
=
map
(
lambda
v
:
regex
.
compile
(
v
),
s
tring
.
s
plit
(
v
))
v= map(lambda v: regex.compile(v), split(v))
if v: return v
def field2regexs(v):
try: v=v.read()
except: v=str(v)
v
=
map
(
lambda
v
:
regex
.
compile
(
v
,
regex
.
casefold
),
s
tring
.
s
plit
(
v
))
v= map(lambda v: regex.compile(v, regex.casefold), split(v))
if v: return v
def field2tokens(v):
try: v=v.read()
except: v=str(v)
return
s
tring
.
s
plit
(
v
)
return split(v)
def field2lines(v, crlf=regex.compile('
\
r
\
n
\
|
\
n
\
r')):
try: v=v.read()
except: v=str(v)
v=regsub.gsub(crlf,'
\
n
',v)
return
s
tring
.
s
plit
(
v
,
'
\
n
'
)
return split(v,'
\
n
')
def field2date(v):
from DateTime import DateTime
...
...
@@ -1395,34 +1223,26 @@ class Request:
"""
def __init__(self,environ,form,stdin):
try
:
environ
[
'HTTP_AUTHORIZATION'
]
=
\
environ
[
'HTTP_CGI_AUTHORIZATION'
]
except
:
pass
self.environ=environ
self
.
form
=
form
self.
other
=form
self.stdin=stdin
self
.
other
=
{}
def
env
(
key
,
d
=
environ
):
try
:
return
d
[
key
]
except
:
return
''
b
=
script
=
string
.
strip
(
environ
[
'SCRIPT_NAME'
])
b=script=strip(environ['
SCRIPT_NAME
'])
while b and b[-1]=='
/
': b=b[:-1]
p
=
string
.
rfind
(
b
,
'/'
)
p = rfind(b,'
/
')
if p >= 0: b=b[:p+1]
else: b=''
while b and b[0]=='
/
': b=b[1:]
try:
try:
server_url
=
"http://%s"
%
stri
ng
.
stri
p
(
environ
[
'HTTP_HOST'
])
server_url="http://%s" % strip(environ['
HTTP_HOST
'])
except:
server_url
=
stri
ng
.
stri
p
(
environ
[
'SERVER_URL'
])
server_url=strip(environ['
SERVER_URL
'])
if server_url[-1:]=='
/
': server_url=server_url[:-1]
except:
server_port
=
env
(
'SERVER_PORT'
)
server_port=env
iron['
SERVER_PORT
']
server_url=('
http
:
//
'+
stri
ng
.
stri
p
(
environ
[
'SERVER_NAME'
])
+
strip(environ['
SERVER_NAME
']) +
(server_port and '
:
'+server_port)
)
...
...
@@ -1439,23 +1259,20 @@ class Request:
self.other[key]=value
__http_colon
=
regex
.
compile
(
"
\
(:
\
|
\
(%
3
[aA]
\
)
\
)"
)
def __str__(self):
def str(self,name):
dict=getattr(self,name)
return "%s:
\
n
\
t
%s
\
n
\
n
" % (
name,
string
.
joinfields
(
join
(
map(lambda k, d=dict: "%s: %s" % (k, d[k]), dict.keys()),
"
\
n
\
t
"
)
)
return
"%s
\
n
%s
\
n
%s
\
n
%s
"
%
(
str
(
self
,
'other'
),
str
(
self
,
'
form'
),
str
(
self
,
'
environ'
),
return "%s
\
n
%s
\
n
%s" % (
str(self,'
other
'),str(self,'
environ
'),
str(self,'
cookies
'))
__repr__=__str__
...
...
@@ -1466,7 +1283,10 @@ class Request:
return 1
except: return 0
def
__getitem__
(
self
,
key
):
def __getitem__(self,key,
URLmatch=regex.compile('
URL
[
0
-
9
]
$
').match,
BASEmatch=regex.compile('
BASE
[
0
-
9
]
$
').match,
):
"""Get a variable value
Return a value for the required variable name.
...
...
@@ -1480,60 +1300,28 @@ class Request:
try: return other[key]
except: pass
if
self
.
special_names
.
has_key
(
key
)
or
key
[:
5
]
==
'HTTP_'
:
if URLmatch(key) >= 0 and other.has_key('
URL
'):
n=ord(key[3])-ord('
0
')
URL=other['
URL
']
for i in range(0,n):
l=rfind(URL,'
/
')
if l >= 0: URL=URL[:l]
else: raise KeyError, key
other[key]=URL
return URL
if isCGI_NAME(key) or key[:5] == '
HTTP_
':
try: return self.environ[key]
except: return ''
if key=='
REQUEST
': return self
if
key
!=
'cookies'
:
try
:
converter
=
None
try
:
v
=
self
.
form
[
key
]
except
:
# Hm, maybe someone used a form with a name like: name:type
try
:
tf
=
self
.
__dict__
[
'___typed_form'
]
except
:
tf
=
self
.
__dict__
[
'___typed_form'
]
=
{}
form
=
self
.
form
colon
=
self
.
__http_colon
search
=
colon
.
search
group
=
colon
.
group
for
k
in
form
.
keys
():
l
=
search
(
k
)
if
l
>
0
:
tf
[
k
[:
l
]]
=
form
[
k
],
k
[
l
+
len
(
group
(
1
)):]
v
,
t
=
tf
[
key
]
try
:
converter
=
type_converters
[
t
]
except
:
pass
v
=
flatten_field
(
v
,
converter
)
other
[
key
]
=
v
return
v
except
(
KeyError
,
AttributeError
,
IndexError
):
pass
if
not
self
.
__dict__
.
has_key
(
'cookies'
):
if
self
.
environ
.
has_key
(
'HTTP_COOKIE'
):
cookies
=
parse_cookie
(
self
.
environ
[
'HTTP_COOKIE'
])
else
:
cookies
=
{}
self
.
cookies
=
cookies
if
key
==
'cookies'
:
return
self
.
cookies
try
:
r
=
self
.
cookies
[
key
]
other
[
key
]
=
r
return
r
except
:
pass
try
:
if
regex
.
match
(
'BASE[0-9]$'
,
key
)
>=
0
:
if BASEmatch(key) >= 0 and other.has_key('
URL
'):
n=ord(key[4])-ord('
0
')
URL
=
self
[
'URL'
]
URL=other
['
URL
']
baselen=len(self.base)
for i in range(0,n):
baselen
=
string
.
find
(
URL
,
'/'
,
baselen
+
1
)
baselen=
find(URL,'
/
',baselen+1)
if baselen < 0:
baselen=len(URL)
break
...
...
@@ -1541,23 +1329,13 @@ class Request:
if base[-1:]=='
/
': base=base[:-1]
other[key]=base
return base
if
regex
.
match
(
'URL[0-9]$'
,
key
)
>=
0
:
n
=
ord
(
key
[
3
])
-
ord
(
'0'
)
URL
=
self
[
'URL'
]
if
URL
[
-
1
:]
==
'/'
:
URL
=
URL
[:
-
1
]
for
i
in
range
(
0
,
n
):
l
=
string
.
rfind
(
URL
,
'/'
)
if
l
>=
0
:
URL
=
URL
[:
l
]
else
:
raise
KeyError
,
key
other
[
key
]
=
URL
return
URL
except
:
pass
raise KeyError, key
__getattr__=__getitem__
special_names
=
{
isCGI_NAME = {
'
SERVER_SOFTWARE
' : 1,
'
SERVER_NAME
' : 1,
'
GATEWAY_INTERFACE
' : 1,
...
...
@@ -1575,7 +1353,8 @@ class Request:
'
REMOTE_IDENT
' : 1,
'
CONTENT_TYPE
' : 1,
'
CONTENT_LENGTH
' : 1,
}
}.has_key
def parse_cookie(text,
...
...
@@ -1610,44 +1389,42 @@ def parse_cookie(text,
return apply(parse_cookie,(text[l:],result))
def old_validation(groups, HTTP_AUTHORIZATION, roles=UNSPECIFIED_ROLES):
if lower(HTTP_AUTHORIZATION[:6]) != '
basic
': return None
[name,password] = string.splitfields(
base64.decodestring(
split(HTTP_AUTHORIZATION)[-1]), '
:
')
if roles is None: return name
class CGIModulePublisher(ModulePublisher):
def __init__(self,
stdin=sys.stdin, stdout=sys.stdout, stderr=sys.stderr,
environ=os.environ):
self.environ=environ
fp=None
keys=None
try:
if environ['
REQUEST_METHOD
'] != '
GET
': fp=stdin
keys=groups.keys
except:
try:
groups=groups() # Maybe it was a method defining a group
keys=groups.keys
except: pass
fs=FieldStorage(fp=fp,environ=environ,keep_blank_values=1)
try: list=fs.list
except: list=None
if list is None: form={'
BODY
':fs}
else:
form={}
lt=type([])
for item in list:
key=item.name
try:
found=form[key]
if type(found) is lt: found.append(item)
else:
found=[found,item]
form[key]=found
except:
form[key]=item
if keys is not None:
# OK, we have a named group, so apply the roles to the named
# group.
if roles is UNSPECIFIED_ROLES: roles=keys()
g=[]
for role in roles:
if groups.has_key(role): g.append(groups[role])
groups=g
for d in groups:
if d.has_key(name) and d[name]==password: return name
if keys is None:
# Not a named group, so don'
t
go
further
raise
'Forbidden'
,
(
"""<strong>You are not authorized to access this resource"""
)
return
None
request=self.request=Request(environ,form,stdin)
self.response=Response(stdout=stdout, stderr=stderr)
self.stdin=stdin
self.stdout=stdout
self.stderr=stderr
self.base=request.base
self.script=request.script
def
publish_module
(
module_name
,
stdin
=
sys
.
stdin
,
stdout
=
sys
.
stdout
,
stderr
=
sys
.
stderr
,
...
...
@@ -1657,8 +1434,7 @@ def publish_module(module_name,
after_list
=
[
None
]
try
:
response
=
Response
(
stdout
=
stdout
,
stderr
=
stderr
)
publisher = CGIModulePublisher(stdin=stdin, stdout=stdout,
stderr=stderr,
publisher
=
ModulePublisher
(
stdin
=
stdin
,
stdout
=
stdout
,
stderr
=
stderr
,
environ
=
environ
)
response
=
publisher
.
response
response
=
publisher
.
publish
(
module_name
,
after_list
,
debug
=
debug
)
...
...
@@ -1687,6 +1463,10 @@ def publish_module(module_name,
#
# $Log: Publish.py,v $
# Revision 1.47 1997/09/02 21:18:53 jim
# Implemented new authorization model.
# No longer use Realm module.
#
# Revision 1.46 1997/07/28 22:01:58 jim
# Tries to get rid of base ref.
#
...
...
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