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
d2b68599
Commit
d2b68599
authored
Jun 19, 2010
by
Hanno Schlichting
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Use the external AccessControl distribution
parent
ccc10355
Changes
66
Show whitespace changes
Inline
Side-by-side
Showing
66 changed files
with
3 additions
and
12139 deletions
+3
-12139
buildout.cfg
buildout.cfg
+1
-0
setup.py
setup.py
+1
-9
src/AccessControl/AccessControl.txt
src/AccessControl/AccessControl.txt
+0
-220
src/AccessControl/AuthEncoding.py
src/AccessControl/AuthEncoding.py
+0
-178
src/AccessControl/DTML.py
src/AccessControl/DTML.py
+0
-21
src/AccessControl/ImplC.py
src/AccessControl/ImplC.py
+0
-46
src/AccessControl/ImplPython.py
src/AccessControl/ImplPython.py
+0
-847
src/AccessControl/Implementation.py
src/AccessControl/Implementation.py
+0
-99
src/AccessControl/Owned.py
src/AccessControl/Owned.py
+0
-29
src/AccessControl/Permission.py
src/AccessControl/Permission.py
+0
-176
src/AccessControl/PermissionMapping.py
src/AccessControl/PermissionMapping.py
+0
-158
src/AccessControl/PermissionRole.py
src/AccessControl/PermissionRole.py
+0
-19
src/AccessControl/Permissions.py
src/AccessControl/Permissions.py
+0
-76
src/AccessControl/Role.py
src/AccessControl/Role.py
+0
-33
src/AccessControl/SecurityInfo.py
src/AccessControl/SecurityInfo.py
+0
-315
src/AccessControl/SecurityManagement.py
src/AccessControl/SecurityManagement.py
+0
-78
src/AccessControl/SecurityManager.py
src/AccessControl/SecurityManager.py
+0
-31
src/AccessControl/SimpleObjectPolicies.py
src/AccessControl/SimpleObjectPolicies.py
+0
-121
src/AccessControl/SpecialUsers.py
src/AccessControl/SpecialUsers.py
+0
-25
src/AccessControl/User.py
src/AccessControl/User.py
+0
-45
src/AccessControl/ZopeGuards.py
src/AccessControl/ZopeGuards.py
+0
-536
src/AccessControl/ZopeSecurityPolicy.py
src/AccessControl/ZopeSecurityPolicy.py
+0
-59
src/AccessControl/__init__.py
src/AccessControl/__init__.py
+0
-33
src/AccessControl/cAccessControl.c
src/AccessControl/cAccessControl.c
+0
-2318
src/AccessControl/class_init.py
src/AccessControl/class_init.py
+0
-87
src/AccessControl/configure.zcml
src/AccessControl/configure.zcml
+0
-5
src/AccessControl/interfaces.py
src/AccessControl/interfaces.py
+0
-346
src/AccessControl/logger_wrapper.py
src/AccessControl/logger_wrapper.py
+0
-6
src/AccessControl/meta.zcml
src/AccessControl/meta.zcml
+0
-41
src/AccessControl/metaconfigure.py
src/AccessControl/metaconfigure.py
+0
-49
src/AccessControl/owner.py
src/AccessControl/owner.py
+0
-263
src/AccessControl/permissions.zcml
src/AccessControl/permissions.zcml
+0
-111
src/AccessControl/requestmethod.py
src/AccessControl/requestmethod.py
+0
-83
src/AccessControl/requestmethod.txt
src/AccessControl/requestmethod.txt
+0
-92
src/AccessControl/rolemanager.py
src/AccessControl/rolemanager.py
+0
-506
src/AccessControl/security.py
src/AccessControl/security.py
+0
-167
src/AccessControl/tainted.py
src/AccessControl/tainted.py
+0
-153
src/AccessControl/tests/__init__.py
src/AccessControl/tests/__init__.py
+0
-0
src/AccessControl/tests/actual_python.py
src/AccessControl/tests/actual_python.py
+0
-186
src/AccessControl/tests/mixed_module/__init__.py
src/AccessControl/tests/mixed_module/__init__.py
+0
-7
src/AccessControl/tests/mixed_module/submodule/__init__.py
src/AccessControl/tests/mixed_module/submodule/__init__.py
+0
-4
src/AccessControl/tests/private_module/__init__.py
src/AccessControl/tests/private_module/__init__.py
+0
-4
src/AccessControl/tests/private_module/submodule/__init__.py
src/AccessControl/tests/private_module/submodule/__init__.py
+0
-4
src/AccessControl/tests/public_module/__init__.py
src/AccessControl/tests/public_module/__init__.py
+0
-6
src/AccessControl/tests/public_module/submodule/__init__.py
src/AccessControl/tests/public_module/submodule/__init__.py
+0
-4
src/AccessControl/tests/testClassSecurityInfo.py
src/AccessControl/tests/testClassSecurityInfo.py
+0
-84
src/AccessControl/tests/testImplementation.py
src/AccessControl/tests/testImplementation.py
+0
-67
src/AccessControl/tests/testModuleSecurity.py
src/AccessControl/tests/testModuleSecurity.py
+0
-80
src/AccessControl/tests/testOwned.py
src/AccessControl/tests/testOwned.py
+0
-299
src/AccessControl/tests/testPasswordDigest.py
src/AccessControl/tests/testPasswordDigest.py
+0
-92
src/AccessControl/tests/testPermissionMapping.py
src/AccessControl/tests/testPermissionMapping.py
+0
-17
src/AccessControl/tests/testPermissionRole.py
src/AccessControl/tests/testPermissionRole.py
+0
-127
src/AccessControl/tests/testRole.py
src/AccessControl/tests/testRole.py
+0
-17
src/AccessControl/tests/testSecurityManager.py
src/AccessControl/tests/testSecurityManager.py
+0
-271
src/AccessControl/tests/testZCML.py
src/AccessControl/tests/testZCML.py
+0
-398
src/AccessControl/tests/testZopeGuards.py
src/AccessControl/tests/testZopeGuards.py
+0
-884
src/AccessControl/tests/testZopeSecurityPolicy.py
src/AccessControl/tests/testZopeSecurityPolicy.py
+0
-578
src/AccessControl/tests/test_requestmethod.py
src/AccessControl/tests/test_requestmethod.py
+0
-31
src/AccessControl/tests/test_safeiter.py
src/AccessControl/tests/test_safeiter.py
+0
-66
src/AccessControl/tests/test_tainted.py
src/AccessControl/tests/test_tainted.py
+0
-159
src/AccessControl/tests/test_userfolder.py
src/AccessControl/tests/test_userfolder.py
+0
-176
src/AccessControl/tests/test_users.py
src/AccessControl/tests/test_users.py
+0
-234
src/AccessControl/unauthorized.py
src/AccessControl/unauthorized.py
+0
-33
src/AccessControl/userfolder.py
src/AccessControl/userfolder.py
+0
-421
src/AccessControl/users.py
src/AccessControl/users.py
+0
-509
versions.cfg
versions.cfg
+1
-0
No files found.
buildout.cfg
View file @
d2b68599
...
@@ -36,6 +36,7 @@ scripts = zopepy
...
@@ -36,6 +36,7 @@ scripts = zopepy
recipe = zc.recipe.testrunner
recipe = zc.recipe.testrunner
eggs =
eggs =
Zope2
Zope2
AccessControl
Acquisition
Acquisition
DateTime
DateTime
ExtensionClass
ExtensionClass
...
...
setup.py
View file @
d2b68599
...
@@ -31,15 +31,6 @@ setup(name='Zope2',
...
@@ -31,15 +31,6 @@ setup(name='Zope2',
package_dir
=
{
''
:
'src'
},
package_dir
=
{
''
:
'src'
},
ext_modules
=
[
ext_modules
=
[
# AccessControl
Extension
(
name
=
'AccessControl.cAccessControl'
,
include_dirs
=
[
'include'
,
'src'
],
sources
=
[
'src/AccessControl/cAccessControl.c'
],
depends
=
[
'include/ExtensionClass/ExtensionClass.h'
,
'include/Acquisition/Acquisition.h'
]),
# DocumentTemplate
# DocumentTemplate
Extension
(
Extension
(
name
=
'DocumentTemplate.cDocumentTemplate'
,
name
=
'DocumentTemplate.cDocumentTemplate'
,
...
@@ -58,6 +49,7 @@ setup(name='Zope2',
...
@@ -58,6 +49,7 @@ setup(name='Zope2',
],
],
install_requires
=
[
install_requires
=
[
'AccessControl'
,
'Acquisition'
,
'Acquisition'
,
'DateTime'
,
'DateTime'
,
'ExtensionClass'
,
'ExtensionClass'
,
...
...
src/AccessControl/AccessControl.txt
deleted
100644 → 0
View file @
ccc10355
Security Architecture
---------------------
Users
-----
Objects representing users may be created in Principia
User Folder objects. User objects maintain the information
used to authenticate users, and allow roles to be associated
with a user.
Permissions
-----------
A "permission" is the smallest unit of access to an object,
roughly equivalent to the atomic permissions seen in NT:
R (Read), W(Write), X(Execute), etc. In Principia, a permission
usually describes a fine-grained logical operation on an object,
such as "View Management Screens", "Add Properties", etc.
Different types of objects will define different permissions
as appropriate for the object.
Types of access
---------------
A "type of access" is a named grouping of 0 or more of the
permissions defined by an object. All objects have one predefined
type of access called Full Access (all permissions defined by that
object). A user who has the special role "Manager" always has Full
Access to all objects at or below the level in the object hierarchy
at which the user is defined.
New types of access may be defined as combinations of the
various permissions defined by a given object. These new
types of access may be defined by the programmer, or by
users at runtime.
Roles
-----
A role is a name that ties users (authentication of identity)
to permissions (authorization for that identity) in the system.
Roles may be defined in any Folder (or Folderish) object in the
system. Sub folders can make use of roles defined higher in the
hierarchy. These roles can be assigned to users. All users,
including non-authenticated users have the built-in role of
"Anonymous".
Principia objects allow the association of defined roles
with a single "type of access" each, in the context of that
object. A single role is associated with one and only one
type of access in the context of a given object.
Examples
--------
User Object1
o has the role "RoleA" o has given "RoleA" Full Access
Result: the user has Full Access to Object1.
User Object2
o has the role "RoleA" o has given "RoleB" Full Access
o has given the role "RoleA" View Access,
a custom type of access that allows only
viewing of the object.
Result: the user has only View Access.
Notes
-----
All objects define a permission called "Default permission". If this
permission is given to a role, users with that role will be able to
access subobjects which do not explicitly restrict access.
Technical
---------
Objects define their permissions as logical operations.
Programmers have to determine the appropriate operations
for their object type, and provide a mapping of permission
name to attribute names. It is important to note that permissions
cannot overlap - none of the attributes named in a permission
can occur in any of the other permissions. The following are
proposed permissions for some current principia objects:
Folder
o View management screens
o Change permissions
o Undo changes
o Add objects
o Delete objects
o Add properties
o Change properties
o Delete properties
o Default permission
Confera Topic
o View management screens
o Change permissions
o Undo changes
o Add objects
o Delete objects
o Add properties
o Change properties
o Delete properties
o Default permission
o Change Configuration
o Add Messages
o Change Messages
o Delete Messages
Tabula Collection
o View management screens
o Change permissions
o Undo changes
o Add objects
o Delete objects
o Add properties
o Change properties
o Delete properties
o Default permission
o Change schema
o Upload data
o Add computed fields
o Change computed fields
o Delete computed fields
Document/Image/File
o View management screens
o Change permissions
o Change/upload data
o View
Session
o View management screens
o Change permissions
o Change session config
o Join/leave session
o Save/discard session
Mail Host
o View management screens
o Change permissions
o Change configuration
To support the architecture, developers must derive an
object from the AccessControl.rolemanager.RoleManager mixin class,
and define in their class an __ac_permissions__ attribute.
This should be a tuple of tuples, where each tuple represents
a permission and contains a string permission name as its first
element and a list of attribute names as its second element.
Example:
__ac_permissions__=(
('View management screens',
['manage','manage_menu','manage_main','manage_copyright',
'manage_tabs','manage_propertiesForm','manage_UndoForm']),
('Undo changes', ['manage_undo_transactions']),
('Change permissions', ['manage_access']),
('Add objects', ['manage_addObject']),
('Delete objects', ['manage_delObjects']),
('Add properties', ['manage_addProperty']),
('Change properties', ['manage_editProperties']),
('Delete properties', ['manage_delProperties']),
('Default permission', ['']),
)
The developer may also predefine useful types of access, by
specifying an __ac_types__ attribute. This should be a tuple of
tuples, where each tuple represents a type of access and contains
a string name as its first element and a list of permission names
as its second element.
By default, only "Full Access" is defined (by the RoleManager mixin).
If you wish to override __ac_types__ to provide convenient types of
access, you must always be sure to define "Full Access" as containing
the names of all possible permissions for your object.
Example:
__ac_types__=(
('Full Access', map(lambda x: x[0], __ac_permissions__)),
('Change', ['Add Objects', 'Add Properties', 'Change Properties']),
)
Developers may also provide pre-defined role names that are
not deletable via the interface by specifying an __ac_roles__
attribute. This is probably not something we'll ever use under
the new architecture, but it's there if you need it.
Example:
__ac_roles__=('Manager', 'Anonymous')
src/AccessControl/AuthEncoding.py
deleted
100644 → 0
View file @
ccc10355
##############################################################################
#
# 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
#
##############################################################################
__version__
=
'$Revision: 1.9 $'
[
11
:
-
2
]
try
:
from
hashlib
import
sha1
as
sha
except
:
from
sha
import
new
as
sha
import
binascii
from
binascii
import
b2a_base64
,
a2b_base64
from
random
import
choice
,
randrange
class
PasswordEncryptionScheme
:
# An Interface
def
encrypt
(
pw
):
"""
Encrypt the provided plain text password.
"""
def
validate
(
reference
,
attempt
):
"""
Validate the provided password string. Reference is the
correct password, which may be encrypted; attempt is clear text
password attempt.
"""
_schemes
=
[]
def
registerScheme
(
id
,
s
):
'''
Registers an LDAP password encoding scheme.
'''
_schemes
.
append
((
id
,
'{%s}'
%
id
,
s
))
def
listSchemes
():
r
=
[]
for
id
,
prefix
,
scheme
in
_schemes
:
r
.
append
(
id
)
return
r
class
SSHADigestScheme
:
'''
SSHA is a modification of the SHA digest scheme with a salt
starting at byte 20 of the base64-encoded string.
'''
# Source: http://developer.netscape.com/docs/technote/ldap/pass_sha.html
def
generate_salt
(
self
):
# Salt can be any length, but not more than about 37 characters
# because of limitations of the binascii module.
# 7 is what Netscape's example used and should be enough.
# All 256 characters are available.
salt
=
''
for
n
in
range
(
7
):
salt
+=
chr
(
randrange
(
256
))
return
salt
def
encrypt
(
self
,
pw
):
pw
=
str
(
pw
)
salt
=
self
.
generate_salt
()
return
b2a_base64
(
sha
(
pw
+
salt
).
digest
()
+
salt
)[:
-
1
]
def
validate
(
self
,
reference
,
attempt
):
try
:
ref
=
a2b_base64
(
reference
)
except
binascii
.
Error
:
# Not valid base64.
return
0
salt
=
ref
[
20
:]
compare
=
b2a_base64
(
sha
(
attempt
+
salt
).
digest
()
+
salt
)[:
-
1
]
return
(
compare
==
reference
)
registerScheme
(
'SSHA'
,
SSHADigestScheme
())
class
SHADigestScheme
:
def
encrypt
(
self
,
pw
):
return
b2a_base64
(
sha
(
pw
).
digest
())[:
-
1
]
def
validate
(
self
,
reference
,
attempt
):
compare
=
b2a_base64
(
sha
(
attempt
).
digest
())[:
-
1
]
return
(
compare
==
reference
)
registerScheme
(
'SHA'
,
SHADigestScheme
())
# Bogosity on various platforms due to ITAR restrictions
try
:
from
crypt
import
crypt
except
ImportError
:
crypt
=
None
if
crypt
is
not
None
:
class
CryptDigestScheme
:
def
generate_salt
(
self
):
choices
=
(
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789./"
)
return
choice
(
choices
)
+
choice
(
choices
)
def
encrypt
(
self
,
pw
):
return
crypt
(
pw
,
self
.
generate_salt
())
def
validate
(
self
,
reference
,
attempt
):
a
=
crypt
(
attempt
,
reference
[:
2
])
return
(
a
==
reference
)
registerScheme
(
'CRYPT'
,
CryptDigestScheme
())
class
MySQLDigestScheme
:
def
encrypt
(
self
,
pw
):
nr
=
1345345333L
add
=
7
nr2
=
0x12345671
L
for
i
in
pw
:
if
i
==
' '
or
i
==
'
\
t
'
:
continue
nr
^=
(((
nr
&
63
)
+
add
)
*
ord
(
i
))
+
(
nr
<<
8
)
nr2
+=
(
nr2
<<
8
)
^
nr
add
+=
ord
(
i
)
r0
=
nr
&
((
1L
<<
31
)
-
1L
)
r1
=
nr2
&
((
1L
<<
31
)
-
1L
)
return
"%08lx%08lx"
%
(
r0
,
r1
)
def
validate
(
self
,
reference
,
attempt
):
a
=
self
.
encrypt
(
attempt
)
return
(
a
==
reference
)
registerScheme
(
'MYSQL'
,
MySQLDigestScheme
())
def
pw_validate
(
reference
,
attempt
):
"""Validate the provided password string, which uses LDAP-style encoding
notation. Reference is the correct password, attempt is clear text
password attempt."""
for
id
,
prefix
,
scheme
in
_schemes
:
lp
=
len
(
prefix
)
if
reference
[:
lp
]
==
prefix
:
return
scheme
.
validate
(
reference
[
lp
:],
attempt
)
# Assume cleartext.
return
(
reference
==
attempt
)
def
is_encrypted
(
pw
):
for
id
,
prefix
,
scheme
in
_schemes
:
lp
=
len
(
prefix
)
if
pw
[:
lp
]
==
prefix
:
return
1
return
0
def
pw_encrypt
(
pw
,
encoding
=
'SSHA'
):
"""Encrypt the provided plain text password using the encoding if provided
and return it in an LDAP-style representation."""
for
id
,
prefix
,
scheme
in
_schemes
:
if
encoding
==
id
:
return
prefix
+
scheme
.
encrypt
(
pw
)
raise
ValueError
,
'Not supported: %s'
%
encoding
pw_encode
=
pw_encrypt
# backward compatibility
src/AccessControl/DTML.py
deleted
100644 → 0
View file @
ccc10355
##############################################################################
#
# 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
#
##############################################################################
"""Add security system support to Document Templates
"""
from
zope.deferredimport
import
deprecated
deprecated
(
"Please import from DocumentTemplate.security"
,
DTMLSecurityAPI
=
'DocumentTemplate.security:DTMLSecurityAPI'
,
RestrictedDTML
=
'DocumentTemplate.security:RestrictedDTML'
,
)
src/AccessControl/ImplC.py
deleted
100644 → 0
View file @
ccc10355
##############################################################################
#
# Copyright (c) 2003 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.
#
##############################################################################
"""C implementation of the access control machinery."""
try
:
from
AccessControl.cAccessControl
import
rolesForPermissionOn
from
AccessControl.cAccessControl
import
PermissionRole
from
AccessControl.cAccessControl
import
imPermissionRole
from
AccessControl.cAccessControl
import
_what_not_even_god_should_do
from
AccessControl.cAccessControl
import
aq_validate
from
AccessControl.cAccessControl
import
guarded_getattr
from
AccessControl.cAccessControl
import
setDefaultBehaviors
from
AccessControl.cAccessControl
import
ZopeSecurityPolicy
\
as
cZopeSecurityPolicy
from
AccessControl.cAccessControl
import
SecurityManager
\
as
cSecurityManager
except
ImportError
:
import
sys
# make sure a partial import doesn't pollute sys.modules
del
sys
.
modules
[
__name__
]
raise
from
AccessControl.ImplPython
import
SecurityManager
from
AccessControl.ImplPython
import
ZopeSecurityPolicy
class
ZopeSecurityPolicy
(
cZopeSecurityPolicy
,
ZopeSecurityPolicy
):
"""A security manager provides methods for checking access and managing
executable context and policies
"""
class
SecurityManager
(
cSecurityManager
,
SecurityManager
):
"""A security manager provides methods for checking access and managing
executable context and policies
"""
src/AccessControl/ImplPython.py
deleted
100644 → 0
View file @
ccc10355
##############################################################################
#
# Copyright (c) 2003 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 implementation of the access control machinery."""
import
os
import
string
from
logging
import
getLogger
from
Acquisition
import
aq_acquire
from
Acquisition
import
aq_base
from
Acquisition
import
aq_inner
from
Acquisition
import
aq_inContextOf
from
Acquisition
import
aq_parent
from
ExtensionClass
import
Base
from
zope.interface
import
implements
# This is used when a permission maps explicitly to no permission. We
# try and get this from cAccessControl first to make sure that if both
# security implementations exist, we can switch between them later.
try
:
from
cAccessControl
import
_what_not_even_god_should_do
except
ImportError
:
_what_not_even_god_should_do
=
[]
from
AccessControl.SecurityManagement
import
getSecurityManager
from
AccessControl.unauthorized
import
Unauthorized
from
AccessControl.interfaces
import
ISecurityPolicy
from
AccessControl.interfaces
import
ISecurityManager
from
AccessControl.SimpleObjectPolicies
import
Containers
from
AccessControl.SimpleObjectPolicies
import
_noroles
from
AccessControl.ZopeGuards
import
guarded_getitem
LOG
=
getLogger
(
'ImplPython'
)
# AccessControl.PermissionRole
# ----------------------------
_ident_chars
=
string
.
ascii_letters
+
string
.
digits
+
"_"
name_trans
=
filter
(
lambda
c
,
an
=
_ident_chars
:
c
not
in
an
,
map
(
chr
,
range
(
256
)))
name_trans
=
string
.
maketrans
(
''
.
join
(
name_trans
),
'_'
*
len
(
name_trans
))
_default_roles
=
(
'Manager'
,)
# If _embed_permission_in_roles is enabled, computed __roles__
# attributes will often include a special role that encodes the name
# of the permission from which the roles were derived. This is useful
# for verbose security exceptions.
_embed_permission_in_roles
=
0
def
rolesForPermissionOn
(
perm
,
object
,
default
=
_default_roles
,
n
=
None
):
"""Return the roles that have the given permission on the given object
"""
n
=
n
or
'_'
+
string
.
translate
(
perm
,
name_trans
)
+
"_Permission"
r
=
None
while
1
:
if
hasattr
(
object
,
n
):
roles
=
getattr
(
object
,
n
)
if
roles
is
None
:
if
_embed_permission_in_roles
:
return
(
'Anonymous'
,
n
)
return
'Anonymous'
,
t
=
type
(
roles
)
if
t
is
tuple
:
# If we get a tuple, then we don't acquire
if
r
is
None
:
if
_embed_permission_in_roles
:
return
roles
+
(
n
,)
return
roles
if
_embed_permission_in_roles
:
return
r
+
list
(
roles
)
+
[
n
]
return
r
+
list
(
roles
)
if
t
is
str
:
# We found roles set to a name. Start over
# with the new permission name. If the permission
# name is '', then treat as private!
if
roles
:
n
=
roles
else
:
return
_what_not_even_god_should_do
elif
roles
:
if
r
is
None
:
r
=
list
(
roles
)
else
:
r
=
r
+
list
(
roles
)
object
=
aq_inner
(
object
)
if
object
is
None
:
break
object
=
aq_parent
(
object
)
if
r
is
None
:
if
_embed_permission_in_roles
:
if
default
:
if
isinstance
(
default
,
tuple
):
return
default
+
(
n
,)
else
:
return
default
+
[
n
]
else
:
return
[
n
]
return
default
if
_embed_permission_in_roles
:
return
r
+
[
n
]
return
r
class
PermissionRole
(
Base
):
"""Implement permission-based roles.
Under normal circumstances, our __of__ method will be
called with an unwrapped object. The result will then be called
with a wrapped object, if the original object was wrapped.
To deal with this, we have to create an intermediate object.
"""
def
__init__
(
self
,
name
,
default
=
(
'Manager'
,)):
self
.
__name__
=
name
self
.
_p
=
'_'
+
string
.
translate
(
name
,
name_trans
)
+
"_Permission"
self
.
_d
=
self
.
__roles__
=
default
def
__of__
(
self
,
parent
):
r
=
imPermissionRole
()
r
.
_p
=
self
.
_p
r
.
_pa
=
parent
r
.
_d
=
self
.
_d
p
=
getattr
(
parent
,
'aq_inner'
,
None
)
if
p
is
not
None
:
return
r
.
__of__
(
p
)
else
:
return
r
def
rolesForPermissionOn
(
self
,
value
):
return
rolesForPermissionOn
(
None
,
value
,
self
.
_d
,
self
.
_p
)
class
imPermissionRole
(
Base
):
"""Implement permission-based roles"""
def
__of__
(
self
,
value
):
return
rolesForPermissionOn
(
None
,
value
,
self
.
_d
,
self
.
_p
)
rolesForPermissionOn
=
__of__
# The following methods are needed in the unlikely case that an unwrapped
# object is accessed:
def
__getitem__
(
self
,
i
):
try
:
v
=
self
.
_v
except
:
v
=
self
.
_v
=
self
.
__of__
(
self
.
_pa
)
del
self
.
_pa
return
v
[
i
]
def
__len__
(
self
):
try
:
v
=
self
.
_v
except
:
v
=
self
.
_v
=
self
.
__of__
(
self
.
_pa
)
del
self
.
_pa
return
len
(
v
)
# AccessControl.ZopeSecurityPolicy
# --------------------------------
#
# TODO: implement this in cAccessControl, and have Implementation
# do the indirection.
#
from
AccessControl.ZopeSecurityPolicy
import
getRoles
# XXX
class
ZopeSecurityPolicy
:
implements
(
ISecurityPolicy
)
def
__init__
(
self
,
ownerous
=
1
,
authenticated
=
1
,
verbose
=
0
):
"""Create a Zope security policy.
Optional arguments may be provided:
ownerous -- Untrusted users can create code
(e.g. Python scripts or templates),
so check that code owners can access resources.
The argument must have a truth value.
The default is true.
authenticated -- Allow access to resources based on the
privaledges of the authenticated user.
The argument must have a truth value.
The default is true.
This (somewhat experimental) option can be set
to false on sites that allow only public
(unauthenticated) access. An anticipated
scenario is a ZEO configuration in which some
clients allow only public access and other
clients allow full management.
verbose -- Include debugging information in Unauthorized
exceptions. Not suitable for public sites.
"""
self
.
_ownerous
=
ownerous
self
.
_authenticated
=
authenticated
self
.
_verbose
=
verbose
def
validate
(
self
,
accessed
,
container
,
name
,
value
,
context
,
roles
=
_noroles
,
getattr
=
getattr
,
_noroles
=
_noroles
,
valid_aq_
=
(
'aq_parent'
,
'aq_inner'
,
'aq_explicit'
)):
############################################################
# Provide special rules for the acquisition attributes
if
isinstance
(
name
,
str
):
if
name
.
startswith
(
'aq_'
)
and
name
not
in
valid_aq_
:
if
self
.
_verbose
:
raiseVerbose
(
'aq_* names (other than %s) are not allowed'
%
', '
.
join
(
valid_aq_
),
accessed
,
container
,
name
,
value
,
context
)
raise
Unauthorized
(
name
,
value
)
containerbase
=
aq_base
(
container
)
accessedbase
=
aq_base
(
accessed
)
if
accessedbase
is
accessed
:
# accessed is not a wrapper, so assume that the
# value could not have been acquired.
accessedbase
=
container
############################################################
# If roles weren't passed in, we'll try to get them from the object
if
roles
is
_noroles
:
roles
=
getRoles
(
container
,
name
,
value
,
_noroles
)
############################################################
# We still might not have any roles
if
roles
is
_noroles
:
############################################################
# We have an object without roles and we didn't get a list
# of roles passed in. Presumably, the value is some simple
# object like a string or a list. We'll try to get roles
# from its container.
if
container
is
None
:
# Either container or a list of roles is required
# for ZopeSecurityPolicy to know whether access is
# allowable.
if
self
.
_verbose
:
raiseVerbose
(
'No container provided'
,
accessed
,
container
,
name
,
value
,
context
)
raise
Unauthorized
(
name
,
value
)
roles
=
getattr
(
container
,
'__roles__'
,
roles
)
if
roles
is
_noroles
:
if
containerbase
is
container
:
# Container is not wrapped.
if
containerbase
is
not
accessedbase
:
if
self
.
_verbose
:
raiseVerbose
(
'Unable to find __roles__ in the container '
'and the container is not wrapped'
,
accessed
,
container
,
name
,
value
,
context
)
raise
Unauthorized
(
name
,
value
)
else
:
# Try to acquire roles
try
:
roles
=
aq_acquire
(
container
,
'__roles__'
)
except
AttributeError
:
if
containerbase
is
not
accessedbase
:
if
self
.
_verbose
:
raiseVerbose
(
'Unable to find or acquire __roles__ '
'from the container'
,
accessed
,
container
,
name
,
value
,
context
)
raise
Unauthorized
(
name
,
value
)
# We need to make sure that we are allowed to
# get unprotected attributes from the container. We are
# allowed for certain simple containers and if the
# container says we can. Simple containers
# may also impose name restrictions.
p
=
Containers
(
type
(
container
),
None
)
if
p
is
None
:
p
=
getattr
(
container
,
'__allow_access_to_unprotected_subobjects__'
,
None
)
if
p
is
not
None
:
if
not
isinstance
(
p
,
int
):
# catches bool too
if
isinstance
(
p
,
dict
):
if
isinstance
(
name
,
basestring
):
p
=
p
.
get
(
name
)
else
:
p
=
1
else
:
p
=
p
(
name
,
value
)
if
not
p
:
if
self
.
_verbose
:
raiseVerbose
(
'The container has no security assertions'
,
accessed
,
container
,
name
,
value
,
context
)
raise
Unauthorized
(
name
,
value
)
if
roles
is
_noroles
:
return
1
# We are going to need a security-aware object to pass
# to allowed(). We'll use the container.
value
=
container
# Short-circuit tests if we can:
try
:
if
roles
is
None
or
'Anonymous'
in
roles
:
return
1
except
TypeError
:
# 'roles' isn't a sequence
LOG
.
error
(
"'%s' passed as roles"
" during validation of '%s' is not a sequence."
%
(
`roles`
,
name
))
raise
# Check executable security
stack
=
context
.
stack
if
stack
:
eo
=
stack
[
-
1
]
# If the executable had an owner, can it execute?
if
self
.
_ownerous
:
owner
=
eo
.
getOwner
()
if
(
owner
is
not
None
)
and
not
owner
.
allowed
(
value
,
roles
):
# We don't want someone to acquire if they can't
# get an unacquired!
if
self
.
_verbose
:
if
len
(
roles
)
<
1
:
raiseVerbose
(
"The object is marked as private"
,
accessed
,
container
,
name
,
value
,
context
)
elif
userHasRolesButNotInContext
(
owner
,
value
,
roles
):
raiseVerbose
(
"The owner of the executing script is defined "
"outside the context of the object being "
"accessed"
,
accessed
,
container
,
name
,
value
,
context
,
required_roles
=
roles
,
eo_owner
=
owner
,
eo
=
eo
)
else
:
raiseVerbose
(
"The owner of the executing script does not "
"have the required permission"
,
accessed
,
container
,
name
,
value
,
context
,
required_roles
=
roles
,
eo_owner
=
owner
,
eo
=
eo
,
eo_owner_roles
=
getUserRolesInContext
(
owner
,
value
))
raise
Unauthorized
(
name
,
value
)
# Proxy roles, which are a lot safer now.
proxy_roles
=
getattr
(
eo
,
'_proxy_roles'
,
None
)
if
proxy_roles
:
# Verify that the owner actually can state the proxy role
# in the context of the accessed item; users in subfolders
# should not be able to use proxy roles to access items
# above their subfolder!
owner
=
eo
.
getWrappedOwner
()
if
owner
is
not
None
:
if
container
is
not
containerbase
:
# Unwrapped objects don't need checking
if
not
owner
.
_check_context
(
container
):
# container is higher up than the owner,
# deny access
if
self
.
_verbose
:
raiseVerbose
(
"The owner of the executing script is "
"defined outside the context of the "
"object being accessed. The script has "
"proxy roles, but they do not apply in "
"this context."
,
accessed
,
container
,
name
,
value
,
context
,
required_roles
=
roles
,
eo_owner
=
owner
,
eo
=
eo
)
raise
Unauthorized
(
name
,
value
)
for
r
in
proxy_roles
:
if
r
in
roles
:
return
1
# Proxy roles actually limit access!
if
self
.
_verbose
:
if
len
(
roles
)
<
1
:
raiseVerbose
(
"The object is marked as private"
,
accessed
,
container
,
name
,
value
,
context
)
else
:
raiseVerbose
(
"The proxy roles set on the executing script "
"do not allow access"
,
accessed
,
container
,
name
,
value
,
context
,
eo
=
eo
,
eo_proxy_roles
=
proxy_roles
,
required_roles
=
roles
)
raise
Unauthorized
(
name
,
value
)
try
:
if
self
.
_authenticated
and
context
.
user
.
allowed
(
value
,
roles
):
return
1
except
AttributeError
:
pass
if
self
.
_verbose
:
if
len
(
roles
)
<
1
:
raiseVerbose
(
"The object is marked as private"
,
accessed
,
container
,
name
,
value
,
context
)
elif
not
self
.
_authenticated
:
raiseVerbose
(
"Authenticated access is not allowed by this "
"security policy"
,
accessed
,
container
,
name
,
value
,
context
)
elif
userHasRolesButNotInContext
(
context
.
user
,
value
,
roles
):
raiseVerbose
(
"Your user account is defined outside "
"the context of the object being accessed"
,
accessed
,
container
,
name
,
value
,
context
,
required_roles
=
roles
,
user
=
context
.
user
)
else
:
raiseVerbose
(
"Your user account does not "
"have the required permission"
,
accessed
,
container
,
name
,
value
,
context
,
required_roles
=
roles
,
user
=
context
.
user
,
user_roles
=
getUserRolesInContext
(
context
.
user
,
value
))
raise
Unauthorized
(
name
,
value
)
def
checkPermission
(
self
,
permission
,
object
,
context
):
roles
=
rolesForPermissionOn
(
permission
,
object
)
if
isinstance
(
roles
,
basestring
):
roles
=
[
roles
]
# check executable owner and proxy roles
stack
=
context
.
stack
if
stack
:
eo
=
stack
[
-
1
]
# If the executable had an owner, can it execute?
if
self
.
_ownerous
:
owner
=
eo
.
getOwner
()
if
(
owner
is
not
None
)
and
not
owner
.
allowed
(
object
,
roles
):
# We don't want someone to acquire if they can't
# get an unacquired!
return
0
proxy_roles
=
getattr
(
eo
,
'_proxy_roles'
,
None
)
if
proxy_roles
:
# Verify that the owner actually can state the proxy role
# in the context of the accessed item; users in subfolders
# should not be able to use proxy roles to access items
# above their subfolder!
owner
=
eo
.
getWrappedOwner
()
if
owner
is
not
None
:
if
object
is
not
aq_base
(
object
):
if
not
owner
.
_check_context
(
object
):
# object is higher up than the owner,
# deny access
return
0
for
r
in
proxy_roles
:
if
r
in
roles
:
return
1
return
0
return
context
.
user
.
allowed
(
object
,
roles
)
# AccessControl.SecurityManager
# -----------------------------
# There is no corresponding control in the C implementation of the
# access control machinery (cAccessControl.c); this should probably go
# away in a future version. If you're concerned about the size of
# security stack, you probably have bigger problems.
#
try
:
max_stack_size
=
int
(
os
.
environ
.
get
(
'Z_MAX_STACK_SIZE'
,
'100'
))
except
:
max_stack_size
=
100
def
setDefaultBehaviors
(
ownerous
,
authenticated
,
verbose
):
global
_defaultPolicy
global
_embed_permission_in_roles
_defaultPolicy
=
ZopeSecurityPolicy
(
ownerous
=
ownerous
,
authenticated
=
authenticated
,
verbose
=
verbose
)
_embed_permission_in_roles
=
verbose
setDefaultBehaviors
(
True
,
True
,
False
)
class
SecurityManager
:
"""A security manager provides methods for checking access and managing
executable context and policies
"""
implements
(
ISecurityManager
)
__allow_access_to_unprotected_subobjects__
=
{
'validate'
:
1
,
'checkPermission'
:
1
,
'getUser'
:
1
,
'calledByExecutable'
:
1
}
def
__init__
(
self
,
thread_id
,
context
):
self
.
_thread_id
=
thread_id
self
.
_context
=
context
self
.
_policy
=
_defaultPolicy
def
validate
(
self
,
accessed
=
None
,
container
=
None
,
name
=
None
,
value
=
None
,
roles
=
_noroles
):
"""Validate access.
Arguments:
accessed -- the object that was being accessed
container -- the object the value was found in
name -- The name used to access the value
value -- The value retrieved though the access.
roles -- The roles of the object if already known.
The arguments may be provided as keyword arguments. Some of these
arguments may be ommitted, however, the policy may reject access
in some cases when arguments are ommitted. It is best to provide
all the values possible.
"""
policy
=
self
.
_policy
if
roles
is
_noroles
:
return
policy
.
validate
(
accessed
,
container
,
name
,
value
,
self
.
_context
)
else
:
return
policy
.
validate
(
accessed
,
container
,
name
,
value
,
self
.
_context
,
roles
)
def
DTMLValidate
(
self
,
accessed
=
None
,
container
=
None
,
name
=
None
,
value
=
None
,
md
=
None
):
"""Validate access.
* THIS EXISTS FOR DTML COMPATIBILITY *
Arguments:
accessed -- the object that was being accessed
container -- the object the value was found in
name -- The name used to access the value
value -- The value retrieved though the access.
md -- multidict for DTML (ignored)
The arguments may be provided as keyword arguments. Some of these
arguments may be ommitted, however, the policy may reject access
in some cases when arguments are ommitted. It is best to provide
all the values possible.
"""
policy
=
self
.
_policy
return
policy
.
validate
(
accessed
,
container
,
name
,
value
,
self
.
_context
)
def
checkPermission
(
self
,
permission
,
object
):
"""Check whether the security context allows the given permission on
the given object.
Arguments:
permission -- A permission name
object -- The object being accessed according to the permission
"""
policy
=
self
.
_policy
return
policy
.
checkPermission
(
permission
,
object
,
self
.
_context
)
def
addContext
(
self
,
anExecutableObject
,
getattr
=
getattr
):
"""Add an ExecutableObject to the current security
context. Optionally, add a new SecurityPolicy as well.
"""
stack
=
self
.
_context
.
stack
if
len
(
stack
)
>
max_stack_size
:
raise
SystemError
,
'Excessive recursion'
stack
.
append
(
anExecutableObject
)
p
=
getattr
(
anExecutableObject
,
'_customSecurityPolicy'
,
None
)
if
p
is
not
None
:
p
=
p
()
else
:
p
=
_defaultPolicy
self
.
_policy
=
p
def
removeContext
(
self
,
anExecutableObject
):
"""Remove an ExecutableObject, and optionally, a
SecurityPolicy, from the current security context.
"""
stack
=
self
.
_context
.
stack
if
not
stack
:
return
top
=
stack
[
-
1
]
if
top
is
anExecutableObject
:
del
stack
[
-
1
]
else
:
indexes
=
range
(
len
(
stack
))
indexes
.
reverse
()
for
i
in
indexes
:
top
=
stack
[
i
]
if
top
is
anExecutableObject
:
del
stack
[
i
:]
break
else
:
return
if
stack
:
top
=
stack
[
-
1
]
p
=
getattr
(
top
,
'_customSecurityPolicy'
,
None
)
if
p
is
not
None
:
p
=
p
()
else
:
p
=
_defaultPolicy
self
.
_policy
=
p
else
:
self
.
_policy
=
_defaultPolicy
def
getUser
(
self
):
"""Get the current authenticated user"""
return
self
.
_context
.
user
def
calledByExecutable
(
self
):
"""Return a boolean value indicating if this context was called
by an executable"""
return
len
(
self
.
_context
.
stack
)
# AccessControl.ZopeGuards
# ------------------------
def
aq_validate
(
inst
,
object
,
name
,
v
,
validate
):
return
validate
(
inst
,
object
,
name
,
v
)
_marker
=
object
()
def
guarded_getattr
(
inst
,
name
,
default
=
_marker
):
"""Retrieves an attribute, checking security in the process.
Raises Unauthorized if the attribute is found but the user is
not allowed to access the attribute.
"""
if
name
[:
1
]
==
'_'
:
raise
Unauthorized
,
name
# Try to get the attribute normally so that unusual
# exceptions are caught early.
try
:
v
=
getattr
(
inst
,
name
)
except
AttributeError
:
if
default
is
not
_marker
:
return
default
raise
try
:
container
=
v
.
im_self
except
AttributeError
:
container
=
aq_parent
(
aq_inner
(
v
))
or
inst
assertion
=
Containers
(
type
(
container
))
if
isinstance
(
assertion
,
dict
):
# We got a table that lets us reason about individual
# attrs
assertion
=
assertion
.
get
(
name
)
if
assertion
:
# There's an entry, but it may be a function.
if
callable
(
assertion
):
return
assertion
(
inst
,
name
)
# Nope, it's boolean
return
v
raise
Unauthorized
,
name
if
assertion
:
if
callable
(
assertion
):
factory
=
assertion
(
name
,
v
)
if
callable
(
factory
):
return
factory
(
inst
,
name
)
assert
factory
==
1
else
:
assert
assertion
==
1
return
v
# See if we can get the value doing a filtered acquire.
# aq_acquire will either return the same value as held by
# v or it will return an Unauthorized raised by validate.
validate
=
getSecurityManager
().
validate
aq_acquire
(
inst
,
name
,
aq_validate
,
validate
)
return
v
# Helpers for verbose authorization exceptions
# --------------------------------------------
def
item_repr
(
ob
):
"""Generates a repr without angle brackets (to avoid HTML quoting)"""
return
repr
(
ob
).
replace
(
'<'
,
'('
).
replace
(
'>'
,
')'
)
def
simplifyRoles
(
roles
):
"""Sorts and removes duplicates from a role list."""
d
=
{}
for
r
in
roles
:
d
[
r
]
=
1
lst
=
d
.
keys
()
lst
.
sort
()
return
lst
def
raiseVerbose
(
msg
,
accessed
,
container
,
name
,
value
,
context
,
required_roles
=
None
,
user_roles
=
None
,
user
=
None
,
eo
=
None
,
eo_owner
=
None
,
eo_owner_roles
=
None
,
eo_proxy_roles
=
None
,
):
"""Raises an Unauthorized error with a verbose explanation."""
s
=
'%s. Access to %s of %s'
%
(
msg
,
repr
(
name
),
item_repr
(
container
))
if
aq_base
(
container
)
is
not
aq_base
(
accessed
):
s
+=
', acquired through %s,'
%
item_repr
(
accessed
)
info
=
[
s
+
' denied.'
]
if
user
is
not
None
:
try
:
ufolder
=
'/'
.
join
(
aq_parent
(
aq_inner
(
user
)).
getPhysicalPath
())
except
:
ufolder
=
'(unknown)'
info
.
append
(
'Your user account, %s, exists at %s.'
%
(
str
(
user
),
ufolder
))
if
required_roles
is
not
None
:
p
=
None
required_roles
=
list
(
required_roles
)
for
r
in
required_roles
:
if
r
.
startswith
(
'_'
)
and
r
.
endswith
(
'_Permission'
):
p
=
r
[
1
:]
required_roles
.
remove
(
r
)
break
sr
=
simplifyRoles
(
required_roles
)
if
p
:
# got a permission name
info
.
append
(
'Access requires %s, '
'granted to the following roles: %s.'
%
(
p
,
sr
))
else
:
# permission name unknown
info
.
append
(
'Access requires one of the following roles: %s.'
%
sr
)
if
user_roles
is
not
None
:
info
.
append
(
'Your roles in this context are %s.'
%
simplifyRoles
(
user_roles
))
if
eo
is
not
None
:
s
=
'The executing script is %s'
%
item_repr
(
eo
)
if
eo_proxy_roles
is
not
None
:
s
+=
', with proxy roles: %s'
%
simplifyRoles
(
eo_proxy_roles
)
if
eo_owner
is
not
None
:
s
+=
', owned by %s'
%
repr
(
eo_owner
)
if
eo_owner_roles
is
not
None
:
s
+=
', who has the roles %s'
%
simplifyRoles
(
eo_owner_roles
)
info
.
append
(
s
+
'.'
)
text
=
' '
.
join
(
info
)
LOG
.
debug
(
'Unauthorized: %s'
%
text
)
raise
Unauthorized
(
text
)
def
getUserRolesInContext
(
user
,
context
):
"""Returns user roles for a context."""
if
hasattr
(
aq_base
(
user
),
'getRolesInContext'
):
return
user
.
getRolesInContext
(
context
)
else
:
return
()
def
userHasRolesButNotInContext
(
user
,
object
,
object_roles
):
'''Returns 1 if the user has any of the listed roles but
is not defined in a context which is not an ancestor of object.
'''
if
object_roles
is
None
or
'Anonymous'
in
object_roles
:
return
0
usr_roles
=
getUserRolesInContext
(
user
,
object
)
for
role
in
object_roles
:
if
role
in
usr_roles
:
# User has the roles.
return
(
not
verifyAcquisitionContext
(
user
,
object
,
object_roles
))
return
0
def
verifyAcquisitionContext
(
user
,
object
,
object_roles
=
None
):
"""Mimics the relevant section of User.allowed().
Returns true if the object is in the context of the user's user folder.
"""
ufolder
=
aq_parent
(
user
)
ucontext
=
aq_parent
(
ufolder
)
if
ucontext
is
not
None
:
if
object
is
None
:
# This is a strange rule, though
# it doesn't cause any security holes. SDH
return
1
if
hasattr
(
object
,
'im_self'
):
# This is a method. Grab its self.
object
=
object
.
im_self
if
not
aq_inContextOf
(
object
,
ucontext
,
1
):
if
'Shared'
in
object_roles
:
# Old role setting. Waaa
object_roles
=
user
.
_shared_roles
(
object
)
if
'Anonymous'
in
object_roles
:
return
1
return
None
# Note that if the user were not wrapped, it would
# not be possible to determine the user's context
# and this method would return 1.
# However, as long as user folders always return
# wrapped user objects, this is safe.
return
1
src/AccessControl/Implementation.py
deleted
100644 → 0
View file @
ccc10355
##############################################################################
#
# Copyright (c) 2003 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.
#
##############################################################################
"""Controller that can switch between security machinery implementations.
This module allows configuration of the security implementation after
the initial import of the modules. It is intended to allow runtime
selection of the machinery based on Zope's configuration file.
The helper function defined here switches between the 'C' and 'PYTHON'
security implementations by loading the appropriate implementation
module and wiring the implementation into the other modules of the
AccessControl package that defined the various components before this
module was introduced.
"""
def
getImplementationName
():
"""Return the name of the implementation currently being used."""
return
_implementation_name
def
setImplementation
(
name
):
"""Select the policy implementation to use. The 'name' must be either
'PYTHON' or 'C'. NOTE: this function is intended to be called
exactly once, so that the Zope config file can dictate the policy
implementation to be used. Subsequent calls to this function will
have no effect!!
"""
import
sys
global
_implementation_name
global
_implementation_set
if
_implementation_set
:
return
name
=
name
.
upper
()
if
name
==
_implementation_name
:
return
if
name
==
"C"
:
from
AccessControl
import
ImplC
as
impl
elif
name
==
"PYTHON"
:
from
AccessControl
import
ImplPython
as
impl
else
:
raise
ValueError
(
"unknown policy implementation: %r"
%
name
)
_implementation_name
=
name
for
modname
,
names
in
_policy_names
.
items
():
__import__
(
modname
)
mod
=
sys
.
modules
[
modname
]
for
n
in
names
:
setattr
(
mod
,
n
,
getattr
(
impl
,
n
))
if
hasattr
(
mod
,
"initialize"
):
mod
.
initialize
(
impl
)
from
AccessControl.SecurityManager
import
setSecurityPolicy
policy
=
impl
.
ZopeSecurityPolicy
(
True
,
True
)
setSecurityPolicy
(
policy
)
_implementation_set
=
1
_implementation_name
=
None
_implementation_set
=
0
_policy_names
=
{
"AccessControl"
:
(
"setDefaultBehaviors"
,
),
"AccessControl.PermissionRole"
:
(
"_what_not_even_god_should_do"
,
"rolesForPermissionOn"
,
"PermissionRole"
,
"imPermissionRole"
,
),
"AccessControl.SecurityManagement"
:
(
"SecurityManager"
,
),
"AccessControl.SecurityManager"
:
(
"SecurityManager"
,
),
"AccessControl.ZopeGuards"
:
(
"aq_validate"
,
"guarded_getattr"
,
),
"AccessControl.ZopeSecurityPolicy"
:
(
"ZopeSecurityPolicy"
,
),
}
# start with the default, mostly because we need something for the tests
setImplementation
(
"C"
)
# allow the implementation to change from the default
_implementation_set
=
0
src/AccessControl/Owned.py
deleted
100644 → 0
View file @
ccc10355
##############################################################################
#
# 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
#
##############################################################################
"""Support for owned objects
"""
# BBB
from
.owner
import
absattr
from
.owner
import
EditUnowned
from
.owner
import
EmergencyUserCannotOwn
from
.owner
import
ownableFilter
from
.owner
import
ownerInfo
from
.owner
import
UnownableOwner
from
zope.deferredimport
import
deprecated
deprecated
(
"Owned is no longer part of AccessControl, please "
"depend on Zope2 and import from OFS.owner or use the "
"new minimal Owned class from AccessControl.owner."
,
Owned
=
'OFS.owner:Owned'
,
)
src/AccessControl/Permission.py
deleted
100644 → 0
View file @
ccc10355
##############################################################################
#
# 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.
#
##############################################################################
"""Permissions
"""
import
string
from
Acquisition
import
aq_base
name_trans
=
filter
(
lambda
c
,
an
=
string
.
letters
+
string
.
digits
+
'_'
:
c
not
in
an
,
map
(
chr
,
range
(
256
)))
name_trans
=
string
.
maketrans
(
''
.
join
(
name_trans
),
'_'
*
len
(
name_trans
))
def
pname
(
name
,
translate
=
string
.
translate
,
name_trans
=
name_trans
):
return
'_'
+
translate
(
name
,
name_trans
)
+
"_Permission"
_marker
=
[]
class
Permission
:
# A Permission maps a named logical permission to a set
# of attribute names. Attribute names which appear in a
# permission may not appear in any other permission defined
# by the object.
def
__init__
(
self
,
name
,
data
,
obj
,
default
=
None
):
self
.
name
=
name
self
.
_p
=
'_'
+
string
.
translate
(
name
,
name_trans
)
+
"_Permission"
self
.
data
=
data
self
.
obj
=
aq_base
(
obj
)
self
.
default
=
default
def
getRoles
(
self
,
default
=
_marker
):
# Return the list of role names which have been given
# this permission for the object in question. To do
# this, we try to get __roles__ from all of the object
# attributes that this permission represents.
obj
=
self
.
obj
name
=
self
.
_p
if
hasattr
(
obj
,
name
):
return
getattr
(
obj
,
name
)
roles
=
default
for
name
in
self
.
data
:
if
name
:
if
hasattr
(
obj
,
name
):
attr
=
getattr
(
obj
,
name
)
if
hasattr
(
attr
,
'im_self'
):
attr
=
attr
.
im_self
if
hasattr
(
attr
,
'__dict__'
):
attr
=
attr
.
__dict__
name
=
name
+
'__roles__'
if
name
in
attr
:
roles
=
attr
[
name
]
break
elif
hasattr
(
obj
,
'__dict__'
):
attr
=
obj
.
__dict__
if
'__roles__'
in
attr
:
roles
=
attr
[
'__roles__'
]
break
if
roles
:
try
:
if
'Shared'
not
in
roles
:
return
tuple
(
roles
)
roles
=
list
(
roles
)
roles
.
remove
(
'Shared'
)
return
roles
except
:
return
[]
if
roles
is
None
:
return
[
'Manager'
,
'Anonymous'
]
if
roles
is
_marker
:
return
[
'Manager'
]
return
roles
def
setRoles
(
self
,
roles
):
obj
=
self
.
obj
if
isinstance
(
roles
,
list
)
and
not
roles
:
if
hasattr
(
obj
,
self
.
_p
):
delattr
(
obj
,
self
.
_p
)
else
:
setattr
(
obj
,
self
.
_p
,
roles
)
for
name
in
self
.
data
:
if
name
==
''
:
attr
=
obj
else
:
attr
=
getattr
(
obj
,
name
)
try
:
del
attr
.
__roles__
except
:
pass
try
:
delattr
(
obj
,
name
+
'__roles__'
)
except
:
pass
def
setRole
(
self
,
role
,
present
):
roles
=
self
.
getRoles
()
if
role
in
roles
:
if
present
:
return
if
isinstance
(
roles
,
list
):
roles
.
remove
(
role
)
else
:
roles
=
list
(
roles
)
roles
.
remove
(
role
)
roles
=
tuple
(
roles
)
elif
not
present
:
return
else
:
if
isinstance
(
roles
,
list
):
roles
.
append
(
role
)
else
:
roles
=
roles
+
(
role
,
)
self
.
setRoles
(
roles
)
def
__len__
(
self
):
return
1
def
__str__
(
self
):
return
self
.
name
_registeredPermissions
=
{}
_ac_permissions
=
()
def
getPermissions
():
return
_ac_permissions
def
addPermission
(
perm
,
default_roles
=
(
'Manager'
,
)):
if
perm
in
_registeredPermissions
:
return
entry
=
((
perm
,
(),
default_roles
),
)
global
_ac_permissions
_ac_permissions
=
_ac_permissions
+
entry
_registeredPermissions
[
perm
]
=
1
mangled
=
pname
(
perm
)
# get mangled permission name
if
not
hasattr
(
ApplicationDefaultPermissions
,
mangled
):
setattr
(
ApplicationDefaultPermissions
,
mangled
,
default_roles
)
def
registerPermissions
(
permissions
,
defaultDefault
=
(
'Manager'
,
)):
"""Register an __ac_permissions__ sequence.
"""
for
setting
in
permissions
:
if
setting
[
0
]
in
_registeredPermissions
:
continue
if
len
(
setting
)
==
2
:
perm
,
methods
=
setting
default
=
defaultDefault
else
:
perm
,
methods
,
default
=
setting
addPermission
(
perm
,
default
)
class
ApplicationDefaultPermissions
:
_View_Permission
=
(
'Manager'
,
'Anonymous'
)
_Access_contents_information_Permission
=
(
'Manager'
,
'Anonymous'
)
src/AccessControl/PermissionMapping.py
deleted
100644 → 0
View file @
ccc10355
##############################################################################
#
# 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
#
##############################################################################
"""Permission Mapping
Sometimes, we need an object's permissions to be remapped to other permissions
when the object is used in special ways. This is rather hard, since we
need the object's ordinary permissions intact so we can manage it.
"""
from
cgi
import
escape
from
Acquisition
import
ImplicitAcquisitionWrapper
from
ExtensionClass
import
Base
from
zope.interface
import
implements
from
AccessControl.class_init
import
InitializeClass
from
AccessControl.interfaces
import
IPermissionMappingSupport
from
AccessControl.owner
import
UnownableOwner
from
AccessControl.Permission
import
pname
from
AccessControl.requestmethod
import
requestmethod
class
RoleManager
:
implements
(
IPermissionMappingSupport
)
# XXX: No security declarations?
def
manage_getPermissionMapping
(
self
):
"""Return the permission mapping for the object
This is a list of dictionaries with:
permission_name -- The name of the native object permission
class_permission -- The class permission the permission is
mapped to.
"""
wrapper
=
getattr
(
self
,
'_permissionMapper'
,
None
)
if
wrapper
is
None
:
wrapper
=
PM
()
perms
=
{}
for
p
in
self
.
possible_permissions
():
perms
[
pname
(
p
)]
=
p
r
=
[]
a
=
r
.
append
for
ac_perms
in
self
.
ac_inherited_permissions
(
1
):
p
=
perms
.
get
(
getPermissionMapping
(
ac_perms
[
0
],
wrapper
),
''
)
a
({
'permission_name'
:
ac_perms
[
0
],
'class_permission'
:
p
})
return
r
@
requestmethod
(
'POST'
)
def
manage_setPermissionMapping
(
self
,
permission_names
=
[],
class_permissions
=
[],
REQUEST
=
None
):
"""Change the permission mapping
"""
wrapper
=
getattr
(
self
,
'_permissionMapper'
,
None
)
if
wrapper
is
None
:
wrapper
=
PM
()
perms
=
self
.
possible_permissions
()
for
i
in
range
(
len
(
permission_names
)):
name
=
permission_names
[
i
]
p
=
class_permissions
[
i
]
if
p
and
(
p
not
in
perms
):
__traceback_info__
=
perms
,
p
,
i
raise
ValueError
,
(
"""Attempted to map a permission to a permission, %s,
that is not valid. This should never happen. (Waaa).
"""
%
escape
(
p
))
setPermissionMapping
(
name
,
wrapper
,
p
)
self
.
_permissionMapper
=
wrapper
if
REQUEST
is
not
None
:
return
self
.
manage_access
(
REQUEST
,
manage_tabs_message
=
'The permission mapping has been updated'
)
def
_isBeingUsedAsAMethod
(
self
,
REQUEST
=
None
,
wannaBe
=
0
):
try
:
if
hasattr
(
self
,
'aq_self'
):
r
=
self
.
aq_acquire
(
'_isBeingUsedAsAMethod_'
)
else
:
r
=
self
.
_isBeingUsedAsAMethod_
except
:
r
=
0
if
REQUEST
is
not
None
:
if
not
r
!=
(
not
wannaBe
):
REQUEST
.
response
.
notFoundError
()
return
r
InitializeClass
(
RoleManager
)
def
getPermissionMapping
(
name
,
obj
,
st
=
type
(
''
)):
obj
=
getattr
(
obj
,
'aq_base'
,
obj
)
name
=
pname
(
name
)
r
=
getattr
(
obj
,
name
,
''
)
if
type
(
r
)
is
not
st
:
r
=
''
return
r
def
setPermissionMapping
(
name
,
obj
,
v
):
name
=
pname
(
name
)
if
v
:
setattr
(
obj
,
name
,
pname
(
v
))
elif
obj
.
__dict__
.
has_key
(
name
):
delattr
(
obj
,
name
)
class
PM
(
Base
):
_owner
=
UnownableOwner
_View_Permission
=
'_View_Permission'
_is_wrapperish
=
1
def
__getattr__
(
self
,
name
):
# We want to make sure that any non-explicitly set methods are
# private!
if
name
.
startswith
(
'_'
)
and
name
.
endswith
(
"_Permission"
):
return
''
raise
AttributeError
,
escape
(
name
)
PermissionMapper
=
PM
def
aqwrap
(
object
,
wrapper
,
parent
):
r
=
Rewrapper
()
r
.
_ugh
=
wrapper
,
object
,
parent
return
r
class
Rewrapper
(
Base
):
def
__of__
(
self
,
parent
):
w
,
m
,
p
=
self
.
_ugh
return
m
.
__of__
(
ImplicitAcquisitionWrapper
(
w
,
parent
))
def
__getattr__
(
self
,
name
):
w
,
m
,
parent
=
self
.
_ugh
self
=
m
.
__of__
(
ImplicitAcquisitionWrapper
(
w
,
parent
))
return
getattr
(
self
,
name
)
def
__call__
(
self
,
*
args
,
**
kw
):
w
,
m
,
parent
=
self
.
_ugh
self
=
m
.
__of__
(
ImplicitAcquisitionWrapper
(
w
,
parent
))
return
apply
(
self
,
args
,
kw
)
src/AccessControl/PermissionRole.py
deleted
100644 → 0
View file @
ccc10355
##############################################################################
#
# 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
#
##############################################################################
'''Objects that implement Permission-based roles.
'''
# The following names are inserted by AccessControl.Implementation:
#
# rolesForPermissionOn, PermissionRole, imPermissionRole,
# _what_not_even_god_should_do
src/AccessControl/Permissions.py
deleted
100644 → 0
View file @
ccc10355
##############################################################################
#
# 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
#
##############################################################################
"""Constant definitions for built-in Zope permissions
"""
access_contents_information
=
'Access contents information'
add_database_methods
=
'Add Database Methods'
add_documents_images_and_files
=
'Add Documents, Images, and Files'
add_external_methods
=
'Add External Methods'
add_folders
=
'Add Folders'
add_mailhost_objects
=
'Add MailHost objects'
add_page_templates
=
'Add Page Templates'
add_python_scripts
=
'Add Python Scripts'
add_user_folders
=
'Add User Folders'
add_vocabularies
=
'Add Vocabularies'
add_z_gadfly_database_connections
=
'Add Z Gadfly Database Connections'
add_zcatalogs
=
'Add ZCatalogs'
add_zope_tutorials
=
'Add Zope Tutorials'
change_database_connections
=
'Change Database Connections'
change_database_methods
=
'Change Database Methods'
change_external_methods
=
'Change External Methods'
change_images_and_files
=
'Change Images and Files'
change_python_scripts
=
'Change Python Scripts'
change_configuration
=
'Change configuration'
change_page_templates
=
'Change Page Templates'
change_permissions
=
'Change permissions'
change_proxy_roles
=
'Change proxy roles'
copy_or_move
=
'Copy or Move'
create_class_instances
=
'Create class instances'
define_permissions
=
'Define permissions'
delete_objects
=
'Delete objects'
edit_factories
=
'Edit Factories'
ftp_access
=
'FTP access'
import_export_objects
=
'Import/Export objects'
manage_vocabulary
=
'Manage Vocabulary'
manage_zcatalog_entries
=
'Manage ZCatalog Entries'
manage_zcatalog_indexes
=
'Manage ZCatalogIndex Entries'
manage_properties
=
'Manage properties'
manage_users
=
'Manage users'
open_close_database_connection
=
'Open/Close Database Connection'
open_close_database_connections
=
'Open/Close Database Connections'
query_vocabulary
=
'Query Vocabulary'
search_zcatalog
=
'Search ZCatalog'
take_ownership
=
'Take ownership'
test_database_connections
=
'Test Database Connections'
undo_changes
=
'Undo changes'
use_database_methods
=
'Use Database Methods'
use_factories
=
'Use Factories'
use_mailhost_services
=
'Use mailhost services'
view
=
'View'
view_history
=
'View History'
view_management_screens
=
'View management screens'
webdav_access
=
'WebDAV access'
webdav_lock_items
=
'WebDAV Lock items'
webdav_unlock_items
=
'WebDAV Unlock items'
from
zope.deferredimport
import
deprecated
new_loc
=
'DocumentTemplate.permissions'
deprecated
(
"Please import from %s"
%
new_loc
,
change_dtml_documents
=
'%s:change_dtml_documents'
%
new_loc
,
change_dtml_methods
=
'%s:change_dtml_methods'
%
new_loc
,
)
src/AccessControl/Role.py
deleted
100644 → 0
View file @
ccc10355
##############################################################################
#
# 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
#
##############################################################################
"""Access control support
"""
# BBB
from
.rolemanager
import
DEFAULTMAXLISTUSERS
from
.rolemanager
import
_isBeingUsedAsAMethod
from
.rolemanager
import
_isNotBeingUsedAsAMethod
from
.rolemanager
import
reqattr
from
.rolemanager
import
classattr
from
.rolemanager
import
instance_dict
from
.rolemanager
import
class_dict
from
.rolemanager
import
instance_attrs
from
.rolemanager
import
class_attrs
from
.rolemanager
import
gather_permissions
from
zope.deferredimport
import
deprecated
deprecated
(
"RoleManager is no longer part of AccessControl, please "
"depend on Zope2 and import from OFS.role or use the new minimal "
"RoleManager class from AccessControl.rolemanager."
,
RoleManager
=
'OFS.role:RoleManager'
,
)
src/AccessControl/SecurityInfo.py
deleted
100644 → 0
View file @
ccc10355
##############################################################################
#
# 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
#
##############################################################################
"""SecurityInfo objects and access control constants.
SecurityInfo objects are used in class definitions to allow
a declarative style of associating access control information
with class attributes.
More information on using SecurityInfo and guide to Zope security
for developers can be found in the dev.zope.org "Declarative Security"
project:
http://dev.zope.org/Wikis/DevSite/Projects/DeclarativeSecurity
While SecurityInfo objects largely remove the need for Python
programmers to care about the underlying implementation, there
are several constants defined that should be used by code that
must set __roles__ attributes directly. (the constants are also
accessible from the AccessControl namespace). The defined access
control constants and their meanings are:
ACCESS_PUBLIC: accessible from restricted code and possibly
through the web (if object has a docstring)
ACCESS_PRIVATE: accessible only from python code
ACCESS_NONE: no access
"""
import
sys
from
logging
import
getLogger
from
AccessControl.ImplPython
import
_what_not_even_god_should_do
from
Acquisition
import
Implicit
LOG
=
getLogger
(
'SecurityInfo'
)
# Security constants - these are imported into the AccessControl
# namespace and can be referenced as AccessControl.PUBLIC etc.
ACCESS_NONE
=
_what_not_even_god_should_do
ACCESS_PRIVATE
=
()
ACCESS_PUBLIC
=
None
_marker
=
[]
class
SecurityInfo
(
Implicit
):
"""Encapsulate security information."""
__security_info__
=
1
__roles__
=
ACCESS_PRIVATE
def
__init__
(
self
):
self
.
names
=
{}
self
.
roles
=
{}
def
_setaccess
(
self
,
names
,
access
):
for
name
in
names
:
if
self
.
names
.
get
(
name
,
access
)
!=
access
:
LOG
.
warn
(
'Conflicting security declarations for "%s"'
%
name
)
self
.
_warnings
=
1
self
.
names
[
name
]
=
access
declarePublic__roles__
=
ACCESS_PRIVATE
def
declarePublic
(
self
,
name
,
*
names
):
"""Declare names to be publicly accessible."""
self
.
_setaccess
((
name
,)
+
names
,
ACCESS_PUBLIC
)
declarePrivate__roles__
=
ACCESS_PRIVATE
def
declarePrivate
(
self
,
name
,
*
names
):
"""Declare names to be inaccessible to restricted code."""
self
.
_setaccess
((
name
,)
+
names
,
ACCESS_PRIVATE
)
declareProtected__roles__
=
ACCESS_PRIVATE
def
declareProtected
(
self
,
permission_name
,
name
,
*
names
):
"""Declare names to be associated with a permission."""
self
.
_setaccess
((
name
,)
+
names
,
permission_name
)
declareObjectPublic__roles__
=
ACCESS_PRIVATE
def
declareObjectPublic
(
self
):
"""Declare the object to be publicly accessible."""
self
.
_setaccess
((
''
,),
ACCESS_PUBLIC
)
declareObjectPrivate__roles__
=
ACCESS_PRIVATE
def
declareObjectPrivate
(
self
):
"""Declare the object to be inaccessible to restricted code."""
self
.
_setaccess
((
''
,),
ACCESS_PRIVATE
)
declareObjectProtected__roles__
=
ACCESS_PRIVATE
def
declareObjectProtected
(
self
,
permission_name
):
"""Declare the object to be associated with a permission."""
self
.
_setaccess
((
''
,),
permission_name
)
setPermissionDefault__roles__
=
ACCESS_PRIVATE
def
setPermissionDefault
(
self
,
permission_name
,
roles
):
"""Declare default roles for a permission"""
rdict
=
{}
for
role
in
roles
:
rdict
[
role
]
=
1
if
self
.
roles
.
get
(
permission_name
,
rdict
)
!=
rdict
:
LOG
.
warn
(
'Conflicting default role'
'declarations for permission "%s"'
%
permission_name
)
self
.
_warnings
=
1
self
.
roles
[
permission_name
]
=
rdict
setDefaultAccess__roles__
=
ACCESS_PRIVATE
def
setDefaultAccess
(
self
,
access
):
"""Declare default attribute access policy.
This should be a boolean value, a map of attribute names to
booleans, or a callable (name, value) -> boolean.
"""
if
isinstance
(
access
,
str
):
access
=
access
.
lower
()
if
access
==
'allow'
:
access
=
1
elif
access
==
'deny'
:
access
=
0
else
:
raise
ValueError
,
"'allow' or 'deny' expected"
self
.
access
=
access
class
ClassSecurityInfo
(
SecurityInfo
):
"""Encapsulate security information for class objects."""
__roles__
=
ACCESS_PRIVATE
apply__roles__
=
ACCESS_PRIVATE
def
apply
(
self
,
classobj
):
"""Apply security information to the given class object."""
dict
=
classobj
.
__dict__
# Check the class for an existing __ac_permissions__ and
# incorporate that if present to support older classes or
# classes that haven't fully switched to using SecurityInfo.
if
dict
.
has_key
(
'__ac_permissions__'
):
for
item
in
dict
[
'__ac_permissions__'
]:
permission_name
=
item
[
0
]
self
.
_setaccess
(
item
[
1
],
permission_name
)
if
len
(
item
)
>
2
:
self
.
setPermissionDefault
(
permission_name
,
item
[
2
])
# Set __roles__ for attributes declared public or private.
# Collect protected attribute names in ac_permissions.
ac_permissions
=
{}
for
name
,
access
in
self
.
names
.
items
():
if
access
in
(
ACCESS_PRIVATE
,
ACCESS_PUBLIC
,
ACCESS_NONE
):
setattr
(
classobj
,
'%s__roles__'
%
name
,
access
)
else
:
if
not
ac_permissions
.
has_key
(
access
):
ac_permissions
[
access
]
=
[]
ac_permissions
[
access
].
append
(
name
)
# Now transform our nested dict structure into the nested tuple
# structure expected of __ac_permissions__ attributes and set
# it on the class object.
getRoles
=
self
.
roles
.
get
__ac_permissions__
=
[]
permissions
=
ac_permissions
.
items
()
permissions
.
sort
()
for
permission_name
,
names
in
permissions
:
roles
=
getRoles
(
permission_name
,
())
if
len
(
roles
):
entry
=
(
permission_name
,
tuple
(
names
),
tuple
(
roles
.
keys
()))
else
:
entry
=
(
permission_name
,
tuple
(
names
))
__ac_permissions__
.
append
(
entry
)
for
permission_name
,
roles
in
self
.
roles
.
items
():
if
permission_name
not
in
ac_permissions
:
entry
=
(
permission_name
,
(),
tuple
(
roles
.
keys
()))
__ac_permissions__
.
append
(
entry
)
setattr
(
classobj
,
'__ac_permissions__'
,
tuple
(
__ac_permissions__
))
# Take care of default attribute access policy
access
=
getattr
(
self
,
'access'
,
_marker
)
if
access
is
not
_marker
:
setattr
(
classobj
,
'__allow_access_to_unprotected_subobjects__'
,
access
)
if
getattr
(
self
,
'_warnings'
,
None
):
LOG
.
warn
(
'Class "%s" had conflicting '
'security declarations'
%
classobj
.
__name__
)
class
ClassSecurityInformation
(
ClassSecurityInfo
):
# Default policy is disallow
access
=
0
_moduleSecurity
=
{}
_appliedModuleSecurity
=
{}
def
secureModule
(
mname
,
*
imp
):
modsec
=
_moduleSecurity
.
get
(
mname
,
None
)
if
modsec
is
None
:
return
if
imp
:
__import__
(
mname
,
*
imp
)
del
_moduleSecurity
[
mname
]
module
=
sys
.
modules
[
mname
]
modsec
.
apply
(
module
.
__dict__
)
_appliedModuleSecurity
[
mname
]
=
modsec
return
module
def
ModuleSecurityInfo
(
module_name
=
None
):
if
module_name
is
not
None
:
modsec
=
_moduleSecurity
.
get
(
module_name
,
None
)
if
modsec
is
not
None
:
return
modsec
modsec
=
_appliedModuleSecurity
.
get
(
module_name
,
None
)
if
modsec
is
not
None
:
# Move security info back to to-apply dict (needed for product
# refresh). Also invoke this check for parent packages already
# applied
del
_appliedModuleSecurity
[
module_name
]
_moduleSecurity
[
module_name
]
=
modsec
dot
=
module_name
.
rfind
(
'.'
)
if
dot
>
0
:
ModuleSecurityInfo
(
module_name
[:
dot
])
return
modsec
dot
=
module_name
.
rfind
(
'.'
)
if
dot
>
0
:
# If the module is in a package, recursively make sure
# there are security declarations for the package steps
# leading to the module
modname
=
module_name
[
dot
+
1
:]
pmodsec
=
ModuleSecurityInfo
(
module_name
[:
dot
])
if
not
pmodsec
.
names
.
has_key
(
modname
):
pmodsec
.
declarePublic
(
modname
)
return
_ModuleSecurityInfo
(
module_name
)
class
_ModuleSecurityInfo
(
SecurityInfo
):
"""Encapsulate security information for modules."""
__roles__
=
ACCESS_PRIVATE
def
__init__
(
self
,
module_name
=
None
):
self
.
names
=
{}
if
module_name
is
not
None
:
global
_moduleSecurity
_moduleSecurity
[
module_name
]
=
self
__call____roles__
=
ACCESS_PRIVATE
def
__call__
(
self
,
name
,
value
):
"""Callback for __allow_access_to_unprotected_subobjects__ hook."""
access
=
self
.
names
.
get
(
name
,
_marker
)
if
access
is
not
_marker
:
return
access
==
ACCESS_PUBLIC
return
getattr
(
self
,
'access'
,
0
)
apply__roles__
=
ACCESS_PRIVATE
def
apply
(
self
,
dict
):
"""Apply security information to the given module dict."""
# Start with default attribute access policy
access
=
getattr
(
self
,
'access'
,
_marker
)
if
access
is
not
_marker
or
len
(
self
.
names
):
dict
[
'__allow_access_to_unprotected_subobjects__'
]
=
self
if
getattr
(
self
,
'_warnings'
,
None
):
LOG
.
warn
(
'Module "%s" had conflicting '
'security declarations'
%
dict
[
'__name__'
])
declareProtected__roles__
=
ACCESS_PRIVATE
def
declareProtected
(
self
,
permission_name
,
*
names
):
"""Cannot declare module names protected."""
pass
declareObjectProtected__roles__
=
ACCESS_PRIVATE
def
declareObjectProtected
(
self
,
permission_name
):
"""Cannot declare module protected."""
pass
setDefaultRoles__roles__
=
ACCESS_PRIVATE
def
setDefaultRoles
(
self
,
permission_name
,
roles
):
"""Cannot set default roles for permissions in a module."""
pass
# Handy little utility functions
def
allow_module
(
module_name
):
"""Allow a module and all its contents to be used from a
restricted Script. The argument module_name may be a simple
or dotted module or package name. Note that if a package
path is given, all modules in the path will be available."""
ModuleSecurityInfo
(
module_name
).
setDefaultAccess
(
1
)
dot
=
module_name
.
find
(
'.'
)
while
dot
>
0
:
ModuleSecurityInfo
(
module_name
[:
dot
]).
setDefaultAccess
(
1
)
dot
=
module_name
.
find
(
'.'
,
dot
+
1
)
def
allow_class
(
Class
):
"""Allow a class and all of its methods to be used from a
restricted Script. The argument Class must be a class."""
Class
.
_security
=
sec
=
ClassSecurityInfo
()
sec
.
declareObjectPublic
()
sec
.
setDefaultAccess
(
1
)
sec
.
apply
(
Class
)
from
AccessControl.class_init
import
InitializeClass
InitializeClass
(
Class
)
src/AccessControl/SecurityManagement.py
deleted
100644 → 0
View file @
ccc10355
##############################################################################
#
# 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
#
##############################################################################
"""Security management
"""
def
getSecurityManager
():
"""Get a security manager, for the current thread.
"""
thread_id
=
get_ident
()
manager
=
_managers
.
get
(
thread_id
,
None
)
if
manager
is
None
:
nobody
=
getattr
(
SpecialUsers
,
'nobody'
,
None
)
if
nobody
is
None
:
# Initialize SpecialUsers by importing User.py.
import
User
nobody
=
SpecialUsers
.
nobody
manager
=
SecurityManager
(
thread_id
,
SecurityContext
(
nobody
))
_managers
[
thread_id
]
=
manager
return
manager
def
setSecurityManager
(
manager
):
"""install *manager* as current security manager for this thread."""
thread_id
=
get_ident
()
_managers
[
thread_id
]
=
manager
import
SpecialUsers
# AccessControl.Implementation inserts SecurityManager.
try
:
from
thread
import
get_ident
except
ImportError
:
def
get_ident
():
return
0
_managers
=
{}
def
newSecurityManager
(
request
,
user
):
"""Set up a new security context for a request for a user
"""
thread_id
=
get_ident
()
_managers
[
thread_id
]
=
SecurityManager
(
thread_id
,
SecurityContext
(
user
),
)
def
noSecurityManager
():
try
:
del
_managers
[
get_ident
()]
except
:
pass
def
setSecurityPolicy
(
aSecurityPolicy
):
"""Set the system default security policy.
This method should only be caused by system startup code. It should
never, for example, be called during a web request.
"""
SecurityManager
.
setSecurityPolicy
(
aSecurityPolicy
)
class
SecurityContext
:
"""The security context is an object used internally to the security
machinery. It captures data about the current security context.
"""
def
__init__
(
self
,
user
):
self
.
stack
=
[]
self
.
user
=
user
self
.
objectCache
=
{}
src/AccessControl/SecurityManager.py
deleted
100644 → 0
View file @
ccc10355
##############################################################################
#
# 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
#
##############################################################################
'''API module to set the security policy
'''
from
AccessControl
import
ImplPython
as
_ImplPython
from
AccessControl.SimpleObjectPolicies
import
_noroles
def
setSecurityPolicy
(
aSecurityPolicy
):
"""Set the system default security policy.
This method should only be caused by system startup code. It should
never, for example, be called during a web request.
"""
last
=
_ImplPython
.
_defaultPolicy
_ImplPython
.
_defaultPolicy
=
aSecurityPolicy
return
last
# AccessControl.Implementation inserts SecurityManager.
src/AccessControl/SimpleObjectPolicies.py
deleted
100644 → 0
View file @
ccc10355
##############################################################################
#
# 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
#
##############################################################################
'''Collect rules for access to objects that don
\
'
t have roles.
The rules are expressed as a mapping from type -> assertion
An assertion can be:
- A dict
- A callable
- Something with a truth value
If the assertion is a callable, then it will be called with
a name being accessed and the name used. Its return value is ignored,
but in may veto an access by raising an exception.
If the assertion is a dictionary, then the keys are attribute names.
The values may be callables or objects with boolean values. If a value
is callable, it will be called with the object we are accessing an
attribute of and the attribute name. It should return an attribute
value. Callables are often used to returned guarded versions of
methods. Otherwise, accesses are allowed if values in this dictionary
are true and disallowed if the values are false or if an item for an
attribute name is not present.
If the assertion is not a dict and is not callable, then access to
unprotected attributes is allowed if the assertion is true, and
disallowed otherwise.
XXX This descrition doesn't actually match what's done in ZopeGuards
or in ZopeSecurityPolicy. :(
'''
_noroles
=
[]
# this is imported in various places
import
Record
# Allow access to unprotected attributes
Record
.
Record
.
__allow_access_to_unprotected_subobjects__
=
1
# ContainerAssertions are used by cAccessControl to check access to
# attributes of container types, like dict, list, or string.
# ContainerAssertions maps types to a either a dict, a function, or a
# simple boolean value. When guarded_getattr checks the type of its
# first argument against ContainerAssertions, and invokes checking
# logic depending on what value it finds.
# If the value for a type is:
# - a boolean value:
# - the value determines whether access is allowed
# - a function (or callable):
# - The function is called with the name of the attribute and
# the actual attribute value, then the value is returned.
# The function can raise an exception.
# - a dict:
# - The dict maps attribute names to boolean values or functions.
# The boolean values behave as above, but the functions do not.
# The value returned for attribute access is the result of
# calling the function with the object and the attribute name.
ContainerAssertions
=
{
type
(()):
1
,
type
(
''
):
1
,
type
(
u''
):
1
,
}
Containers
=
ContainerAssertions
.
get
def
allow_type
(
Type
,
allowed
=
1
):
"""Allow a type and all of its methods and attributes to be used from
restricted code. The argument Type must be a type."""
if
type
(
Type
)
is
not
type
:
raise
ValueError
,
"%s is not a type"
%
`Type`
if
hasattr
(
Type
,
'__roles__'
):
raise
ValueError
,
"%s handles its own security"
%
`Type`
if
not
(
isinstance
(
allowed
,
int
)
or
isinstance
(
allowed
,
dict
)):
raise
ValueError
,
"The 'allowed' argument must be an int or dict."
ContainerAssertions
[
Type
]
=
allowed
#
# WAAAA!
#
from
BTrees.OOBTree
import
OOBTree
,
OOBucket
,
OOSet
from
BTrees.OIBTree
import
OIBTree
,
OIBucket
,
OISet
from
BTrees.IOBTree
import
IOBTree
,
IOBucket
,
IOSet
from
BTrees.IIBTree
import
IIBTree
,
IIBucket
,
IISet
for
tree_type
,
has_values
in
[(
OOBTree
,
1
),
(
OOBucket
,
1
),
(
OOSet
,
0
),
(
OIBTree
,
1
),
(
OIBucket
,
1
),
(
OISet
,
0
),
(
IOBTree
,
1
),
(
IOBucket
,
1
),
(
IOSet
,
0
),
(
IIBTree
,
1
),
(
IIBucket
,
1
),
(
IISet
,
0
),
]:
tree
=
tree_type
()
key_type
=
type
(
tree
.
keys
())
if
key_type
is
not
list
:
# lists have their own declarations
allow_type
(
key_type
)
if
has_values
:
assert
key_type
is
type
(
tree
.
values
())
assert
key_type
is
type
(
tree
.
items
())
src/AccessControl/SpecialUsers.py
deleted
100644 → 0
View file @
ccc10355
##############################################################################
#
# 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.
#
##############################################################################
"""Place to find special users
This is needed to avoid a circular import problem. The 'real' values
are stored here by the AccessControl.User module as part of it's
initialization.
"""
nobody
=
None
system
=
None
emergency_user
=
None
# Note: use of the 'super' name is deprecated.
super
=
None
src/AccessControl/User.py
deleted
100644 → 0
View file @
ccc10355
##############################################################################
#
# 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.
#
##############################################################################
"""Access control package.
"""
# BBB
from
.users
import
BasicUser
from
.users
import
SimpleUser
from
.users
import
SpecialUser
from
.users
import
User
from
.users
import
UnrestrictedUser
from
.users
import
NullUnrestrictedUser
from
.users
import
readUserAccessFile
from
.users
import
emergency_user
from
.users
import
emergency_user
as
super
from
.users
import
_remote_user_mode
from
.users
import
nobody
from
.users
import
system
from
.users
import
rolejoin
from
.users
import
addr_match
from
.users
import
host_match
from
.users
import
domainSpecMatch
from
.users
import
absattr
from
.users
import
reqattr
from
.users
import
UnrestrictedUser
as
Super
from
zope.deferredimport
import
deprecated
deprecated
(
"User folders are no longer part of AccessControl, please depend "
"on Zope2 and import from OFS.userfolder or use the new minimal "
"user folder classes from AccessControl.userfolder."
,
BasicUserFolder
=
'OFS.userfolder:BasicUserFolder'
,
manage_addUserFolder
=
'OFS.userfolder:manage_addUserFolder'
,
UserFolder
=
'OFS.userfolder:UserFolder'
,
)
src/AccessControl/ZopeGuards.py
deleted
100644 → 0
View file @
ccc10355
#############################################################################
#
# 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
#
##############################################################################
__version__
=
'$Revision: 1.18 $'
[
11
:
-
2
]
import
sys
import
RestrictedPython
from
RestrictedPython.Guards
import
safe_builtins
,
full_write_guard
from
RestrictedPython.Utilities
import
utility_builtins
from
RestrictedPython.Eval
import
RestrictionCapableEval
from
SecurityManagement
import
getSecurityManager
from
SecurityInfo
import
secureModule
from
SimpleObjectPolicies
import
Containers
,
ContainerAssertions
from
zExceptions
import
Unauthorized
_marker
=
[]
# Create a new marker object.
safe_builtins
=
safe_builtins
.
copy
()
safe_builtins
.
update
(
utility_builtins
)
# AccessControl.Implementation inserts these names into this module as
# module globals: aq_validate, guarded_getattr
def
initialize
(
impl
):
# Called by AccessControl.Implementation.setImplementation()
# whenever the selected implementation changes.
global
guarded_getattr
guarded_getattr
=
impl
.
guarded_getattr
safe_builtins
[
'getattr'
]
=
guarded_getattr
def
guarded_hasattr
(
object
,
name
):
try
:
guarded_getattr
(
object
,
name
)
except
(
AttributeError
,
Unauthorized
):
return
0
return
1
safe_builtins
[
'hasattr'
]
=
guarded_hasattr
SliceType
=
type
(
slice
(
0
))
def
guarded_getitem
(
object
,
index
):
if
type
(
index
)
is
SliceType
:
if
index
.
step
is
not
None
:
v
=
object
[
index
]
else
:
start
=
index
.
start
stop
=
index
.
stop
if
start
is
None
:
start
=
0
if
stop
is
None
:
v
=
object
[
start
:]
else
:
v
=
object
[
start
:
stop
]
# We don't guard slices.
return
v
v
=
object
[
index
]
if
Containers
(
type
(
object
))
and
Containers
(
type
(
v
)):
# Simple type. Short circuit.
return
v
if
getSecurityManager
().
validate
(
object
,
object
,
None
,
v
):
return
v
raise
Unauthorized
,
'unauthorized access to element %s'
%
`i`
# Create functions using nested scope to store state
# This is less expensive then instantiating and calling instances
def
get_dict_get
(
d
,
name
):
def
guarded_get
(
key
,
default
=
None
):
try
:
return
guarded_getitem
(
d
,
key
)
except
KeyError
:
return
default
return
guarded_get
def
get_dict_pop
(
d
,
name
):
def
guarded_pop
(
key
,
default
=
_marker
):
try
:
v
=
guarded_getitem
(
d
,
key
)
except
KeyError
:
if
default
is
not
_marker
:
return
default
raise
else
:
del
d
[
key
]
return
v
return
guarded_pop
def
get_iter
(
c
,
name
):
iter
=
getattr
(
c
,
name
)
def
guarded_iter
():
return
SafeIter
(
iter
(),
c
)
return
guarded_iter
def
get_list_pop
(
lst
,
name
):
def
guarded_pop
(
index
=-
1
):
# XXX This is not thread safe, but we don't expect
# XXX thread interactions between python scripts <wink>
v
=
guarded_getitem
(
lst
,
index
)
del
lst
[
index
]
return
v
return
guarded_pop
# See comment in SimpleObjectPolicies for an explanation of what the
# dicts below actually mean.
_dict_white_list
=
{
'clear'
:
1
,
'copy'
:
1
,
'fromkeys'
:
1
,
'get'
:
get_dict_get
,
'has_key'
:
1
,
'items'
:
1
,
'iteritems'
:
1
,
'keys'
:
1
,
'iterkeys'
:
get_iter
,
'itervalues'
:
get_iter
,
'pop'
:
get_dict_pop
,
'popitem'
:
1
,
'setdefault'
:
1
,
'update'
:
1
,
'values'
:
1
}
def
_check_dict_access
(
name
,
value
):
# Check whether value is a dict method
self
=
getattr
(
value
,
'__self__'
,
None
)
if
self
is
None
:
# item
return
1
# Disallow spoofing
if
type
(
self
)
is
not
dict
:
return
0
if
getattr
(
value
,
'__name__'
,
None
)
!=
name
:
return
0
return
_dict_white_list
.
get
(
name
,
0
)
ContainerAssertions
[
type
({})]
=
_check_dict_access
_list_white_list
=
{
'append'
:
1
,
'count'
:
1
,
'extend'
:
1
,
'index'
:
1
,
'insert'
:
1
,
'pop'
:
get_list_pop
,
'remove'
:
1
,
'reverse'
:
1
,
'sort'
:
1
}
def
_check_list_access
(
name
,
value
):
# Check whether value is a dict method
self
=
getattr
(
value
,
'__self__'
,
None
)
if
self
is
None
:
# item
return
1
# Disallow spoofing
if
type
(
self
)
is
not
list
:
return
0
if
getattr
(
value
,
'__name__'
,
None
)
!=
name
:
return
0
return
_list_white_list
.
get
(
name
,
0
)
ContainerAssertions
[
type
([])]
=
_check_list_access
# This implementation of a "safe" iterator uses a global guard()
# function to implement the actual guard. This check is defined as a
# global so that it can delay imports of some module to avoid circular
# dependencies while also making it possible to use a faster
# implementation once the imports are done (by avoiding the import
# machinery on subsequent calls). Use of a method on the SafeIter
# class is avoided to ensure the best performance of the resulting
# function.
# The NullIter class skips the guard, and can be used to wrap an
# iterator that is known to be safe (as in guarded_enumerate).
class
SafeIter
(
object
):
#__slots__ = '_next', 'container'
__allow_access_to_unprotected_subobjects__
=
1
def
__init__
(
self
,
ob
,
container
=
None
):
self
.
_next
=
iter
(
ob
).
next
if
container
is
None
:
container
=
ob
self
.
container
=
container
def
__iter__
(
self
):
return
self
def
next
(
self
):
ob
=
self
.
_next
()
guard
(
self
.
container
,
ob
)
return
ob
class
NullIter
(
SafeIter
):
def
__init__
(
self
,
ob
):
self
.
_next
=
ob
.
next
def
next
(
self
):
return
self
.
_next
()
def
_error
(
index
):
raise
Unauthorized
,
'unauthorized access to element'
def
guarded_iter
(
*
args
):
if
len
(
args
)
==
1
:
i
=
args
[
0
]
# Don't double-wrap
if
isinstance
(
i
,
SafeIter
):
return
i
if
not
isinstance
(
i
,
xrange
):
return
SafeIter
(
i
)
# Other call styles / targets don't need to be guarded
return
NullIter
(
iter
(
*
args
))
safe_builtins
[
'iter'
]
=
guarded_iter
def
guard
(
container
,
value
,
index
=
None
):
if
Containers
(
type
(
container
))
and
Containers
(
type
(
value
)):
# Simple type. Short circuit.
return
if
getSecurityManager
().
validate
(
container
,
container
,
index
,
value
):
return
_error
(
index
)
# More replacement built-ins.
def
guarded_filter
(
f
,
seq
,
skip_unauthorized
=
0
):
if
type
(
seq
)
is
type
(
''
):
return
filter
(
f
,
seq
)
if
f
is
None
:
def
f
(
x
):
return
x
v
=
getSecurityManager
().
validate
result
=
[]
a
=
result
.
append
for
el
in
seq
:
if
v
(
seq
,
seq
,
None
,
el
):
if
f
(
el
):
a
(
el
)
elif
not
skip_unauthorized
:
raise
Unauthorized
,
'unauthorized access to element'
return
result
safe_builtins
[
'filter'
]
=
guarded_filter
def
guarded_reduce
(
f
,
seq
,
initial
=
_marker
):
if
initial
is
_marker
:
return
reduce
(
f
,
guarded_iter
(
seq
))
else
:
return
reduce
(
f
,
guarded_iter
(
seq
),
initial
)
safe_builtins
[
'reduce'
]
=
guarded_reduce
def
guarded_max
(
item
,
*
items
,
**
kw
):
if
items
:
item
=
[
item
]
item
.
extend
(
items
)
return
max
(
guarded_iter
(
item
),
**
kw
)
safe_builtins
[
'max'
]
=
guarded_max
def
guarded_min
(
item
,
*
items
,
**
kw
):
if
items
:
item
=
[
item
]
item
.
extend
(
items
)
return
min
(
guarded_iter
(
item
),
**
kw
)
safe_builtins
[
'min'
]
=
guarded_min
def
guarded_map
(
f
,
*
seqs
):
safe_seqs
=
[]
for
seqno
in
range
(
len
(
seqs
)):
seq
=
guarded_getitem
(
seqs
,
seqno
)
safe_seqs
.
append
(
guarded_iter
(
seq
))
return
map
(
f
,
*
safe_seqs
)
safe_builtins
[
'map'
]
=
guarded_map
def
guarded_zip
(
*
seqs
):
safe_seqs
=
[]
for
seqno
in
range
(
len
(
seqs
)):
seq
=
guarded_getitem
(
seqs
,
seqno
)
safe_seqs
.
append
(
guarded_iter
(
seq
))
return
zip
(
*
safe_seqs
)
safe_builtins
[
'zip'
]
=
guarded_zip
def
guarded_import
(
mname
,
globals
=
None
,
locals
=
None
,
fromlist
=
None
):
if
fromlist
is
None
:
fromlist
=
()
if
'*'
in
fromlist
:
raise
Unauthorized
,
"'from %s import *' is not allowed"
if
globals
is
None
:
globals
=
{}
if
locals
is
None
:
locals
=
{}
mnameparts
=
mname
.
split
(
'.'
)
firstmname
=
mnameparts
[
0
]
validate
=
getSecurityManager
().
validate
module
=
load_module
(
None
,
None
,
mnameparts
,
validate
,
globals
,
locals
)
if
module
is
None
:
raise
Unauthorized
,
"import of '%s' is unauthorized"
%
mname
if
fromlist
is
None
:
fromlist
=
()
for
name
in
fromlist
:
v
=
getattr
(
module
,
name
,
None
)
if
v
is
None
:
v
=
load_module
(
module
,
mname
,
[
name
],
validate
,
globals
,
locals
)
if
not
validate
(
module
,
module
,
name
,
v
):
raise
Unauthorized
else
:
return
__import__
(
mname
,
globals
,
locals
,
fromlist
)
safe_builtins
[
'__import__'
]
=
guarded_import
class
GuardedListType
:
def
__call__
(
self
,
*
args
,
**
kwargs
):
return
list
(
*
args
,
**
kwargs
)
if
sys
.
version_info
>=
(
2
,
4
):
def
sorted
(
self
,
iterable
,
cmp
=
None
,
key
=
None
,
reverse
=
False
):
return
list
.
sorted
(
iterable
,
cmp
=
None
,
key
=
None
,
reverse
=
False
)
safe_builtins
[
'list'
]
=
GuardedListType
()
class
GuardedDictType
:
def
__call__
(
self
,
*
args
,
**
kwargs
):
return
dict
(
*
args
,
**
kwargs
)
def
fromkeys
(
self
,
S
,
v
=
None
):
return
dict
.
fromkeys
(
S
,
v
)
safe_builtins
[
'dict'
]
=
GuardedDictType
()
def
guarded_enumerate
(
seq
):
return
NullIter
(
enumerate
(
guarded_iter
(
seq
)))
safe_builtins
[
'enumerate'
]
=
guarded_enumerate
def
guarded_sum
(
sequence
,
start
=
0
):
return
sum
(
guarded_iter
(
sequence
),
start
)
safe_builtins
[
'sum'
]
=
guarded_sum
def
load_module
(
module
,
mname
,
mnameparts
,
validate
,
globals
,
locals
):
modules
=
sys
.
modules
while
mnameparts
:
nextname
=
mnameparts
.
pop
(
0
)
if
mname
is
None
:
mname
=
nextname
else
:
mname
=
'%s.%s'
%
(
mname
,
nextname
)
nextmodule
=
modules
.
get
(
mname
,
None
)
if
nextmodule
is
None
:
nextmodule
=
secureModule
(
mname
,
globals
,
locals
)
if
nextmodule
is
None
:
return
else
:
secureModule
(
mname
)
if
module
and
not
validate
(
module
,
module
,
nextname
,
nextmodule
):
return
module
=
nextmodule
return
module
# This version of apply is used by restricted Python, which transforms
# extended call syntax into a call of _apply_(), after tucking the callable
# into the first element of args. For example,
# f(3, eggs=1, spam=False)
# is changed to
# _apply_(f, 3, eggs=1, spam=False)
def
guarded_apply
(
func
,
*
args
,
**
kws
):
return
builtin_guarded_apply
(
func
,
args
,
kws
)
# This version is the safe_builtins apply() replacement, so needs to match the
# signature of __builtin__.apply.
def
builtin_guarded_apply
(
func
,
args
=
(),
kws
=
{}):
# Check the args elements. args may be an arbitrary iterable, and
# iterating over it may consume it, so we also need to save away
# the arguments in a new list to pass on to the real apply().
i
,
arglist
=
0
,
[]
for
elt
in
args
:
guard
(
args
,
elt
,
i
)
arglist
.
append
(
elt
)
i
+=
1
# Check kws similarly. Checking the keys may not be strictly necessary,
# but better safe than sorry. A new argument dict is created just in
# case kws is a hostile user-defined instance that may do horrid things
# as a side-effect of calling items().
argdict
=
{}
for
k
,
v
in
kws
.
items
():
guard
(
kws
,
k
)
guard
(
kws
,
v
,
k
)
argdict
[
k
]
=
v
return
func
(
*
arglist
,
**
argdict
)
safe_builtins
[
'apply'
]
=
builtin_guarded_apply
# Similar to min and reduce, use guarded_iter on the sequence being
# tested and apply the original function.
if
sys
.
version_info
>=
(
2
,
5
):
def
guarded_any
(
seq
):
return
any
(
guarded_iter
(
seq
))
safe_builtins
[
'any'
]
=
guarded_any
def
guarded_all
(
seq
):
return
all
(
guarded_iter
(
seq
))
safe_builtins
[
'all'
]
=
guarded_all
# This metaclass supplies the security declarations that allow all
# attributes of a class and its instances to be read and written.
def
_metaclass
(
name
,
bases
,
dict
):
for
k
,
v
in
dict
.
items
():
if
k
.
endswith
(
'__roles__'
)
and
k
[:
len
(
'__roles__'
)]
not
in
dict
:
raise
Unauthorized
,
"Can't override security: %s"
%
k
ob
=
type
(
name
,
bases
,
dict
)
ob
.
__allow_access_to_unprotected_subobjects__
=
1
ob
.
_guarded_writes
=
1
return
ob
try
:
valid_inplace_types
=
list
,
set
except
NameError
:
# Python 2.3
valid_inplace_types
=
list
inplace_slots
=
{
'+='
:
'__iadd__'
,
'-='
:
'__isub__'
,
'*='
:
'__imul__'
,
'/='
:
(
1
/
2
==
0
)
and
'__idiv__'
or
'__itruediv__'
,
'//='
:
'__ifloordiv__'
,
'%='
:
'__imod__'
,
'**='
:
'__ipow__'
,
'<<='
:
'__ilshift__'
,
'>>='
:
'__irshift__'
,
'&='
:
'__iand__'
,
'^='
:
'__ixor__'
,
'|='
:
'__ior_'
,
}
def
__iadd__
(
x
,
y
):
x
+=
y
return
x
def
__isub__
(
x
,
y
):
x
-=
y
return
x
def
__imul__
(
x
,
y
):
x
*=
y
return
x
def
__idiv__
(
x
,
y
):
x
/=
y
return
x
def
__ifloordiv__
(
x
,
y
):
x
//=
y
return
x
def
__imod__
(
x
,
y
):
x
%=
y
return
x
def
__ipow__
(
x
,
y
):
x
**=
y
return
x
def
__ilshift__
(
x
,
y
):
x
<<=
y
return
x
def
__irshift__
(
x
,
y
):
x
>>=
y
return
x
def
__iand__
(
x
,
y
):
x
&=
y
return
x
def
__ixor__
(
x
,
y
):
x
^=
y
return
x
def
__ior__
(
x
,
y
):
x
|=
y
return
x
inplace_ops
=
{
'+='
:
__iadd__
,
'-='
:
__isub__
,
'*='
:
__imul__
,
'/='
:
__idiv__
,
'//='
:
__ifloordiv__
,
'%='
:
__imod__
,
'**='
:
__ipow__
,
'<<='
:
__ilshift__
,
'>>='
:
__irshift__
,
'&='
:
__iand__
,
'^='
:
__ixor__
,
'|='
:
__ior__
,
}
def
protected_inplacevar
(
op
,
var
,
expr
):
"""Do an inplace operation
If the var has an inplace slot, then disallow the operation
unless the var is a list.
"""
if
(
hasattr
(
var
,
inplace_slots
[
op
])
and
not
isinstance
(
var
,
valid_inplace_types
)
):
try
:
cls
=
var
.
__class__
except
AttributeError
:
cls
=
type
(
var
)
raise
TypeError
(
"Augmented assignment to %s objects is not allowed"
" in untrusted code"
%
cls
.
__name__
)
return
inplace_ops
[
op
](
var
,
expr
)
# AccessControl clients generally need to set up a safe globals dict for
# use by restricted code. The get_safe_globals() function returns such
# a dict, containing '__builtins__' mapped to our safe bulitins, and
# bindings for all the special functions inserted into Python code by
# RestrictionMutator transformations. A client may wish to add more
# bindings to this dict. It's generally safe to do so, as
# get_safe_globals returns a (shallow) copy of a canonical safe globals
# dict.
# Exception: For obscure technical reasons, clients have to import
# guarded_getattr from this module (ZopeGuards) and plug it into the
# dict themselves, with key '_getattr_'.
_safe_globals
=
{
'__builtins__'
:
safe_builtins
,
'__metaclass__'
:
_metaclass
,
'_apply_'
:
guarded_apply
,
'_getitem_'
:
guarded_getitem
,
'_getiter_'
:
guarded_iter
,
'_print_'
:
RestrictedPython
.
PrintCollector
,
'_write_'
:
full_write_guard
,
'_inplacevar_'
:
protected_inplacevar
,
# The correct implementation of _getattr_, aka
# guarded_getattr, isn't known until
# AccessControl.Implementation figures that out, then
# stuffs it into *this* module's globals bound to
# 'guarded_getattr'. We can't know what that is at
## '_getattr_': guarded_getattr,
}
get_safe_globals
=
_safe_globals
.
copy
RestrictionCapableEval
.
globals
.
update
(
_safe_globals
)
src/AccessControl/ZopeSecurityPolicy.py
deleted
100644 → 0
View file @
ccc10355
##############################################################################
#
# 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
#
##############################################################################
"""Define Zope's default security policy
"""
from
types
import
MethodType
# AccessControl.Implementation inserts:
# ZopeSecurityPolicy, getRoles, rolesForPermissionOn
from
AccessControl.SimpleObjectPolicies
import
_noroles
rolesForPermissionOn
=
None
# XXX: avoid import loop
tuple_or_list
=
tuple
,
list
def
getRoles
(
container
,
name
,
value
,
default
):
global
rolesForPermissionOn
# XXX: avoid import loop
if
rolesForPermissionOn
is
None
:
from
PermissionRole
import
rolesForPermissionOn
roles
=
getattr
(
value
,
'__roles__'
,
_noroles
)
if
roles
is
_noroles
:
if
not
name
or
not
isinstance
(
name
,
basestring
):
return
default
if
type
(
value
)
is
MethodType
:
container
=
value
.
im_self
cls
=
getattr
(
container
,
'__class__'
,
None
)
if
cls
is
None
:
return
default
roles
=
getattr
(
cls
,
name
+
'__roles__'
,
_noroles
)
if
roles
is
_noroles
:
return
default
value
=
container
if
roles
is
None
or
isinstance
(
roles
,
tuple_or_list
):
return
roles
rolesForPermissionOn
=
getattr
(
roles
,
'rolesForPermissionOn'
,
None
)
if
rolesForPermissionOn
is
not
None
:
roles
=
rolesForPermissionOn
(
value
)
return
roles
src/AccessControl/__init__.py
deleted
100644 → 0
View file @
ccc10355
##############################################################################
#
# 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
#
##############################################################################
# This has to happen early so things get initialized properly
from
AccessControl.Implementation
import
setImplementation
from
AccessControl.SecurityManagement
import
getSecurityManager
from
AccessControl.SecurityManagement
import
setSecurityPolicy
from
AccessControl.SecurityInfo
import
ClassSecurityInfo
from
AccessControl.SecurityInfo
import
ModuleSecurityInfo
from
AccessControl.SecurityInfo
import
ACCESS_PRIVATE
from
AccessControl.SecurityInfo
import
ACCESS_PUBLIC
from
AccessControl.SecurityInfo
import
ACCESS_NONE
from
AccessControl.SecurityInfo
import
secureModule
from
AccessControl.SecurityInfo
import
allow_module
from
AccessControl.SecurityInfo
import
allow_class
from
AccessControl.SimpleObjectPolicies
import
allow_type
from
AccessControl.unauthorized
import
Unauthorized
# XXX
from
AccessControl.ZopeGuards
import
full_write_guard
from
AccessControl.ZopeGuards
import
safe_builtins
ModuleSecurityInfo
(
'AccessControl'
).
declarePublic
(
'getSecurityManager'
)
src/AccessControl/cAccessControl.c
deleted
100644 → 0
View file @
ccc10355
/*
** cAccessControl.c
**
** Access control acceleration routines
Copyright (c) 2001, Zope Foundation and Contributors.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
o Redistributions of source code must retain the above copyright
notice, this list of conditions, and the disclaimer that follows.
o Redistributions in binary form must reproduce the above copyright
notice, this list of conditions, and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
o Neither the name of Digital Creations nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS AND CONTRIBUTORS *AS
IS* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL
CREATIONS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.
If you have questions regarding this software,
contact:
Digital Creations L.C.
info@digicool.com
(540) 371-6909
*/
#include "ExtensionClass/ExtensionClass.h"
#include "Acquisition/Acquisition.h"
#include <stdio.h>
#include <stdlib.h>
#if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN)
typedef
int
Py_ssize_t
;
typedef
Py_ssize_t
(
*
lenfunc
)(
PyObject
*
);
typedef
PyObject
*
(
*
ssizeargfunc
)(
PyObject
*
,
Py_ssize_t
);
typedef
PyObject
*
(
*
ssizessizeargfunc
)(
PyObject
*
,
Py_ssize_t
,
Py_ssize_t
);
typedef
int
(
*
ssizeobjargproc
)(
PyObject
*
,
Py_ssize_t
,
PyObject
*
);
typedef
int
(
*
ssizessizeobjargproc
)(
PyObject
*
,
Py_ssize_t
,
Py_ssize_t
,
PyObject
*
);
#define PY_SSIZE_T_MAX INT_MAX
#define PY_SSIZE_T_MIN INT_MIN
#endif
static
void
PyVar_Assign
(
PyObject
**
v
,
PyObject
*
e
)
{
Py_XDECREF
(
*
v
);
*
v
=
e
;
}
#define ASSIGN(V,E) PyVar_Assign(&(V),(E))
#define UNLESS(E) if (!(E))
#define OBJECT(o) ((PyObject *) (o))
static
PyObject
*
callfunction1
(
PyObject
*
function
,
PyObject
*
arg
)
{
PyObject
*
t
,
*
r
;
t
=
PyTuple_New
(
1
);
if
(
t
==
NULL
)
return
NULL
;
Py_INCREF
(
arg
);
PyTuple_SET_ITEM
(
t
,
0
,
arg
);
r
=
PyObject_CallObject
(
function
,
t
);
Py_DECREF
(
t
);
return
r
;
}
static
PyObject
*
callmethod1
(
PyObject
*
self
,
PyObject
*
name
,
PyObject
*
arg
)
{
UNLESS
(
self
=
PyObject_GetAttr
(
self
,
name
))
return
NULL
;
ASSIGN
(
self
,
callfunction1
(
self
,
arg
));
return
self
;
}
static
PyObject
*
callfunction2
(
PyObject
*
function
,
PyObject
*
arg0
,
PyObject
*
arg1
)
{
PyObject
*
t
,
*
r
;
t
=
PyTuple_New
(
2
);
if
(
t
==
NULL
)
return
NULL
;
Py_INCREF
(
arg0
);
Py_INCREF
(
arg1
);
PyTuple_SET_ITEM
(
t
,
0
,
arg0
);
PyTuple_SET_ITEM
(
t
,
1
,
arg1
);
r
=
PyObject_CallObject
(
function
,
t
);
Py_DECREF
(
t
);
return
r
;
}
static
PyObject
*
callfunction3
(
PyObject
*
function
,
PyObject
*
arg0
,
PyObject
*
arg1
,
PyObject
*
arg2
)
{
PyObject
*
t
,
*
r
;
t
=
PyTuple_New
(
3
);
if
(
t
==
NULL
)
return
NULL
;
Py_INCREF
(
arg0
);
Py_INCREF
(
arg1
);
Py_INCREF
(
arg2
);
PyTuple_SET_ITEM
(
t
,
0
,
arg0
);
PyTuple_SET_ITEM
(
t
,
1
,
arg1
);
PyTuple_SET_ITEM
(
t
,
2
,
arg2
);
r
=
PyObject_CallObject
(
function
,
t
);
Py_DECREF
(
t
);
return
r
;
}
static
PyObject
*
callfunction4
(
PyObject
*
function
,
PyObject
*
arg0
,
PyObject
*
arg1
,
PyObject
*
arg2
,
PyObject
*
arg3
)
{
PyObject
*
t
,
*
r
;
t
=
PyTuple_New
(
4
);
if
(
t
==
NULL
)
return
NULL
;
Py_INCREF
(
arg0
);
Py_INCREF
(
arg1
);
Py_INCREF
(
arg2
);
Py_INCREF
(
arg3
);
PyTuple_SET_ITEM
(
t
,
0
,
arg0
);
PyTuple_SET_ITEM
(
t
,
1
,
arg1
);
PyTuple_SET_ITEM
(
t
,
2
,
arg2
);
PyTuple_SET_ITEM
(
t
,
3
,
arg3
);
r
=
PyObject_CallObject
(
function
,
t
);
Py_DECREF
(
t
);
return
r
;
}
static
PyObject
*
callfunction5
(
PyObject
*
function
,
PyObject
*
arg0
,
PyObject
*
arg1
,
PyObject
*
arg2
,
PyObject
*
arg3
,
PyObject
*
arg4
)
{
PyObject
*
t
,
*
r
;
t
=
PyTuple_New
(
5
);
if
(
t
==
NULL
)
return
NULL
;
Py_INCREF
(
arg0
);
Py_INCREF
(
arg1
);
Py_INCREF
(
arg2
);
Py_INCREF
(
arg3
);
Py_INCREF
(
arg4
);
PyTuple_SET_ITEM
(
t
,
0
,
arg0
);
PyTuple_SET_ITEM
(
t
,
1
,
arg1
);
PyTuple_SET_ITEM
(
t
,
2
,
arg2
);
PyTuple_SET_ITEM
(
t
,
3
,
arg3
);
PyTuple_SET_ITEM
(
t
,
4
,
arg4
);
r
=
PyObject_CallObject
(
function
,
t
);
Py_DECREF
(
t
);
return
r
;
}
static
PyObject
*
callfunction6
(
PyObject
*
function
,
PyObject
*
arg0
,
PyObject
*
arg1
,
PyObject
*
arg2
,
PyObject
*
arg3
,
PyObject
*
arg4
,
PyObject
*
arg5
)
{
PyObject
*
t
,
*
r
;
t
=
PyTuple_New
(
6
);
if
(
t
==
NULL
)
return
NULL
;
Py_INCREF
(
arg0
);
Py_INCREF
(
arg1
);
Py_INCREF
(
arg2
);
Py_INCREF
(
arg3
);
Py_INCREF
(
arg4
);
Py_INCREF
(
arg5
);
PyTuple_SET_ITEM
(
t
,
0
,
arg0
);
PyTuple_SET_ITEM
(
t
,
1
,
arg1
);
PyTuple_SET_ITEM
(
t
,
2
,
arg2
);
PyTuple_SET_ITEM
(
t
,
3
,
arg3
);
PyTuple_SET_ITEM
(
t
,
4
,
arg4
);
PyTuple_SET_ITEM
(
t
,
5
,
arg5
);
r
=
PyObject_CallObject
(
function
,
t
);
Py_DECREF
(
t
);
return
r
;
}
static
int
unpacktuple2
(
PyObject
*
args
,
char
*
name
,
int
min
,
PyObject
**
a0
,
PyObject
**
a1
)
{
int
l
;
l
=
PyTuple_Size
(
args
);
if
(
l
<
0
)
return
-
1
;
if
(
l
<
min
)
{
PyErr_Format
(
PyExc_TypeError
,
"expected %d arguments, got %d"
,
min
,
l
);
return
-
1
;
}
if
(
l
>
0
)
*
a0
=
PyTuple_GET_ITEM
(
args
,
0
);
if
(
l
>
1
)
*
a1
=
PyTuple_GET_ITEM
(
args
,
1
);
return
0
;
}
static
int
unpacktuple3
(
PyObject
*
args
,
char
*
name
,
int
min
,
PyObject
**
a0
,
PyObject
**
a1
,
PyObject
**
a2
)
{
int
l
;
l
=
PyTuple_Size
(
args
);
if
(
l
<
0
)
return
-
1
;
if
(
l
<
min
)
{
PyErr_Format
(
PyExc_TypeError
,
"expected %d arguments, got %d"
,
min
,
l
);
return
-
1
;
}
if
(
l
>
0
)
*
a0
=
PyTuple_GET_ITEM
(
args
,
0
);
if
(
l
>
1
)
*
a1
=
PyTuple_GET_ITEM
(
args
,
1
);
if
(
l
>
2
)
*
a2
=
PyTuple_GET_ITEM
(
args
,
2
);
return
0
;
}
static
int
unpacktuple4
(
PyObject
*
args
,
char
*
name
,
int
min
,
PyObject
**
a0
,
PyObject
**
a1
,
PyObject
**
a2
,
PyObject
**
a3
)
{
int
l
;
l
=
PyTuple_Size
(
args
);
if
(
l
<
0
)
return
-
1
;
if
(
l
<
min
)
{
PyErr_Format
(
PyExc_TypeError
,
"expected %d arguments, got %d"
,
min
,
l
);
return
-
1
;
}
if
(
l
>
0
)
*
a0
=
PyTuple_GET_ITEM
(
args
,
0
);
if
(
l
>
1
)
*
a1
=
PyTuple_GET_ITEM
(
args
,
1
);
if
(
l
>
2
)
*
a2
=
PyTuple_GET_ITEM
(
args
,
2
);
if
(
l
>
3
)
*
a3
=
PyTuple_GET_ITEM
(
args
,
3
);
return
0
;
}
static
int
unpacktuple5
(
PyObject
*
args
,
char
*
name
,
int
min
,
PyObject
**
a0
,
PyObject
**
a1
,
PyObject
**
a2
,
PyObject
**
a3
,
PyObject
**
a4
)
{
int
l
;
l
=
PyTuple_Size
(
args
);
if
(
l
<
0
)
return
-
1
;
if
(
l
<
min
)
{
PyErr_Format
(
PyExc_TypeError
,
"expected %d arguments, got %d"
,
min
,
l
);
return
-
1
;
}
if
(
l
>
0
)
*
a0
=
PyTuple_GET_ITEM
(
args
,
0
);
if
(
l
>
1
)
*
a1
=
PyTuple_GET_ITEM
(
args
,
1
);
if
(
l
>
2
)
*
a2
=
PyTuple_GET_ITEM
(
args
,
2
);
if
(
l
>
3
)
*
a3
=
PyTuple_GET_ITEM
(
args
,
3
);
if
(
l
>
4
)
*
a4
=
PyTuple_GET_ITEM
(
args
,
4
);
return
0
;
}
static
int
unpacktuple6
(
PyObject
*
args
,
char
*
name
,
int
min
,
PyObject
**
a0
,
PyObject
**
a1
,
PyObject
**
a2
,
PyObject
**
a3
,
PyObject
**
a4
,
PyObject
**
a5
)
{
int
l
;
l
=
PyTuple_Size
(
args
);
if
(
l
<
0
)
return
-
1
;
if
(
l
<
min
)
{
PyErr_Format
(
PyExc_TypeError
,
"expected %d arguments, got %d"
,
min
,
l
);
return
-
1
;
}
if
(
l
>
0
)
*
a0
=
PyTuple_GET_ITEM
(
args
,
0
);
if
(
l
>
1
)
*
a1
=
PyTuple_GET_ITEM
(
args
,
1
);
if
(
l
>
2
)
*
a2
=
PyTuple_GET_ITEM
(
args
,
2
);
if
(
l
>
3
)
*
a3
=
PyTuple_GET_ITEM
(
args
,
3
);
if
(
l
>
4
)
*
a4
=
PyTuple_GET_ITEM
(
args
,
4
);
if
(
l
>
5
)
*
a5
=
PyTuple_GET_ITEM
(
args
,
5
);
return
0
;
}
/*
** Structures
*/
typedef
struct
{
PyObject_HEAD
}
ZopeSecurityPolicy
;
typedef
struct
{
PyObject_HEAD
PyObject
*
thread_id
;
PyObject
*
context
;
PyObject
*
policy
;
PyObject
*
validate
;
PyObject
*
checkPermission
;
}
SecurityManager
;
typedef
struct
{
PyObject_HEAD
PyObject
*
__name__
;
PyObject
*
_p
;
PyObject
*
__roles__
;
}
PermissionRole
;
typedef
struct
{
PyObject_HEAD
PyObject
*
_p
;
PyObject
*
_pa
;
PyObject
*
__roles__
;
PyObject
*
_v
;
}
imPermissionRole
;
/*
** Prototypes
*/
static
PyObject
*
ZopeSecurityPolicy_validate
(
PyObject
*
self
,
PyObject
*
args
);
static
void
ZopeSecurityPolicy_dealloc
(
ZopeSecurityPolicy
*
self
);
static
PyObject
*
PermissionRole_init
(
PermissionRole
*
self
,
PyObject
*
args
);
static
PyObject
*
PermissionRole_of
(
PermissionRole
*
self
,
PyObject
*
parent
);
static
PyObject
*
PermissionRole_rolesForPermissionOn
(
PermissionRole
*
self
,
PyObject
*
value
);
static
void
PermissionRole_dealloc
(
PermissionRole
*
self
);
static
PyObject
*
PermissionRole_getattro
(
PermissionRole
*
self
,
PyObject
*
name
);
static
PyObject
*
imPermissionRole_of
(
imPermissionRole
*
self
,
PyObject
*
parent
);
static
Py_ssize_t
imPermissionRole_length
(
imPermissionRole
*
self
);
static
PyObject
*
imPermissionRole_get
(
imPermissionRole
*
self
,
Py_ssize_t
item
);
static
void
imPermissionRole_dealloc
(
imPermissionRole
*
self
);
static
PyObject
*
rolesForPermissionOn
(
PyObject
*
self
,
PyObject
*
args
);
static
PyObject
*
module_guarded_getattr
(
PyObject
*
self
,
PyObject
*
args
);
static
PyObject
*
module_aq_validate
(
PyObject
*
self
,
PyObject
*
args
);
static
PyObject
*
module_setDefaultBehaviors
(
PyObject
*
self
,
PyObject
*
args
);
static
PyObject
*
c_rolesForPermissionOn
(
PyObject
*
self
,
PyObject
*
perm
,
PyObject
*
object
,
PyObject
*
deflt
);
static
PyObject
*
permissionName
(
PyObject
*
name
);
static
PyObject
*
SecurityManager_validate
(
SecurityManager
*
self
,
PyObject
*
args
);
static
PyObject
*
SecurityManager_DTMLValidate
(
SecurityManager
*
self
,
PyObject
*
args
);
static
PyObject
*
SecurityManager_checkPermission
(
SecurityManager
*
self
,
PyObject
*
args
);
static
void
SecurityManager_dealloc
(
SecurityManager
*
self
);
static
PyObject
*
SecurityManager_getattro
(
SecurityManager
*
self
,
PyObject
*
name
);
static
int
SecurityManager_setattro
(
SecurityManager
*
self
,
PyObject
*
name
,
PyObject
*
value
);
static
getattrofunc
ExtensionClassGetattro
;
/*
** Constants
*/
static
PyMethodDef
cAccessControl_methods
[]
=
{
{
"rolesForPermissionOn"
,
(
PyCFunction
)
rolesForPermissionOn
,
METH_VARARGS
,
""
},
{
"guarded_getattr"
,
(
PyCFunction
)
module_guarded_getattr
,
METH_VARARGS
,
""
},
{
"aq_validate"
,
(
PyCFunction
)
module_aq_validate
,
METH_VARARGS
,
""
},
{
"setDefaultBehaviors"
,
(
PyCFunction
)
module_setDefaultBehaviors
,
METH_VARARGS
,
""
},
{
NULL
,
NULL
}
};
static
char
ZopeSecurityPolicy__doc__
[]
=
"ZopeSecurityPolicy C implementation"
;
static
PyMethodDef
ZopeSecurityPolicy_methods
[]
=
{
{
"validate"
,
(
PyCFunction
)
ZopeSecurityPolicy_validate
,
METH_VARARGS
,
""
},
{
NULL
,
NULL
}
};
static
PyExtensionClass
ZopeSecurityPolicyType
=
{
PyObject_HEAD_INIT
(
NULL
)
0
,
"ZopeSecurityPolicy"
,
/* tp_name */
sizeof
(
ZopeSecurityPolicy
),
/* tp_basicsize */
0
,
/* tp_itemsize */
/* Standard methods */
(
destructor
)
ZopeSecurityPolicy_dealloc
,
/* tp_dealloc */
NULL
,
/* tp_print */
NULL
,
/* tp_getattr */
NULL
,
/* tp_setattr */
NULL
,
/* tp_compare */
NULL
,
/* tp_repr */
/* Method suites */
NULL
,
/* tp_as_number */
NULL
,
/* tp_as_sequence*/
NULL
,
/* tp_as_mapping */
/* More standard ops */
NULL
,
/* tp_hash */
NULL
,
/* tp_call */
NULL
,
/* tp_str */
NULL
,
/* tp_getattro */
NULL
,
/* tp_setattro */
/* Reserved fields */
0
,
/* tp_xxx3 */
0
,
/* tp_xxx4 */
/* Docstring */
ZopeSecurityPolicy__doc__
,
/* tp_doc */
#ifdef COUNT_ALLOCS
0
,
/* tp_alloc */
0
,
/* tp_free */
0
,
/* tp_maxalloc */
NULL
,
/* tp_next */
#endif
METHOD_CHAIN
(
ZopeSecurityPolicy_methods
),
/* methods */
(
void
*
)(
EXTENSIONCLASS_BINDABLE_FLAG
),
/* flags */
};
static
char
SecurityManager__doc__
[]
=
"ZopeSecurityPolicy C implementation"
;
static
PyMethodDef
SecurityManager_methods
[]
=
{
{
"validate"
,
(
PyCFunction
)
SecurityManager_validate
,
METH_VARARGS
,
""
},
{
"DTMLValidate"
,
(
PyCFunction
)
SecurityManager_DTMLValidate
,
METH_VARARGS
,
""
},
{
"checkPermission"
,
(
PyCFunction
)
SecurityManager_checkPermission
,
METH_VARARGS
,
""
},
{
NULL
,
NULL
}
};
static
PyExtensionClass
SecurityManagerType
=
{
PyObject_HEAD_INIT
(
NULL
)
0
,
"SecurityManager"
,
/* tp_name */
sizeof
(
SecurityManager
),
/* tp_basicsize */
0
,
/* tp_itemsize */
/* Standard methods */
(
destructor
)
SecurityManager_dealloc
,
/* tp_dealloc */
NULL
,
/* tp_print */
NULL
,
/* tp_getattr */
NULL
,
/* tp_setattr */
NULL
,
/* tp_compare */
NULL
,
/* tp_repr */
/* Method suites */
NULL
,
/* tp_as_number */
NULL
,
/* tp_as_sequence*/
NULL
,
/* tp_as_mapping */
/* More standard ops */
NULL
,
/* tp_hash */
NULL
,
/* tp_call */
NULL
,
/* tp_str */
(
getattrofunc
)
SecurityManager_getattro
,
/* tp_getattro */
(
setattrofunc
)
SecurityManager_setattro
,
/* tp_setattro */
/* Reserved fields */
0
,
/* tp_xxx3 */
0
,
/* tp_xxx4 */
/* Docstring */
SecurityManager__doc__
,
/* tp_doc */
#ifdef COUNT_ALLOCS
0
,
/* tp_alloc */
0
,
/* tp_free */
0
,
/* tp_maxalloc */
NULL
,
/* tp_next */
#endif
METHOD_CHAIN
(
SecurityManager_methods
),
/* methods */
0
,
/* flags */
};
static
char
PermissionRole__doc__
[]
=
"PermissionRole C implementation"
;
static
PyMethodDef
PermissionRole_methods
[]
=
{
{
"__init__"
,
(
PyCFunction
)
PermissionRole_init
,
METH_VARARGS
,
""
},
{
"__of__"
,
(
PyCFunction
)
PermissionRole_of
,
METH_O
,
""
},
{
"rolesForPermissionOn"
,
(
PyCFunction
)
PermissionRole_rolesForPermissionOn
,
METH_O
,
""
},
{
NULL
,
NULL
}
};
static
PyExtensionClass
PermissionRoleType
=
{
PyObject_HEAD_INIT
(
NULL
)
0
,
"PermissionRole"
,
/* tp_name */
sizeof
(
PermissionRole
),
/* tp_basicsize */
0
,
/* tp_itemsize */
/* Standard methods */
(
destructor
)
PermissionRole_dealloc
,
/* tp_dealloc */
NULL
,
/* tp_print */
NULL
,
/* tp_getattr */
NULL
,
/* tp_setattr */
NULL
,
/* tp_compare */
NULL
,
/* tp_repr */
/* Method suites */
NULL
,
/* tp_as_number */
NULL
,
/* tp_as_sequence*/
NULL
,
/* tp_as_mapping */
/* More standard ops */
NULL
,
/* tp_hash */
NULL
,
/* tp_call */
NULL
,
/* tp_str */
(
getattrofunc
)
PermissionRole_getattro
,
/* tp_getattro */
NULL
,
/* tp_setattro */
/* Reserved fields */
0
,
/* tp_xxx3 */
0
,
/* tp_xxx4 */
/* Docstring */
PermissionRole__doc__
,
/* tp_doc */
#ifdef COUNT_ALLOCS
0
,
/* tp_alloc */
0
,
/* tp_free */
0
,
/* tp_maxalloc */
NULL
,
/* tp_next */
#endif
METHOD_CHAIN
(
PermissionRole_methods
),
/* methods */
(
void
*
)(
EXTENSIONCLASS_BINDABLE_FLAG
)
/*|
EXTENSIONCLASS_INSTDICT_FLAG*/
,
/* flags */
NULL
,
/* Class dict */
0
,
/* bases */
NULL
,
/* reserved */
};
static
char
imPermissionRole__doc__
[]
=
"imPermissionRole C implementation"
;
static
PyMethodDef
imPermissionRole_methods
[]
=
{
{
"__of__"
,
(
PyCFunction
)
imPermissionRole_of
,
METH_O
,
""
},
{
"rolesForPermissionOn"
,
(
PyCFunction
)
imPermissionRole_of
,
METH_O
,
""
},
{
NULL
,
NULL
}
};
static
PySequenceMethods
imSequenceMethods
=
{
(
lenfunc
)
imPermissionRole_length
,
/* sq_length */
(
binaryfunc
)
NULL
,
/* sq_concat */
(
ssizeargfunc
)
NULL
,
/* sq_repeat */
(
ssizeargfunc
)
imPermissionRole_get
,
/* sq_item */
(
ssizessizeargfunc
)
NULL
,
/* sq_slice */
(
ssizeobjargproc
)
NULL
,
/* sq_ass_item */
(
ssizessizeobjargproc
)
NULL
,
/* sq_ass_slice */
(
objobjproc
)
NULL
,
/* sq_contains */
(
binaryfunc
)
NULL
,
/* sq_inplace_concat */
(
ssizeargfunc
)
NULL
/* sq_inplace_repeat */
};
static
PyExtensionClass
imPermissionRoleType
=
{
PyObject_HEAD_INIT
(
NULL
)
0
,
"imPermissionRole"
,
/* tp_name */
sizeof
(
imPermissionRole
),
/* tp_basicsize */
0
,
/* tp_itemsize */
/* Standard methods */
(
destructor
)
imPermissionRole_dealloc
,
/* tp_dealloc */
NULL
,
/* tp_print */
NULL
,
/* tp_getattr */
NULL
,
/* tp_setattr */
NULL
,
/* tp_compare */
NULL
,
/* tp_repr */
/* Method suites */
NULL
,
/* tp_as_number */
&
imSequenceMethods
,
/* tp_as_sequence*/
NULL
,
/* tp_as_mapping */
/* More standard ops */
NULL
,
/* tp_hash */
NULL
,
/* tp_call */
NULL
,
/* tp_str */
NULL
,
/* tp_getattro */
NULL
,
/* tp_setattro */
/* Reserved fields */
0
,
/* tp_xxx3 */
0
,
/* tp_xxx4 */
/* Docstring */
imPermissionRole__doc__
,
/* tp_doc */
#ifdef COUNT_ALLOCS
0
,
/* tp_alloc */
0
,
/* tp_free */
0
,
/* tp_maxalloc */
NULL
,
/* tp_next */
#endif
METHOD_CHAIN
(
imPermissionRole_methods
),
/* methods */
(
void
*
)(
EXTENSIONCLASS_BINDABLE_FLAG
),
/* flags */
};
/* --------------------------------------------------------------
** STATIC OBJECTS
** --------------------------------------------------------------
*/
static
PyObject
*
Containers
=
NULL
;
static
PyObject
*
ContainerAssertions
=
NULL
;
static
PyObject
*
Unauthorized
=
NULL
;
static
PyObject
*
warn
=
NULL
;
static
PyObject
*
NoSequenceFormat
=
NULL
;
static
PyObject
*
_what_not_even_god_should_do
=
NULL
;
static
PyObject
*
Anonymous
=
NULL
;
static
PyObject
*
AnonymousTuple
=
NULL
;
static
PyObject
*
ManagerTuple
=
NULL
;
static
PyObject
*
imPermissionRoleObj
=
NULL
;
static
PyObject
*
defaultPermission
=
NULL
;
static
PyObject
*
__roles__
=
NULL
;
static
PyObject
*
__of__
=
NULL
;
static
PyObject
*
__allow_access_to_unprotected_subobjects__
=
NULL
;
static
PyObject
*
stack_str
=
NULL
;
static
PyObject
*
user_str
=
NULL
;
static
PyObject
*
validate_str
=
NULL
;
static
PyObject
*
_proxy_roles_str
=
NULL
;
static
PyObject
*
allowed_str
=
NULL
;
static
PyObject
*
getOwner_str
=
NULL
;
static
PyObject
*
getPhysicalRoot_str
=
NULL
;
static
PyObject
*
checkPermission_str
=
NULL
;
static
PyObject
*
getSecurityManager
=
NULL
;
static
PyObject
*
unrestrictedTraverse_str
=
NULL
;
static
PyObject
*
aq_validate
=
NULL
;
static
PyObject
*
aq_parent_str
=
NULL
;
static
PyObject
*
_check_context_str
=
NULL
;
static
PyObject
*
getRoles
=
NULL
;
static
PyObject
*
getWrappedOwner_str
=
NULL
;
static
int
ownerous
=
1
;
static
int
authenticated
=
1
;
/* --------------------------------------------------------------
** ZopeSecurityPolicy Methods
** --------------------------------------------------------------
*/
/* ZopeSecurityPolicy_setup
**
** Setup for ZopeSecurityPolicy -- load all necessary objects from
** elsewhere... (e.g. imports)
*/
static
int
ZopeSecurityPolicy_setup
(
void
)
{
UNLESS
(
NoSequenceFormat
=
PyString_FromString
(
"'%s' passed as roles"
" during validation of '%s' is not a sequence."
))
return
-
1
;
UNLESS
(
defaultPermission
=
Py_BuildValue
(
"(s)"
,
"Manager"
))
return
-
1
;
UNLESS
(
_what_not_even_god_should_do
=
Py_BuildValue
(
"[]"
))
return
-
1
;
UNLESS
(
__roles__
=
PyString_FromString
(
"__roles__"
))
return
-
1
;
UNLESS
(
__of__
=
PyString_FromString
(
"__of__"
))
return
-
1
;
UNLESS
(
Anonymous
=
PyString_FromString
(
"Anonymous"
))
return
-
1
;
UNLESS
(
AnonymousTuple
=
Py_BuildValue
(
"(O)"
,
Anonymous
))
return
-
1
;
UNLESS
(
ManagerTuple
=
Py_BuildValue
(
"(s)"
,
"Manager"
))
return
-
1
;
UNLESS
(
stack_str
=
PyString_FromString
(
"stack"
))
return
-
1
;
UNLESS
(
user_str
=
PyString_FromString
(
"user"
))
return
-
1
;
UNLESS
(
validate_str
=
PyString_FromString
(
"validate"
))
return
-
1
;
UNLESS
(
_proxy_roles_str
=
PyString_FromString
(
"_proxy_roles"
))
return
-
1
;
UNLESS
(
allowed_str
=
PyString_FromString
(
"allowed"
))
return
-
1
;
UNLESS
(
getOwner_str
=
PyString_FromString
(
"getOwner"
))
return
-
1
;
UNLESS
(
getWrappedOwner_str
=
PyString_FromString
(
"getWrappedOwner"
))
return
-
1
;
UNLESS
(
getPhysicalRoot_str
=
PyString_FromString
(
"getPhysicalRoot"
))
return
-
1
;
UNLESS
(
aq_parent_str
=
PyString_FromString
(
"aq_parent"
))
return
-
1
;
UNLESS
(
_check_context_str
=
PyString_FromString
(
"_check_context"
))
return
-
1
;
UNLESS
(
unrestrictedTraverse_str
=
PyString_FromString
(
"unrestrictedTraverse"
))
return
-
1
;
UNLESS
(
checkPermission_str
=
PyString_FromString
(
"checkPermission"
))
return
-
1
;
UNLESS
(
__allow_access_to_unprotected_subobjects__
=
PyString_FromString
(
"__allow_access_to_unprotected_subobjects__"
))
return
-
1
;
return
0
;
}
/*
** unauthErr
**
** Generate the unauthorized error
*/
static
void
unauthErr
(
PyObject
*
name
,
PyObject
*
value
)
{
PyObject
*
v
;
if
((
v
=
Py_BuildValue
(
"OO"
,
name
,
value
)))
{
PyErr_SetObject
(
Unauthorized
,
v
);
Py_DECREF
(
v
);
}
}
/*
** ZopeSecurityPolicy_validate
*/
static
PyObject
*
ZopeSecurityPolicy_validate
(
PyObject
*
self
,
PyObject
*
args
)
{
PyObject
*
accessed
=
NULL
;
/* Note: accessed is not used. */
PyObject
*
container
=
NULL
;
PyObject
*
name
=
NULL
;
PyObject
*
value
=
NULL
;
PyObject
*
context
=
NULL
;
PyObject
*
roles
=
NULL
;
/* Import from SimpleObject Policy._noroles */
/* Note that _noroles means missing roles, spelled with a NULL in C.
Jim. */
PyObject
*
containerbase
=
NULL
;
PyObject
*
accessedbase
=
NULL
;
PyObject
*
p
=
NULL
;
PyObject
*
rval
=
NULL
;
PyObject
*
stack
=
NULL
;
PyObject
*
user
=
NULL
;
PyObject
*
method
=
NULL
;
PyObject
*
tmp
=
NULL
;
int
i
,
l
,
contains
;
PyObject
*
r
;
/*| def validate(self, accessed, container, name, value, context
**| roles=_noroles ...
*/
if
(
unpacktuple6
(
args
,
"validate"
,
5
,
&
accessed
,
&
container
,
&
name
,
&
value
,
&
context
,
&
roles
)
<
0
)
return
NULL
;
/*| # Provide special rules for acquisition attributes
**| if type(name) in (StringType, UnicodeType):
**| if name[:3] == 'aq_' and name not in valid_aq_:
**| raise Unauthorized(name, value)
*/
if
(
PyString_Check
(
name
)
||
PyUnicode_Check
(
name
))
{
char
*
sname
=
PyString_AsString
(
name
);
/* Conversion to string may have failed, e.g. if name is Unicode
* and can't be bashed into the default encoding. Unclear what
* to do then. It's arguably conservative to raise Unauthorized
* in this case.
*/
if
(
sname
==
NULL
||
/* or starts with "aq_" */
(
sname
[
0
]
==
'a'
&&
sname
[
1
]
==
'q'
&&
sname
[
2
]
==
'_'
&&
/* and isn't aq_{parent, inner, explicit} */
strcmp
(
sname
+
3
,
"parent"
)
&&
strcmp
(
sname
+
3
,
"inner"
)
&&
strcmp
(
sname
+
3
,
"explicit"
)
)
)
{
/* Access control violation */
unauthErr
(
name
,
value
);
return
NULL
;
/* roles is not owned yet */
}
}
Py_XINCREF
(
roles
);
/* Convert the borrowed ref to a real one */
/*| containerbase = aq_base(container)
**| accessedbase = aq_base(accessed)
**| if accessedbase is accessed:
**| # accessed is not a wrapper, so assume that the
**| # value could not have been acquired.
**| accessedbase = container
*/
containerbase
=
aq_base
(
container
);
if
(
containerbase
==
NULL
)
goto
err
;
if
(
aq_isWrapper
(
accessed
))
accessedbase
=
aq_base
(
accessed
);
else
{
Py_INCREF
(
container
);
accessedbase
=
container
;
}
/*| # If roles weren't passed in, we'll try to get them from
**| # the object
**|
**| if roles is _noroles:
**| roles = getRoles(container, name, value, _noroles)
*/
if
(
roles
==
NULL
)
{
roles
=
callfunction4
(
getRoles
,
container
,
name
,
value
,
getRoles
);
if
(
roles
==
getRoles
)
{
Py_DECREF
(
roles
);
roles
=
NULL
;
}
if
(
roles
==
NULL
)
PyErr_Clear
();
}
/*| # We still might not have any roles
**|
**| if roles is _noroles:
*/
if
(
roles
==
NULL
)
{
/*| # We have an object without roles and we didn't get
**| # a list of roles passed in. Presumably, the value
**| # is some simple object like a string or a list.
**| # We'll try to get roles from it's container
**|
**| if container is None: raise Unauthorized(name, value)
*/
if
(
container
==
Py_None
)
{
unauthErr
(
name
,
value
);
goto
err
;
}
/*| roles = getattr(container, "__roles__", _noroles)
**| if roles is _noroles:
**| if containerbase is container:
**| # Container is not wrapped.
**| if containerbase is not accessedbase:
**| raise Unauthorized(name, value)
**| else:
**| # Try to acquire roles
**| try: roles = container.aq_aquire('__roles__')
**| except AttributeError:
**| if containerbase is not accessedbase:
**| raise Unauthorized(name, value)
*/
roles
=
PyObject_GetAttr
(
container
,
__roles__
);
if
(
roles
==
NULL
)
{
PyErr_Clear
();
if
(
!
aq_isWrapper
(
container
))
{
if
(
containerbase
!=
accessedbase
)
{
unauthErr
(
name
,
value
);
goto
err
;
}
}
else
{
roles
=
aq_acquire
(
container
,
__roles__
);
if
(
roles
==
NULL
)
{
if
(
PyErr_ExceptionMatches
(
PyExc_AttributeError
))
{
PyErr_Clear
();
if
(
containerbase
!=
accessedbase
)
{
unauthErr
(
name
,
value
);
goto
err
;
}
}
else
goto
err
;
}
}
}
/*| # We need to make sure that we are allowed to get
**| # unprotected attributes from the container. We are
**| # allowed for certain simple containers and if the
**| # container says we can. Simple containers may also
**| # impose name restrictions.
**|
**| p = Containers(type(container), None)
**| if p is None:
**| p = getattr(container,
**| "__allow_access_to_unprotected_subobjects__", None)
*/
p
=
callfunction2
(
Containers
,
OBJECT
(
container
->
ob_type
),
Py_None
);
if
(
p
==
NULL
)
goto
err
;
if
(
p
==
Py_None
)
{
ASSIGN
(
p
,
PyObject_GetAttr
(
container
,
__allow_access_to_unprotected_subobjects__
));
if
(
p
==
NULL
)
PyErr_Clear
();
}
/*| if p is not None:
**| tp = type(p)
**| if tp is not IntType:
**| if tp is DictType:
**| if (isinstance(name, StringType) or
**| isinstance(name, UnicodeType)):
**| p=p.get(name, None)
**| else:
**| p = 1
**| else:
**| p = p(name, value)
*/
if
(
p
)
{
if
(
!
PyInt_Check
(
p
))
{
if
(
PyDict_Check
(
p
))
{
if
(
PyString_Check
(
name
)
||
PyUnicode_Check
(
name
))
{
ASSIGN
(
p
,
PyObject_GetItem
(
p
,
name
));
if
(
p
==
NULL
)
PyErr_Clear
();
}
else
{
ASSIGN
(
p
,
PyInt_FromLong
(
1
));
if
(
p
==
NULL
)
goto
err
;
}
}
else
{
ASSIGN
(
p
,
callfunction2
(
p
,
name
,
value
));
if
(
p
==
NULL
)
goto
err
;
}
}
}
/*| if not p:
**| raise Unauthorized, cleanupName(name, value)
*/
if
(
p
==
NULL
||
!
PyObject_IsTrue
(
p
))
{
Py_XDECREF
(
p
);
unauthErr
(
name
,
value
);
goto
err
;
}
else
Py_DECREF
(
p
);
/*| if roles is _noroles: return 1
*/
if
(
roles
==
NULL
)
{
rval
=
PyInt_FromLong
(
1
);
goto
err
;
}
/*| # We are going to need a security-aware object to pass
**| # to allowed(). We'll use the container
**|
**| value = container
*/
value
=
container
;
/* Both are borrowed references */
}
/* if (roles == NULL) */
/*| # Short-circuit tests if we can
**| try:
**| if roles is None or 'Anonymous' in roles: return 1
**| except TypeError:
**| LOG.warn('"%s' passed as roles"
**| " during validation of '%s' is not a sequence." %
**| ('roles', name))
**| raise
*/
if
(
roles
==
Py_None
)
{
rval
=
PyInt_FromLong
(
1
);
goto
err
;
}
else
{
int
i
;
i
=
PySequence_Contains
(
roles
,
Anonymous
);
if
(
i
>
0
)
{
rval
=
PyInt_FromLong
(
1
);
goto
err
;
}
else
if
(
i
<
0
)
{
/* Error */
PyObject
*
m
,
*
t
,
*
v
,
*
tb
;
if
(
!
PyErr_ExceptionMatches
(
PyExc_TypeError
))
goto
err
;
PyErr_Fetch
(
&
t
,
&
v
,
&
tb
);
m
=
PyObject_Repr
(
roles
);
if
(
m
)
ASSIGN
(
m
,
Py_BuildValue
(
"OO"
,
m
,
name
));
if
(
m
)
ASSIGN
(
m
,
PyString_Format
(
NoSequenceFormat
,
m
));
if
(
m
)
ASSIGN
(
m
,
PyObject_CallFunction
(
warn
,
"O"
,
m
));
Py_XDECREF
(
m
);
PyErr_Restore
(
t
,
v
,
tb
);
goto
err
;
}
}
/*| # Check executable security
**| stack = context.stack
**| if stack:
*/
stack
=
PyObject_GetAttr
(
context
,
stack_str
);
if
(
stack
==
NULL
)
goto
err
;
if
(
PyObject_IsTrue
(
stack
))
{
PyObject
*
eo
;
PyObject
*
owner
;
PyObject
*
proxy_roles
;
/*| eo = stack[-1]
**| # If the executable had an owner, can it execute?
**| owner = eo.getOwner()
**| if (owner is not None) and not owner.allowed(value, roles)
**| # We don't want someone to acquire if they can't
**| # get an unacquired!
**| raise Unauthorized, ('You are not authorized to'
**| 'access <em>%s</em>.' % cleanupName(name, value))
*/
eo
=
PySequence_GetItem
(
stack
,
-
1
);
if
(
eo
==
NULL
)
goto
err
;
if
(
ownerous
)
{
/* Tabbing not adjusted for diff reasons*/
owner
=
PyObject_GetAttr
(
eo
,
getOwner_str
);
if
(
owner
)
ASSIGN
(
owner
,
PyObject_CallObject
(
owner
,
NULL
));
if
(
owner
==
NULL
)
{
Py_DECREF
(
eo
);
goto
err
;
}
if
(
owner
!=
Py_None
)
{
ASSIGN
(
owner
,
PyObject_GetAttr
(
owner
,
allowed_str
));
if
(
owner
)
ASSIGN
(
owner
,
callfunction2
(
owner
,
value
,
roles
));
if
(
owner
==
NULL
)
{
Py_DECREF
(
eo
);
goto
err
;
}
if
(
!
PyObject_IsTrue
(
owner
))
{
Py_DECREF
(
owner
);
Py_DECREF
(
eo
);
unauthErr
(
name
,
value
);
goto
err
;
}
}
Py_DECREF
(
owner
);
}
/* End of if ownerous */
/*| # Proxy roles, which are a lot safer now
**| proxy_roles = getattr(eo, "_proxy_roles", None)
**| if proxy_roles:
**| # Verify that the owner actually can state the proxy role
**| # in the context of the accessed item; users in subfolders
**| # should not be able to use proxy roles to access items
**| # above their subfolder!
**| owner = eo.getWrappedOwner()
**|
**| if owner is not None:
**| if container is not containerbase:
**| if not owner._check_context(container):
**| # container is higher up than the owner,
**| # deny access
**| raise Unauthorized(name, value)
**|
**| for r in proxy_roles:
**| if r in roles:
**| return 1
**|
**| raise Unauthorized(name, value)
*/
proxy_roles
=
PyObject_GetAttr
(
eo
,
_proxy_roles_str
);
if
(
proxy_roles
==
NULL
)
{
Py_DECREF
(
eo
);
PyErr_Clear
();
}
else
if
(
PyObject_IsTrue
(
proxy_roles
))
{
method
=
PyObject_GetAttr
(
eo
,
getWrappedOwner_str
);
if
(
method
==
NULL
)
{
Py_DECREF
(
eo
);
Py_DECREF
(
proxy_roles
);
goto
err
;
}
owner
=
PyObject_CallObject
(
method
,
NULL
);
Py_DECREF
(
method
);
if
(
owner
==
NULL
)
{
Py_DECREF
(
eo
);
Py_DECREF
(
proxy_roles
);
goto
err
;
}
Py_DECREF
(
eo
);
if
(
owner
!=
Py_None
)
{
if
(
containerbase
!=
container
)
{
tmp
=
callmethod1
(
owner
,
_check_context_str
,
container
);
if
(
tmp
==
NULL
)
{
Py_DECREF
(
proxy_roles
);
Py_DECREF
(
owner
);
goto
err
;
}
if
(
!
PyObject_IsTrue
(
tmp
))
{
Py_DECREF
(
proxy_roles
);
Py_DECREF
(
owner
);
Py_DECREF
(
tmp
);
unauthErr
(
name
,
value
);
goto
err
;
}
Py_DECREF
(
tmp
);
}
Py_DECREF
(
owner
);
}
contains
=
0
;
if
(
PyTuple_Check
(
proxy_roles
))
{
l
=
PyTuple_GET_SIZE
(
proxy_roles
);
for
(
i
=
0
;
i
<
l
;
i
++
)
{
r
=
PyTuple_GET_ITEM
(
proxy_roles
,
i
);
if
((
contains
=
PySequence_Contains
(
roles
,
r
)))
break
;
}
}
else
{
l
=
PySequence_Size
(
proxy_roles
);
if
(
l
<
0
)
contains
=
-
1
;
for
(
i
=
0
;
i
<
l
;
i
++
)
{
if
((
r
=
PySequence_GetItem
(
proxy_roles
,
i
)))
{
contains
=
PySequence_Contains
(
roles
,
r
);
Py_DECREF
(
r
);
}
else
contains
=
-
1
;
if
(
contains
<
0
)
break
;
}
}
Py_DECREF
(
proxy_roles
);
if
(
contains
>
0
)
rval
=
PyInt_FromLong
(
contains
);
else
if
(
contains
==
0
)
{
unauthErr
(
name
,
value
);
}
goto
err
;
}
else
{
Py_DECREF
(
eo
);
Py_DECREF
(
proxy_roles
);
}
}
/* End of stack check */
/*| try:
**| if context.user.allowed(value, roles): return 1
**| except AttributeError: pass
*/
if
(
authenticated
)
{
/* Authentication skip for public only access */
user
=
PyObject_GetAttr
(
context
,
user_str
);
if
(
user
)
ASSIGN
(
user
,
PyObject_GetAttr
(
user
,
allowed_str
));
if
(
user
==
NULL
)
{
if
(
PyErr_ExceptionMatches
(
PyExc_AttributeError
))
PyErr_Clear
();
else
goto
err
;
}
else
{
ASSIGN
(
user
,
callfunction2
(
user
,
value
,
roles
));
if
(
user
==
NULL
)
goto
err
;
if
(
PyObject_IsTrue
(
user
))
{
rval
=
PyInt_FromLong
(
1
);
Py_DECREF
(
user
);
goto
err
;
}
Py_DECREF
(
user
);
}
}
/* End of authentiction skip for public only access */
/*| raise Unauthorized(name, value)
*/
unauthErr
(
name
,
value
);
err:
Py_XDECREF
(
containerbase
);
Py_XDECREF
(
accessedbase
);
Py_XDECREF
(
stack
);
Py_XDECREF
(
roles
);
return
rval
;
}
/*
** ZopeSecurityPolicy_dealloc
**
*/
static
void
ZopeSecurityPolicy_dealloc
(
ZopeSecurityPolicy
*
self
)
{
Py_DECREF
(
self
->
ob_type
);
/* Extensionclass init incref'd */
PyObject_DEL
(
self
);
}
/* SecurityManager */
#define CHECK_SECURITY_MANAGER_STATE(self, R) \
UNLESS (self->policy) { \
PyErr_SetString(PyExc_AttributeError, "_policy"); return R; } \
UNLESS (self->context) { \
PyErr_SetString(PyExc_AttributeError, "_policy"); return R; }
#define GET_SECURITY_MANAGER_VALIDATE(self, R) \
if (self->validate == NULL && \
((self->validate = PyObject_GetAttr(self->policy, validate_str)) \
== NULL)) return R;
static
PyObject
*
SecurityManager_validate
(
SecurityManager
*
self
,
PyObject
*
args
)
{
PyObject
*
accessed
=
Py_None
,
*
container
=
Py_None
,
*
name
=
Py_None
,
*
value
=
Py_None
,
*
roles
=
NULL
;
if
(
unpacktuple5
(
args
,
"validate"
,
0
,
&
accessed
,
&
container
,
&
name
,
&
value
,
&
roles
)
<
0
)
return
NULL
;
CHECK_SECURITY_MANAGER_STATE
(
self
,
NULL
);
GET_SECURITY_MANAGER_VALIDATE
(
self
,
NULL
);
if
(
roles
==
NULL
)
return
callfunction5
(
self
->
validate
,
accessed
,
container
,
name
,
value
,
self
->
context
);
return
callfunction6
(
self
->
validate
,
accessed
,
container
,
name
,
value
,
self
->
context
,
roles
);
}
static
PyObject
*
SecurityManager_DTMLValidate
(
SecurityManager
*
self
,
PyObject
*
args
)
{
PyObject
*
accessed
=
Py_None
,
*
container
=
Py_None
,
*
name
=
Py_None
,
*
value
=
Py_None
,
*
md
=
NULL
;
if
(
unpacktuple5
(
args
,
"DTMLValidate"
,
0
,
&
accessed
,
&
container
,
&
name
,
&
value
,
&
md
)
<
0
)
return
NULL
;
CHECK_SECURITY_MANAGER_STATE
(
self
,
NULL
);
GET_SECURITY_MANAGER_VALIDATE
(
self
,
NULL
);
return
callfunction5
(
self
->
validate
,
accessed
,
container
,
name
,
value
,
self
->
context
);
}
static
PyObject
*
SecurityManager_checkPermission
(
SecurityManager
*
self
,
PyObject
*
args
)
{
PyObject
*
permission
,
*
object
;
if
(
unpacktuple2
(
args
,
"checkPermission"
,
2
,
&
permission
,
&
object
)
<
0
)
return
NULL
;
CHECK_SECURITY_MANAGER_STATE
(
self
,
NULL
);
if
(
self
->
checkPermission
==
NULL
&&
((
self
->
checkPermission
=
PyObject_GetAttr
(
self
->
policy
,
checkPermission_str
))
==
NULL
))
return
NULL
;
return
callfunction3
(
self
->
checkPermission
,
permission
,
object
,
self
->
context
);
}
static
void
SecurityManager_dealloc
(
SecurityManager
*
self
)
{
Py_XDECREF
(
self
->
thread_id
);
Py_XDECREF
(
self
->
context
);
Py_XDECREF
(
self
->
policy
);
Py_XDECREF
(
self
->
validate
);
Py_XDECREF
(
self
->
checkPermission
);
Py_DECREF
(
self
->
ob_type
);
/* Extensionclass init incref'd */
PyObject_DEL
(
self
);
}
static
PyObject
*
SecurityManager_getattro
(
SecurityManager
*
self
,
PyObject
*
name
)
{
if
(
PyString_Check
(
name
)
||
PyUnicode_Check
(
name
))
{
char
*
name_s
=
PyString_AsString
(
name
);
if
(
name_s
==
NULL
)
return
NULL
;
if
(
name_s
[
0
]
==
'_'
)
{
if
(
!
strcmp
(
name_s
,
"_thread_id"
)
&&
self
->
thread_id
)
{
Py_INCREF
(
self
->
thread_id
);
return
self
->
thread_id
;
}
else
if
(
!
strcmp
(
name_s
,
"_context"
)
&&
self
->
context
)
{
Py_INCREF
(
self
->
context
);
return
self
->
context
;
}
else
if
(
!
strcmp
(
name_s
,
"_policy"
)
&&
self
->
policy
)
{
Py_INCREF
(
self
->
policy
);
return
self
->
policy
;
}
}
}
return
Py_FindAttr
(
OBJECT
(
self
),
name
);
}
static
int
SecurityManager_setattro
(
SecurityManager
*
self
,
PyObject
*
name
,
PyObject
*
v
)
{
if
(
PyString_Check
(
name
)
||
PyUnicode_Check
(
name
))
{
char
*
name_s
=
PyString_AsString
(
name
);
if
(
name_s
==
NULL
)
return
-
1
;
if
(
name_s
[
0
]
==
'_'
)
{
if
(
!
strcmp
(
name_s
,
"_thread_id"
))
{
Py_INCREF
(
v
);
ASSIGN
(
self
->
thread_id
,
v
);
return
0
;
}
else
if
(
!
strcmp
(
name_s
,
"_context"
))
{
Py_INCREF
(
v
);
ASSIGN
(
self
->
context
,
v
);
return
0
;
}
else
if
(
!
strcmp
(
name_s
,
"_policy"
))
{
Py_INCREF
(
v
);
ASSIGN
(
self
->
policy
,
v
);
if
(
self
->
validate
)
{
Py_DECREF
(
self
->
validate
);
self
->
validate
=
0
;
}
if
(
self
->
checkPermission
)
{
Py_DECREF
(
self
->
checkPermission
);
self
->
checkPermission
=
0
;
}
return
0
;
}
}
}
PyErr_SetObject
(
PyExc_AttributeError
,
name
);
return
-
1
;
}
/*
** PermissionRole_init
**
*/
static
PyObject
*
PermissionRole_init
(
PermissionRole
*
self
,
PyObject
*
args
)
{
PyObject
*
name
=
NULL
;
PyObject
*
deflt
=
NULL
;
/*|def __init__(self, name, default=('Manager',)):
**| self.__name__ = name
**| self._p = "_" + string.translate(name, name_trans) + "_Permission"
**| self._d = default
*/
if
(
unpacktuple2
(
args
,
"__init__"
,
1
,
&
name
,
&
deflt
)
<
0
)
return
NULL
;
if
(
deflt
==
NULL
)
deflt
=
defaultPermission
;
UNLESS
(
self
->
_p
=
permissionName
(
name
))
return
NULL
;
self
->
__name__
=
name
;
Py_INCREF
(
name
);
self
->
__roles__
=
deflt
;
Py_INCREF
(
deflt
);
Py_INCREF
(
Py_None
);
return
Py_None
;
}
/*
def __of__(self, parent):
*/
static
PyObject
*
PermissionRole_of
(
PermissionRole
*
self
,
PyObject
*
parent
)
{
imPermissionRole
*
r
=
NULL
;
PyObject
*
_p
=
NULL
;
PyObject
*
result
=
NULL
;
/*| r = imPermissionRole()
*/
r
=
(
imPermissionRole
*
)
PyObject_CallObject
(
imPermissionRoleObj
,
NULL
);
if
(
r
==
NULL
)
return
NULL
;
/*| r._p = self._p
*/
r
->
_p
=
self
->
_p
;
Py_INCREF
(
r
->
_p
);
/*| r._pa = parent
*/
r
->
_pa
=
parent
;
Py_INCREF
(
parent
);
/*| r._d = self._d
*/
r
->
__roles__
=
self
->
__roles__
;
Py_INCREF
(
r
->
__roles__
);
/*| p = getattr(parent, 'aq_inner', None)
**| if p is not None:
**| return r.__of__(p)
**| else:
**| return r
*/
if
(
aq_isWrapper
(
parent
))
{
_p
=
aq_inner
(
parent
);
result
=
callmethod1
(
OBJECT
(
r
),
__of__
,
_p
);
Py_DECREF
(
_p
);
/* Dont need goto */
}
else
{
result
=
OBJECT
(
r
);
Py_INCREF
(
r
);
}
Py_DECREF
(
r
);
return
result
;
}
/*
def rolesForPermissionOn(self, value):
return rolesForPermissionOn(None, value, self._d, self._p)
*/
static
PyObject
*
PermissionRole_rolesForPermissionOn
(
PermissionRole
*
self
,
PyObject
*
value
)
{
return
c_rolesForPermissionOn
(
NULL
,
value
,
self
->
__roles__
,
self
->
_p
);
}
/*
** PermissionRole_dealloc
**
*/
static
void
PermissionRole_dealloc
(
PermissionRole
*
self
)
{
Py_XDECREF
(
self
->
__name__
);
Py_XDECREF
(
self
->
_p
);
Py_XDECREF
(
self
->
__roles__
);
Py_XDECREF
(
self
->
ob_type
);
/* Extensionclass init incref'd */
PyObject_DEL
(
self
);
}
/* for DocFinder */
/*
** PermissionRole_getattro
**
*/
static
PyObject
*
PermissionRole_getattro
(
PermissionRole
*
self
,
PyObject
*
name
)
{
PyObject
*
result
=
NULL
;
char
*
name_s
=
PyString_AsString
(
name
);
/* see whether we know the attribute */
/* we support both the old "_d" (from the Python implementation)
and the new "__roles__"
*/
if
(
name_s
==
NULL
)
PyErr_Clear
();
/* defer to ExtensionClassGetattro */
else
if
(
name_s
[
0
]
==
'_'
)
{
if
(
!
strcmp
(
name_s
,
"__name__"
))
result
=
self
->
__name__
;
else
if
(
!
strcmp
(
name_s
,
"__roles__"
))
result
=
self
->
__roles__
;
else
if
(
!
strcmp
(
name_s
,
"_p"
))
result
=
self
->
_p
;
else
if
(
!
strcmp
(
name_s
,
"_d"
))
result
=
self
->
__roles__
;
}
if
(
result
)
{
Py_INCREF
(
result
);
return
result
;
}
else
return
ExtensionClassGetattro
((
PyObject
*
)
self
,
name
);
}
/*
def __of__(self, value):
return rolesForPermissionOn(None, value, self._d, self._p)
*/
static
PyObject
*
imPermissionRole_of
(
imPermissionRole
*
self
,
PyObject
*
value
)
{
return
c_rolesForPermissionOn
(
NULL
,
value
,
self
->
__roles__
,
self
->
_p
);
}
/*
** imPermissionRole_length
*/
static
Py_ssize_t
imPermissionRole_length
(
imPermissionRole
*
self
)
{
Py_ssize_t
l
;
PyObject
*
v
;
PyObject
*
pa
;
/*|
**| try:
**| v=self._v
**| except:
**| v = self._v = self.__of__(self._pa)
**| del self._pa
**|
**| return len(v)
*/
v
=
self
->
_v
;
if
(
v
==
NULL
)
{
pa
=
self
->
_pa
;
if
(
pa
==
NULL
)
{
PyErr_SetString
(
PyExc_AttributeError
,
"_pa"
);
return
-
1
;
}
v
=
callmethod1
(
OBJECT
(
self
),
__of__
,
pa
);
if
(
v
==
NULL
)
return
-
1
;
self
->
_v
=
v
;
Py_DECREF
(
pa
);
self
->
_pa
=
NULL
;
}
l
=
PyObject_Length
(
v
);
return
l
;
}
/*
** imPermissionRole_get
*/
static
PyObject
*
imPermissionRole_get
(
imPermissionRole
*
self
,
Py_ssize_t
item
)
{
PyObject
*
v
;
PyObject
*
pa
;
PyObject
*
result
;
/*| try:
**| v = self._v
**| except:
**| v = self._v = self.__of__(self._pa)
**| del self._pa
**| return v[i]
*/
v
=
self
->
_v
;
if
(
v
==
NULL
)
{
pa
=
self
->
_pa
;
if
(
pa
==
NULL
)
{
PyErr_SetString
(
PyExc_AttributeError
,
"_pa"
);
return
NULL
;
}
v
=
callmethod1
(
OBJECT
(
self
),
__of__
,
pa
);
if
(
v
==
NULL
)
return
NULL
;
self
->
_v
=
v
;
Py_DECREF
(
pa
);
self
->
_pa
=
NULL
;
}
result
=
PySequence_GetItem
(
v
,
item
);
return
result
;
}
/*
** imPermissionRole_dealloc
**
*/
static
void
imPermissionRole_dealloc
(
imPermissionRole
*
self
)
{
Py_XDECREF
(
self
->
_p
);
Py_XDECREF
(
self
->
_pa
);
Py_XDECREF
(
self
->
__roles__
);
Py_XDECREF
(
self
->
_v
);
Py_DECREF
(
self
->
ob_type
);
/* Extensionclass init incref'd */
PyObject_DEL
(
self
);
}
/*
** rolesForPermissionOn
*/
static
PyObject
*
rolesForPermissionOn
(
PyObject
*
self
,
PyObject
*
args
)
{
PyObject
*
perm
=
NULL
;
PyObject
*
object
=
NULL
;
PyObject
*
deflt
=
NULL
;
PyObject
*
n
=
NULL
;
/*|def rolesForPermissionOn(perm, object, default=('Manager',)):
**|
**| """Return the roles that have the permisson on the given object"""
*/
if
(
unpacktuple4
(
args
,
"rolesForPermissionOn"
,
2
,
&
perm
,
&
object
,
&
deflt
,
&
n
)
<
0
)
return
NULL
;
return
c_rolesForPermissionOn
(
perm
,
object
,
deflt
,
n
);
}
/*
def rolesForPermissionOn(perm, object, default=_default_roles, n=None):
"""Return the roles that have the given permission on the given object
"""
*/
static
PyObject
*
c_rolesForPermissionOn
(
PyObject
*
perm
,
PyObject
*
object
,
PyObject
*
_default_roles
,
PyObject
*
n
)
{
PyObject
*
r
,
*
result
=
NULL
;
/*
n = n or '_' + string.translate(perm, name_trans) + "_Permission"
*/
if
(
n
)
Py_INCREF
(
n
);
else
{
n
=
permissionName
(
perm
);
if
(
n
==
NULL
)
return
NULL
;
}
Py_INCREF
(
object
);
/*
r = None
*/
r
=
Py_None
;
Py_INCREF
(
r
);
/*
while 1:
*/
while
(
1
)
{
/*
if hasattr(object, n):
roles = getattr(object, n)
*/
PyObject
*
roles
=
PyObject_GetAttr
(
object
,
n
);
if
(
roles
!=
NULL
)
{
/*
if roles is None:
return 'Anonymous',
*/
if
(
roles
==
Py_None
)
{
Py_DECREF
(
roles
);
result
=
AnonymousTuple
;
Py_INCREF
(
result
);
goto
end
;
}
/*
t = type(roles)
*/
/*
if t is tuple:
# If we get a tuple, then we don't acquire
if r is None:
return roles
return r+list(roles)
*/
if
(
PyTuple_Check
(
roles
))
{
if
(
r
==
Py_None
)
result
=
roles
;
else
{
PyObject
*
list_roles
=
PySequence_List
(
roles
);
Py_DECREF
(
roles
);
if
(
list_roles
==
NULL
)
goto
end
;
result
=
PySequence_Concat
(
r
,
list_roles
);
Py_DECREF
(
list_roles
);
}
goto
end
;
}
/*
if t is str:
# We found roles set to a name. Start over
# with the new permission name. If the permission
# name is '', then treat as private!
if roles:
n = roles
else:
return _what_not_even_god_should_do
*/
if
(
PyString_Check
(
roles
))
{
if
(
PyString_GET_SIZE
(
roles
))
{
Py_DECREF
(
n
);
n
=
roles
;
}
else
{
Py_DECREF
(
roles
);
result
=
_what_not_even_god_should_do
;
Py_INCREF
(
result
);
goto
end
;
}
}
/*
elif roles:
if r is None:
r = list(roles)
else: r = r + list(roles)
*/
else
{
int
bool
=
PyObject_IsTrue
(
roles
);
if
(
bool
<
0
)
goto
end
;
if
(
bool
)
{
PyObject
*
list_roles
=
PySequence_List
(
roles
);
Py_DECREF
(
roles
);
if
(
list_roles
==
NULL
)
goto
end
;
if
(
r
==
Py_None
)
{
Py_DECREF
(
r
);
r
=
list_roles
;
}
else
{
PyObject
*
tmp
=
PySequence_Concat
(
r
,
list_roles
);
Py_DECREF
(
list_roles
);
if
(
tmp
==
NULL
)
goto
end
;
Py_DECREF
(
r
);
r
=
tmp
;
}
}
}
}
else
/* roles == NULL */
PyErr_Clear
();
/*
object = aq_inner(object)
if object is None:
break
object = aq_parent(object)
*/
{
PyObject
*
tobj
=
aq_inner
(
object
);
if
(
tobj
==
NULL
)
goto
end
;
Py_DECREF
(
object
);
object
=
tobj
;
if
(
object
==
Py_None
)
break
;
tobj
=
aq_parent
(
object
);
if
(
tobj
==
NULL
)
goto
end
;
Py_DECREF
(
object
);
object
=
tobj
;
}
}
/*
if r is None:
return default
return r
*/
if
(
r
==
Py_None
)
{
result
=
_default_roles
;
if
(
result
==
NULL
)
result
=
ManagerTuple
;
Py_INCREF
(
result
);
goto
end
;
}
Py_INCREF
(
r
);
result
=
r
;
end:
Py_DECREF
(
n
);
Py_DECREF
(
object
);
Py_DECREF
(
r
);
return
result
;
}
/*
** permissionName
**
** Can silently truncate permission names if they are really long
*/
static
PyObject
*
permissionName
(
PyObject
*
name
)
{
char
namebuff
[
512
];
register
int
len
=
sizeof
(
namebuff
)
-
1
;
char
*
c
=
namebuff
;
char
*
in
;
char
r
;
*
c
=
'_'
;
c
++
;
len
--
;
in
=
PyString_AsString
(
name
);
if
(
in
==
NULL
)
return
NULL
;
while
(
len
&&
*
in
)
{
r
=
*
(
in
++
);
if
(
!
isalnum
(
r
))
r
=
'_'
;
*
(
c
++
)
=
r
;
len
--
;
}
if
(
len
)
{
in
=
"_Permission"
;
while
(
len
&&
*
in
)
{
*
(
c
++
)
=
*
(
in
++
);
len
--
;
}
}
*
c
=
'\0'
;
/* Saved room in len */
return
PyString_FromString
(
namebuff
);
}
/* def guarded_getattr(inst, name, default=_marker): */
static
PyObject
*
guarded_getattr
(
PyObject
*
inst
,
PyObject
*
name
,
PyObject
*
default_
,
PyObject
*
validate
)
{
PyObject
*
v
=
0
,
*
t
=
0
;
int
i
;
/* if name[:1] != '_': */
if
(
PyString_Check
(
name
)
||
PyUnicode_Check
(
name
))
{
char
*
name_s
=
PyString_AsString
(
name
);
if
(
name_s
==
NULL
)
return
NULL
;
if
(
name_s
[
0
]
!=
'_'
)
{
/*
# Try to get the attribute normally so that unusual
# exceptions are caught early.
try: v = getattr(inst, name)
except AttributeError:
if default is not _marker:
return default
raise
*/
v
=
PyObject_GetAttr
(
inst
,
name
);
if
(
v
==
NULL
)
{
if
(
default_
&&
PyErr_Occurred
()
==
PyExc_AttributeError
)
{
PyErr_Clear
();
Py_INCREF
(
default_
);
return
default_
;
}
return
NULL
;
}
/*
assertion = Containers(type(inst))
*/
t
=
PyDict_GetItem
(
ContainerAssertions
,
OBJECT
(
inst
->
ob_type
));
if
(
t
!=
NULL
)
{
/*
if isinstance(assertion, dict):
# We got a table that lets us reason about individual
# attrs
assertion = assertion.get(name)
if assertion:
# There's an entry, but it may be a function.
if callable(assertion):
return assertion(inst, name)
# Nope, it's boolean
return v
raise Unauthorized, name
*/
if
(
PyDict_Check
(
t
))
{
PyObject
*
attrv
;
attrv
=
PyDict_GetItem
(
t
,
name
);
if
(
attrv
!=
NULL
)
{
i
=
PyObject_IsTrue
(
attrv
);
if
(
i
<
0
)
goto
err
;
if
(
i
)
{
if
(
attrv
->
ob_type
->
tp_call
)
{
Py_DECREF
(
v
);
v
=
callfunction2
(
attrv
,
inst
,
name
);
return
v
;
}
return
v
;
}
}
Py_DECREF
(
v
);
goto
unauth
;
}
/*
if assertion:
if callable(assertion):
factory = assertion(name, v)
if callable(factory):
return factory(inst, name)
assert factory == 1
assert callable == 1
return v
*/
if
(
PyCallable_Check
(
t
))
{
PyObject
*
factory
;
factory
=
callfunction2
(
t
,
name
,
v
);
if
(
factory
==
NULL
)
goto
err
;
if
(
PyCallable_Check
(
factory
))
{
Py_DECREF
(
v
);
v
=
callfunction2
(
factory
,
inst
,
name
);
}
Py_DECREF
(
factory
);
}
return
v
;
}
/*
# See if we can get the value doing a filtered acquire.
# aq_acquire will either return the same value as held by
# v or it will return an Unauthorized raised by validate.
validate = SecurityManagement.getSecurityManager().validate
aq_acquire(inst, name, aq_validate, validate)
return v
*/
t
=
aq_Acquire
(
inst
,
name
,
aq_validate
,
validate
,
1
,
NULL
,
0
);
if
(
t
==
NULL
)
{
Py_DECREF
(
v
);
return
NULL
;
}
Py_DECREF
(
t
);
return
v
;
unauthErr
(
name
,
v
);
err:
Py_DECREF
(
v
);
return
NULL
;
}
}
unauth:
/* raise Unauthorized, name */
PyErr_SetObject
(
Unauthorized
,
name
);
return
NULL
;
}
static
PyObject
*
module_guarded_getattr
(
PyObject
*
ignored
,
PyObject
*
args
)
{
PyObject
*
inst
,
*
name
,
*
default_
=
0
,
*
validate
;
if
(
unpacktuple3
(
args
,
"guarded_getattr"
,
2
,
&
inst
,
&
name
,
&
default_
)
<
0
)
return
NULL
;
/*
validate = getSecurityManager().validate
*/
validate
=
PyObject_CallObject
(
getSecurityManager
,
NULL
);
if
(
!
validate
)
return
NULL
;
ASSIGN
(
validate
,
PyObject_GetAttr
(
validate
,
validate_str
));
if
(
!
validate
)
return
NULL
;
ASSIGN
(
validate
,
guarded_getattr
(
inst
,
name
,
default_
,
validate
));
return
validate
;
}
/*
def aq_validate(inst, obj, name, v, validate):
return validate(inst, obj, name, v)
*/
static
PyObject
*
module_aq_validate
(
PyObject
*
ignored
,
PyObject
*
args
)
{
PyObject
*
inst
=
NULL
,
*
obj
=
NULL
,
*
name
=
NULL
,
*
v
=
NULL
,
*
validate
=
NULL
;
if
(
unpacktuple5
(
args
,
"validate"
,
0
,
&
inst
,
&
obj
,
&
name
,
&
v
,
&
validate
)
<
0
)
return
NULL
;
return
callfunction4
(
validate
,
inst
,
obj
,
name
,
v
);
}
static
PyObject
*
module_setDefaultBehaviors
(
PyObject
*
ignored
,
PyObject
*
args
)
{
PyObject
*
result
=
NULL
;
int
own
,
auth
,
verbose
;
if
(
PyArg_ParseTuple
(
args
,
"iii:setDefaultBehaviors"
,
&
own
,
&
auth
,
&
verbose
))
{
if
(
verbose
)
{
PyErr_SetString
(
PyExc_NotImplementedError
,
"This security policy implementation does not implement "
"the verbose option. To enable verbose security "
"exceptions, add 'security-policy-implementation "
"python' to etc/zope.conf."
);
return
NULL
;
}
ownerous
=
own
;
authenticated
=
authenticated
;
result
=
Py_None
;
Py_INCREF
(
result
);
}
return
result
;
}
static
PyObject
*
dtml_guarded_getattr
(
PyObject
*
self
,
PyObject
*
args
)
{
PyObject
*
ob
,
*
name
,
*
default_
=
0
,
*
validate
;
if
(
unpacktuple3
(
args
,
"guarded_getattr"
,
2
,
&
ob
,
&
name
,
&
default_
)
<
0
)
return
NULL
;
UNLESS
(
validate
=
PyObject_GetAttr
(
self
,
validate_str
))
{
/* This section is pure paranoia at this point. It was necessary
while debugging. */
PyErr_Clear
();
validate
=
PyObject_CallObject
(
getSecurityManager
,
NULL
);
if
(
!
validate
)
return
NULL
;
ASSIGN
(
validate
,
PyObject_GetAttr
(
validate
,
validate_str
));
if
(
!
validate
)
return
NULL
;
}
ASSIGN
(
validate
,
guarded_getattr
(
ob
,
name
,
default_
,
validate
));
return
validate
;
}
static
struct
PyMethodDef
dtml_methods
[]
=
{
{
"guarded_getattr"
,
(
PyCFunction
)
dtml_guarded_getattr
,
METH_VARARGS
|
METH_KEYWORDS
,
""
},
{
NULL
,
NULL
}
};
/* ----------------------------------------------------------------
** Module initialization
** ----------------------------------------------------------------
*/
#define IMPORT(module, name) if ((module = PyImport_ImportModule(name)) == NULL) return;
#define GETATTR(module, name) if ((name = PyObject_GetAttrString(module, #name)) == NULL) return;
void
initcAccessControl
(
void
)
{
PyObject
*
module
;
PyObject
*
dict
;
PURE_MIXIN_CLASS
(
RestrictedDTMLMixin
,
"A mix-in for derivatives of DT_String.String "
"that adds Zope security."
,
dtml_methods
);
if
(
!
ExtensionClassImported
)
return
;
if
(
ZopeSecurityPolicy_setup
()
<
0
)
return
;
ExtensionClassGetattro
=
Py_FindAttr
;
module
=
Py_InitModule3
(
"cAccessControl"
,
cAccessControl_methods
,
"cAccessControl.c
\n
"
);
aq_init
();
/* For Python <= 2.1.1, aq_init() should be after
Py_InitModule(). */
dict
=
PyModule_GetDict
(
module
);
PyDict_SetItemString
(
dict
,
"_what_not_even_god_should_do"
,
_what_not_even_god_should_do
);
PyExtensionClass_Export
(
dict
,
"RestrictedDTMLMixin"
,
RestrictedDTMLMixinType
);
PyExtensionClass_Export
(
dict
,
"ZopeSecurityPolicy"
,
ZopeSecurityPolicyType
);
PyExtensionClass_Export
(
dict
,
"SecurityManager"
,
SecurityManagerType
);
PyExtensionClass_Export
(
dict
,
"PermissionRole"
,
PermissionRoleType
);
PyExtensionClass_Export
(
dict
,
"imPermissionRole"
,
imPermissionRoleType
);
imPermissionRoleObj
=
PyMapping_GetItemString
(
dict
,
"imPermissionRole"
);
aq_validate
=
PyMapping_GetItemString
(
dict
,
"aq_validate"
);
/*| from SimpleObjectPolicies import Containers
*/
IMPORT
(
module
,
"AccessControl.SimpleObjectPolicies"
);
GETATTR
(
module
,
Containers
);
GETATTR
(
module
,
ContainerAssertions
);
Py_DECREF
(
module
);
module
=
NULL
;
/*| from ZopeSecurityPolicy import getRoles
*/
IMPORT
(
module
,
"AccessControl.ZopeSecurityPolicy"
);
GETATTR
(
module
,
getRoles
);
Py_DECREF
(
module
);
module
=
NULL
;
/*| from unauthorized import Unauthorized
*/
IMPORT
(
module
,
"AccessControl.unauthorized"
);
GETATTR
(
module
,
Unauthorized
);
Py_DECREF
(
module
);
module
=
NULL
;
/*| from AccessControl.SecurityManagement import getSecurityManager
*/
IMPORT
(
module
,
"AccessControl.SecurityManagement"
);
GETATTR
(
module
,
getSecurityManager
);
Py_DECREF
(
module
);
module
=
NULL
;
/*| from logger_wrapper import warn
*/
IMPORT
(
module
,
"AccessControl.logger_wrapper"
);
GETATTR
(
module
,
warn
);
Py_DECREF
(
module
);
module
=
NULL
;
}
src/AccessControl/class_init.py
deleted
100644 → 0
View file @
ccc10355
##############################################################################
#
# 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 initialization.
"""
import
logging
from
AccessControl.Permission
import
ApplicationDefaultPermissions
# BBB
def
InitializeClass
(
self
):
from
AccessControl.Permission
import
registerPermissions
from
AccessControl.PermissionRole
import
PermissionRole
dict
=
self
.
__dict__
have
=
dict
.
has_key
ft
=
type
(
InitializeClass
)
dict_items
=
dict
.
items
()
for
name
,
v
in
dict_items
:
if
getattr
(
v
,
'_need__name__'
,
0
):
d
=
v
.
__dict__
oldname
=
d
.
get
(
'__name__'
,
''
)
if
d
.
get
(
'_implicit__name__'
,
0
):
# Already supplied a name.
if
name
!=
oldname
:
# Tried to implicitly assign a different name!
try
:
classname
=
'%s.%s'
%
(
self
.
__module__
,
self
.
__name__
)
except
AttributeError
:
classname
=
`self`
logging
.
getLogger
(
"Init"
).
warning
(
'Ambiguous name for method of %s: %r != %r'
,
classname
,
d
[
'__name__'
],
name
)
else
:
# Supply a name implicitly so that the method can
# find the security assertions on its container.
v
.
_implicit__name__
=
1
v
.
__name__
=
name
if
name
==
'manage'
or
name
[:
7
]
==
'manage_'
:
name
=
name
+
'__roles__'
if
not
have
(
name
):
setattr
(
self
,
name
,
(
'Manager'
,))
elif
name
==
'manage'
or
name
[:
7
]
==
'manage_'
and
type
(
v
)
is
ft
:
name
=
name
+
'__roles__'
if
not
have
(
name
):
setattr
(
self
,
name
,
(
'Manager'
,))
# Look for a SecurityInfo object on the class. If found, call its
# apply() method to generate __ac_permissions__ for the class. We
# delete the SecurityInfo from the class dict after it has been
# applied out of paranoia.
for
key
,
value
in
dict_items
:
if
hasattr
(
value
,
'__security_info__'
):
security_info
=
value
security_info
.
apply
(
self
)
delattr
(
self
,
key
)
break
if
self
.
__dict__
.
has_key
(
'__ac_permissions__'
):
registerPermissions
(
self
.
__ac_permissions__
)
for
acp
in
self
.
__ac_permissions__
:
pname
,
mnames
=
acp
[:
2
]
if
len
(
acp
)
>
2
:
roles
=
acp
[
2
]
pr
=
PermissionRole
(
pname
,
roles
)
else
:
pr
=
PermissionRole
(
pname
)
for
mname
in
mnames
:
setattr
(
self
,
mname
+
'__roles__'
,
pr
)
if
(
mname
and
mname
not
in
(
'context'
,
'request'
)
and
not
hasattr
(
self
,
mname
)):
# don't complain about context or request, as they are
# frequently not available as class attributes
logging
.
getLogger
(
"Init"
).
warning
(
"Class %s.%s has a security declaration for "
"nonexistent method %r"
,
self
.
__module__
,
self
.
__name__
,
mname
)
default__class_init__
=
InitializeClass
# BBB: old name
src/AccessControl/configure.zcml
deleted
100644 → 0
View file @
ccc10355
<configure xmlns="http://namespaces.zope.org/zope">
<include file="permissions.zcml"/>
</configure>
src/AccessControl/interfaces.py
deleted
100644 → 0
View file @
ccc10355
##############################################################################
#
# Copyright (c) 2005 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.
#
##############################################################################
"""AccessControl interfaces.
"""
from
AccessControl.SimpleObjectPolicies
import
_noroles
from
zope.interface
import
Attribute
from
zope.interface
import
Interface
class
IOwned
(
Interface
):
def
owner_info
():
"""Get ownership info for display
"""
def
getOwner
(
info
=
0
):
"""Get the owner
If a true argument is provided, then only the owner path and id are
returned. Otherwise, the owner object is returned.
"""
def
getOwnerTuple
():
"""Return a tuple, (userdb_path, user_id) for the owner.
o Ownership can be acquired, but only from the containment path.
o If unowned, return None.
"""
def
getWrappedOwner
():
"""Get the owner, modestly wrapped in the user folder.
o If the object is not owned, return None.
o If the owner's user database doesn't exist, return Nobody.
o If the owner ID does not exist in the user database, return Nobody.
"""
def
changeOwnership
(
user
,
recursive
=
0
):
"""Change the ownership to the given user.
If 'recursive' is true then also take ownership of all sub-objects,
otherwise sub-objects retain their ownership information.
"""
def
userCanTakeOwnership
():
"""
"""
def
_deleteOwnershipAfterAdd
():
"""
"""
def
manage_fixupOwnershipAfterAdd
():
"""
"""
class
IPermissionMappingSupport
(
Interface
):
def
manage_getPermissionMapping
():
"""Return the permission mapping for the object
This is a list of dictionaries with:
permission_name -- The name of the native object permission
class_permission -- The class permission the permission is
mapped to.
"""
def
manage_setPermissionMapping
(
permission_names
=
[],
class_permissions
=
[],
REQUEST
=
None
):
"""Change the permission mapping
"""
class
IRoleManager
(
IPermissionMappingSupport
):
"""An object that has configurable permissions"""
permissionMappingPossibleValues
=
Attribute
(
"""Acquired attribute"""
)
def
ac_inherited_permissions
(
all
=
0
):
"""Get all permissions not defined in ourself that are inherited.
This will be a sequence of tuples with a name as the first item and an
empty tuple as the second.
"""
def
permission_settings
(
permission
=
None
):
"""Return user-role permission settings.
If 'permission' is passed to the method then only the settings for
'permission' is returned.
"""
def
manage_role
(
role_to_manage
,
permissions
=
[]):
"""Change the permissions given to the given role.
"""
def
manage_acquiredPermissions
(
permissions
=
[]):
"""Change the permissions that acquire.
"""
def
manage_permission
(
permission_to_manage
,
roles
=
[],
acquire
=
0
):
"""Change the settings for the given permission.
If optional arg acquire is true, then the roles for the permission
are acquired, in addition to the ones specified, otherwise the
permissions are restricted to only the designated roles.
"""
def
permissionsOfRole
(
role
):
"""Returns a role to permission mapping.
"""
def
rolesOfPermission
(
permission
):
"""Returns a permission to role mapping.
"""
def
acquiredRolesAreUsedBy
(
permission
):
"""
"""
def
has_local_roles
():
"""
"""
def
get_local_roles
():
"""
"""
def
users_with_local_role
(
role
):
"""
"""
def
get_valid_userids
():
"""
"""
def
get_local_roles_for_userid
(
userid
):
"""
"""
def
manage_addLocalRoles
(
userid
,
roles
):
"""Set local roles for a user."""
def
manage_setLocalRoles
(
userid
,
roles
):
"""Set local roles for a user."""
def
manage_delLocalRoles
(
userids
):
"""Remove all local roles for a user."""
#------------------------------------------------------------
def
access_debug_info
():
"""Return debug info.
"""
def
valid_roles
():
"""Return list of valid roles.
"""
def
validate_roles
(
roles
):
"""Return true if all given roles are valid.
"""
def
userdefined_roles
():
"""Return list of user-defined roles.
"""
def
possible_permissions
():
"""
"""
def
manage_getUserRolesAndPermissions
(
user_id
):
""" Used for permission/role reporting for a given user_id.
Returns a dict mapping
'user_defined_in' -> path where the user account is defined
'roles' -> global roles,
'roles_in_context' -> roles in context of the current object,
'allowed_permissions' -> permissions allowed for the user,
'disallowed_permissions' -> all other permissions
"""
class
IStandardUserFolder
(
Interface
):
def
getUser
(
name
):
"""Get the user object specified by name.
If there is no user named 'name' in the user folder, return None.
"""
def
getUsers
():
"""Get a sequence of all user objects which reside in the user folder.
"""
def
getUserNames
():
"""Get a sequence of names of the users which reside in the user folder.
"""
class
ISecurityPolicy
(
Interface
):
"""Plug-in policy for checking access to objects within untrusted code.
"""
def
validate
(
accessed
,
container
,
name
,
value
,
context
,
roles
=
_noroles
):
"""Check that the current user (from context) has access.
o Raise Unauthorized if access is not allowed; otherwise, return
a true value.
Arguments:
accessed -- the object that was being accessed
container -- the object the value was found in
name -- The name used to access the value
value -- The value retrieved though the access.
context -- the security context (normally supplied by the security
manager).
roles -- The roles of the object if already known.
"""
def
checkPermission
(
permission
,
object
,
context
):
"""Check whether the current user has a permission w.r.t. an object.
"""
class
ISecurityManager
(
Interface
):
"""Check access and manages executable context and policies.
"""
_policy
=
Attribute
(
u'Current Security Policy'
)
def
validate
(
accessed
=
None
,
container
=
None
,
name
=
None
,
value
=
None
,
roles
=
_noroles
,
):
"""Validate access.
Arguments:
accessed -- the object that was being accessed
container -- the object the value was found in
name -- The name used to access the value
value -- The value retrieved though the access.
roles -- The roles of the object if already known.
The arguments may be provided as keyword arguments. Some of these
arguments may be ommitted, however, the policy may reject access
in some cases when arguments are ommitted. It is best to provide
all the values possible.
"""
def
DTMLValidate
(
accessed
=
None
,
container
=
None
,
name
=
None
,
value
=
None
,
md
=
None
,
):
"""Validate access.
* THIS EXISTS FOR DTML COMPATIBILITY *
Arguments:
accessed -- the object that was being accessed
container -- the object the value was found in
name -- The name used to access the value
value -- The value retrieved though the access.
md -- multidict for DTML (ignored)
The arguments may be provided as keyword arguments. Some of these
arguments may be ommitted, however, the policy may reject access
in some cases when arguments are ommitted. It is best to provide
all the values possible.
"""
def
checkPermission
(
permission
,
object
):
"""Check whether the security context allows the given permission on
the given object.
Arguments:
permission -- A permission name
object -- The object being accessed according to the permission
"""
def
addContext
(
anExecutableObject
):
"""Add an ExecutableObject to the current security context.
o If it declares a custom security policy, make that policy
"current"; otherwise, make the "default" security policy
current.
"""
def
removeContext
(
anExecutableObject
):
"""Remove an ExecutableObject from the current security context.
o Remove all objects from the top of the stack "down" to the
supplied object.
o If the top object on the stack declares a custom security policy,
make that policy "current".
o If the stack is empty, or if the top declares no custom security
policy, restore the 'default" security policy as current.
"""
def
getUser
():
"""Get the currently authenticated user
"""
def
calledByExecutable
():
"""Return a boolean value indicating whether this context was called
in the context of an by an executable (i.e., one added via
'addContext').
"""
src/AccessControl/logger_wrapper.py
deleted
100644 → 0
View file @
ccc10355
# A wrapper to replace the usage of the zLOG module in cAccessControl without
# having the need to change the C code significantly.
from
logging
import
getLogger
LOG
=
getLogger
(
'AccessControl'
)
warn
=
LOG
.
warn
src/AccessControl/meta.zcml
deleted
100644 → 0
View file @
ccc10355
<configure
xmlns="http://namespaces.zope.org/zope"
xmlns:meta="http://namespaces.zope.org/meta">
<include package="zope.component" file="meta.zcml" />
<include package="zope.security" file="meta.zcml" />
<meta:directives namespace="http://namespaces.zope.org/zope">
<meta:complexDirective
name="class"
schema="zope.security.metadirectives.IClassDirective"
handler=".metaconfigure.ClassDirective"
>
<meta:subdirective
name="implements"
schema="zope.security.metadirectives.IImplementsSubdirective"
/>
<meta:subdirective
name="require"
schema="zope.security.metadirectives.IRequireSubdirective"
/>
<meta:subdirective
name="allow"
schema="zope.security.metadirectives.IAllowSubdirective"
/>
</meta:complexDirective>
<meta:directive
name="securityPolicy"
schema="zope.security.zcml.ISecurityPolicyDirective"
handler="zope.security.zcml.securityPolicy"
/>
</meta:directives>
</configure>
src/AccessControl/metaconfigure.py
deleted
100644 → 0
View file @
ccc10355
##############################################################################
#
# Copyright (c) 2004, 2005 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.
#
##############################################################################
import
warnings
from
zope.security
import
metaconfigure
from
AccessControl.class_init
import
InitializeClass
from
AccessControl.security
import
protectName
class
ClassDirective
(
metaconfigure
.
ClassDirective
):
def
__protectName
(
self
,
name
,
permission_id
):
self
.
__context
.
action
(
discriminator
=
(
'five:protectName'
,
self
.
__class
,
name
),
callable
=
protectName
,
args
=
(
self
.
__class
,
name
,
permission_id
)
)
def
__protectSetAttributes
(
self
,
names
,
permission_id
):
warnings
.
warn
(
"The set_attribute option of the <require /> directive "
"is not supported in Zope 2. "
"Ignored for %s"
%
str
(
self
.
__class
),
stacklevel
=
3
)
def
__protectSetSchema
(
self
,
schema
,
permission
):
warnings
.
warn
(
"The set_schema option of the <require /> directive "
"is not supported in Zope 2. "
"Ignored for %s"
%
str
(
self
.
__class
),
stacklevel
=
3
)
def
__mimic
(
self
,
_context
,
class_
):
warnings
.
warn
(
"The like_class option of the <require /> directive "
"is not supported in Zope 2. "
"Ignored for %s"
%
str
(
self
.
__class
),
stacklevel
=
3
)
def
__call__
(
self
):
return
self
.
__context
.
action
(
discriminator
=
None
,
callable
=
InitializeClass
,
args
=
(
self
.
__class
,)
)
src/AccessControl/owner.py
deleted
100644 → 0
View file @
ccc10355
##############################################################################
#
# 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
#
##############################################################################
"""Support for owned objects
"""
from
Acquisition
import
aq_base
from
Acquisition
import
aq_get
from
Acquisition
import
aq_inner
from
Acquisition
import
aq_parent
from
ExtensionClass
import
Base
from
zope.interface
import
implements
from
AccessControl.class_init
import
InitializeClass
from
AccessControl.interfaces
import
IOwned
from
AccessControl.Permissions
import
view_management_screens
from
AccessControl.Permissions
import
take_ownership
from
AccessControl.SecurityInfo
import
ClassSecurityInfo
from
AccessControl.SecurityManagement
import
getSecurityManager
# avoid importing 'emergency_user' / 'nobody' before set
from
AccessControl
import
SpecialUsers
as
SU
UnownableOwner
=
[]
def
ownableFilter
(
self
):
_owner
=
aq_get
(
self
,
'_owner'
,
None
,
1
)
return
_owner
is
not
UnownableOwner
# Marker to use as a getattr default.
_mark
=
ownableFilter
class
Owned
(
Base
):
implements
(
IOwned
)
security
=
ClassSecurityInfo
()
security
.
setPermissionDefault
(
take_ownership
,
(
'Owner'
,
))
security
.
declareProtected
(
view_management_screens
,
'owner_info'
)
def
owner_info
(
self
):
"""Get ownership info for display
"""
owner
=
self
.
getOwnerTuple
()
if
owner
is
None
or
owner
is
UnownableOwner
:
return
owner
d
=
{
'path'
:
'/'
.
join
(
owner
[
0
]),
'id'
:
owner
[
1
],
'explicit'
:
hasattr
(
self
,
'_owner'
),
'userCanChangeOwnershipType'
:
getSecurityManager
().
checkPermission
(
'Take ownership'
,
self
)
}
return
d
security
.
declarePrivate
(
'getOwner'
)
def
getOwner
(
self
,
info
=
0
,
aq_get
=
aq_get
,
UnownableOwner
=
UnownableOwner
,
getSecurityManager
=
getSecurityManager
,
):
"""Get the owner
If a true argument is provided, then only the owner path and id are
returned. Otherwise, the owner object is returned.
"""
if
info
:
import
warnings
warnings
.
warn
(
'Owned.getOwner(1) is deprecated; '
'please use getOwnerTuple() instead.'
,
DeprecationWarning
,
stacklevel
=
2
)
owner
=
aq_get
(
self
,
'_owner'
,
None
,
1
)
if
info
or
(
owner
is
None
):
return
owner
if
owner
is
UnownableOwner
:
return
None
udb
,
oid
=
owner
root
=
self
.
getPhysicalRoot
()
udb
=
root
.
unrestrictedTraverse
(
udb
,
None
)
if
udb
is
None
:
user
=
SU
.
nobody
else
:
user
=
udb
.
getUserById
(
oid
,
None
)
if
user
is
None
:
user
=
SU
.
nobody
return
user
security
.
declarePrivate
(
'getOwnerTuple'
)
def
getOwnerTuple
(
self
):
"""Return a tuple, (userdb_path, user_id) for the owner.
o Ownership can be acquired, but only from the containment path.
o If unowned, return None.
"""
return
aq_get
(
self
,
'_owner'
,
None
,
1
)
security
.
declarePrivate
(
'getWrappedOwner'
)
def
getWrappedOwner
(
self
):
"""Get the owner, modestly wrapped in the user folder.
o If the object is not owned, return None.
o If the owner's user database doesn't exist, return Nobody.
o If the owner ID does not exist in the user database, return Nobody.
"""
owner
=
self
.
getOwnerTuple
()
if
owner
is
None
or
owner
is
UnownableOwner
:
return
None
udb_path
,
oid
=
owner
root
=
self
.
getPhysicalRoot
()
udb
=
root
.
unrestrictedTraverse
(
udb_path
,
None
)
if
udb
is
None
:
return
SU
.
nobody
user
=
udb
.
getUserById
(
oid
,
None
)
if
user
is
None
:
return
SU
.
nobody
return
user
.
__of__
(
udb
)
security
.
declarePrivate
(
'changeOwnership'
)
def
changeOwnership
(
self
,
user
,
recursive
=
0
):
"""Change the ownership to the given user.
If 'recursive' is true then also take ownership of all sub-objects,
otherwise sub-objects retain their ownership information.
"""
new
=
ownerInfo
(
user
)
if
new
is
None
:
return
# Special user!
old
=
self
.
getOwnerTuple
()
if
not
recursive
:
if
old
==
new
or
old
is
UnownableOwner
:
return
if
recursive
:
children
=
getattr
(
aq_base
(
self
),
'objectValues'
,
lambda
:()
)()
for
child
in
children
:
child
.
changeOwnership
(
user
,
1
)
if
old
is
not
UnownableOwner
:
self
.
_owner
=
new
def
userCanTakeOwnership
(
self
):
security
=
getSecurityManager
()
user
=
security
.
getUser
()
info
=
ownerInfo
(
user
)
if
info
is
None
:
return
0
owner
=
self
.
getOwnerTuple
()
if
owner
==
info
:
return
0
return
security
.
checkPermission
(
'Take ownership'
,
self
)
def
_deleteOwnershipAfterAdd
(
self
):
# Only delete _owner if it is an instance attribute.
if
self
.
__dict__
.
get
(
'_owner'
,
_mark
)
is
not
_mark
:
del
self
.
_owner
for
object
in
self
.
objectValues
():
try
:
s
=
object
.
_p_changed
except
:
s
=
0
try
:
object
.
_deleteOwnershipAfterAdd
()
except
:
pass
if
s
is
None
:
object
.
_p_deactivate
()
def
manage_fixupOwnershipAfterAdd
(
self
):
# Sigh, get the parent's _owner
parent
=
getattr
(
self
,
'__parent__'
,
None
)
if
parent
is
not
None
:
_owner
=
aq_get
(
parent
,
'_owner'
,
None
,
1
)
else
:
_owner
=
None
if
(
_owner
is
None
and
((
getattr
(
self
,
'__parent__'
,
None
)
is
None
)
or
(
not
hasattr
(
self
,
'getPhysicalRoot'
))
)
):
# This is a special case. An object is
# being added to an object that hasn't
# been added to the object hierarchy yet.
# We can delay fixing up the ownership until the
# object is actually added.
return
None
if
_owner
is
UnownableOwner
:
# We want to acquire Unownable ownership!
return
self
.
_deleteOwnershipAfterAdd
()
else
:
# Otherwise change the ownership
user
=
getSecurityManager
().
getUser
()
if
(
SU
.
emergency_user
and
aq_base
(
user
)
is
SU
.
emergency_user
):
__creatable_by_emergency_user__
=
getattr
(
self
,
'__creatable_by_emergency_user__'
,
None
)
if
(
__creatable_by_emergency_user__
is
None
or
(
not
__creatable_by_emergency_user__
())):
raise
EmergencyUserCannotOwn
(
"Objects cannot be owned by the emergency user"
)
self
.
changeOwnership
(
user
)
# Force all subs to acquire ownership!
for
object
in
self
.
objectValues
():
try
:
s
=
object
.
_p_changed
except
:
s
=
0
try
:
object
.
_deleteOwnershipAfterAdd
()
except
:
pass
if
s
is
None
:
object
.
_p_deactivate
()
InitializeClass
(
Owned
)
class
EmergencyUserCannotOwn
(
Exception
):
"The emergency user cannot own anything"
class
EditUnowned
(
Exception
):
"Can't edit unowned executables"
def
absattr
(
attr
):
if
callable
(
attr
):
return
attr
()
return
attr
def
ownerInfo
(
user
,
getattr
=
getattr
):
if
user
is
None
:
return
None
uid
=
user
.
getId
()
if
uid
is
None
:
return
uid
db
=
aq_parent
(
aq_inner
(
user
))
path
=
[
absattr
(
db
.
id
)]
root
=
db
.
getPhysicalRoot
()
while
1
:
db
=
getattr
(
db
,
'aq_inner'
,
None
)
if
db
is
None
:
break
db
=
aq_parent
(
db
)
if
db
is
root
:
break
id
=
db
.
id
if
not
isinstance
(
id
,
str
):
try
:
id
=
id
()
except
:
id
=
str
(
id
)
path
.
append
(
id
)
path
.
reverse
()
return
path
,
uid
src/AccessControl/permissions.zcml
deleted
100644 → 0
View file @
ccc10355
<configure xmlns="http://namespaces.zope.org/zope"
i18n_domain="Zope2">
<!-- Create permissions declared in ZCML if they don't exist already -->
<subscriber
for="zope.security.interfaces.IPermission
zope.component.interfaces.IRegistered"
handler=".security.create_permission_from_permission_directive"
/>
<permission
id="zope2.Public"
title="Public, everyone can access"
/>
<permission
id="zope2.Private"
title="Private, only accessible from trusted code"
/>
<permission
id="zope2.AccessContentsInformation"
title="Access contents information"
/>
<permission
id="zope2.ChangeImagesFiles"
title="Change Images and Files"
/>
<permission
id="zope2.ChangeConfig"
title="Change configuration"
/>
<permission
id="zope2.ChangePermissions"
title="Change permissions"
/>
<permission
id="zope2.CopyOrMove"
title="Copy or Move"
/>
<permission
id="zope2.DefinePermissions"
title="Define permissions"
/>
<permission
id="zope2.DeleteObjects"
title="Delete objects"
/>
<permission
id="zope2.FTPAccess"
title="FTP access"
/>
<permission
id="zope2.ImportExport"
title="Import/Export objects"
/>
<permission
id="zope2.ManageProperties"
title="Manage properties"
/>
<permission
id="zope2.ManageUsers"
title="Manage users"
/>
<permission
id="zope2.Undo"
title="Undo changes"
/>
<permission
id="zope2.View"
title="View"
/>
<permission
id="zope2.ViewHistory"
title="View History"
/>
<permission
id="zope2.ViewManagementScreens"
title="View management screens"
/>
<permission
id="zope2.WebDAVLock"
title="WebDAV Lock items"
/>
<permission
id="zope2.WebDAVUnlock"
title="WebDAV Unlock items"
/>
<permission
id="zope2.WebDAVAccess"
title="WebDAV access"
/>
</configure>
src/AccessControl/requestmethod.py
deleted
100644 → 0
View file @
ccc10355
#############################################################################
#
# Copyright (c) 2007 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
inspect
from
zExceptions
import
Forbidden
from
zope.publisher.interfaces.browser
import
IBrowserRequest
_default
=
[]
def
_buildFacade
(
name
,
spec
,
docstring
):
"""Build a facade function, matching the decorated method in signature.
Note that defaults are replaced by _default, and _curried will reconstruct
these to preserve mutable defaults.
"""
args
=
inspect
.
formatargspec
(
formatvalue
=
lambda
v
:
'=_default'
,
*
spec
)
callargs
=
inspect
.
formatargspec
(
formatvalue
=
lambda
v
:
''
,
*
spec
)
return
'def %s%s:
\
n
"""%s"""
\
n
return _curried%s'
%
(
name
,
args
,
docstring
,
callargs
)
def
requestmethod
(
*
methods
):
"""Create a request method specific decorator"""
methods
=
map
(
lambda
m
:
m
.
upper
(),
methods
)
if
len
(
methods
)
>
1
:
methodsstr
=
', '
.
join
(
methods
[:
-
1
])
methodsstr
+=
' or '
+
methods
[
-
1
]
else
:
methodsstr
=
methods
[
0
]
def
_methodtest
(
callable
):
"""Only allow callable when request method is %s."""
%
methodsstr
spec
=
inspect
.
getargspec
(
callable
)
args
,
defaults
=
spec
[
0
],
spec
[
3
]
try
:
r_index
=
args
.
index
(
'REQUEST'
)
except
ValueError
:
raise
ValueError
(
'No REQUEST parameter in callable signature'
)
arglen
=
len
(
args
)
if
defaults
is
not
None
:
defaults
=
zip
(
args
[
arglen
-
len
(
defaults
):],
defaults
)
arglen
-=
len
(
defaults
)
def
_curried
(
*
args
,
**
kw
):
request
=
args
[
r_index
]
if
IBrowserRequest
.
providedBy
(
request
):
if
request
.
method
not
in
methods
:
raise
Forbidden
(
'Request must be %s'
%
methodsstr
)
# Reconstruct keyword arguments
if
defaults
is
not
None
:
args
,
kwparams
=
args
[:
arglen
],
args
[
arglen
:]
for
positional
,
(
key
,
default
)
in
zip
(
kwparams
,
defaults
):
if
positional
is
_default
:
kw
[
key
]
=
default
else
:
kw
[
key
]
=
positional
return
callable
(
*
args
,
**
kw
)
# Build a facade, with a reference to our locally-scoped _curried
name
=
callable
.
__name__
facade_globs
=
dict
(
_curried
=
_curried
,
_default
=
_default
)
exec
_buildFacade
(
name
,
spec
,
callable
.
__doc__
)
in
facade_globs
return
facade_globs
[
name
]
return
_methodtest
# For Zope versions 2.8 - 2.10
postonly
=
requestmethod
(
'POST'
)
__all__
=
(
'requestmethod'
,
'postonly'
)
src/AccessControl/requestmethod.txt
deleted
100644 → 0
View file @
ccc10355
Request method decorators
=========================
Using request method decorators, you can limit functions or methods to only
be callable when the HTTP request was made using a particular method.
To limit access to a function or method to POST requests, use the requestmethod
decorator factory::
>>> from AccessControl.requestmethod import requestmethod
>>> @requestmethod('POST')
... def foo(bar, REQUEST):
... return bar
When this method is accessed through a request that does not use POST, the
Forbidden exception will be raised::
>>> foo('spam', GET)
Traceback (most recent call last):
...
Forbidden: Request must be POST
Only when the request was made using POST, will the call succeed::
>>> foo('spam', POST)
'spam'
It doesn't matter if REQUEST is a positional or a keyword parameter::
>>> @requestmethod('POST')
... def foo(bar, REQUEST=None):
... return bar
>>> foo('spam', REQUEST=GET)
Traceback (most recent call last):
...
Forbidden: Request must be POST
*Not* passing an optional REQUEST always succeeds::
>>> foo('spam')
'spam'
Note that the REQUEST parameter is a requirement for the decorator to operate,
not including it in the callable signature results in an error::
>>> @requestmethod('POST')
... def foo(bar):
... return bar
Traceback (most recent call last):
...
ValueError: No REQUEST parameter in callable signature
Because the Zope Publisher uses introspection to match REQUEST variables
against callable signatures, the result of the decorator must match the
original closely, and keyword parameter defaults must be preserved::
>>> import inspect
>>> mutabledefault = dict()
>>> @requestmethod('POST')
... def foo(bar, baz=mutabledefault, egg=mutabledefault, REQUEST=None, *args):
... return bar, baz is mutabledefault, egg is None, REQUEST
>>> inspect.getargspec(foo)[:3]
(['bar', 'baz', 'egg', 'REQUEST'], 'args', None)
>>> foo('spam', egg=None)
('spam', True, True, None)
>>> foo(monty='python')
Traceback (most recent call last):
...
TypeError: foo() got an unexpected keyword argument 'monty'
The requestmethod decorator factory can be used for any request method, simply
pass in the desired request method::
>>> @requestmethod('PUT')
... def foo(bar, REQUEST=None):
... return bar
>>> foo('spam', GET)
Traceback (most recent call last):
...
Forbidden: Request must be PUT
You can pass in multiple request methods allow access by any of them::
>>> @requestmethod('GET', 'HEAD', 'PROPFIND')
... def foo(bar, REQUEST=None):
... return bar
>>> foo('spam', GET)
'spam'
>>> foo('spam', POST)
Traceback (most recent call last):
...
Forbidden: Request must be GET, HEAD or PROPFIND
src/AccessControl/rolemanager.py
deleted
100644 → 0
View file @
ccc10355
##############################################################################
#
# 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
#
##############################################################################
"""Access control support
"""
from
cgi
import
escape
from
Acquisition
import
Acquired
from
Acquisition
import
aq_base
from
Acquisition
import
aq_get
from
ExtensionClass
import
Base
from
zope.interface
import
implements
from
AccessControl
import
ClassSecurityInfo
from
AccessControl.class_init
import
InitializeClass
from
AccessControl.interfaces
import
IRoleManager
from
AccessControl.Permission
import
getPermissions
from
AccessControl.Permission
import
Permission
from
AccessControl.PermissionMapping
import
RoleManager
from
AccessControl.Permissions
import
change_permissions
from
AccessControl.SecurityManagement
import
newSecurityManager
DEFAULTMAXLISTUSERS
=
250
def
_isBeingUsedAsAMethod
(
self
):
return
aq_get
(
self
,
'_isBeingUsedAsAMethod_'
,
0
)
def
_isNotBeingUsedAsAMethod
(
self
):
return
not
aq_get
(
self
,
'_isBeingUsedAsAMethod_'
,
0
)
class
RoleManager
(
Base
,
RoleManager
):
"""An object that has configurable permissions"""
implements
(
IRoleManager
)
permissionMappingPossibleValues
=
Acquired
security
=
ClassSecurityInfo
()
__ac_roles__
=
(
'Manager'
,
'Owner'
,
'Anonymous'
,
'Authenticated'
)
__ac_local_roles__
=
None
security
.
declareProtected
(
change_permissions
,
'ac_inherited_permissions'
)
def
ac_inherited_permissions
(
self
,
all
=
0
):
# Get all permissions not defined in ourself that are inherited
# This will be a sequence of tuples with a name as the first item and
# an empty tuple as the second.
d
=
{}
perms
=
self
.
__ac_permissions__
for
p
in
perms
:
d
[
p
[
0
]]
=
None
r
=
gather_permissions
(
self
.
__class__
,
[],
d
)
if
all
:
if
hasattr
(
self
,
'_subobject_permissions'
):
for
p
in
self
.
_subobject_permissions
():
pname
=
p
[
0
]
if
not
pname
in
d
:
d
[
pname
]
=
1
r
.
append
(
p
)
r
=
list
(
perms
)
+
r
r
.
sort
()
return
tuple
(
r
)
security
.
declareProtected
(
change_permissions
,
'permission_settings'
)
def
permission_settings
(
self
,
permission
=
None
):
"""Return user-role permission settings.
If 'permission' is passed to the method then only the settings for
'permission' is returned.
"""
result
=
[]
valid
=
self
.
valid_roles
()
indexes
=
range
(
len
(
valid
))
ip
=
0
permissions
=
self
.
ac_inherited_permissions
(
1
)
# Filter permissions
if
permission
:
permissions
=
[
p
for
p
in
permissions
if
p
[
0
]
==
permission
]
for
p
in
permissions
:
name
,
value
=
p
[:
2
]
p
=
Permission
(
name
,
value
,
self
)
roles
=
p
.
getRoles
(
default
=
[])
d
=
{
'name'
:
name
,
'acquire'
:
isinstance
(
roles
,
list
)
and
'CHECKED'
or
''
,
'roles'
:
map
(
lambda
ir
,
roles
=
roles
,
valid
=
valid
,
ip
=
ip
:
{
'name'
:
"p%dr%d"
%
(
ip
,
ir
),
'checked'
:
(
valid
[
ir
]
in
roles
)
and
'CHECKED'
or
''
,
},
indexes
)
}
ip
=
ip
+
1
result
.
append
(
d
)
return
result
security
.
declareProtected
(
change_permissions
,
'manage_role'
)
def
manage_role
(
self
,
role_to_manage
,
permissions
=
[]):
"""Change the permissions given to the given role.
"""
for
p
in
self
.
ac_inherited_permissions
(
1
):
name
,
value
=
p
[:
2
]
p
=
Permission
(
name
,
value
,
self
)
p
.
setRole
(
role_to_manage
,
name
in
permissions
)
security
.
declareProtected
(
change_permissions
,
'manage_acquiredPermissions'
)
def
manage_acquiredPermissions
(
self
,
permissions
=
[]):
"""Change the permissions that acquire.
"""
for
p
in
self
.
ac_inherited_permissions
(
1
):
name
,
value
=
p
[:
2
]
p
=
Permission
(
name
,
value
,
self
)
roles
=
p
.
getRoles
()
if
roles
is
None
:
continue
if
name
in
permissions
:
p
.
setRoles
(
list
(
roles
))
else
:
p
.
setRoles
(
tuple
(
roles
))
def
manage_getUserRolesAndPermissions
(
self
,
user_id
):
""" Used for permission/role reporting for a given user_id.
Returns a dict mapping
'user_defined_in' -> path where the user account is defined
'roles' -> global roles,
'roles_in_context' -> roles in context of the current object,
'allowed_permissions' -> permissions allowed for the user,
'disallowed_permissions' -> all other permissions
"""
d
=
{}
current
=
self
while
1
:
try
:
uf
=
current
.
acl_users
except
AttributeError
:
raise
ValueError
(
'User %s could not be found'
%
user_id
)
userObj
=
uf
.
getUser
(
user_id
)
if
userObj
:
break
else
:
current
=
current
.
__parent__
newSecurityManager
(
None
,
userObj
)
# necessary?
userObj
=
userObj
.
__of__
(
uf
)
d
=
{
'user_defined_in'
:
'/'
+
uf
.
absolute_url
(
1
)}
# roles
roles
=
list
(
userObj
.
getRoles
())
roles
.
sort
()
d
[
'roles'
]
=
roles
# roles in context
roles
=
list
(
userObj
.
getRolesInContext
(
self
))
roles
.
sort
()
d
[
'roles_in_context'
]
=
roles
# permissions
allowed
=
[]
disallowed
=
[]
permMap
=
self
.
manage_getPermissionMapping
()
for
item
in
permMap
:
p
=
item
[
'permission_name'
]
if
userObj
.
has_permission
(
p
,
self
):
allowed
.
append
(
p
)
else
:
disallowed
.
append
(
p
)
d
[
'allowed_permissions'
]
=
allowed
d
[
'disallowed_permissions'
]
=
disallowed
return
d
security
.
declareProtected
(
change_permissions
,
'manage_permission'
)
def
manage_permission
(
self
,
permission_to_manage
,
roles
=
[],
acquire
=
0
):
"""Change the settings for the given permission.
If optional arg acquire is true, then the roles for the permission
are acquired, in addition to the ones specified, otherwise the
permissions are restricted to only the designated roles.
"""
for
p
in
self
.
ac_inherited_permissions
(
1
):
name
,
value
=
p
[:
2
]
if
name
==
permission_to_manage
:
p
=
Permission
(
name
,
value
,
self
)
if
acquire
:
roles
=
list
(
roles
)
else
:
roles
=
tuple
(
roles
)
p
.
setRoles
(
roles
)
return
raise
ValueError
(
"The permission <em>%s</em> is invalid."
%
escape
(
permission_to_manage
))
security
.
declareProtected
(
change_permissions
,
'permissionsOfRole'
)
def
permissionsOfRole
(
self
,
role
):
"""Returns a role to permission mapping.
"""
r
=
[]
for
p
in
self
.
ac_inherited_permissions
(
1
):
name
,
value
=
p
[:
2
]
p
=
Permission
(
name
,
value
,
self
)
roles
=
p
.
getRoles
()
r
.
append
({
'name'
:
name
,
'selected'
:
role
in
roles
and
'SELECTED'
or
''
,
})
return
r
security
.
declareProtected
(
change_permissions
,
'rolesOfPermission'
)
def
rolesOfPermission
(
self
,
permission
):
"""Returns a permission to role mapping.
"""
valid_roles
=
self
.
valid_roles
()
for
p
in
self
.
ac_inherited_permissions
(
1
):
name
,
value
=
p
[:
2
]
if
name
==
permission
:
p
=
Permission
(
name
,
value
,
self
)
roles
=
p
.
getRoles
()
return
map
(
lambda
role
,
roles
=
roles
:
{
'name'
:
role
,
'selected'
:
role
in
roles
and
'SELECTED'
or
''
,
},
valid_roles
)
raise
ValueError
(
"The permission <em>%s</em> is invalid."
%
escape
(
permission
))
security
.
declareProtected
(
change_permissions
,
'acquiredRolesAreUsedBy'
)
def
acquiredRolesAreUsedBy
(
self
,
permission
):
"""
"""
for
p
in
self
.
ac_inherited_permissions
(
1
):
name
,
value
=
p
[:
2
]
if
name
==
permission
:
p
=
Permission
(
name
,
value
,
self
)
roles
=
p
.
getRoles
()
return
isinstance
(
roles
,
list
)
and
'CHECKED'
or
''
raise
ValueError
(
"The permission <em>%s</em> is invalid."
%
escape
(
permission
))
# Local roles support
# -------------------
#
# Local roles allow a user to be given extra roles in the context
# of a particular object (and its children). When a user is given
# extra roles in a particular object, an entry for that user is made
# in the __ac_local_roles__ dict containing the extra roles.
def
has_local_roles
(
self
):
dict
=
self
.
__ac_local_roles__
or
{}
return
len
(
dict
)
def
get_local_roles
(
self
):
dict
=
self
.
__ac_local_roles__
or
{}
keys
=
dict
.
keys
()
keys
.
sort
()
info
=
[]
for
key
in
keys
:
value
=
tuple
(
dict
[
key
])
info
.
append
((
key
,
value
))
return
tuple
(
info
)
def
users_with_local_role
(
self
,
role
):
got
=
{}
for
user
,
roles
in
self
.
get_local_roles
():
if
role
in
roles
:
got
[
user
]
=
1
return
got
.
keys
()
def
get_valid_userids
(
self
):
item
=
self
dict
=
{}
_notfound
=
[]
while
1
:
aclu
=
getattr
(
aq_base
(
item
),
'__allow_groups__'
,
_notfound
)
if
aclu
is
not
_notfound
:
mlu
=
getattr
(
aclu
,
'maxlistusers'
,
_notfound
)
if
not
isinstance
(
mlu
,
int
):
mlu
=
DEFAULTMAXLISTUSERS
if
mlu
<
0
:
raise
OverflowError
un
=
getattr
(
aclu
,
'user_names'
,
_notfound
)
if
un
is
not
_notfound
:
un
=
aclu
.
__of__
(
item
).
user_names
# rewrap
unl
=
un
()
# maxlistusers of 0 is list all
if
len
(
unl
)
>
mlu
and
mlu
!=
0
:
raise
OverflowError
for
name
in
unl
:
dict
[
name
]
=
1
item
=
getattr
(
item
,
'__parent__'
,
_notfound
)
if
item
is
_notfound
:
break
keys
=
dict
.
keys
()
keys
.
sort
()
return
tuple
(
keys
)
def
get_local_roles_for_userid
(
self
,
userid
):
dict
=
self
.
__ac_local_roles__
or
{}
return
tuple
(
dict
.
get
(
userid
,
[]))
security
.
declareProtected
(
change_permissions
,
'manage_addLocalRoles'
)
def
manage_addLocalRoles
(
self
,
userid
,
roles
):
"""Set local roles for a user."""
if
not
roles
:
raise
ValueError
(
'One or more roles must be given!'
)
dict
=
self
.
__ac_local_roles__
if
dict
is
None
:
self
.
__ac_local_roles__
=
dict
=
{}
local_roles
=
list
(
dict
.
get
(
userid
,
[]))
for
r
in
roles
:
if
r
not
in
local_roles
:
local_roles
.
append
(
r
)
dict
[
userid
]
=
local_roles
self
.
_p_changed
=
True
security
.
declareProtected
(
change_permissions
,
'manage_setLocalRoles'
)
def
manage_setLocalRoles
(
self
,
userid
,
roles
):
"""Set local roles for a user."""
if
not
roles
:
raise
ValueError
(
'One or more roles must be given!'
)
dict
=
self
.
__ac_local_roles__
if
dict
is
None
:
self
.
__ac_local_roles__
=
dict
=
{}
dict
[
userid
]
=
roles
self
.
_p_changed
=
True
security
.
declareProtected
(
change_permissions
,
'manage_delLocalRoles'
)
def
manage_delLocalRoles
(
self
,
userids
):
"""Remove all local roles for a user."""
dict
=
self
.
__ac_local_roles__
if
dict
is
None
:
self
.
__ac_local_roles__
=
dict
=
{}
for
userid
in
userids
:
if
userid
in
dict
:
del
dict
[
userid
]
self
.
_p_changed
=
True
#------------------------------------------------------------
security
.
declarePrivate
(
'access_debug_info'
)
def
access_debug_info
(
self
):
"""Return debug info.
"""
clas
=
class_attrs
(
self
)
inst
=
instance_attrs
(
self
)
data
=
[]
_add
=
data
.
append
for
key
,
value
in
inst
.
items
():
if
key
.
find
(
'__roles__'
)
>=
0
:
_add
({
'name'
:
key
,
'value'
:
value
,
'class'
:
0
})
if
hasattr
(
value
,
'__roles__'
):
_add
({
'name'
:
'%s.__roles__'
%
key
,
'value'
:
value
.
__roles__
,
'class'
:
0
})
for
key
,
value
in
clas
.
items
():
if
key
.
find
(
'__roles__'
)
>=
0
:
_add
({
'name'
:
key
,
'value'
:
value
,
'class'
:
1
})
if
hasattr
(
value
,
'__roles__'
):
_add
({
'name'
:
'%s.__roles__'
%
key
,
'value'
:
value
.
__roles__
,
'class'
:
1
})
return
data
def
valid_roles
(
self
):
"""Return list of valid roles.
"""
obj
=
self
dict
=
{}
dup
=
dict
.
has_key
x
=
0
while
x
<
100
:
if
hasattr
(
obj
,
'__ac_roles__'
):
roles
=
obj
.
__ac_roles__
for
role
in
roles
:
if
not
dup
(
role
):
dict
[
role
]
=
1
if
getattr
(
obj
,
'__parent__'
,
None
)
is
None
:
break
obj
=
obj
.
__parent__
x
=
x
+
1
roles
=
dict
.
keys
()
roles
.
sort
()
return
tuple
(
roles
)
def
validate_roles
(
self
,
roles
):
"""Return true if all given roles are valid.
"""
valid
=
self
.
valid_roles
()
for
role
in
roles
:
if
role
not
in
valid
:
return
0
return
1
security
.
declareProtected
(
change_permissions
,
'userdefined_roles'
)
def
userdefined_roles
(
self
):
"""Return list of user-defined roles.
"""
roles
=
list
(
self
.
__ac_roles__
)
for
role
in
classattr
(
self
.
__class__
,
'__ac_roles__'
):
try
:
roles
.
remove
(
role
)
except
:
pass
return
tuple
(
roles
)
def
possible_permissions
(
self
):
d
=
{}
permissions
=
getPermissions
()
for
p
in
permissions
:
d
[
p
[
0
]]
=
1
for
p
in
self
.
ac_inherited_permissions
(
1
):
d
[
p
[
0
]]
=
1
d
=
d
.
keys
()
d
.
sort
()
return
d
InitializeClass
(
RoleManager
)
def
reqattr
(
request
,
attr
):
try
:
return
request
[
attr
]
except
:
return
None
def
classattr
(
cls
,
attr
):
if
hasattr
(
cls
,
attr
):
return
getattr
(
cls
,
attr
)
try
:
bases
=
cls
.
__bases__
except
:
bases
=
()
for
base
in
bases
:
if
classattr
(
base
,
attr
):
return
attr
return
None
def
instance_dict
(
inst
):
try
:
return
inst
.
__dict__
except
:
return
{}
def
class_dict
(
_class
):
try
:
return
_class
.
__dict__
except
:
return
{}
def
instance_attrs
(
inst
):
return
instance_dict
(
inst
)
def
class_attrs
(
inst
,
_class
=
None
,
data
=
None
):
if
_class
is
None
:
_class
=
inst
.
__class__
data
=
{}
clas_dict
=
class_dict
(
_class
)
inst_dict
=
instance_dict
(
inst
)
inst_attr
=
inst_dict
.
has_key
for
key
,
value
in
clas_dict
.
items
():
if
not
inst_attr
(
key
):
data
[
key
]
=
value
for
base
in
_class
.
__bases__
:
data
=
class_attrs
(
inst
,
base
,
data
)
return
data
def
gather_permissions
(
klass
,
result
,
seen
):
for
base
in
klass
.
__bases__
:
if
'__ac_permissions__'
in
base
.
__dict__
:
for
p
in
base
.
__ac_permissions__
:
name
=
p
[
0
]
if
name
in
seen
:
continue
result
.
append
((
name
,
()))
seen
[
name
]
=
None
gather_permissions
(
base
,
result
,
seen
)
return
result
src/AccessControl/security.py
deleted
100644 → 0
View file @
ccc10355
##############################################################################
#
# Copyright (c) 2004-2009 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.
#
##############################################################################
"""Security handling
"""
from
zope.component
import
getUtility
from
zope.component
import
queryUtility
from
zope.interface
import
classProvides
from
zope.interface
import
implements
from
zope.security.checker
import
CheckerPublic
from
zope.security.interfaces
import
IInteraction
from
zope.security.interfaces
import
ISecurityPolicy
from
zope.security.interfaces
import
IPermission
from
zope.security.management
import
thread_local
from
zope.security.simplepolicies
import
ParanoidSecurityPolicy
from
AccessControl.SecurityInfo
import
ClassSecurityInfo
from
AccessControl.SecurityManagement
import
getSecurityManager
from
AccessControl.Permission
import
addPermission
CheckerPublicId
=
'zope.Public'
CheckerPrivateId
=
'zope2.Private'
def
getSecurityInfo
(
klass
):
sec
=
{}
info
=
vars
(
klass
)
if
info
.
has_key
(
'__ac_permissions__'
):
sec
[
'__ac_permissions__'
]
=
info
[
'__ac_permissions__'
]
for
k
,
v
in
info
.
items
():
if
k
.
endswith
(
'__roles__'
):
sec
[
k
]
=
v
return
sec
def
clearSecurityInfo
(
klass
):
info
=
vars
(
klass
)
if
info
.
has_key
(
'__ac_permissions__'
):
delattr
(
klass
,
'__ac_permissions__'
)
for
k
,
v
in
info
.
items
():
if
k
.
endswith
(
'__roles__'
):
delattr
(
klass
,
k
)
def
checkPermission
(
permission
,
object
,
interaction
=
None
):
"""Return whether security policy allows permission on object.
Arguments:
permission -- A permission name
object -- The object being accessed according to the permission
interaction -- This zope.security concept has no equivalent in Zope 2,
and is ignored.
checkPermission is guaranteed to return True if permission is
CheckerPublic or None.
"""
if
(
permission
in
(
'zope.Public'
,
'zope2.Public'
)
or
permission
is
None
or
permission
is
CheckerPublic
):
return
True
if
isinstance
(
permission
,
basestring
):
permission
=
queryUtility
(
IPermission
,
unicode
(
permission
))
if
permission
is
None
:
return
False
if
getSecurityManager
().
checkPermission
(
permission
.
title
,
object
):
return
True
return
False
class
SecurityPolicy
(
ParanoidSecurityPolicy
):
"""Security policy that bridges between zope.security security mechanisms
and Zope 2's security policy.
Don't let the name of the base class fool you... This really just
delegates to Zope 2's security manager."""
classProvides
(
ISecurityPolicy
)
implements
(
IInteraction
)
def
checkPermission
(
self
,
permission
,
object
):
return
checkPermission
(
permission
,
object
)
def
newInteraction
():
"""Con zope.security to use Zope 2's checkPermission.
zope.security when it does a checkPermission will turn around and
ask the thread local interaction for the checkPermission method.
By making the interaction *be* Zope 2's security manager, we can
con zope.security into using Zope 2's checker...
"""
if
getattr
(
thread_local
,
'interaction'
,
None
)
is
None
:
thread_local
.
interaction
=
SecurityPolicy
()
def
_getSecurity
(
klass
):
# a Zope 2 class can contain some attribute that is an instance
# of ClassSecurityInfo. Zope 2 scans through things looking for
# an attribute that has the name __security_info__ first
info
=
vars
(
klass
)
for
k
,
v
in
info
.
items
():
if
hasattr
(
v
,
'__security_info__'
):
return
v
# we stuff the name ourselves as __security__, not security, as this
# could theoretically lead to name clashes, and doesn't matter for
# zope 2 anyway.
security
=
ClassSecurityInfo
()
setattr
(
klass
,
'__security__'
,
security
)
return
security
def
protectName
(
klass
,
name
,
permission_id
):
"""Protect the attribute 'name' on 'klass' using the given
permission"""
security
=
_getSecurity
(
klass
)
# Zope 2 uses string, not unicode yet
name
=
str
(
name
)
if
permission_id
==
CheckerPublicId
or
permission_id
is
CheckerPublic
:
# Sometimes, we already get a processed permission id, which
# can mean that 'zope.Public' has been interchanged for the
# CheckerPublic object
security
.
declarePublic
(
name
)
elif
permission_id
==
CheckerPrivateId
:
security
.
declarePrivate
(
name
)
else
:
permission
=
getUtility
(
IPermission
,
name
=
permission_id
)
# Zope 2 uses string, not unicode yet
perm
=
str
(
permission
.
title
)
security
.
declareProtected
(
perm
,
name
)
def
protectClass
(
klass
,
permission_id
):
"""Protect the whole class with the given permission"""
security
=
_getSecurity
(
klass
)
if
permission_id
==
CheckerPublicId
or
permission_id
is
CheckerPublic
:
# Sometimes, we already get a processed permission id, which
# can mean that 'zope.Public' has been interchanged for the
# CheckerPublic object
security
.
declareObjectPublic
()
elif
permission_id
==
CheckerPrivateId
:
security
.
declareObjectPrivate
()
else
:
permission
=
getUtility
(
IPermission
,
name
=
permission_id
)
# Zope 2 uses string, not unicode yet
perm
=
str
(
permission
.
title
)
security
.
declareObjectProtected
(
perm
)
def
create_permission_from_permission_directive
(
permission
,
event
):
"""When a new IPermission utility is registered (via the <permission />
directive), create the equivalent Zope2 style permission.
"""
# Zope 2 uses string, not unicode yet
zope2_permission
=
str
(
permission
.
title
)
addPermission
(
zope2_permission
)
src/AccessControl/tainted.py
deleted
100644 → 0
View file @
ccc10355
##############################################################################
#
# 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.
#
##############################################################################
""" TaintedString implementation.
TaintedStrings hold potentially dangerous untrusted data; anything that could
possibly hold HTML is considered dangerous. DTML code will use the quoted
value of this string, and raised exceptions in Zope will use the repr()
conversion.
"""
from
cgi
import
escape
class
TaintedString
:
def
__init__
(
self
,
value
):
self
.
_value
=
value
def
__str__
(
self
):
return
self
.
_value
def
__repr__
(
self
):
return
repr
(
self
.
quoted
())
def
__cmp__
(
self
,
o
):
return
cmp
(
self
.
_value
,
o
)
def
__hash__
(
self
):
return
hash
(
self
.
_value
)
def
__len__
(
self
):
return
len
(
self
.
_value
)
def
__getitem__
(
self
,
index
):
v
=
self
.
_value
[
index
]
if
'<'
in
v
:
v
=
self
.
__class__
(
v
)
return
v
def
__getslice__
(
self
,
i
,
j
):
i
=
max
(
i
,
0
)
j
=
max
(
j
,
0
)
v
=
self
.
_value
[
i
:
j
]
if
'<'
in
v
:
v
=
self
.
__class__
(
v
)
return
v
def
__add__
(
self
,
o
):
return
self
.
__class__
(
self
.
_value
+
o
)
def
__radd__
(
self
,
o
):
return
self
.
__class__
(
o
+
self
.
_value
)
def
__mul__
(
self
,
o
):
return
self
.
__class__
(
self
.
_value
*
o
)
def
__rmul__
(
self
,
o
):
return
self
.
__class__
(
o
*
self
.
_value
)
def
__mod__
(
self
,
o
):
return
self
.
__class__
(
self
.
_value
%
o
)
def
__int__
(
self
):
return
int
(
self
.
_value
)
def
__float__
(
self
):
return
float
(
self
.
_value
)
def
__long__
(
self
):
return
long
(
self
.
_value
)
def
__getstate__
(
self
):
# If an object tries to store a TaintedString, it obviously wasn't
# aware that it was playing with untrusted data. Complain acordingly.
raise
SystemError
(
"A TaintedString cannot be pickled. Code that "
"caused this TaintedString to be stored should be more careful "
"with untrusted data from the REQUEST."
)
def
__getattr__
(
self
,
a
):
# for string methods support other than those defined below
return
getattr
(
self
.
_value
,
a
)
# Python 2.2 only.
def
decode
(
self
,
*
args
):
return
self
.
__class__
(
self
.
_value
.
decode
(
*
args
))
def
encode
(
self
,
*
args
):
return
self
.
__class__
(
self
.
_value
.
encode
(
*
args
))
def
expandtabs
(
self
,
*
args
):
return
self
.
__class__
(
self
.
_value
.
expandtabs
(
*
args
))
def
replace
(
self
,
*
args
):
v
=
self
.
_value
.
replace
(
*
args
)
if
'<'
in
v
:
v
=
self
.
__class__
(
v
)
return
v
def
split
(
self
,
*
args
):
r
=
self
.
_value
.
split
(
*
args
)
return
map
(
lambda
v
,
c
=
self
.
__class__
:
'<'
in
v
and
c
(
v
)
or
v
,
r
)
def
splitlines
(
self
,
*
args
):
r
=
self
.
_value
.
splitlines
(
*
args
)
return
map
(
lambda
v
,
c
=
self
.
__class__
:
'<'
in
v
and
c
(
v
)
or
v
,
r
)
def
translate
(
self
,
*
args
):
v
=
self
.
_value
.
translate
(
*
args
)
if
'<'
in
v
:
v
=
self
.
__class__
(
v
)
return
v
def
quoted
(
self
):
return
escape
(
self
.
_value
,
1
)
# As called by cDocumentTemplate
__untaint__
=
quoted
def
createSimpleWrapper
(
func
):
return
lambda
s
,
f
=
func
:
s
.
__class__
(
getattr
(
s
.
_value
,
f
)())
def
createOneArgWrapper
(
func
):
return
lambda
s
,
a
,
f
=
func
:
s
.
__class__
(
getattr
(
s
.
_value
,
f
)(
a
))
def
createOneOptArgWrapper
(
func
):
return
lambda
s
,
a
=
None
,
f
=
func
:
s
.
__class__
(
getattr
(
s
.
_value
,
f
)(
a
))
simpleWrappedMethods
=
[
"capitalize"
,
"lower"
,
"swapcase"
,
"title"
,
"upper"
]
oneArgWrappedMethods
=
[
"center"
,
"join"
,
"ljust"
,
"rjust"
]
oneOptArgWrappedMethods
=
[
"lstrip"
,
"rstrip"
,
"strip"
]
for
f
in
simpleWrappedMethods
:
setattr
(
TaintedString
,
f
,
createSimpleWrapper
(
f
))
for
f
in
oneArgWrappedMethods
:
setattr
(
TaintedString
,
f
,
createOneArgWrapper
(
f
))
for
f
in
oneOptArgWrappedMethods
:
setattr
(
TaintedString
,
f
,
createOneOptArgWrapper
(
f
))
src/AccessControl/tests/__init__.py
deleted
100644 → 0
View file @
ccc10355
src/AccessControl/tests/actual_python.py
deleted
100644 → 0
View file @
ccc10355
# The code in this file is executed after being compiled as restricted code,
# and given a globals() dict with our idea of safe builtins, and the
# Zope production implementations of the special restricted-Python functions
# (like _getitem_ and _getiter_, etc).
#
# This isn't trying to provoke security problems, it's just trying to verify
# that Python code continues to work as intended after all the transformations,
# and with all the special wrappers we supply.
def
f1
():
next
=
iter
(
xrange
(
3
)).
next
assert
next
()
==
0
assert
next
()
==
1
assert
next
()
==
2
try
:
next
()
except
StopIteration
:
pass
else
:
assert
0
,
"expected StopIteration"
f1
()
def
f2
():
assert
map
(
lambda
x
:
x
+
1
,
range
(
3
))
==
range
(
1
,
4
)
f2
()
def
f3
():
assert
filter
(
None
,
range
(
10
))
==
range
(
1
,
10
)
f3
()
def
f4
():
assert
[
i
+
1
for
i
in
range
(
3
)]
==
range
(
*
(
1
,
4
))
f4
()
def
f5
():
x
=
range
(
5
)
def
add
(
a
,
b
):
return
a
+
b
assert
sum
(
x
)
==
reduce
(
add
,
x
,
0
)
f5
()
def
f6
():
class
C
:
def
display
(
self
):
return
str
(
self
.
value
)
c1
=
C
()
c2
=
C
()
c1
.
value
=
12
assert
getattr
(
c1
,
'value'
)
==
12
assert
c1
.
display
()
==
'12'
assert
not
hasattr
(
c2
,
'value'
)
setattr
(
c2
,
'value'
,
34
)
assert
c2
.
value
==
34
assert
hasattr
(
c2
,
'value'
)
del
c2
.
value
assert
not
hasattr
(
c2
,
'value'
)
# OK, if we can't set new attributes, at least verify that we can't.
#try:
# c1.value = 12
#except TypeError:
# pass
#else:
# assert 0, "expected direct attribute creation to fail"
#try:
# setattr(c1, 'value', 12)
#except TypeError:
# pass
#else:
# assert 0, "expected indirect attribute creation to fail"
assert
getattr
(
C
,
"display"
,
None
)
==
getattr
(
C
,
"display"
)
delattr
(
C
,
"display"
)
#try:
# setattr(C, "display", lambda self: "replaced")
#except TypeError:
# pass
#else:
# assert 0, "expected setattr() attribute replacement to fail"
#try:
# delattr(C, "display")
#except TypeError:
# pass
#else:
# assert 0, "expected delattr() attribute deletion to fail"
f6
()
def
f7
():
d
=
apply
(
dict
,
[((
1
,
2
),
(
3
,
4
))])
# {1: 2, 3: 4}
expected
=
{
'k'
:
[
1
,
3
],
'v'
:
[
2
,
4
],
'i'
:
[(
1
,
2
),
(
3
,
4
)]}
for
meth
,
kind
in
[(
'iterkeys'
,
'k'
),
(
'iteritems'
,
'i'
),
(
'itervalues'
,
'v'
),
(
'keys'
,
'k'
),
(
'items'
,
'i'
),
(
'values'
,
'v'
)]:
access
=
getattr
(
d
,
meth
)
result
=
list
(
access
())
result
.
sort
()
assert
result
==
expected
[
kind
],
(
meth
,
kind
,
result
,
expected
[
kind
])
f7
()
def
f8
():
import
math
ceil
=
getattr
(
math
,
'ceil'
)
smallest
=
1e100
smallest_index
=
None
largest
=
-
1e100
largest_index
=
None
all
=
[]
for
i
,
x
in
enumerate
((
2.2
,
1.1
,
3.3
,
5.5
,
4.4
)):
all
.
append
(
x
)
effective
=
ceil
(
x
)
if
effective
<
smallest
:
assert
min
(
effective
,
smallest
)
==
effective
smallest
=
effective
smallest_index
=
i
if
effective
>
largest
:
assert
max
(
effective
,
largest
)
==
effective
largest
=
effective
largest_index
=
i
assert
smallest
==
2
assert
smallest_index
==
1
assert
largest
==
6
assert
largest_index
==
3
assert
min
([
ceil
(
x
)
for
x
in
all
])
==
smallest
assert
max
(
map
(
ceil
,
all
))
==
largest
f8
()
# After all the above, these wrappers were still untouched:
# ['DateTime', '_print_', 'reorder', 'same_type', 'test']
# So do something to touch them.
def
f9
():
d
=
DateTime
()
print
d
# this one provoked _print_
# Funky. This probably isn't an intended use of reorder, but I'm
# not sure why it exists.
assert
reorder
(
'edcbaxyz'
,
'abcdef'
,
'c'
)
==
zip
(
'abde'
,
'abde'
)
assert
test
(
0
,
'a'
,
0
,
'b'
,
1
,
'c'
,
0
,
'd'
)
==
'c'
assert
test
(
0
,
'a'
,
0
,
'b'
,
0
,
'c'
,
0
,
'd'
,
'e'
)
==
'e'
# Unclear that the next one is *intended* to return None (it falls off
# the end of test's implementation without explicitly returning anything).
assert
test
(
0
,
'a'
,
0
,
'b'
,
0
,
'c'
,
0
,
'd'
)
==
None
assert
same_type
(
3
,
2
,
1
),
'expected same type'
assert
not
same_type
(
3
,
2
,
'a'
),
'expected not same type'
f9
()
def
f10
():
assert
iter
(
enumerate
(
iter
(
iter
(
range
(
9
))))).
next
()
==
(
0
,
0
)
f10
()
def
f11
():
x
=
1
x
+=
1
f11
()
def
f12
():
try
:
all
except
NameError
:
pass
# Python < 2.5
else
:
assert
all
([
True
,
True
,
True
])
==
True
assert
all
([
True
,
False
,
True
])
==
False
f12
()
def
f13
():
try
:
any
except
NameError
:
pass
# Python < 2.5
else
:
assert
any
([
True
,
True
,
True
])
==
True
assert
any
([
True
,
False
,
True
])
==
True
assert
any
([
False
,
False
,
False
])
==
False
f13
()
src/AccessControl/tests/mixed_module/__init__.py
deleted
100644 → 0
View file @
ccc10355
# test module, partially private
def
priv
():
pass
def
pub
():
pass
src/AccessControl/tests/mixed_module/submodule/__init__.py
deleted
100644 → 0
View file @
ccc10355
# test module, private
def
priv
():
pass
src/AccessControl/tests/private_module/__init__.py
deleted
100644 → 0
View file @
ccc10355
# test module, all private
def
priv
():
pass
src/AccessControl/tests/private_module/submodule/__init__.py
deleted
100644 → 0
View file @
ccc10355
# test module, all private
def
priv
():
pass
src/AccessControl/tests/public_module/__init__.py
deleted
100644 → 0
View file @
ccc10355
# test module, public
from
Acquisition
import
aq_base
# Foil the old ZopeSecurityPolicy
def
pub
():
pass
src/AccessControl/tests/public_module/submodule/__init__.py
deleted
100644 → 0
View file @
ccc10355
# test module, public
def
pub
():
pass
src/AccessControl/tests/testClassSecurityInfo.py
deleted
100644 → 0
View file @
ccc10355
##############################################################################
#
# 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
#
##############################################################################
""" Unit tests for ClassSecurityInfo.
"""
import
unittest
class
ClassSecurityInfoTests
(
unittest
.
TestCase
):
def
_getTargetClass
(
self
):
from
AccessControl.SecurityInfo
import
ClassSecurityInfo
return
ClassSecurityInfo
def
test_SetPermissionDefault
(
self
):
# Test setting default roles for permissions.
from
AccessControl.class_init
import
InitializeClass
from
ExtensionClass
import
Base
ClassSecurityInfo
=
self
.
_getTargetClass
()
# Setup a test class with default role -> permission decls.
class
Test
(
Base
):
"""Test class
"""
__ac_roles__
=
(
'Role A'
,
'Role B'
,
'Role C'
)
meta_type
=
"Test"
security
=
ClassSecurityInfo
()
security
.
setPermissionDefault
(
'Make food'
,
(
'Chef'
,))
security
.
setPermissionDefault
(
'Test permission'
,
(
'Manager'
,
'Role A'
,
'Role B'
,
'Role C'
)
)
security
.
declareProtected
(
'Test permission'
,
'foo'
)
def
foo
(
self
,
REQUEST
=
None
):
""" """
pass
# Do class initialization.
InitializeClass
(
Test
)
# Now check the resulting class to see if the mapping was made
# correctly. Note that this uses carnal knowledge of the internal
# structures used to store this information!
object
=
Test
()
imPermissionRole
=
[
r
for
r
in
object
.
foo__roles__
if
not
r
.
endswith
(
'_Permission'
)]
self
.
failUnless
(
len
(
imPermissionRole
)
==
4
)
for
item
in
(
'Manager'
,
'Role A'
,
'Role B'
,
'Role C'
):
self
.
failUnless
(
item
in
imPermissionRole
)
# Make sure that a permission defined without accompanying method
# is still reflected in __ac_permissions__
self
.
assertEquals
([
t
for
t
in
Test
.
__ac_permissions__
if
not
t
[
1
]],
[(
'Make food'
,
(),
(
'Chef'
,))])
def
test_suite
():
suite
=
unittest
.
TestSuite
()
suite
.
addTest
(
unittest
.
makeSuite
(
ClassSecurityInfoTests
))
return
suite
if
__name__
==
'__main__'
:
unittest
.
main
(
defaultTest
=
'test_suite'
)
src/AccessControl/tests/testImplementation.py
deleted
100644 → 0
View file @
ccc10355
##############################################################################
#
# 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 of the implementation selection support."""
import
unittest
from
AccessControl.Implementation
import
getImplementationName
from
AccessControl.Implementation
import
setImplementation
class
AccessControlImplementationTest
(
unittest
.
TestCase
):
have_cAccessControl
=
None
def
setUp
(
self
):
if
self
.
have_cAccessControl
is
None
:
try
:
import
AccessControl.cAccessControl
except
ImportError
:
v
=
False
else
:
v
=
True
self
.
__class__
.
have_cAccessControl
=
v
self
.
original
=
getImplementationName
()
def
tearDown
(
self
):
setImplementation
(
self
.
original
)
## Note - this test is disabled because the intent for 2.7 was *not*
## to support the ability to arbitrarily switch the security policy
## at any time (which would currently be nearly impossible to do in
## a way that would be sane for 3rd party apps that may already have
## imported parts of the security machinery), but just to make sure
## that the config file could be used to initially set the implementation
## to be used. The policy setting is 'initialize once' - setImplementation
## should not be called either by user code or unit tests, as the
## effects are officially undefined.
## def test_setImplemenationC(self):
## setImplementation("C")
## name = getImplementationName()
## if self.have_cAccessControl:
## self.assertEqual(name, "C")
## else:
## self.assertEqual(name, "PYTHON")
## def test_setImplemenationPython(self):
## setImplementation("Python")
## self.assertEqual(getImplementationName(), "PYTHON")
def
test_suite
():
return
unittest
.
makeSuite
(
AccessControlImplementationTest
)
if
__name__
==
"__main__"
:
unittest
.
main
(
defaultTest
=
"test_suite"
)
src/AccessControl/tests/testModuleSecurity.py
deleted
100644 → 0
View file @
ccc10355
##############################################################################
#
# Copyright (c) 2008 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
unittest
class
ModuleSecurityTests
(
unittest
.
TestCase
):
def
setUp
(
self
):
from
AccessControl
import
ModuleSecurityInfo
as
MSI
MSI
(
'AccessControl.tests.mixed_module'
).
declarePublic
(
'pub'
)
MSI
(
'AccessControl.tests.public_module'
).
declarePublic
(
'pub'
)
MSI
(
'AccessControl.tests.public_module.submodule'
).
declarePublic
(
'pub'
)
def
tearDown
(
self
):
import
sys
for
module
in
(
'AccessControl.tests.public_module'
,
'AccessControl.tests.public_module.submodule'
,
'AccessControl.tests.mixed_module'
,
'AccessControl.tests.mixed_module.submodule'
,
'AccessControl.tests.private_module'
,
'AccessControl.tests.private_module.submodule'
,
):
if
module
in
sys
.
modules
:
del
sys
.
modules
[
module
]
def
assertUnauth
(
self
,
module
,
fromlist
):
from
zExceptions
import
Unauthorized
from
AccessControl.ZopeGuards
import
guarded_import
self
.
assertRaises
(
Unauthorized
,
guarded_import
,
module
,
fromlist
=
fromlist
)
def
assertAuth
(
self
,
module
,
fromlist
):
from
AccessControl.ZopeGuards
import
guarded_import
guarded_import
(
module
,
fromlist
=
fromlist
)
def
testPrivateModule
(
self
):
self
.
assertUnauth
(
'AccessControl.tests.private_module'
,
())
self
.
assertUnauth
(
'AccessControl.tests.private_module'
,
(
'priv'
,))
self
.
assertUnauth
(
'AccessControl.tests.private_module.submodule'
,
())
self
.
assertUnauth
(
'AccessControl.tests.private_module.submodule'
,
(
'priv'
,))
def
testMixedModule
(
self
):
self
.
assertAuth
(
'AccessControl.tests.mixed_module'
,
())
self
.
assertAuth
(
'AccessControl.tests.mixed_module'
,
(
'pub'
,))
self
.
assertUnauth
(
'AccessControl.tests.mixed_module'
,
(
'priv'
,))
self
.
assertUnauth
(
'AccessControl.tests.mixed_module.submodule'
,
())
def
testPublicModule
(
self
):
self
.
assertAuth
(
'AccessControl.tests.public_module'
,
())
self
.
assertAuth
(
'AccessControl.tests.public_module'
,
(
'pub'
,))
self
.
assertAuth
(
'AccessControl.tests.public_module.submodule'
,
())
self
.
assertAuth
(
'AccessControl.tests.public_module.submodule'
,
(
'pub'
,))
def
test_public_module_asterisk_not_allowed
(
self
):
self
.
assertUnauth
(
'AccessControl.tests.public_module'
,
(
'*'
,))
def
test_failed_import_keeps_MSI
(
self
):
# LP #281156
from
AccessControl
import
ModuleSecurityInfo
as
MSI
from
AccessControl.SecurityInfo
import
_moduleSecurity
as
MS
from
AccessControl.ZopeGuards
import
guarded_import
MSI
(
'AccessControl.tests.nonesuch'
).
declarePublic
(
'pub'
)
self
.
failUnless
(
'AccessControl.tests.nonesuch'
in
MS
)
self
.
assertRaises
(
ImportError
,
guarded_import
,
'AccessControl.tests.nonesuch'
,
())
self
.
failUnless
(
'AccessControl.tests.nonesuch'
in
MS
)
def
test_suite
():
return
unittest
.
makeSuite
(
ModuleSecurityTests
)
src/AccessControl/tests/testOwned.py
deleted
100644 → 0
View file @
ccc10355
"""Unit tests for AccessControl.Owned
"""
import
unittest
from
persistent
import
Persistent
from
Acquisition
import
Implicit
,
aq_inner
from
AccessControl.owner
import
Owned
class
FauxUser
(
Implicit
):
def
__init__
(
self
,
id
):
self
.
_id
=
id
def
getId
(
self
):
return
self
.
_id
class
FauxUserFolder
(
Implicit
):
def
getUserById
(
self
,
id
,
default
):
return
FauxUser
(
id
)
class
FauxRoot
(
Implicit
):
def
getPhysicalRoot
(
self
):
return
aq_inner
(
self
)
def
unrestrictedTraverse
(
self
,
path
,
default
=
None
):
if
type
(
path
)
is
type
(
''
):
path
=
path
.
split
(
'/'
)
if
not
path
[
0
]:
path
=
path
[
1
:]
obj
=
self
try
:
while
path
:
next
,
path
=
path
[
0
],
path
[
1
:]
obj
=
getattr
(
obj
,
next
)
except
AttributeError
:
obj
=
default
return
obj
class
Folder
(
Implicit
,
Persistent
,
Owned
):
def
__init__
(
self
,
id
):
self
.
id
=
id
self
.
names
=
set
()
def
_setObject
(
self
,
name
,
value
):
setattr
(
self
,
name
,
value
)
self
.
names
.
add
(
name
)
def
objectValues
(
self
):
result
=
[]
for
name
in
self
.
names
:
result
.
append
(
getattr
(
self
,
name
))
return
result
class
OwnedTests
(
unittest
.
TestCase
):
def
_getTargetClass
(
self
):
return
Owned
def
_makeOne
(
self
,
*
args
,
**
kw
):
return
self
.
_getTargetClass
()(
*
args
,
**
kw
)
def
_makeDummy
(
self
,
*
args
,
**
kw
):
class
Dummy
(
Implicit
,
Owned
):
pass
return
Dummy
(
*
args
,
**
kw
)
def
test_interfaces
(
self
):
from
AccessControl.interfaces
import
IOwned
from
zope.interface.verify
import
verifyClass
verifyClass
(
IOwned
,
Owned
)
def
test_getOwnerTuple_unowned
(
self
):
owned
=
self
.
_makeOne
()
owner_tuple
=
owned
.
getOwnerTuple
()
self
.
assertEqual
(
owner_tuple
,
None
)
def
test_getOwnerTuple_simple
(
self
):
owned
=
self
.
_makeOne
()
owned
.
_owner
=
(
'/foobar'
,
'baz'
)
owner_tuple
=
owned
.
getOwnerTuple
()
self
.
assertEqual
(
len
(
owner_tuple
),
2
)
self
.
assertEqual
(
owner_tuple
[
0
],
'/foobar'
)
self
.
assertEqual
(
owner_tuple
[
1
],
'baz'
)
def
test_getOwnerTuple_acquired
(
self
):
root
=
FauxRoot
()
root
.
_owner
=
(
'/foobar'
,
'baz'
)
owned
=
self
.
_makeDummy
().
__of__
(
root
)
owner_tuple
=
owned
.
getOwnerTuple
()
self
.
assertEqual
(
len
(
owner_tuple
),
2
)
self
.
assertEqual
(
owner_tuple
[
0
],
'/foobar'
)
self
.
assertEqual
(
owner_tuple
[
1
],
'baz'
)
def
test_getOwnerTuple_acquired_no_tricks
(
self
):
# Ensure that we acquire ownership only through containment.
root
=
FauxRoot
()
root
.
_owner
=
(
'/foobar'
,
'baz'
)
owned
=
self
.
_makeDummy
().
__of__
(
root
)
owner_tuple
=
owned
.
getOwnerTuple
()
tricky
=
self
.
_makeDummy
()
tricky
.
_owner
=
(
'/bambam'
,
'qux'
)
tricky
=
tricky
.
__of__
(
root
)
not_tricked
=
owned
.
__of__
(
tricky
)
owner_tuple
=
not_tricked
.
getOwnerTuple
()
self
.
assertEqual
(
len
(
owner_tuple
),
2
)
self
.
assertEqual
(
owner_tuple
[
0
],
'/foobar'
)
self
.
assertEqual
(
owner_tuple
[
1
],
'baz'
)
def
test_getWrappedOwner_unowned
(
self
):
owned
=
self
.
_makeOne
()
wrapped_owner
=
owned
.
getWrappedOwner
()
self
.
assertEqual
(
wrapped_owner
,
None
)
def
test_getWrappedOwner_unownable
(
self
):
from
AccessControl.owner
import
UnownableOwner
owned
=
self
.
_makeOne
()
owned
.
_owner
=
UnownableOwner
wrapped_owner
=
owned
.
getWrappedOwner
()
self
.
assertEqual
(
wrapped_owner
,
None
)
def
test_getWrappedOwner_simple
(
self
):
root
=
FauxRoot
()
root
.
acl_users
=
FauxUserFolder
()
owned
=
self
.
_makeDummy
().
__of__
(
root
)
owned
.
_owner
=
(
'/acl_users'
,
'user'
)
wrapped_owner
=
owned
.
getWrappedOwner
()
self
.
assertEqual
(
wrapped_owner
.
getId
(),
'user'
)
def
test_getWrappedOwner_acquired
(
self
):
root
=
FauxRoot
()
root
.
_owner
=
(
'/acl_users'
,
'user'
)
root
.
acl_users
=
FauxUserFolder
()
owned
=
self
.
_makeDummy
().
__of__
(
root
)
wrapped_owner
=
owned
.
getWrappedOwner
()
self
.
assertEqual
(
wrapped_owner
.
getId
(),
'user'
)
def
test_getWrappedOwner_acquired_no_tricks
(
self
):
root
=
FauxRoot
()
root
.
_owner
=
(
'/acl_users'
,
'user'
)
root
.
acl_users
=
FauxUserFolder
()
owned
=
self
.
_makeDummy
().
__of__
(
root
)
tricky
=
self
.
_makeDummy
()
tricky
.
_owner
=
(
'/acl_users'
,
'black_hat'
)
tricky
=
tricky
.
__of__
(
root
)
not_tricked
=
owned
.
__of__
(
tricky
)
wrapped_owner
=
not_tricked
.
getWrappedOwner
()
self
.
assertEqual
(
wrapped_owner
.
getId
(),
'user'
)
class
OwnershipChangeTests
(
unittest
.
TestCase
):
def
setUp
(
self
):
from
AccessControl.owner
import
UnownableOwner
from
AccessControl.userfolder
import
UserFolder
super
(
OwnershipChangeTests
,
self
).
setUp
()
self
.
root
=
FauxRoot
()
self
.
root
.
acl_users
=
UserFolder
()
self
.
uf
=
self
.
root
.
acl_users
self
.
uf
.
_doAddUser
(
'user1'
,
'xxx'
,
[
'role1'
],
[])
self
.
uf
.
_doAddUser
(
'user2'
,
'xxx'
,
[
'role1'
],
[])
self
.
root
.
unownable
=
Folder
(
'unownable'
)
self
.
root
.
unownable
.
_owner
=
UnownableOwner
self
.
root
.
parent
=
Folder
(
'parent'
)
parent
=
self
.
root
.
parent
parent
.
_owner
=
([
'acl_users'
],
'user1'
)
parent
.
_setObject
(
'child'
,
Folder
(
'child'
))
parent
.
child
.
_owner
=
([
'acl_users'
],
'user1'
)
parent
.
child
.
_setObject
(
'grandchild'
,
Folder
(
'grandchild'
))
parent
.
child
.
grandchild
.
_owner
=
([
'acl_users'
],
'user1'
)
def
test_changeOwnership_bad_owner
(
self
):
from
AccessControl.User
import
nobody
previous
=
self
.
root
.
parent
.
_owner
self
.
root
.
parent
.
changeOwnership
(
nobody
)
self
.
assertEquals
(
self
.
root
.
parent
.
_owner
,
previous
)
def
test_changeOwnership_same_owner
(
self
):
previous
=
self
.
root
.
parent
.
_owner
sameuser
=
self
.
uf
.
getUser
(
'user1'
).
__of__
(
self
.
uf
)
self
.
root
.
parent
.
changeOwnership
(
sameuser
)
self
.
assertEquals
(
self
.
root
.
parent
.
_owner
,
previous
)
def
test_changeOwnership_unownable_owner
(
self
):
previous
=
self
.
root
.
unownable
.
_owner
newuser
=
self
.
uf
.
getUser
(
'user1'
).
__of__
(
self
.
uf
)
self
.
root
.
unownable
.
changeOwnership
(
newuser
)
self
.
assertEquals
(
self
.
root
.
unownable
.
_owner
,
previous
)
def
test_changeOwnership_nonrecursive
(
self
):
previous_parent_owner
=
self
.
root
.
parent
.
_owner
previous_child_owner
=
self
.
root
.
parent
.
child
.
_owner
previous_grandchild_owner
=
self
.
root
.
parent
.
child
.
grandchild
.
_owner
newuser
=
self
.
uf
.
getUser
(
'user2'
).
__of__
(
self
.
uf
)
self
.
root
.
parent
.
changeOwnership
(
newuser
)
self
.
assertNotEquals
(
self
.
root
.
parent
.
_owner
,
previous_parent_owner
)
self
.
assertEquals
(
self
.
root
.
parent
.
_owner
,
([
'acl_users'
],
'user2'
))
self
.
assertEquals
(
self
.
root
.
parent
.
child
.
_owner
,
previous_child_owner
)
self
.
assertEquals
(
self
.
root
.
parent
.
child
.
grandchild
.
_owner
,
previous_grandchild_owner
)
def
test_changeOwnership_recursive
(
self
):
previous_parent_owner
=
self
.
root
.
parent
.
_owner
previous_child_owner
=
self
.
root
.
parent
.
child
.
_owner
previous_grandchild_owner
=
self
.
root
.
parent
.
child
.
grandchild
.
_owner
newuser
=
self
.
uf
.
getUser
(
'user2'
).
__of__
(
self
.
uf
)
self
.
root
.
parent
.
changeOwnership
(
newuser
,
recursive
=
True
)
self
.
assertNotEquals
(
self
.
root
.
parent
.
_owner
,
previous_parent_owner
)
self
.
assertEquals
(
self
.
root
.
parent
.
_owner
,
([
'acl_users'
],
'user2'
))
self
.
assertNotEquals
(
self
.
root
.
parent
.
child
.
_owner
,
previous_child_owner
)
self
.
assertEquals
(
self
.
root
.
parent
.
child
.
_owner
,
([
'acl_users'
],
'user2'
)
)
self
.
assertNotEquals
(
self
.
root
.
parent
.
child
.
grandchild
.
_owner
,
previous_grandchild_owner
)
self
.
assertEquals
(
self
.
root
.
parent
.
child
.
grandchild
.
_owner
,
([
'acl_users'
],
'user2'
)
)
def
test_changeOwnership_recursive_objectValues_acquisition
(
self
):
# See https://bugs.launchpad.net/bugs/143403
from
AccessControl.owner
import
Owned
class
FauxContent
(
Implicit
,
Owned
):
pass
previous_parent_owner
=
self
.
root
.
parent
.
_owner
previous_child_owner
=
self
.
root
.
parent
.
child
.
_owner
previous_grandchild_owner
=
self
.
root
.
parent
.
child
.
grandchild
.
_owner
newuser
=
self
.
uf
.
getUser
(
'user2'
).
__of__
(
self
.
uf
)
self
.
root
.
parent
.
bad
=
FauxContent
()
self
.
root
.
parent
.
bad
.
changeOwnership
(
newuser
,
recursive
=
True
)
self
.
assertEquals
(
self
.
root
.
parent
.
_owner
,
previous_parent_owner
)
self
.
assertEquals
(
self
.
root
.
parent
.
child
.
_owner
,
previous_child_owner
)
self
.
assertEquals
(
self
.
root
.
parent
.
child
.
grandchild
.
_owner
,
previous_grandchild_owner
)
def
test_suite
():
return
unittest
.
TestSuite
((
unittest
.
makeSuite
(
OwnedTests
),
unittest
.
makeSuite
(
OwnershipChangeTests
),
))
src/AccessControl/tests/testPasswordDigest.py
deleted
100644 → 0
View file @
ccc10355
##############################################################################
#
# 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
#
##############################################################################
"""Test of AuthEncoding
"""
import
unittest
from
AccessControl
import
AuthEncoding
class
PasswordDigestTests
(
unittest
.
TestCase
):
def
testGoodPassword
(
self
):
pw
=
'good_password'
assert
len
(
AuthEncoding
.
listSchemes
())
>
0
# At least one must exist!
for
id
in
AuthEncoding
.
listSchemes
():
enc
=
AuthEncoding
.
pw_encrypt
(
pw
,
id
)
assert
enc
!=
pw
assert
AuthEncoding
.
pw_validate
(
enc
,
pw
)
assert
AuthEncoding
.
is_encrypted
(
enc
)
assert
not
AuthEncoding
.
is_encrypted
(
pw
)
def
testBadPasword
(
self
):
pw
=
'OK_pa55w0rd
\
n
'
for
id
in
AuthEncoding
.
listSchemes
():
enc
=
AuthEncoding
.
pw_encrypt
(
pw
,
id
)
assert
enc
!=
pw
assert
not
AuthEncoding
.
pw_validate
(
enc
,
'xxx'
)
assert
not
AuthEncoding
.
pw_validate
(
enc
,
enc
)
if
id
!=
'CRYPT'
:
# crypt truncates passwords and would fail this test.
assert
not
AuthEncoding
.
pw_validate
(
enc
,
pw
[:
-
1
])
assert
not
AuthEncoding
.
pw_validate
(
enc
,
pw
[
1
:])
assert
AuthEncoding
.
pw_validate
(
enc
,
pw
)
def
testShortPassword
(
self
):
pw
=
'1'
for
id
in
AuthEncoding
.
listSchemes
():
enc
=
AuthEncoding
.
pw_encrypt
(
pw
,
id
)
assert
enc
!=
pw
assert
AuthEncoding
.
pw_validate
(
enc
,
pw
)
assert
not
AuthEncoding
.
pw_validate
(
enc
,
enc
)
assert
not
AuthEncoding
.
pw_validate
(
enc
,
'xxx'
)
def
testLongPassword
(
self
):
pw
=
'Pw'
*
2000
for
id
in
AuthEncoding
.
listSchemes
():
enc
=
AuthEncoding
.
pw_encrypt
(
pw
,
id
)
assert
enc
!=
pw
assert
AuthEncoding
.
pw_validate
(
enc
,
pw
)
assert
not
AuthEncoding
.
pw_validate
(
enc
,
enc
)
assert
not
AuthEncoding
.
pw_validate
(
enc
,
'xxx'
)
if
id
!=
'CRYPT'
:
# crypt truncates passwords and would fail these tests.
assert
not
AuthEncoding
.
pw_validate
(
enc
,
pw
[:
-
2
])
assert
not
AuthEncoding
.
pw_validate
(
enc
,
pw
[
2
:])
def
testBlankPassword
(
self
):
pw
=
''
for
id
in
AuthEncoding
.
listSchemes
():
enc
=
AuthEncoding
.
pw_encrypt
(
pw
,
id
)
assert
enc
!=
pw
assert
AuthEncoding
.
pw_validate
(
enc
,
pw
)
assert
not
AuthEncoding
.
pw_validate
(
enc
,
enc
)
assert
not
AuthEncoding
.
pw_validate
(
enc
,
'xxx'
)
def
testUnencryptedPassword
(
self
):
# Sanity check
pw
=
'my-password'
assert
AuthEncoding
.
pw_validate
(
pw
,
pw
)
def
test_suite
():
suite
=
unittest
.
TestSuite
()
suite
.
addTest
(
unittest
.
makeSuite
(
PasswordDigestTests
)
)
return
suite
def
main
():
unittest
.
TextTestRunner
().
run
(
test_suite
())
if
__name__
==
'__main__'
:
main
()
src/AccessControl/tests/testPermissionMapping.py
deleted
100644 → 0
View file @
ccc10355
import
unittest
class
TestRoleManager
(
unittest
.
TestCase
):
def
test_interfaces
(
self
):
from
AccessControl.interfaces
import
IPermissionMappingSupport
from
AccessControl.PermissionMapping
import
RoleManager
from
zope.interface.verify
import
verifyClass
verifyClass
(
IPermissionMappingSupport
,
RoleManager
)
def
test_suite
():
return
unittest
.
TestSuite
((
unittest
.
makeSuite
(
TestRoleManager
),
))
src/AccessControl/tests/testPermissionRole.py
deleted
100644 → 0
View file @
ccc10355
##############################################################################
#
# 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
#
##############################################################################
"""Tests of PermissionRole
"""
import
unittest
from
AccessControl.PermissionRole
import
PermissionRole
from
Acquisition
import
Implicit
,
Explicit
,
aq_base
ViewPermission
=
'View'
EditThingsPermission
=
'Edit Things!'
DeletePermission
=
'Delete'
class
AppRoot
(
Explicit
):
_View_Permission
=
None
_Edit_Things__Permission
=
(
'Manager'
,
'Owner'
)
# No default for delete permission.
class
ImplicitContainer
(
Implicit
):
pass
class
ExplicitContainer
(
Explicit
):
pass
class
RestrictiveObject
(
Implicit
):
_View_Permission
=
(
'Manager'
,)
_Delete_Permission
=
()
# Nobody
class
PermissiveObject
(
Explicit
):
_Edit_Things__Permission
=
[
'Anonymous'
]
def
assertPRoles
(
ob
,
permission
,
expect
):
"""
Asserts that in the context of ob, the given permission maps to
the given roles.
"""
pr
=
PermissionRole
(
permission
)
roles
=
pr
.
__of__
(
ob
)
roles2
=
aq_base
(
pr
).
__of__
(
ob
)
assert
roles
==
roles2
or
tuple
(
roles
)
==
tuple
(
roles2
),
(
'Different methods of checking roles computed unequal results'
)
same
=
0
if
roles
:
# When verbose security is enabled, permission names are
# embedded in the computed roles. Remove the permission
# names.
roles
=
[
r
for
r
in
roles
if
not
r
.
endswith
(
'_Permission'
)]
if
roles
is
None
or
expect
is
None
:
if
(
roles
is
None
or
tuple
(
roles
)
==
(
'Anonymous'
,))
and
(
expect
is
None
or
tuple
(
expect
)
==
(
'Anonymous'
,)):
same
=
1
else
:
got
=
{}
for
r
in
roles
:
got
[
r
]
=
1
expected
=
{}
for
r
in
expect
:
expected
[
r
]
=
1
if
got
==
expected
:
# Dict compare does the Right Thing.
same
=
1
assert
same
,
'Expected roles: %s, got: %s'
%
(
`expect`
,
`roles`
)
class
PermissionRoleTests
(
unittest
.
TestCase
):
def
testRestrictive
(
self
,
explicit
=
0
):
app
=
AppRoot
()
if
explicit
:
app
.
c
=
ExplicitContainer
()
else
:
app
.
c
=
ImplicitContainer
()
app
.
c
.
o
=
RestrictiveObject
()
o
=
app
.
c
.
o
assertPRoles
(
o
,
ViewPermission
,
(
'Manager'
,))
assertPRoles
(
o
,
EditThingsPermission
,
(
'Manager'
,
'Owner'
,))
assertPRoles
(
o
,
DeletePermission
,
())
def
testPermissive
(
self
,
explicit
=
0
):
app
=
AppRoot
()
if
explicit
:
app
.
c
=
ExplicitContainer
()
else
:
app
.
c
=
ImplicitContainer
()
app
.
c
.
o
=
PermissiveObject
()
o
=
app
.
c
.
o
assertPRoles
(
o
,
ViewPermission
,
(
'Anonymous'
,))
assertPRoles
(
o
,
EditThingsPermission
,
(
'Anonymous'
,
'Manager'
,
'Owner'
,))
assertPRoles
(
o
,
DeletePermission
,
(
'Manager'
,))
def
testExplicit
(
self
):
self
.
testRestrictive
(
1
)
self
.
testPermissive
(
1
)
def
testAppDefaults
(
self
):
o
=
AppRoot
()
assertPRoles
(
o
,
ViewPermission
,
(
'Anonymous'
,))
assertPRoles
(
o
,
EditThingsPermission
,
(
'Manager'
,
'Owner'
,))
assertPRoles
(
o
,
DeletePermission
,
(
'Manager'
,))
def
testPermissionRoleSupportsGetattr
(
self
):
a
=
PermissionRole
(
'a'
)
self
.
failUnless
(
getattr
(
a
,
'__roles__'
)
==
(
'Manager'
,))
self
.
failUnless
(
getattr
(
a
,
'_d'
)
==
(
'Manager'
,))
self
.
failUnless
(
getattr
(
a
,
'__name__'
)
==
'a'
)
self
.
failUnless
(
getattr
(
a
,
'_p'
)
==
'_a_Permission'
)
def
test_suite
():
suite
=
unittest
.
TestSuite
()
suite
.
addTest
(
unittest
.
makeSuite
(
PermissionRoleTests
))
return
suite
def
main
():
unittest
.
TextTestRunner
().
run
(
test_suite
())
if
__name__
==
'__main__'
:
main
()
src/AccessControl/tests/testRole.py
deleted
100644 → 0
View file @
ccc10355
import
unittest
class
TestRoleManager
(
unittest
.
TestCase
):
def
test_interfaces
(
self
):
from
AccessControl.interfaces
import
IRoleManager
from
AccessControl.rolemanager
import
RoleManager
from
zope.interface.verify
import
verifyClass
verifyClass
(
IRoleManager
,
RoleManager
)
def
test_suite
():
return
unittest
.
TestSuite
((
unittest
.
makeSuite
(
TestRoleManager
),
))
src/AccessControl/tests/testSecurityManager.py
deleted
100644 → 0
View file @
ccc10355
##############################################################################
#
# Copyright (c) 2005 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.
#
##############################################################################
"""Tests for the SecurityManager implementations
"""
import
unittest
_THREAD_ID
=
123
class
DummyContext
:
def
__init__
(
self
):
self
.
user
=
object
()
self
.
stack
=
[]
class
DummyPolicy
:
CHECK_PERMISSION_ARGS
=
None
CHECK_PERMISSION_RESULT
=
object
()
VALIDATE_ARGS
=
None
def
checkPermission
(
self
,
*
args
):
self
.
CHECK_PERMISSION_ARGS
=
args
return
self
.
CHECK_PERMISSION_RESULT
def
validate
(
self
,
*
args
):
self
.
VALIDATE_ARGS
=
args
return
True
class
ExecutableObject
:
def
__init__
(
self
,
new_policy
):
self
.
_new_policy
=
new_policy
def
_customSecurityPolicy
(
self
):
return
self
.
_new_policy
class
ISecurityManagerConformance
:
def
test_conforms_to_ISecurityManager
(
self
):
from
AccessControl.interfaces
import
ISecurityManager
from
zope.interface.verify
import
verifyClass
verifyClass
(
ISecurityManager
,
self
.
_getTargetClass
())
class
SecurityManagerTestBase
(
unittest
.
TestCase
):
def
_makeOne
(
self
,
thread_id
,
context
):
return
self
.
_getTargetClass
()(
thread_id
,
context
)
def
test_getUser
(
self
):
context
=
DummyContext
()
mgr
=
self
.
_makeOne
(
_THREAD_ID
,
context
)
self
.
failUnless
(
mgr
.
getUser
()
is
context
.
user
)
def
test_calledByExecutable_no_stack
(
self
):
context
=
DummyContext
()
mgr
=
self
.
_makeOne
(
_THREAD_ID
,
context
)
self
.
failIf
(
mgr
.
calledByExecutable
())
def
test_calledByExecutable_with_stack
(
self
):
context
=
DummyContext
()
mgr
=
self
.
_makeOne
(
_THREAD_ID
,
context
)
executableObject
=
object
()
mgr
.
addContext
(
executableObject
)
self
.
failUnless
(
mgr
.
calledByExecutable
())
def
test_addContext_no_custom_policy
(
self
):
context
=
DummyContext
()
mgr
=
self
.
_makeOne
(
_THREAD_ID
,
context
)
original_policy
=
mgr
.
_policy
executableObject
=
object
()
mgr
.
addContext
(
executableObject
)
self
.
failUnless
(
mgr
.
_policy
is
original_policy
)
def
test_addContext_with_custom_policy
(
self
):
context
=
DummyContext
()
mgr
=
self
.
_makeOne
(
_THREAD_ID
,
context
)
new_policy
=
DummyPolicy
()
executableObject
=
ExecutableObject
(
new_policy
)
mgr
.
addContext
(
executableObject
)
self
.
failUnless
(
mgr
.
_policy
is
new_policy
)
def
test_addContext_with_custom_policy_then_none
(
self
):
context
=
DummyContext
()
mgr
=
self
.
_makeOne
(
_THREAD_ID
,
context
)
original_policy
=
mgr
.
_policy
new_policy
=
DummyPolicy
()
executableObject
=
ExecutableObject
(
new_policy
)
mgr
.
addContext
(
executableObject
)
mgr
.
addContext
(
object
())
self
.
failUnless
(
mgr
.
_policy
is
original_policy
)
def
test_removeContext_pops_items_above_EO
(
self
):
context
=
DummyContext
()
ALPHA
,
BETA
,
GAMMA
,
DELTA
=
object
(),
object
(),
object
(),
object
()
context
.
stack
.
append
(
ALPHA
)
context
.
stack
.
append
(
BETA
)
context
.
stack
.
append
(
GAMMA
)
context
.
stack
.
append
(
DELTA
)
mgr
=
self
.
_makeOne
(
_THREAD_ID
,
context
)
mgr
.
removeContext
(
GAMMA
)
self
.
assertEqual
(
len
(
context
.
stack
),
2
)
self
.
failUnless
(
context
.
stack
[
0
]
is
ALPHA
)
self
.
failUnless
(
context
.
stack
[
1
]
is
BETA
)
def
test_removeContext_last_EO_restores_default_policy
(
self
):
context
=
DummyContext
()
mgr
=
self
.
_makeOne
(
_THREAD_ID
,
context
)
original_policy
=
mgr
.
_policy
new_policy
=
mgr
.
_policy
=
DummyPolicy
()
top
=
object
()
context
.
stack
.
append
(
top
)
mgr
.
removeContext
(
top
)
self
.
failUnless
(
mgr
.
_policy
is
original_policy
)
def
test_removeContext_with_top_having_custom_policy
(
self
):
context
=
DummyContext
()
mgr
=
self
.
_makeOne
(
_THREAD_ID
,
context
)
new_policy
=
DummyPolicy
()
context
.
stack
.
append
(
ExecutableObject
(
new_policy
))
top
=
object
()
context
.
stack
.
append
(
top
)
mgr
.
removeContext
(
top
)
self
.
failUnless
(
mgr
.
_policy
is
new_policy
)
def
test_removeContext_with_top_having_no_custom_policy
(
self
):
context
=
DummyContext
()
mgr
=
self
.
_makeOne
(
_THREAD_ID
,
context
)
original_policy
=
mgr
.
_policy
new_policy
=
DummyPolicy
()
executableObject
=
ExecutableObject
(
new_policy
)
context
.
stack
.
append
(
executableObject
)
top
=
object
()
context
.
stack
.
append
(
top
)
mgr
.
removeContext
(
executableObject
)
self
.
failUnless
(
mgr
.
_policy
is
original_policy
)
def
test_checkPermission_delegates_to_policy
(
self
):
context
=
DummyContext
()
PERMISSION
=
'PERMISSION'
TARGET
=
object
()
mgr
=
self
.
_makeOne
(
_THREAD_ID
,
context
)
new_policy
=
mgr
.
_policy
=
DummyPolicy
()
result
=
mgr
.
checkPermission
(
PERMISSION
,
TARGET
)
self
.
failUnless
(
result
is
DummyPolicy
.
CHECK_PERMISSION_RESULT
)
self
.
failUnless
(
new_policy
.
CHECK_PERMISSION_ARGS
[
0
]
is
PERMISSION
)
self
.
failUnless
(
new_policy
.
CHECK_PERMISSION_ARGS
[
1
]
is
TARGET
)
self
.
failUnless
(
new_policy
.
CHECK_PERMISSION_ARGS
[
2
]
is
context
)
def
test_validate_without_roles_delegates_to_policy
(
self
):
from
AccessControl.SimpleObjectPolicies
import
_noroles
context
=
DummyContext
()
ACCESSED
=
object
()
CONTAINER
=
object
()
NAME
=
'NAME'
VALUE
=
object
()
mgr
=
self
.
_makeOne
(
_THREAD_ID
,
context
)
new_policy
=
mgr
.
_policy
=
DummyPolicy
()
result
=
mgr
.
validate
(
ACCESSED
,
CONTAINER
,
NAME
,
VALUE
,
)
self
.
failUnless
(
result
)
self
.
assertEqual
(
len
(
new_policy
.
VALIDATE_ARGS
),
5
)
self
.
failUnless
(
new_policy
.
VALIDATE_ARGS
[
0
]
is
ACCESSED
)
self
.
failUnless
(
new_policy
.
VALIDATE_ARGS
[
1
]
is
CONTAINER
)
self
.
assertEqual
(
new_policy
.
VALIDATE_ARGS
[
2
],
NAME
)
self
.
failUnless
(
new_policy
.
VALIDATE_ARGS
[
3
]
is
VALUE
)
self
.
failUnless
(
new_policy
.
VALIDATE_ARGS
[
4
]
is
context
)
def
test_validate_with_roles_delegates_to_policy
(
self
):
from
AccessControl.SimpleObjectPolicies
import
_noroles
context
=
DummyContext
()
ACCESSED
=
object
()
CONTAINER
=
object
()
NAME
=
'NAME'
VALUE
=
object
()
ROLES
=
(
'Hamlet'
,
'Othello'
)
mgr
=
self
.
_makeOne
(
_THREAD_ID
,
context
)
new_policy
=
mgr
.
_policy
=
DummyPolicy
()
result
=
mgr
.
validate
(
ACCESSED
,
CONTAINER
,
NAME
,
VALUE
,
ROLES
,
)
self
.
failUnless
(
result
)
self
.
assertEqual
(
len
(
new_policy
.
VALIDATE_ARGS
),
6
)
self
.
failUnless
(
new_policy
.
VALIDATE_ARGS
[
0
]
is
ACCESSED
)
self
.
failUnless
(
new_policy
.
VALIDATE_ARGS
[
1
]
is
CONTAINER
)
self
.
assertEqual
(
new_policy
.
VALIDATE_ARGS
[
2
],
NAME
)
self
.
failUnless
(
new_policy
.
VALIDATE_ARGS
[
3
]
is
VALUE
)
self
.
failUnless
(
new_policy
.
VALIDATE_ARGS
[
4
]
is
context
)
self
.
assertEqual
(
new_policy
.
VALIDATE_ARGS
[
5
],
ROLES
)
def
test_DTMLValidate_delegates_to_policy_validate
(
self
):
from
AccessControl.SimpleObjectPolicies
import
_noroles
context
=
DummyContext
()
ACCESSED
=
object
()
CONTAINER
=
object
()
NAME
=
'NAME'
VALUE
=
object
()
MD
=
{}
mgr
=
self
.
_makeOne
(
_THREAD_ID
,
context
)
new_policy
=
mgr
.
_policy
=
DummyPolicy
()
result
=
mgr
.
DTMLValidate
(
ACCESSED
,
CONTAINER
,
NAME
,
VALUE
,
MD
,
)
self
.
failUnless
(
result
)
self
.
assertEqual
(
len
(
new_policy
.
VALIDATE_ARGS
),
5
)
self
.
failUnless
(
new_policy
.
VALIDATE_ARGS
[
0
]
is
ACCESSED
)
self
.
failUnless
(
new_policy
.
VALIDATE_ARGS
[
1
]
is
CONTAINER
)
self
.
assertEqual
(
new_policy
.
VALIDATE_ARGS
[
2
],
NAME
)
self
.
failUnless
(
new_policy
.
VALIDATE_ARGS
[
3
]
is
VALUE
)
self
.
failUnless
(
new_policy
.
VALIDATE_ARGS
[
4
]
is
context
)
class
PythonSecurityManagerTests
(
SecurityManagerTestBase
,
ISecurityManagerConformance
,
):
def
_getTargetClass
(
self
):
from
AccessControl.ImplPython
import
SecurityManager
return
SecurityManager
# N.B.: The C version mixes in the Python version, which is why we
# can test for conformance to ISecurityManager.
class
C_SecurityManagerTests
(
SecurityManagerTestBase
,
ISecurityManagerConformance
,
):
def
_getTargetClass
(
self
):
from
AccessControl.ImplC
import
SecurityManager
return
SecurityManager
def
test_suite
():
suite
=
unittest
.
TestSuite
()
suite
.
addTest
(
unittest
.
makeSuite
(
PythonSecurityManagerTests
)
)
suite
.
addTest
(
unittest
.
makeSuite
(
C_SecurityManagerTests
)
)
return
suite
if
__name__
==
'__main__'
:
unittest
.
main
(
defaultTest
=
'test_suite'
)
src/AccessControl/tests/testZCML.py
deleted
100644 → 0
View file @
ccc10355
##############################################################################
#
# Copyright (c) 2004, 2005 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 security induced by ZCML
"""
from
zope.interface
import
implements
from
zope.interface
import
Interface
from
zope.schema
import
TextLine
from
AccessControl.SecurityInfo
import
ClassSecurityInfo
class
ISuperDummy
(
Interface
):
"""
"""
def
superMethod
():
"""
"""
class
IDummy
(
ISuperDummy
):
"""Just a marker interface"""
def
foo
():
"""
"""
class
Dummy1
:
implements
(
IDummy
)
def
foo
(
self
):
pass
def
bar
(
self
):
pass
def
baz
(
self
):
pass
def
keg
(
self
):
pass
def
wot
(
self
):
pass
def
superMethod
(
self
):
pass
class
Dummy2
(
Dummy1
):
security
=
ClassSecurityInfo
()
security
.
declarePublic
(
'foo'
)
security
.
declareProtected
(
'View management screens'
,
'bar'
)
security
.
declarePrivate
(
'baz'
)
security
.
declareProtected
(
'View management screens'
,
'keg'
)
class
IDummy3
(
Interface
):
attr
=
TextLine
(
title
=
u"Attribute"
)
class
Dummy3
:
implements
(
IDummy3
)
attr
=
None
class
Dummy4
:
foo
=
None
class
Dummy5
:
pass
def
test_security_equivalence
():
"""This test demonstrates that the traditional declarative security of
Zope 2 can be replaced by ZCML statements without any loss of
information.
>>> from zope.component.testing import setUp, tearDown
>>> setUp()
We start out with two classes, ``Dummy1`` and ``Dummy2``. They
are identical in every way, except that ``Dummy2`` has security
declarations and ``Dummy1`` does not. Before we do anything, none
of them have security access controls:
>>> from AccessControl.tests.testZCML import Dummy1, Dummy2
>>> hasattr(Dummy1, '__ac_permissions__')
False
>>> hasattr(Dummy2, '__ac_permissions__')
False
Before we can make security declarations through ZCML, we need to
register the directive and the permission:
>>> import AccessControl
>>> from zope.configuration.xmlconfig import XMLConfig
>>> XMLConfig('meta.zcml', AccessControl)()
>>> XMLConfig('permissions.zcml', AccessControl)()
Now we initialize the security for ``Dummy2`` and provide some
ZCML declarations for ``Dummy1``:
>>> from StringIO import StringIO
>>> configure_zcml = StringIO('''
... <configure xmlns="http://namespaces.zope.org/zope">
... <class class="AccessControl.tests.testZCML.Dummy1">
... <allow attributes="foo" />
... <!--deny attributes="baz" /--> <!-- XXX not yet supported -->
... </class>
... <class class="AccessControl.tests.testZCML.Dummy1">
... <require attributes="bar keg"
... permission="zope2.ViewManagementScreens"
... />
... </class>
... </configure>
... ''')
>>> from zope.configuration.xmlconfig import xmlconfig
>>> xmlconfig(configure_zcml)
>>> from AccessControl.class_init import InitializeClass
>>> InitializeClass(Dummy2)
Now we compare their access controls:
>>> ac1 = getattr(Dummy1, '__ac_permissions__')
>>> ac2 = getattr(Dummy2, '__ac_permissions__')
>>> ac1 == ac2
True
Now we look at the individual permissions:
>>> from AccessControl.ZopeSecurityPolicy import getRoles
>>> from AccessControl import ACCESS_PUBLIC
>>> from AccessControl import ACCESS_PRIVATE
>>> dummy1 = Dummy1()
>>> getRoles(dummy1, 'bar', dummy1.bar, ('Def',))
('Manager',)
>>> getRoles(dummy1, 'keg', dummy1.keg, ('Def',))
('Manager',)
>>> getRoles(dummy1, 'foo', dummy1.foo, ('Def',)) is ACCESS_PUBLIC
True
#>>> getRoles(dummy1, 'baz', dummy1.baz, ('Def',)) is ACCESS_PRIVATE
#True XXX Not yet supported.
>>> dummy2 = Dummy2()
>>> getRoles(dummy2, 'bar', dummy2.bar, ('Def',))
('Manager',)
>>> getRoles(dummy2, 'keg', dummy2.keg, ('Def',))
('Manager',)
>>> getRoles(dummy2, 'foo', dummy2.foo, ('Def',)) is ACCESS_PUBLIC
True
>>> getRoles(dummy2, 'baz', dummy2.baz, ('Def',)) is ACCESS_PRIVATE
True
Before we end we should clean up after ourselves:
>>> from AccessControl.security import clearSecurityInfo
>>> clearSecurityInfo(Dummy1)
>>> clearSecurityInfo(Dummy2)
>>> tearDown()
"""
def
test_set_warnings
():
"""This test demonstrates that set_attributes and set_schema will result
in warnings, not errors. This type of protection doesn't make sense in
Zope 2, but we want to be able to re-use Zope Toolkit packages that use
them without error.
>>> from zope.component.testing import setUp, tearDown
>>> setUp()
Before we can make security declarations through ZCML, we need to
register the directive and the permission:
>>> import AccessControl
>>> from zope.configuration.xmlconfig import XMLConfig
>>> XMLConfig('meta.zcml', AccessControl)()
>>> XMLConfig('permissions.zcml', AccessControl)()
Now we provide some ZCML declarations for ``Dummy1``:
>>> from StringIO import StringIO
>>> configure_zcml = StringIO('''
... <configure xmlns="http://namespaces.zope.org/zope">
...
... <class class="AccessControl.tests.testZCML.Dummy3">
... <require
... permission="zope2.View"
... interface="AccessControl.tests.testZCML.IDummy3"
... />
... <require
... permission="zope2.ChangeConfig"
... set_schema="AccessControl.tests.testZCML.IDummy3"
... />
... </class>
...
... <class class="AccessControl.tests.testZCML.Dummy4">
... <require
... permission="zope2.ChangeConfig"
... set_attributes="foo"
... />
... </class>
...
... </configure>
... ''')
Running this should not throw an exception (but will print a warning to
stderr)
>>> from warnings import catch_warnings
>>> from zope.configuration.xmlconfig import xmlconfig
>>> warned = []
>>> with catch_warnings(record=True) as trapped:
... xmlconfig(configure_zcml)
... warned.extend(list(trapped))
>>> len(warned)
2
>>> str(warned[0].message)
'The set_schema option...'
>>> str(warned[1].message)
'The set_attribute option...'
>>> tearDown()
"""
def
test_checkPermission
():
"""
Test checkPermission
>>> from zope.component.testing import setUp, tearDown
>>> setUp()
>>> from zope.component import eventtesting
>>> eventtesting.setUp()
zope.security has a function zope.security.checkPermission which provides
an easy way of checking whether the currently authenticated user
has the permission to access an object. The function delegates to
the security policy's checkPermission() method.
Zope2 has the same function, AccessControl.security.checkPermission,
but in a Zope2-compatible implementation. It too uses the currently
active security policy of Zope 2 for the actual permission
checking.
>>> import AccessControl
>>> from zope.configuration.xmlconfig import XMLConfig
>>> XMLConfig('meta.zcml', AccessControl)()
>>> XMLConfig('permissions.zcml', AccessControl)()
>>> from AccessControl.tests.testZCML import Dummy5
>>> dummy = Dummy5()
In the following we want to test AccessControl's checkPermission function.
What we want to assure is that checkPermission translates the Zope 2
permissions correctly, especially the edge cases:
a) zope2.Public (which should always be available to everyone)
>>> from AccessControl.security import checkPermission
>>> checkPermission('zope2.Public', dummy)
True
b) zope2.Private (which should never available to anyone)
>>> checkPermission('zope.Private', dummy)
False
>>> checkPermission('zope2.Private', dummy)
False
Any other standard Zope 2 permission will also resolve correctly:
>>> checkPermission('zope2.ViewManagementScreens', dummy)
False
Invalid permissions will obviously result in a negative response:
>>> checkPermission('notapermission', dummy)
False
In addition to using AccessControl's ``checkPermission`` function
directly, we also expect the same behaviour when we use zope.security's
checkPermission function. Code from within other Zope packages will use
that and therefore it should work transparently.
For that to work, a new AccessControl "interaction" needs to be started
(the old one from placelesssetup needs to be ended first):
>>> from zope.security.management import endInteraction
>>> endInteraction()
>>> from AccessControl.security import newInteraction
>>> newInteraction()
a) zope2.Public (which should always be available to everyone)
>>> from zope.security import checkPermission
>>> checkPermission('zope2.Public', dummy)
True
b) zope2.Private (which should never available to anyone)
>>> checkPermission('zope.Private', dummy)
False
>>> checkPermission('zope2.Private', dummy)
False
Any other standard Zope 2 permission will also resolve correctly:
>>> checkPermission('zope2.ViewManagementScreens', dummy)
False
Invalid permissions will obviously result in a negative response:
>>> checkPermission('notapermission', dummy)
False
Clean up:
>>> tearDown()
"""
def
test_register_permission
():
"""This test demonstrates that if the <permission /> directive is used
to create a permission that does not already exist, it is created on
startup, with roles defaulting to Manager.
>>> from zope.component.testing import setUp, tearDown
>>> setUp()
>>> from zope.component import eventtesting
>>> eventtesting.setUp()
First, we need to configure the relevant parts of AccessControl:
>>> import AccessControl
>>> from zope.configuration.xmlconfig import XMLConfig
>>> XMLConfig('meta.zcml', AccessControl)()
>>> XMLConfig('permissions.zcml', AccessControl)()
We can now register a permission in ZCML:
>>> from StringIO import StringIO
>>> configure_zcml = StringIO('''
... <configure xmlns="http://namespaces.zope.org/zope"
... i18n_domain="test">
...
... <permission
... id="AccessControl.tests.DummyPermission"
... title="AccessControl: Dummy permission"
... />
...
... </configure>
... ''')
>>> from zope.configuration.xmlconfig import xmlconfig
>>> xmlconfig(configure_zcml)
The permission will be made available globally, with default role set
of ('Manager',).
>>> from AccessControl.Permission import getPermissions
>>> permissions = getPermissions()
>>> [p[2] for p in permissions
... if p[0] == 'AccessControl: Dummy permission']
[('Manager',)]
Let's also ensure that permissions are not overwritten if they exist
already:
>>> from AccessControl.Permission import addPermission
>>> addPermission('Dummy: Other dummy', ('Anonymous', ))
>>> from StringIO import StringIO
>>> configure_zcml = StringIO('''
... <configure xmlns="http://namespaces.zope.org/zope"
... i18n_domain="test">
...
... <permission
... id="AccessControl.tests.OtherDummy"
... title="Dummy: Other dummy"
... />
...
... </configure>
... ''')
>>> from zope.configuration.xmlconfig import xmlconfig
>>> xmlconfig(configure_zcml)
>>> permissions = getPermissions()
>>> [p[2] for p in permissions if p[0] == 'Dummy: Other dummy']
[('Anonymous',)]
>>> tearDown()
"""
def
test_suite
():
import
doctest
return
doctest
.
DocTestSuite
(
optionflags
=
doctest
.
ELLIPSIS
)
src/AccessControl/tests/testZopeGuards.py
deleted
100644 → 0
View file @
ccc10355
##############################################################################
#
# 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 Zope Guards
"""
import
doctest
import
unittest
import
os
import
operator
import
sys
if
sys
.
version_info
>=
(
2
,
5
):
from
AccessControl.ZopeGuards
import
guarded_any
,
guarded_all
MIN_MAX_TAKE_KEY
=
True
else
:
MIN_MAX_TAKE_KEY
=
False
try
:
__file__
except
NameError
:
__file__
=
os
.
path
.
abspath
(
sys
.
argv
[
1
])
_FILEPATH
=
os
.
path
.
abspath
(
__file__
)
_HERE
=
os
.
path
.
dirname
(
_FILEPATH
)
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
class
GuardTestCase
(
unittest
.
TestCase
):
def
setSecurityManager
(
self
,
manager
):
from
AccessControl.SecurityManagement
import
get_ident
from
AccessControl.SecurityManagement
import
_managers
key
=
get_ident
()
old
=
_managers
.
get
(
key
)
if
manager
is
None
:
del
_managers
[
key
]
else
:
_managers
[
key
]
=
manager
return
old
class
Method
:
def
__init__
(
self
,
*
args
):
self
.
args
=
args
class
TestGuardedGetattr
(
GuardTestCase
):
def
setUp
(
self
):
self
.
__sm
=
SecurityManager
()
self
.
__old
=
self
.
setSecurityManager
(
self
.
__sm
)
def
tearDown
(
self
):
self
.
setSecurityManager
(
self
.
__old
)
def
test_unauthorized
(
self
):
from
AccessControl
import
Unauthorized
from
AccessControl.ZopeGuards
import
guarded_getattr
obj
,
name
=
Method
(),
'args'
value
=
getattr
(
obj
,
name
)
rc
=
sys
.
getrefcount
(
value
)
self
.
__sm
.
reject
=
True
self
.
assertRaises
(
Unauthorized
,
guarded_getattr
,
obj
,
name
)
self
.
assert_
(
self
.
__sm
.
calls
)
del
self
.
__sm
.
calls
[:]
self
.
assertEqual
(
rc
,
sys
.
getrefcount
(
value
))
def
test_calls_validate_for_unknown_type
(
self
):
from
AccessControl.ZopeGuards
import
guarded_getattr
guarded_getattr
(
self
,
'test_calls_validate_for_unknown_type'
)
self
.
assert_
(
self
.
__sm
.
calls
)
def
test_attr_handler_table
(
self
):
from
AccessControl
import
Unauthorized
from
AccessControl.ZopeGuards
import
guarded_getattr
from
AccessControl.SimpleObjectPolicies
import
ContainerAssertions
d
=
{}
_dict
=
type
(
d
)
old
=
ContainerAssertions
.
get
(
_dict
)
mytable
=
{
'keys'
:
1
,
'values'
:
Method
,
}
ContainerAssertions
[
_dict
]
=
mytable
try
:
guarded_getattr
(
d
,
'keys'
)
self
.
assertEqual
(
len
(
self
.
__sm
.
calls
),
0
)
values
=
guarded_getattr
(
d
,
'values'
)
self
.
assertEqual
(
values
.
__class__
,
Method
)
self
.
assertEqual
(
values
.
args
,
(
d
,
'values'
))
self
.
assertRaises
(
Unauthorized
,
guarded_getattr
,
d
,
'items'
)
finally
:
ContainerAssertions
[
_dict
]
=
old
class
TestDictGuards
(
GuardTestCase
):
def
test_get_simple
(
self
):
from
AccessControl.ZopeGuards
import
get_dict_get
get
=
get_dict_get
({
'foo'
:
'bar'
},
'get'
)
self
.
assertEqual
(
get
(
'foo'
),
'bar'
)
def
test_get_default
(
self
):
from
AccessControl.ZopeGuards
import
get_dict_get
get
=
get_dict_get
({
'foo'
:
'bar'
},
'get'
)
self
.
failUnless
(
get
(
'baz'
)
is
None
)
self
.
assertEqual
(
get
(
'baz'
,
'splat'
),
'splat'
)
def
test_get_validates
(
self
):
from
AccessControl.ZopeGuards
import
get_dict_get
sm
=
SecurityManager
()
old
=
self
.
setSecurityManager
(
sm
)
get
=
get_dict_get
({
'foo'
:
GuardTestCase
},
'get'
)
try
:
get
(
'foo'
)
finally
:
self
.
setSecurityManager
(
old
)
self
.
assert_
(
sm
.
calls
)
def
test_pop_simple
(
self
):
from
AccessControl.ZopeGuards
import
get_dict_pop
pop
=
get_dict_pop
({
'foo'
:
'bar'
},
'pop'
)
self
.
assertEqual
(
pop
(
'foo'
),
'bar'
)
def
test_pop_raises
(
self
):
from
AccessControl.ZopeGuards
import
get_dict_pop
pop
=
get_dict_pop
({
'foo'
:
'bar'
},
'pop'
)
self
.
assertRaises
(
KeyError
,
pop
,
'baz'
)
def
test_pop_default
(
self
):
from
AccessControl.ZopeGuards
import
get_dict_pop
pop
=
get_dict_pop
({
'foo'
:
'bar'
},
'pop'
)
self
.
assertEqual
(
pop
(
'baz'
,
'splat'
),
'splat'
)
def
test_pop_validates
(
self
):
from
AccessControl.ZopeGuards
import
get_dict_get
sm
=
SecurityManager
()
old
=
self
.
setSecurityManager
(
sm
)
pop
=
get_dict_get
({
'foo'
:
GuardTestCase
},
'pop'
)
try
:
pop
(
'foo'
)
finally
:
self
.
setSecurityManager
(
old
)
self
.
assert_
(
sm
.
calls
)
if
sys
.
version_info
>=
(
2
,
2
):
def
test_iterkeys_simple
(
self
):
from
AccessControl.ZopeGuards
import
get_iter
d
=
{
'foo'
:
1
,
'bar'
:
2
,
'baz'
:
3
}
iterkeys
=
get_iter
(
d
,
'iterkeys'
)
keys
=
d
.
keys
()
keys
.
sort
()
ikeys
=
list
(
iterkeys
())
ikeys
.
sort
()
self
.
assertEqual
(
keys
,
ikeys
)
def
test_iterkeys_empty
(
self
):
from
AccessControl.ZopeGuards
import
get_iter
iterkeys
=
get_iter
({},
'iterkeys'
)
self
.
assertEqual
(
list
(
iterkeys
()),
[])
def
test_iterkeys_validates
(
self
):
from
AccessControl.ZopeGuards
import
get_iter
sm
=
SecurityManager
()
old
=
self
.
setSecurityManager
(
sm
)
iterkeys
=
get_iter
({
GuardTestCase
:
1
},
'iterkeys'
)
try
:
iterkeys
().
next
()
finally
:
self
.
setSecurityManager
(
old
)
self
.
assert_
(
sm
.
calls
)
def
test_itervalues_simple
(
self
):
from
AccessControl.ZopeGuards
import
get_iter
d
=
{
'foo'
:
1
,
'bar'
:
2
,
'baz'
:
3
}
itervalues
=
get_iter
(
d
,
'itervalues'
)
values
=
d
.
values
()
values
.
sort
()
ivalues
=
list
(
itervalues
())
ivalues
.
sort
()
self
.
assertEqual
(
values
,
ivalues
)
def
test_itervalues_empty
(
self
):
from
AccessControl.ZopeGuards
import
get_iter
itervalues
=
get_iter
({},
'itervalues'
)
self
.
assertEqual
(
list
(
itervalues
()),
[])
def
test_itervalues_validates
(
self
):
from
AccessControl.ZopeGuards
import
get_iter
sm
=
SecurityManager
()
old
=
self
.
setSecurityManager
(
sm
)
itervalues
=
get_iter
({
GuardTestCase
:
1
},
'itervalues'
)
try
:
itervalues
().
next
()
finally
:
self
.
setSecurityManager
(
old
)
self
.
assert_
(
sm
.
calls
)
class
TestListGuards
(
GuardTestCase
):
def
test_pop_simple
(
self
):
from
AccessControl.ZopeGuards
import
get_list_pop
pop
=
get_list_pop
([
'foo'
,
'bar'
,
'baz'
],
'pop'
)
self
.
assertEqual
(
pop
(),
'baz'
)
self
.
assertEqual
(
pop
(
0
),
'foo'
)
def
test_pop_raises
(
self
):
from
AccessControl.ZopeGuards
import
get_list_pop
pop
=
get_list_pop
([],
'pop'
)
self
.
assertRaises
(
IndexError
,
pop
)
def
test_pop_validates
(
self
):
from
AccessControl.ZopeGuards
import
get_list_pop
sm
=
SecurityManager
()
old
=
self
.
setSecurityManager
(
sm
)
pop
=
get_list_pop
([
GuardTestCase
],
'pop'
)
try
:
pop
()
finally
:
self
.
setSecurityManager
(
old
)
self
.
assert_
(
sm
.
calls
)
class
TestBuiltinFunctionGuards
(
GuardTestCase
):
def
test_zip_fails
(
self
):
from
AccessControl
import
Unauthorized
from
AccessControl.ZopeGuards
import
guarded_zip
sm
=
SecurityManager
(
1
)
# rejects
old
=
self
.
setSecurityManager
(
sm
)
self
.
assertRaises
(
Unauthorized
,
guarded_zip
,
[
1
,
2
,
3
],
[
3
,
2
,
1
])
self
.
assertRaises
(
Unauthorized
,
guarded_zip
,
[
1
,
2
,
3
],
[
1
])
self
.
setSecurityManager
(
old
)
def
test_map_fails
(
self
):
from
AccessControl
import
Unauthorized
from
AccessControl.ZopeGuards
import
guarded_map
sm
=
SecurityManager
(
1
)
# rejects
old
=
self
.
setSecurityManager
(
sm
)
self
.
assertRaises
(
Unauthorized
,
guarded_map
,
str
,
[
1
,
2
,
3
])
self
.
assertRaises
(
Unauthorized
,
guarded_map
,
lambda
x
,
y
:
x
+
y
,
[
1
,
2
,
3
],
[
3
,
2
,
1
])
self
.
setSecurityManager
(
old
)
if
sys
.
version_info
>=
(
2
,
5
):
def
test_all_fails
(
self
):
from
AccessControl
import
Unauthorized
sm
=
SecurityManager
(
1
)
# rejects
old
=
self
.
setSecurityManager
(
sm
)
self
.
assertRaises
(
Unauthorized
,
guarded_all
,
[
True
,
True
,
False
])
self
.
setSecurityManager
(
old
)
def
test_any_fails
(
self
):
from
AccessControl
import
Unauthorized
sm
=
SecurityManager
(
1
)
# rejects
old
=
self
.
setSecurityManager
(
sm
)
self
.
assertRaises
(
Unauthorized
,
guarded_any
,
[
True
,
True
,
False
])
self
.
setSecurityManager
(
old
)
def
test_min_fails
(
self
):
from
AccessControl
import
Unauthorized
from
AccessControl.ZopeGuards
import
guarded_min
sm
=
SecurityManager
(
1
)
# rejects
old
=
self
.
setSecurityManager
(
sm
)
self
.
assertRaises
(
Unauthorized
,
guarded_min
,
[
1
,
2
,
3
])
self
.
assertRaises
(
Unauthorized
,
guarded_min
,
1
,
2
,
3
)
if
MIN_MAX_TAKE_KEY
:
class
MyDict
(
dict
):
# guard() skips 'dict' values
pass
self
.
assertRaises
(
Unauthorized
,
guarded_min
,
MyDict
(
x
=
1
),
MyDict
(
x
=
2
),
key
=
operator
.
itemgetter
(
'x'
))
self
.
setSecurityManager
(
old
)
def
test_max_fails
(
self
):
from
AccessControl
import
Unauthorized
from
AccessControl.ZopeGuards
import
guarded_max
sm
=
SecurityManager
(
1
)
# rejects
old
=
self
.
setSecurityManager
(
sm
)
self
.
assertRaises
(
Unauthorized
,
guarded_max
,
[
1
,
2
,
3
])
self
.
assertRaises
(
Unauthorized
,
guarded_max
,
1
,
2
,
3
)
if
MIN_MAX_TAKE_KEY
:
class
MyDict
(
dict
):
# guard() skips 'dict' values
pass
self
.
assertRaises
(
Unauthorized
,
guarded_max
,
MyDict
(
x
=
1
),
MyDict
(
x
=
2
),
key
=
operator
.
itemgetter
(
'x'
))
self
.
setSecurityManager
(
old
)
def
test_enumerate_fails
(
self
):
from
AccessControl
import
Unauthorized
from
AccessControl.ZopeGuards
import
guarded_enumerate
sm
=
SecurityManager
(
1
)
# rejects
old
=
self
.
setSecurityManager
(
sm
)
enum
=
guarded_enumerate
([
1
,
2
,
3
])
self
.
assertRaises
(
Unauthorized
,
enum
.
next
)
self
.
setSecurityManager
(
old
)
def
test_sum_fails
(
self
):
from
AccessControl
import
Unauthorized
from
AccessControl.ZopeGuards
import
guarded_sum
sm
=
SecurityManager
(
1
)
# rejects
old
=
self
.
setSecurityManager
(
sm
)
self
.
assertRaises
(
Unauthorized
,
guarded_sum
,
[
1
,
2
,
3
])
self
.
setSecurityManager
(
old
)
def
test_zip_succeeds
(
self
):
from
AccessControl.ZopeGuards
import
guarded_zip
sm
=
SecurityManager
()
# accepts
old
=
self
.
setSecurityManager
(
sm
)
self
.
assertEqual
(
guarded_zip
([
1
,
2
,
3
],
[
3
,
2
,
1
]),
[(
1
,
3
),(
2
,
2
),(
3
,
1
)])
self
.
assertEqual
(
guarded_zip
([
1
,
2
,
3
],
[
1
]),
[(
1
,
1
)])
self
.
setSecurityManager
(
old
)
def
test_map_succeeds
(
self
):
from
AccessControl.ZopeGuards
import
guarded_map
sm
=
SecurityManager
()
# accepts
old
=
self
.
setSecurityManager
(
sm
)
self
.
assertEqual
(
guarded_map
(
str
,
[
1
,
2
,
3
]),
[
'1'
,
'2'
,
'3'
])
self
.
assertEqual
(
guarded_map
(
lambda
x
,
y
:
x
+
y
,
[
1
,
2
,
3
],
[
3
,
2
,
1
]),
[
4
,
4
,
4
])
self
.
setSecurityManager
(
old
)
if
sys
.
version_info
>=
(
2
,
5
):
def
test_all_succeeds
(
self
):
sm
=
SecurityManager
()
# accepts
old
=
self
.
setSecurityManager
(
sm
)
self
.
assertEqual
(
guarded_all
([
True
,
True
,
False
]),
False
)
self
.
setSecurityManager
(
old
)
def
test_any_succeeds
(
self
):
sm
=
SecurityManager
()
# accepts
old
=
self
.
setSecurityManager
(
sm
)
self
.
assertEquals
(
guarded_any
([
True
,
True
,
False
]),
True
)
self
.
setSecurityManager
(
old
)
def
test_min_succeeds
(
self
):
from
AccessControl.ZopeGuards
import
guarded_min
sm
=
SecurityManager
()
# accepts
old
=
self
.
setSecurityManager
(
sm
)
self
.
assertEqual
(
guarded_min
([
1
,
2
,
3
]),
1
)
self
.
assertEqual
(
guarded_min
(
1
,
2
,
3
),
1
)
if
MIN_MAX_TAKE_KEY
:
class
MyDict
(
dict
):
# guard() skips 'dict' values
pass
self
.
assertEqual
(
guarded_min
(
MyDict
(
x
=
1
),
MyDict
(
x
=
2
),
key
=
operator
.
itemgetter
(
'x'
)),
{
'x'
:
1
})
self
.
setSecurityManager
(
old
)
def
test_max_succeeds
(
self
):
from
AccessControl.ZopeGuards
import
guarded_max
sm
=
SecurityManager
()
# accepts
old
=
self
.
setSecurityManager
(
sm
)
self
.
assertEqual
(
guarded_max
([
1
,
2
,
3
]),
3
)
self
.
assertEqual
(
guarded_max
(
1
,
2
,
3
),
3
)
if
MIN_MAX_TAKE_KEY
:
class
MyDict
(
dict
):
# guard() skips 'dict' values
pass
self
.
assertEqual
(
guarded_max
(
MyDict
(
x
=
1
),
MyDict
(
x
=
2
),
key
=
operator
.
itemgetter
(
'x'
)),
{
'x'
:
2
})
self
.
setSecurityManager
(
old
)
def
test_enumerate_succeeds
(
self
):
from
AccessControl.ZopeGuards
import
guarded_enumerate
sm
=
SecurityManager
()
# accepts
old
=
self
.
setSecurityManager
(
sm
)
enum
=
guarded_enumerate
([
1
,
2
,
3
])
self
.
assertEqual
(
enum
.
next
(),
(
0
,
1
))
self
.
assertEqual
(
enum
.
next
(),
(
1
,
2
))
self
.
assertEqual
(
enum
.
next
(),
(
2
,
3
))
self
.
assertRaises
(
StopIteration
,
enum
.
next
)
self
.
setSecurityManager
(
old
)
def
test_sum_succeeds
(
self
):
from
AccessControl.ZopeGuards
import
guarded_sum
sm
=
SecurityManager
()
# accepts
old
=
self
.
setSecurityManager
(
sm
)
self
.
assertEqual
(
guarded_sum
([
1
,
2
,
3
]),
6
)
self
.
assertEqual
(
guarded_sum
([
1
,
2
,
3
],
start
=
36
),
42
)
self
.
setSecurityManager
(
old
)
def
test_apply
(
self
):
from
AccessControl
import
Unauthorized
from
AccessControl.ZopeGuards
import
safe_builtins
sm
=
SecurityManager
(
1
)
# rejects
old
=
self
.
setSecurityManager
(
sm
)
gapply
=
safe_builtins
[
'apply'
]
def
f
(
a
=
1
,
b
=
2
):
return
a
+
b
# This one actually succeeds, because apply isn't given anything
# to unpack.
self
.
assertEqual
(
gapply
(
f
),
3
)
# Likewise, because the things passed are empty.
self
.
assertEqual
(
gapply
(
f
,
(),
{}),
3
)
self
.
assertRaises
(
Unauthorized
,
gapply
,
f
,
[
1
])
self
.
assertRaises
(
Unauthorized
,
gapply
,
f
,
(),
{
'a'
:
2
})
self
.
assertRaises
(
Unauthorized
,
gapply
,
f
,
[
1
],
{
'a'
:
2
})
sm
=
SecurityManager
(
0
)
# accepts
self
.
setSecurityManager
(
sm
)
self
.
assertEqual
(
gapply
(
f
),
3
)
self
.
assertEqual
(
gapply
(
f
,
(),
{}),
3
)
self
.
assertEqual
(
gapply
(
f
,
[
0
]),
2
)
self
.
assertEqual
(
gapply
(
f
,
[],
{
'b'
:
18
}),
19
)
self
.
assertEqual
(
gapply
(
f
,
[
10
],
{
'b'
:
1
}),
11
)
self
.
setSecurityManager
(
old
)
class
TestGuardedDictListTypes
(
unittest
.
TestCase
):
def
testDictCreation
(
self
):
from
AccessControl.ZopeGuards
import
safe_builtins
d
=
safe_builtins
[
'dict'
]
self
.
assertEquals
(
d
(),
{})
self
.
assertEquals
(
d
({
1
:
2
}),
{
1
:
2
})
self
.
assertEquals
(
d
(((
1
,
2
),)),
{
1
:
2
})
self
.
assertEquals
(
d
(
foo
=
1
),
{
"foo"
:
1
})
self
.
assertEquals
(
d
.
fromkeys
((
1
,
2
,
3
)),
{
1
:
None
,
2
:
None
,
3
:
None
})
self
.
assertEquals
(
d
.
fromkeys
((
1
,
2
,
3
),
'f'
),
{
1
:
'f'
,
2
:
'f'
,
3
:
'f'
})
def
testListCreation
(
self
):
from
AccessControl.ZopeGuards
import
safe_builtins
l
=
safe_builtins
[
'list'
]
self
.
assertEquals
(
l
(),
[])
self
.
assertEquals
(
l
([
1
,
2
,
3
]),
[
1
,
2
,
3
])
x
=
[
3
,
2
,
1
]
self
.
assertEquals
(
l
(
x
),
[
3
,
2
,
1
])
if
sys
.
version_info
>=
(
2
,
4
):
self
.
assertEquals
(
sorted
(
x
),
[
1
,
2
,
3
])
class
TestRestrictedPythonApply
(
GuardTestCase
):
def
test_apply
(
self
):
from
AccessControl
import
Unauthorized
from
AccessControl.ZopeGuards
import
guarded_apply
sm
=
SecurityManager
(
1
)
# rejects
old
=
self
.
setSecurityManager
(
sm
)
gapply
=
guarded_apply
def
f
(
a
=
1
,
b
=
2
):
return
a
+
b
# This one actually succeeds, because apply isn't given anything
# to unpack.
self
.
assertEqual
(
gapply
(
*
(
f
,)),
3
)
# Likewise, because the things passed are empty.
self
.
assertEqual
(
gapply
(
*
(
f
,),
**
{}),
3
)
self
.
assertRaises
(
Unauthorized
,
gapply
,
*
(
f
,
1
))
self
.
assertRaises
(
Unauthorized
,
gapply
,
*
(
f
,),
**
{
'a'
:
2
})
self
.
assertRaises
(
Unauthorized
,
gapply
,
*
(
f
,
1
),
**
{
'a'
:
2
})
sm
=
SecurityManager
(
0
)
# accepts
self
.
setSecurityManager
(
sm
)
self
.
assertEqual
(
gapply
(
*
(
f
,)),
3
)
self
.
assertEqual
(
gapply
(
*
(
f
,),
**
{}),
3
)
self
.
assertEqual
(
gapply
(
*
(
f
,
0
)),
2
)
self
.
assertEqual
(
gapply
(
*
(
f
,),
**
{
'b'
:
18
}),
19
)
self
.
assertEqual
(
gapply
(
*
(
f
,
10
),
**
{
'b'
:
1
}),
11
)
self
.
setSecurityManager
(
old
)
# Map function name to the # of times it's been called.
wrapper_count
=
{}
class
FuncWrapper
:
def
__init__
(
self
,
funcname
,
func
):
self
.
funcname
=
funcname
wrapper_count
[
funcname
]
=
0
self
.
func
=
func
def
__call__
(
self
,
*
args
,
**
kws
):
wrapper_count
[
self
.
funcname
]
+=
1
return
self
.
func
(
*
args
,
**
kws
)
def
__repr__
(
self
):
return
"<FuncWrapper around %r>"
%
self
.
func
# Given the high wall between AccessControl and RestrictedPython, I suppose
# the next one could be called an integration test. But we're simply
# trying to run restricted Python with the *intended* implementations of
# the special wrappers here, so no apologies.
_ProtectedBase
=
None
class
TestActualPython
(
GuardTestCase
):
_old_mgr
=
_old_policy
=
_marker
=
[]
def
setUp
(
self
):
self
.
_wrapped_dicts
=
[]
def
tearDown
(
self
):
self
.
_restorePolicyAndManager
()
for
munged
,
orig
in
self
.
_wrapped_dicts
:
munged
.
update
(
orig
)
del
self
.
_wrapped_dicts
def
_initPolicyAndManager
(
self
,
manager
=
None
):
from
AccessControl.SecurityManagement
import
get_ident
from
AccessControl.SecurityManagement
import
_managers
from
AccessControl.SecurityManagement
import
newSecurityManager
from
AccessControl.SecurityManager
import
setSecurityPolicy
from
AccessControl.ZopeSecurityPolicy
import
ZopeSecurityPolicy
class
UnderprivilegedUser
:
""" Anonymous USer for unit testing purposes.
"""
def
getId
(
self
):
return
'Underprivileged User'
getUserName
=
getId
def
allowed
(
self
,
object
,
object_roles
=
None
):
return
0
def
getRoles
(
self
):
return
()
self
.
_policy
=
ZopeSecurityPolicy
()
self
.
_old_policy
=
setSecurityPolicy
(
self
.
_policy
)
if
manager
is
None
:
thread_id
=
get_ident
()
self
.
_old_mgr
=
manager
=
_managers
.
get
(
thread_id
,
self
.
_marker
)
newSecurityManager
(
None
,
UnderprivilegedUser
())
else
:
self
.
_old_mgr
=
self
.
setSecurityManager
(
manager
)
def
_restorePolicyAndManager
(
self
):
from
AccessControl.SecurityManagement
import
noSecurityManager
from
AccessControl.SecurityManager
import
setSecurityPolicy
if
self
.
_old_mgr
is
not
self
.
_marker
:
self
.
setSecurityManager
(
self
.
_old_mgr
)
else
:
noSecurityManager
()
if
self
.
_old_policy
is
not
self
.
_marker
:
setSecurityPolicy
(
self
.
_old_policy
)
def
_getProtectedBaseClass
(
self
):
from
AccessControl.class_init
import
InitializeClass
from
AccessControl.SecurityInfo
import
ClassSecurityInfo
from
ExtensionClass
import
Base
global
_ProtectedBase
if
_ProtectedBase
is
None
:
class
ProtectedBase
(
Base
):
security
=
ClassSecurityInfo
()
security
.
declarePrivate
(
'private_method'
)
def
private_method
(
self
):
return
'private_method called'
InitializeClass
(
ProtectedBase
)
_ProtectedBase
=
ProtectedBase
return
_ProtectedBase
def
testPython
(
self
):
from
RestrictedPython.tests
import
verify
code
,
its_globals
=
self
.
_compile
(
"actual_python.py"
)
verify
.
verify
(
code
)
# Fiddle the global and safe-builtins dicts to count how many times
# the special functions are called.
self
.
_wrap_replaced_dict_callables
(
its_globals
)
self
.
_wrap_replaced_dict_callables
(
its_globals
[
'__builtins__'
])
sm
=
SecurityManager
()
old
=
self
.
setSecurityManager
(
sm
)
try
:
exec
code
in
its_globals
finally
:
self
.
setSecurityManager
(
old
)
# Use wrapper_count to determine coverage.
## print wrapper_count # uncomment to see wrapper names & counts
untouched
=
[
k
for
k
,
v
in
wrapper_count
.
items
()
if
v
==
0
]
if
untouched
:
untouched
.
sort
()
self
.
fail
(
"Unexercised wrappers: %r"
%
untouched
)
def
testPythonRealAC
(
self
):
code
,
its_globals
=
self
.
_compile
(
"actual_python.py"
)
exec
code
in
its_globals
def
test_derived_class_normal
(
self
):
from
AccessControl
import
Unauthorized
from
RestrictedPython.tests
import
verify
NORMAL_SCRIPT
=
"""
class Normal(ProtectedBase):
pass
normal = Normal()
print normal.private_method()
"""
code
,
its_globals
=
self
.
_compile_str
(
NORMAL_SCRIPT
,
'normal_script'
)
its_globals
[
'ProtectedBase'
]
=
self
.
_getProtectedBaseClass
()
verify
.
verify
(
code
)
self
.
_initPolicyAndManager
()
try
:
exec
code
in
its_globals
except
Unauthorized
:
pass
else
:
self
.
fail
(
"Didn't raise Unauthorized:
\
n
%s"
%
its_globals
[
'_print'
]())
def
test_derived_class_sneaky_en_suite
(
self
):
# Disallow declaration of security-affecting names in classes
# defined in restricted code (compile-time check).
from
RestrictedPython.tests
import
verify
SNEAKY_SCRIPT
=
"""
class Sneaky(ProtectedBase):
private_method__roles__ = None
sneaky = Sneaky()
print sneaky.private_method()
"""
try
:
code
,
its_globals
=
self
.
_compile_str
(
SNEAKY_SCRIPT
,
'sneaky_script'
)
except
SyntaxError
:
pass
else
:
self
.
fail
(
"Didn't raise SyntaxError!"
)
def
test_derived_sneaky_post_facto
(
self
):
# Assignment to a class outside its suite fails at
# compile time with a SyntaxError.
from
RestrictedPython.tests
import
verify
SNEAKY_SCRIPT
=
"""
class Sneaky(ProtectedBase):
pass
Sneaky.private_method__roles__ = None
sneaky = Sneaky()
print sneaky.private_method()
"""
try
:
code
,
its_globals
=
self
.
_compile_str
(
SNEAKY_SCRIPT
,
'sneaky_script'
)
except
SyntaxError
:
pass
else
:
self
.
fail
(
"Didn't raise SyntaxError!"
)
def
test_derived_sneaky_instance
(
self
):
# Assignment of security-sensitive names to an instance
# fails at compile time with a SyntaxError.
from
RestrictedPython.tests
import
verify
SNEAKY_SCRIPT
=
"""
class Sneaky(ProtectedBase):
pass
sneaky = Sneaky()
sneaky.private_method__roles__ = None
print sneaky.private_method()
"""
try
:
code
,
its_globals
=
self
.
_compile_str
(
SNEAKY_SCRIPT
,
'sneaky_script'
)
except
SyntaxError
:
pass
else
:
self
.
fail
(
"Didn't raise SyntaxError!"
)
def
test_dict_access
(
self
):
from
RestrictedPython.tests
import
verify
SIMPLE_DICT_ACCESS_SCRIPT
=
"""
def foo(text):
return text
kw = {'text':'baz'}
print foo(**kw)
kw = {'text':True}
print foo(**kw)
"""
code
,
its_globals
=
self
.
_compile_str
(
SIMPLE_DICT_ACCESS_SCRIPT
,
'x'
)
verify
.
verify
(
code
)
sm
=
SecurityManager
()
old
=
self
.
setSecurityManager
(
sm
)
try
:
exec
code
in
its_globals
finally
:
self
.
setSecurityManager
(
old
)
self
.
assertEqual
(
its_globals
[
'_print'
](),
'baz
\
n
True
\
n
'
)
def
_compile_str
(
self
,
text
,
name
):
from
RestrictedPython
import
compile_restricted
from
AccessControl.ZopeGuards
import
get_safe_globals
,
guarded_getattr
code
=
compile_restricted
(
text
,
name
,
'exec'
)
g
=
get_safe_globals
()
g
[
'_getattr_'
]
=
guarded_getattr
g
[
'__debug__'
]
=
1
# so assert statements are active
g
[
'__name__'
]
=
__name__
# so classes can be defined in the script
return
code
,
g
def
testPythonRealAC
(
self
):
code
,
its_globals
=
self
.
_compile
(
"actual_python.py"
)
exec
code
in
its_globals
# Compile code in fname, as restricted Python. Return the
# compiled code, and a safe globals dict for running it in.
# fname is the string name of a Python file; it must be found
# in the same directory as this file.
def
_compile
(
self
,
fname
):
from
RestrictedPython
import
compile_restricted
from
AccessControl.ZopeGuards
import
get_safe_globals
,
guarded_getattr
fn
=
os
.
path
.
join
(
_HERE
,
fname
)
text
=
open
(
fn
).
read
()
return
self
.
_compile_str
(
text
,
fn
)
# d is a dict, the globals for execution or our safe builtins.
# The callable values which aren't the same as the corresponding
# entries in __builtin__ are wrapped in a FuncWrapper, so we can
# tell whether they're executed.
def
_wrap_replaced_dict_callables
(
self
,
d
):
import
__builtin__
orig
=
d
.
copy
()
self
.
_wrapped_dicts
.
append
((
d
,
orig
))
for
k
,
v
in
d
.
items
():
if
callable
(
v
)
and
v
is
not
getattr
(
__builtin__
,
k
,
None
):
d
[
k
]
=
FuncWrapper
(
k
,
v
)
def
test_inplacevar
():
"""
Verify the correct behavior of protected_inplacevar.
>>> from AccessControl.ZopeGuards import protected_inplacevar
Basic operations on objects without inplace slots work as expected:
>>> protected_inplacevar('+=', 1, 2)
3
>>> protected_inplacevar('-=', 5, 2)
3
>>> protected_inplacevar('*=', 5, 2)
10
>>> protected_inplacevar('/=', 6, 2)
3
>>> protected_inplacevar('%=', 5, 2)
1
>>> protected_inplacevar('**=', 5, 2)
25
>>> protected_inplacevar('<<=', 5, 2)
20
>>> protected_inplacevar('>>=', 5, 2)
1
>>> protected_inplacevar('&=', 5, 2)
0
>>> protected_inplacevar('^=', 7, 2)
5
>>> protected_inplacevar('|=', 5, 2)
7
Inplace operations are allowed on lists:
>>> protected_inplacevar('+=', [1], [2])
[1, 2]
>>> protected_inplacevar('*=', [1], 2)
[1, 1]
But not on custom objects:
>>> class C:
... def __iadd__(self, other):
... return 42
>>> protected_inplacevar('+=', C(), 2) # doctest: +NORMALIZE_WHITESPACE
Traceback (most recent call last):
...
TypeError: Augmented assignment to C objects is not allowed in
untrusted code
"""
if
sys
.
version_info
[:
2
]
>=
(
2
,
4
):
def
test_inplacevar_for_py24
():
"""
protected_inplacevar allows inplce ops on sets:
>>> from AccessControl.ZopeGuards import protected_inplacevar
>>> s = set((1,2,3,4))
>>> sorted(protected_inplacevar('-=', s, set((1, 3))))
[2, 4]
>>> sorted(s)
[2, 4]
>>> sorted(protected_inplacevar('|=', s, set((1, 3, 9))))
[1, 2, 3, 4, 9]
>>> sorted(s)
[1, 2, 3, 4, 9]
>>> sorted(protected_inplacevar('&=', s, set((1, 2, 3, 9))))
[1, 2, 3, 9]
>>> sorted(s)
[1, 2, 3, 9]
>>> sorted(protected_inplacevar('^=', s, set((1, 3, 7, 8))))
[2, 7, 8, 9]
>>> sorted(s)
[2, 7, 8, 9]
"""
def
test_suite
():
suite
=
unittest
.
TestSuite
([
doctest
.
DocTestSuite
(),
])
for
cls
in
(
TestGuardedGetattr
,
TestDictGuards
,
TestBuiltinFunctionGuards
,
TestListGuards
,
TestGuardedDictListTypes
,
TestRestrictedPythonApply
,
TestActualPython
,
):
suite
.
addTest
(
unittest
.
makeSuite
(
cls
))
return
suite
if
__name__
==
'__main__'
:
unittest
.
main
()
src/AccessControl/tests/testZopeSecurityPolicy.py
deleted
100644 → 0
View file @
ccc10355
##############################################################################
#
# 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
#
##############################################################################
"""Tests of ZopeSecurityPolicy
"""
import
sys
import
unittest
from
Acquisition
import
Implicit
,
Explicit
from
MethodObject
import
Method
from
zExceptions
import
Unauthorized
from
AccessControl.userfolder
import
UserFolder
from
AccessControl.SecurityManagement
import
SecurityContext
user_roles
=
(
'RoleOfUser'
,)
eo_roles
=
(
'RoleOfExecutableOwner'
,)
sysadmin_roles
=
(
'RoleOfSysAdmin'
,)
class
App
(
Explicit
):
def
unrestrictedTraverse
(
self
,
path
):
ob
=
self
for
el
in
path
:
ob
=
getattr
(
ob
,
el
)
return
ob
class
PublicMethod
(
Method
):
def
getOwner
(
self
):
return
None
def
__call__
(
*
args
,
**
kw
):
return
args
,
kw
def
getWrappedOwner
(
self
):
return
None
__roles__
=
None
class
ProtectedMethod
(
PublicMethod
):
__roles__
=
user_roles
class
OwnedMethod
(
PublicMethod
):
__roles__
=
eo_roles
def
getOwner
(
self
):
return
self
.
aq_parent
.
aq_parent
.
acl_users
.
getUserById
(
'theowner'
)
def
getWrappedOwner
(
self
):
acl_users
=
self
.
aq_parent
.
aq_parent
.
acl_users
user
=
acl_users
.
getUserById
(
'theowner'
)
return
user
.
__of__
(
acl_users
)
class
setuidMethod
(
PublicMethod
):
_proxy_roles
=
sysadmin_roles
class
OwnedSetuidMethod
(
Implicit
):
__roles__
=
eo_roles
_proxy_roles
=
sysadmin_roles
def
getOwner
(
self
,
info
=
0
):
if
info
:
return
((
'subobject'
,
'acl_users'
),
'theowner'
)
else
:
return
self
.
aq_parent
.
aq_parent
.
acl_users
.
getUserById
(
'theowner'
)
def
getWrappedOwner
(
self
):
acl_users
=
self
.
aq_parent
.
aq_parent
.
acl_users
user
=
acl_users
.
getUserById
(
'theowner'
)
return
user
.
__of__
(
acl_users
)
class
DangerousMethod
(
PublicMethod
):
# Only accessible to sysadmin or people who use proxy roles
__roles__
=
sysadmin_roles
class
SimpleItemish
(
Implicit
):
public_m
=
PublicMethod
()
protected_m
=
ProtectedMethod
()
owned_m
=
OwnedMethod
()
setuid_m
=
setuidMethod
()
dangerous_m
=
DangerousMethod
()
public_prop
=
'Public Value'
private_prop
=
'Private Value'
class
ImplictAcqObject
(
Implicit
):
pass
class
UnprotectedSimpleItem
(
SimpleItemish
):
__allow_access_to_unprotected_subobjects__
=
1
class
UnprotectedSimpleItemBool
(
SimpleItemish
):
__allow_access_to_unprotected_subobjects__
=
True
class
OwnedSimpleItem
(
UnprotectedSimpleItem
):
def
getOwner
(
self
,
info
=
0
):
if
info
:
return
((
'subobject'
,
'acl_users'
),
'theowner'
)
else
:
return
self
.
aq_parent
.
acl_users
.
getuserById
(
'theowner'
)
class
RestrictedSimpleItem
(
SimpleItemish
):
__allow_access_to_unprotected_subobjects__
=
0
_Foo_Permission
=
user_roles
+
eo_roles
_Kill_Permission
=
sysadmin_roles
_View_Permission
=
eo_roles
class
PartlyProtectedSimpleItem1
(
SimpleItemish
):
__allow_access_to_unprotected_subobjects__
=
{
'public_prop'
:
1
,}
class
PartlyProtectedSimpleItem2
(
SimpleItemish
):
def
__allow_access_to_unprotected_subobjects__
(
self
,
name
,
value
):
if
name
==
'public_prop'
:
return
1
return
0
class
PartlyProtectedSimpleItem3
(
PartlyProtectedSimpleItem1
):
# Set the roles of objects that are accessible because of
# __allow_access_to_unprotected_subobjects__ .
__roles__
=
sysadmin_roles
class
SimpleClass
:
attr
=
1
class
ZopeSecurityPolicyTestBase
(
unittest
.
TestCase
):
def
setUp
(
self
):
a
=
App
()
self
.
a
=
a
a
.
item
=
UnprotectedSimpleItem
()
a
.
itemb
=
UnprotectedSimpleItemBool
()
self
.
item
=
a
.
item
a
.
r_item
=
RestrictedSimpleItem
()
a
.
item1
=
PartlyProtectedSimpleItem1
()
a
.
item2
=
PartlyProtectedSimpleItem2
()
a
.
item3
=
PartlyProtectedSimpleItem3
()
uf
=
UserFolder
()
a
.
acl_users
=
uf
self
.
uf
=
a
.
acl_users
uf
.
_doAddUser
(
'joe'
,
'password'
,
user_roles
,
())
uf
.
_doAddUser
(
'theowner'
,
'password'
,
eo_roles
,
())
user
=
uf
.
getUserById
(
'joe'
)
self
.
user
=
user
context
=
SecurityContext
(
user
)
self
.
context
=
context
self
.
policy
=
self
.
_makeOne
()
def
_makeOne
(
self
,
*
args
,
**
kw
):
return
self
.
_getTargetClass
()(
*
args
,
**
kw
)
def
assertPolicyAllows
(
self
,
ob
,
attrname
):
res
=
self
.
policy
.
validate
(
ob
,
ob
,
attrname
,
getattr
(
ob
,
attrname
),
self
.
context
)
if
not
res
:
self
.
fail
(
'Policy quietly denied %s'
%
attrname
)
def
assertPolicyDenies
(
self
,
ob
,
attrname
):
try
:
res
=
self
.
policy
.
validate
(
ob
,
ob
,
attrname
,
getattr
(
ob
,
attrname
),
self
.
context
)
except
Unauthorized
:
# Passed the test.
pass
else
:
if
res
:
self
.
fail
(
'Policy quietly allowed %s'
%
attrname
)
else
:
self
.
fail
(
'Policy denied %s, but did not '
'throw an exception.'
%
attrname
)
def
testUserAccess
(
self
):
item
=
self
.
item
self
.
assertPolicyAllows
(
item
,
'public_m'
)
self
.
assertPolicyAllows
(
item
,
'protected_m'
)
self
.
assertPolicyDenies
(
item
,
'owned_m'
)
self
.
assertPolicyAllows
(
item
,
'setuid_m'
)
self
.
assertPolicyDenies
(
item
,
'dangerous_m'
)
def
testOwnerAccess
(
self
):
self
.
context
=
SecurityContext
(
self
.
uf
.
getUserById
(
'theowner'
))
item
=
self
.
item
self
.
assertPolicyAllows
(
item
,
'public_m'
)
self
.
assertPolicyDenies
(
item
,
'protected_m'
)
self
.
assertPolicyAllows
(
item
,
'owned_m'
)
self
.
assertPolicyAllows
(
item
,
'setuid_m'
)
self
.
assertPolicyDenies
(
item
,
'dangerous_m'
)
def
testProxyAccess
(
self
):
item
=
self
.
item
self
.
context
.
stack
.
append
(
item
.
setuid_m
)
self
.
assertPolicyAllows
(
item
,
'public_m'
)
self
.
assertPolicyDenies
(
item
,
'protected_m'
)
self
.
assertPolicyDenies
(
item
,
'owned_m'
)
self
.
assertPolicyAllows
(
item
,
'setuid_m'
)
self
.
assertPolicyAllows
(
item
,
'dangerous_m'
)
def
testIdentityProxy
(
self
):
eo
=
ImplictAcqObject
()
eo
.
getOwner
=
lambda
:
None
self
.
context
.
stack
.
append
(
eo
)
rc
=
sys
.
getrefcount
(
eo
)
self
.
testUserAccess
()
self
.
assertEqual
(
rc
,
sys
.
getrefcount
(
eo
))
eo
.
_proxy_roles
=
()
self
.
testUserAccess
()
self
.
assertEqual
(
rc
,
sys
.
getrefcount
(
eo
))
def
testAccessToUnprotectedSubobjects
(
self
):
item
=
self
.
item
itemb
=
self
.
a
.
itemb
r_item
=
self
.
a
.
r_item
item1
=
self
.
a
.
item1
item2
=
self
.
a
.
item2
item3
=
self
.
a
.
item3
self
.
assertPolicyAllows
(
item
,
'public_prop'
)
self
.
assertPolicyAllows
(
itemb
,
'public_prop'
)
self
.
assertPolicyDenies
(
r_item
,
'public_prop'
)
self
.
assertPolicyAllows
(
item1
,
'public_prop'
)
self
.
assertPolicyAllows
(
item2
,
'public_prop'
)
self
.
assertPolicyDenies
(
item3
,
'public_prop'
)
self
.
assertPolicyAllows
(
item
,
'private_prop'
)
self
.
assertPolicyDenies
(
r_item
,
'private_prop'
)
self
.
assertPolicyDenies
(
item1
,
'private_prop'
)
self
.
assertPolicyDenies
(
item2
,
'private_prop'
)
self
.
assertPolicyDenies
(
item3
,
'private_prop'
)
def
testAccessToSimpleContainer
(
self
):
self
.
assertPolicyAllows
({},
'keys'
)
self
.
assertPolicyAllows
([],
'append'
)
self
.
assertPolicyDenies
(
SimpleClass
,
'attr'
)
self
.
assertPolicyDenies
(
SimpleClass
(),
'attr'
)
c
=
SimpleClass
()
c
.
attr
=
PublicMethod
()
self
.
assertPolicyAllows
(
c
,
'attr'
)
def
testUnicodeAttributeLookups
(
self
):
item
=
self
.
item
r_item
=
self
.
a
.
r_item
self
.
assertPolicyAllows
(
item
,
u'public_prop'
)
self
.
assertPolicyDenies
(
r_item
,
u'private_prop'
)
self
.
assertPolicyAllows
(
item
,
u'public_m'
)
self
.
assertPolicyDenies
(
item
,
u'dangerous_m'
)
def
testRolesForPermission
(
self
):
# Test of policy.checkPermission().
r_item
=
self
.
a
.
r_item
context
=
self
.
context
v
=
self
.
policy
.
checkPermission
(
'View'
,
r_item
,
context
)
self
.
assert_
(
not
v
,
'_View_Permission should deny access to user'
)
o_context
=
SecurityContext
(
self
.
uf
.
getUserById
(
'theowner'
))
v
=
self
.
policy
.
checkPermission
(
'View'
,
r_item
,
o_context
)
self
.
assert_
(
v
,
'_View_Permission should grant access to theowner'
)
def
test_checkPermission_respects_proxy_roles
(
self
):
r_item
=
self
.
a
.
r_item
context
=
self
.
context
self
.
failIf
(
self
.
policy
.
checkPermission
(
'View'
,
r_item
,
context
))
o_context
=
SecurityContext
(
self
.
uf
.
getUserById
(
'joe'
))
# Push an executable with proxy roles on the stack
eo
=
OwnedSetuidMethod
().
__of__
(
r_item
)
eo
.
_proxy_roles
=
eo_roles
context
.
stack
.
append
(
eo
)
self
.
failUnless
(
self
.
policy
.
checkPermission
(
'View'
,
r_item
,
context
))
def
test_checkPermission_proxy_roles_limit_access
(
self
):
r_item
=
self
.
a
.
r_item
context
=
self
.
context
self
.
failUnless
(
self
.
policy
.
checkPermission
(
'Foo'
,
r_item
,
context
))
o_context
=
SecurityContext
(
self
.
uf
.
getUserById
(
'joe'
))
# Push an executable with proxy roles on the stack
eo
=
OwnedSetuidMethod
().
__of__
(
r_item
)
eo
.
_proxy_roles
=
sysadmin_roles
context
.
stack
.
append
(
eo
)
self
.
failIf
(
self
.
policy
.
checkPermission
(
'Foo'
,
r_item
,
context
))
def
test_checkPermission_proxy_role_scope
(
self
):
self
.
a
.
subobject
=
ImplictAcqObject
()
subobject
=
self
.
a
.
subobject
subobject
.
acl_users
=
UserFolder
()
subobject
.
acl_users
.
_doAddUser
(
'theowner'
,
'password'
,
eo_roles
+
sysadmin_roles
,
())
subobject
.
r_item
=
RestrictedSimpleItem
()
r_subitem
=
subobject
.
r_item
r_subitem
.
owned_setuid_m
=
OwnedSetuidMethod
()
r_subitem
.
getPhysicalRoot
=
lambda
root
=
self
.
a
:
root
r_item
=
self
.
a
.
r_item
r_item
.
getPhysicalRoot
=
lambda
root
=
self
.
a
:
root
context
=
self
.
context
context
.
stack
.
append
(
r_subitem
.
owned_setuid_m
.
__of__
(
r_subitem
))
# Out of owner context
self
.
failIf
(
self
.
policy
.
checkPermission
(
'View'
,
r_item
,
context
))
self
.
failIf
(
self
.
policy
.
checkPermission
(
'Kill'
,
r_item
,
context
))
# Inside owner context
self
.
failIf
(
self
.
policy
.
checkPermission
(
'View'
,
r_subitem
,
context
))
self
.
failUnless
(
self
.
policy
.
checkPermission
(
'Kill'
,
r_subitem
,
context
))
def
testUnicodeRolesForPermission
(
self
):
r_item
=
self
.
a
.
r_item
context
=
self
.
context
v
=
self
.
policy
.
checkPermission
(
u'View'
,
r_item
,
context
)
self
.
assert_
(
not
v
,
'_View_Permission should deny access to user'
)
o_context
=
SecurityContext
(
self
.
uf
.
getUserById
(
'theowner'
))
v
=
self
.
policy
.
checkPermission
(
u'View'
,
r_item
,
o_context
)
self
.
assert_
(
v
,
'_View_Permission should grant access to theowner'
)
def
testAqNames
(
self
):
policy
=
self
.
policy
names
=
{
'aq_self'
:
0
,
'aq_base'
:
0
,
'aq_parent'
:
1
,
'aq_explicit'
:
1
,
'aq_inner'
:
1
}
for
name
,
allowed
in
names
.
items
():
if
not
allowed
:
self
.
assertRaises
(
Unauthorized
,
policy
.
validate
,
''
,
''
,
name
,
''
,
None
)
else
:
policy
.
validate
(
''
,
''
,
name
,
''
,
None
)
def
testProxyRoleScope
(
self
):
self
.
a
.
subobject
=
ImplictAcqObject
()
subobject
=
self
.
a
.
subobject
subobject
.
acl_users
=
UserFolder
()
subobject
.
acl_users
.
_doAddUser
(
'theowner'
,
'password'
,
eo_roles
+
sysadmin_roles
,
())
subobject
.
item
=
UnprotectedSimpleItem
()
subitem
=
subobject
.
item
subitem
.
owned_setuid_m
=
OwnedSetuidMethod
()
subitem
.
getPhysicalRoot
=
lambda
root
=
self
.
a
:
root
item
=
self
.
a
.
item
item
.
getPhysicalRoot
=
lambda
root
=
self
.
a
:
root
self
.
context
.
stack
.
append
(
subitem
.
owned_setuid_m
.
__of__
(
subitem
))
# Out of owner context
self
.
assertPolicyAllows
(
item
,
'public_m'
)
self
.
assertPolicyDenies
(
item
,
'protected_m'
)
self
.
assertPolicyDenies
(
item
,
'owned_m'
)
self
.
assertPolicyAllows
(
item
,
'setuid_m'
)
self
.
assertPolicyDenies
(
item
,
'dangerous_m'
)
# Inside owner context
self
.
assertPolicyAllows
(
subitem
,
'public_m'
)
self
.
assertPolicyDenies
(
subitem
,
'protected_m'
)
self
.
assertPolicyDenies
(
subitem
,
'owned_m'
)
self
.
assertPolicyAllows
(
subitem
,
'setuid_m'
)
self
.
assertPolicyAllows
(
subitem
,
'dangerous_m'
)
def
testUnicodeName
(
self
):
policy
=
self
.
policy
assert
policy
.
validate
(
''
,
''
,
u'foo'
,
''
,
None
)
if
0
:
# This test purposely generates a log entry.
# Enable it if you don't mind it adding to the log.
def
testInsaneRoles
(
self
):
# Makes sure the policy doesn't blow up on bad input.
c
=
SimpleClass
()
m
=
PublicMethod
()
c
.
m
=
m
# Test good roles
self
.
assertPolicyAllows
(
c
,
'm'
)
# Test bad roles
m
.
__roles__
=
1950
try
:
self
.
assertPolicyAllows
(
c
,
'm'
)
except
TypeError
:
pass
else
:
self
.
fail
(
'Policy accepted bad __roles__'
)
class
ISecurityPolicyConformance
:
def
test_conforms_to_ISecurityPolicy
(
self
):
from
AccessControl.interfaces
import
ISecurityPolicy
from
zope.interface.verify
import
verifyClass
verifyClass
(
ISecurityPolicy
,
self
.
_getTargetClass
())
class
Python_ZSPTests
(
ZopeSecurityPolicyTestBase
,
ISecurityPolicyConformance
,
):
def
_getTargetClass
(
self
):
from
AccessControl.ImplPython
import
ZopeSecurityPolicy
return
ZopeSecurityPolicy
class
C_ZSPTests
(
ZopeSecurityPolicyTestBase
,
ISecurityPolicyConformance
,
):
def
_getTargetClass
(
self
):
from
AccessControl.ImplC
import
ZopeSecurityPolicy
return
ZopeSecurityPolicy
def
test_getRoles
():
"""
>>> from AccessControl.ZopeSecurityPolicy import getRoles
>>> class C:
... x = 'CRole'
>>> class V:
... x = 'VRole'
>>> c = C()
>>> c.v = V()
>>> getRoles(c, None, c.v, 42)
42
>>> getRoles(c, 'inabox', c.v, 42)
42
>>> c.v.__roles__ = ['spam', 'eggs']
>>> getRoles(c, None, c.v, 42)
['spam', 'eggs']
>>> getRoles(c, 'withafox', c.v, 42)
['spam', 'eggs']
>>> del c.v.__roles__
>>> V.__roles__ = ('Manager', )
>>> getRoles(c, None, c.v, 42)
('Manager',)
>>> getRoles(c, 'withafox', c.v, 42)
('Manager',)
>>> del V.__roles__
>>> c.foo__roles__ = ('Foo', )
>>> getRoles(c, None, c.v, 42)
42
>>> getRoles(c, 'foo', c.v, 42)
42
>>> C.foo__roles__ = ('Editor', )
>>> getRoles(c, None, c.v, 42)
42
>>> getRoles(c, 'foo', c.v, 42)
('Editor',)
>>> del C.foo__roles__
>>> class ComputedRoles:
... def __init__(self, roles):
... self.roles = roles
... def rolesForPermissionOn(self, ob):
... return [ob.x] + self.roles
>>> c.v.__roles__ = ComputedRoles(['Member'])
>>> getRoles(c, None, c.v, 42)
['VRole', 'Member']
>>> getRoles(c, 'foo', c.v, 42)
['VRole', 'Member']
>>> c.foo__roles__ = ComputedRoles(['Admin'])
>>> getRoles(c, None, c.v, 42)
['VRole', 'Member']
>>> getRoles(c, 'foo', c.v, 42)
['VRole', 'Member']
>>> del c.v.__roles__
>>> getRoles(c, None, c.v, 42)
42
>>> getRoles(c, 'foo', c.v, 42)
42
>>> C.foo__roles__ = ComputedRoles(['Guest'])
>>> getRoles(c, None, c.v, 42)
42
>>> getRoles(c, 'foo', c.v, 42)
['CRole', 'Guest']
>>> V.__roles__ = ComputedRoles(['Member'])
>>> getRoles(c, None, c.v, 42)
['VRole', 'Member']
>>> getRoles(c, 'foo', c.v, 42)
['VRole', 'Member']
"""
def
test_zsp_gets_right_roles_for_methods
():
"""
>>> from AccessControl.ZopeSecurityPolicy import ZopeSecurityPolicy
>>> zsp = ZopeSecurityPolicy()
>>> from ExtensionClass import Base
>>> class C(Base):
... def foo(self):
... pass
... foo__roles__ = ['greeneggs', 'ham']
... def bar(self):
... pass
>>> class User:
... def __init__(self, roles):
... self.roles = roles
... def allowed(self, value, roles):
... for role in roles:
... if role in self.roles:
... return True
... return False
>>> class Context:
... stack = ()
... def __init__(self, user):
... self.user = user
>>> c = C()
>>> bool(zsp.validate(c, c, 'foo', c.foo, Context(User(['greeneggs']))))
True
>>> zsp.validate(c, c, 'foo', c.foo, Context(User(['spam'])))
Traceback (most recent call last):
...
Unauthorized: You are not allowed to access 'foo' in this context
>>> c.__roles__ = ['spam']
>>> zsp.validate(c, c, 'foo', c.foo, Context(User(['spam'])))
Traceback (most recent call last):
...
Unauthorized: You are not allowed to access 'foo' in this context
>>> zsp.validate(c, c, 'bar', c.bar, Context(User(['spam'])))
Traceback (most recent call last):
...
Unauthorized: You are not allowed to access 'bar' in this context
>>> c.__allow_access_to_unprotected_subobjects__ = 1
>>> bool(zsp.validate(c, c, 'bar', c.bar, Context(User(['spam']))))
True
"""
from
doctest
import
DocTestSuite
def
test_suite
():
suite
=
unittest
.
TestSuite
()
suite
.
addTest
(
unittest
.
makeSuite
(
Python_ZSPTests
,
'test'
))
suite
.
addTest
(
unittest
.
makeSuite
(
C_ZSPTests
,
'test'
))
suite
.
addTest
(
DocTestSuite
())
return
suite
src/AccessControl/tests/test_requestmethod.py
deleted
100644 → 0
View file @
ccc10355
#############################################################################
#
# Copyright (c) 2007 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
#
##############################################################################
from
zope.interface
import
implements
from
zope.publisher.interfaces.browser
import
IBrowserRequest
class
DummyRequest
:
implements
(
IBrowserRequest
)
def
__init__
(
self
,
method
):
self
.
method
=
method
def
test_suite
():
from
doctest
import
DocFileSuite
return
DocFileSuite
(
'../requestmethod.txt'
,
globs
=
dict
(
GET
=
DummyRequest
(
'GET'
),
POST
=
DummyRequest
(
'POST'
)))
if
__name__
==
'__main__'
:
import
unittest
unittest
.
main
(
defaultTest
=
'test_suite'
)
src/AccessControl/tests/test_safeiter.py
deleted
100644 → 0
View file @
ccc10355
##############################################################################
#
# 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.
#
##############################################################################
"""Tests for the guarded iterartor.
"""
import
unittest
# Persistence system must be initialized.
import
ZODB
from
AccessControl
import
ZopeGuards
class
SafeIterTestCase
(
unittest
.
TestCase
):
# XXX these tests replace the global guard() function in
# AccessControl.ZopeGuards; this is not the nicest way to check
# that things work, but avoids making the SafeIter unit tests from
# testing things other than the guarded iterator itself. In
# particular, it avoids testing the actual guard checks, which
# should be tested separately.
def
setUp
(
self
):
self
.
original_guard
=
ZopeGuards
.
guard
ZopeGuards
.
guard
=
self
.
guard
self
.
checks
=
[]
def
tearDown
(
self
):
ZopeGuards
.
guard
=
self
.
original_guard
def
guard
(
self
,
container
,
value
,
index
=
None
):
self
.
checks
.
append
((
id
(
container
),
value
))
def
test_iteration
(
self
):
seq
=
[
1
,
2
,
3
]
seqid
=
id
(
seq
)
it
=
ZopeGuards
.
SafeIter
(
seq
)
self
.
assertEqual
(
list
(
it
),
seq
)
self
.
assertEqual
(
self
.
checks
,
[(
seqid
,
1
),
(
seqid
,
2
),
(
seqid
,
3
)])
def
test_iteration_with_container
(
self
):
seq
=
[
1
,
2
,
3
]
container
=
object
()
contid
=
id
(
container
)
it
=
ZopeGuards
.
SafeIter
(
seq
,
container
)
self
.
assertEqual
(
list
(
it
),
seq
)
self
.
assertEqual
(
self
.
checks
,
[(
contid
,
1
),
(
contid
,
2
),
(
contid
,
3
)])
def
test_suite
():
return
unittest
.
makeSuite
(
SafeIterTestCase
)
src/AccessControl/tests/test_tainted.py
deleted
100644 → 0
View file @
ccc10355
##############################################################################
#
# 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.
#
##############################################################################
""" TaintedString tests.
"""
import
unittest
class
TestTaintedString
(
unittest
.
TestCase
):
def
setUp
(
self
):
self
.
unquoted
=
'<test attr="&">'
self
.
quoted
=
'<test attr="&">'
self
.
tainted
=
self
.
_getClass
()(
self
.
unquoted
)
def
_getClass
(
self
):
from
AccessControl.tainted
import
TaintedString
return
TaintedString
def
testStr
(
self
):
self
.
assertEquals
(
str
(
self
.
tainted
),
self
.
unquoted
)
def
testRepr
(
self
):
self
.
assertEquals
(
repr
(
self
.
tainted
),
repr
(
self
.
quoted
))
def
testCmp
(
self
):
self
.
assertEquals
(
cmp
(
self
.
tainted
,
self
.
unquoted
),
0
)
self
.
assertEquals
(
cmp
(
self
.
tainted
,
'a'
),
-
1
)
self
.
assertEquals
(
cmp
(
self
.
tainted
,
'.'
),
1
)
def
testHash
(
self
):
hash
=
{}
hash
[
self
.
tainted
]
=
self
.
quoted
hash
[
self
.
unquoted
]
=
self
.
unquoted
self
.
assertEquals
(
hash
[
self
.
tainted
],
self
.
unquoted
)
def
testLen
(
self
):
self
.
assertEquals
(
len
(
self
.
tainted
),
len
(
self
.
unquoted
))
def
testGetItem
(
self
):
self
.
assert_
(
isinstance
(
self
.
tainted
[
0
],
self
.
_getClass
()))
self
.
assertEquals
(
self
.
tainted
[
0
],
'<'
)
self
.
failIf
(
isinstance
(
self
.
tainted
[
-
1
],
self
.
_getClass
()))
self
.
assertEquals
(
self
.
tainted
[
-
1
],
'>'
)
def
testGetSlice
(
self
):
self
.
assert_
(
isinstance
(
self
.
tainted
[
0
:
1
],
self
.
_getClass
()))
self
.
assertEquals
(
self
.
tainted
[
0
:
1
],
'<'
)
self
.
failIf
(
isinstance
(
self
.
tainted
[
1
:],
self
.
_getClass
()))
self
.
assertEquals
(
self
.
tainted
[
1
:],
self
.
unquoted
[
1
:])
def
testConcat
(
self
):
self
.
assert_
(
isinstance
(
self
.
tainted
+
'test'
,
self
.
_getClass
()))
self
.
assertEquals
(
self
.
tainted
+
'test'
,
self
.
unquoted
+
'test'
)
self
.
assert_
(
isinstance
(
'test'
+
self
.
tainted
,
self
.
_getClass
()))
self
.
assertEquals
(
'test'
+
self
.
tainted
,
'test'
+
self
.
unquoted
)
def
testMultiply
(
self
):
self
.
assert_
(
isinstance
(
2
*
self
.
tainted
,
self
.
_getClass
()))
self
.
assertEquals
(
2
*
self
.
tainted
,
2
*
self
.
unquoted
)
self
.
assert_
(
isinstance
(
self
.
tainted
*
2
,
self
.
_getClass
()))
self
.
assertEquals
(
self
.
tainted
*
2
,
self
.
unquoted
*
2
)
def
testInterpolate
(
self
):
tainted
=
self
.
_getClass
()(
'<%s>'
)
self
.
assert_
(
isinstance
(
tainted
%
'foo'
,
self
.
_getClass
()))
self
.
assertEquals
(
tainted
%
'foo'
,
'<foo>'
)
tainted
=
self
.
_getClass
()(
'<%s attr="%s">'
)
self
.
assert_
(
isinstance
(
tainted
%
(
'foo'
,
'bar'
),
self
.
_getClass
()))
self
.
assertEquals
(
tainted
%
(
'foo'
,
'bar'
),
'<foo attr="bar">'
)
def
testStringMethods
(
self
):
simple
=
"capitalize isalpha isdigit islower isspace istitle isupper"
\
" lower lstrip rstrip strip swapcase upper"
.
split
()
returnsTainted
=
"capitalize lower lstrip rstrip strip swapcase upper"
returnsTainted
=
returnsTainted
.
split
()
unquoted
=
'
\
t
This is a test '
tainted
=
self
.
_getClass
()(
unquoted
)
for
f
in
simple
:
v
=
getattr
(
tainted
,
f
)()
self
.
assertEquals
(
v
,
getattr
(
unquoted
,
f
)())
if
f
in
returnsTainted
:
self
.
assert_
(
isinstance
(
v
,
self
.
_getClass
()))
else
:
self
.
failIf
(
isinstance
(
v
,
self
.
_getClass
()))
optArg
=
"lstrip rstrip strip"
.
split
()
for
f
in
optArg
:
v
=
getattr
(
tainted
,
f
)(
" "
)
self
.
assertEquals
(
v
,
getattr
(
unquoted
,
f
)(
" "
))
self
.
assert_
(
isinstance
(
v
,
self
.
_getClass
()))
justify
=
"center ljust rjust"
.
split
()
for
f
in
justify
:
v
=
getattr
(
tainted
,
f
)(
30
)
self
.
assertEquals
(
v
,
getattr
(
unquoted
,
f
)(
30
))
self
.
assert_
(
isinstance
(
v
,
self
.
_getClass
()))
searches
=
"find index rfind rindex endswith startswith"
.
split
()
searchraises
=
"index rindex"
.
split
()
for
f
in
searches
:
v
=
getattr
(
tainted
,
f
)(
'test'
)
self
.
assertEquals
(
v
,
getattr
(
unquoted
,
f
)(
'test'
))
if
f
in
searchraises
:
self
.
assertRaises
(
ValueError
,
getattr
(
tainted
,
f
),
'nada'
)
self
.
assertEquals
(
tainted
.
count
(
'test'
,
1
,
-
1
),
unquoted
.
count
(
'test'
,
1
,
-
1
))
self
.
assertEquals
(
tainted
.
encode
(),
unquoted
.
encode
())
self
.
assert_
(
isinstance
(
tainted
.
encode
(),
self
.
_getClass
()))
self
.
assertEquals
(
tainted
.
expandtabs
(
10
),
unquoted
.
expandtabs
(
10
))
self
.
assert_
(
isinstance
(
tainted
.
expandtabs
(),
self
.
_getClass
()))
self
.
assertEquals
(
tainted
.
replace
(
'test'
,
'spam'
),
unquoted
.
replace
(
'test'
,
'spam'
))
self
.
assert_
(
isinstance
(
tainted
.
replace
(
'test'
,
'<'
),
self
.
_getClass
()))
self
.
failIf
(
isinstance
(
tainted
.
replace
(
'test'
,
'spam'
),
self
.
_getClass
()))
self
.
assertEquals
(
tainted
.
split
(),
unquoted
.
split
())
for
part
in
self
.
_getClass
()(
'< < <'
).
split
():
self
.
assert_
(
isinstance
(
part
,
self
.
_getClass
()))
for
part
in
tainted
.
split
():
self
.
failIf
(
isinstance
(
part
,
self
.
_getClass
()))
multiline
=
'test
\
n
<tainted>'
lines
=
self
.
_getClass
()(
multiline
).
split
()
self
.
assertEquals
(
lines
,
multiline
.
split
())
self
.
assert_
(
isinstance
(
lines
[
1
],
self
.
_getClass
()))
self
.
failIf
(
isinstance
(
lines
[
0
],
self
.
_getClass
()))
transtable
=
''
.
join
(
map
(
chr
,
range
(
256
)))
self
.
assertEquals
(
tainted
.
translate
(
transtable
),
unquoted
.
translate
(
transtable
))
self
.
assert_
(
isinstance
(
self
.
_getClass
()(
'<'
).
translate
(
transtable
),
self
.
_getClass
()))
self
.
failIf
(
isinstance
(
self
.
_getClass
()(
'<'
).
translate
(
transtable
,
'<'
),
self
.
_getClass
()))
def
testQuoted
(
self
):
self
.
assertEquals
(
self
.
tainted
.
quoted
(),
self
.
quoted
)
def
test_suite
():
suite
=
unittest
.
TestSuite
()
suite
.
addTest
(
unittest
.
makeSuite
(
TestTaintedString
))
return
suite
src/AccessControl/tests/test_userfolder.py
deleted
100644 → 0
View file @
ccc10355
##############################################################################
#
# 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.
#
##############################################################################
""" Unit tests for AccessControl.User
"""
import
unittest
# TODO class Test_readUserAccessFile(unittest.TestCase)
# TODO class BasicUserFoldertests(unittest.TestCase)
class
UserFolderTests
(
unittest
.
TestCase
):
def
setUp
(
self
):
import
transaction
transaction
.
begin
()
def
tearDown
(
self
):
import
transaction
from
AccessControl.SecurityManagement
import
noSecurityManager
noSecurityManager
()
transaction
.
abort
()
def
_getTargetClass
(
self
):
from
AccessControl.userfolder
import
UserFolder
return
UserFolder
def
_makeOne
(
self
):
uf
=
self
.
_getTargetClass
()()
uf
.
_doAddUser
(
'user1'
,
'secret'
,
[
'role1'
],
[])
return
uf
def
_makeBasicAuthToken
(
self
,
creds
=
'user1:secret'
):
import
base64
return
'Basic %s'
%
base64
.
encodestring
(
creds
)
def
_login
(
self
,
uf
,
name
):
from
AccessControl.SecurityManagement
import
newSecurityManager
user
=
uf
.
getUserById
(
name
)
user
=
user
.
__of__
(
uf
)
newSecurityManager
(
None
,
user
)
def
test_class_conforms_to_IStandardUserFolder
(
self
):
from
AccessControl.interfaces
import
IStandardUserFolder
from
zope.interface.verify
import
verifyClass
verifyClass
(
IStandardUserFolder
,
self
.
_getTargetClass
())
def
testGetUser
(
self
):
uf
=
self
.
_makeOne
()
self
.
failIfEqual
(
uf
.
getUser
(
'user1'
),
None
)
def
testGetBadUser
(
self
):
uf
=
self
.
_makeOne
()
self
.
assertEqual
(
uf
.
getUser
(
'user2'
),
None
)
def
testGetUserById
(
self
):
uf
=
self
.
_makeOne
()
self
.
failIfEqual
(
uf
.
getUserById
(
'user1'
),
None
)
def
testGetBadUserById
(
self
):
uf
=
self
.
_makeOne
()
self
.
assertEqual
(
uf
.
getUserById
(
'user2'
),
None
)
def
testGetUsers
(
self
):
uf
=
self
.
_makeOne
()
users
=
uf
.
getUsers
()
self
.
failUnless
(
users
)
self
.
assertEqual
(
users
[
0
].
getUserName
(),
'user1'
)
def
testGetUserNames
(
self
):
uf
=
self
.
_makeOne
()
names
=
uf
.
getUserNames
()
self
.
failUnless
(
names
)
self
.
assertEqual
(
names
[
0
],
'user1'
)
def
testIdentify
(
self
):
uf
=
self
.
_makeOne
()
name
,
password
=
uf
.
identify
(
self
.
_makeBasicAuthToken
())
self
.
assertEqual
(
name
,
'user1'
)
self
.
assertEqual
(
password
,
'secret'
)
def
testGetRoles
(
self
):
uf
=
self
.
_makeOne
()
user
=
uf
.
getUser
(
'user1'
)
self
.
failUnless
(
'role1'
in
user
.
getRoles
())
def
testMaxListUsers
(
self
):
# create a folder-ish thing which contains a roleManager,
# then put an acl_users object into the folde-ish thing
from
AccessControl.userfolder
import
BasicUserFolder
class
Folderish
(
BasicUserFolder
):
def
__init__
(
self
,
size
,
count
):
self
.
maxlistusers
=
size
self
.
users
=
[]
self
.
acl_users
=
self
self
.
__allow_groups__
=
self
for
i
in
xrange
(
count
):
self
.
users
.
append
(
"Nobody"
)
def
getUsers
(
self
):
return
self
.
users
def
user_names
(
self
):
return
self
.
getUsers
()
tinyFolderOver
=
Folderish
(
15
,
20
)
tinyFolderUnder
=
Folderish
(
15
,
10
)
assert
tinyFolderOver
.
maxlistusers
==
15
assert
tinyFolderUnder
.
maxlistusers
==
15
assert
len
(
tinyFolderOver
.
user_names
())
==
20
assert
len
(
tinyFolderUnder
.
user_names
())
==
10
try
:
list
=
tinyFolderOver
.
get_valid_userids
()
assert
0
,
"Did not raise overflow error"
except
OverflowError
:
pass
try
:
list
=
tinyFolderUnder
.
get_valid_userids
()
pass
except
OverflowError
:
assert
0
,
"Raised overflow error erroneously"
def
test__doAddUser_with_not_yet_encrypted_passwords
(
self
):
# See collector #1869 && #1926
from
AccessControl.AuthEncoding
import
pw_validate
USER_ID
=
'not_yet_encrypted'
PASSWORD
=
'password'
uf
=
self
.
_makeOne
()
uf
.
encrypt_passwords
=
True
self
.
failIf
(
uf
.
_isPasswordEncrypted
(
PASSWORD
))
uf
.
_doAddUser
(
USER_ID
,
PASSWORD
,
[],
[])
user
=
uf
.
getUserById
(
USER_ID
)
self
.
failUnless
(
uf
.
_isPasswordEncrypted
(
user
.
__
))
self
.
failUnless
(
pw_validate
(
user
.
__
,
PASSWORD
))
def
test__doAddUser_with_preencrypted_passwords
(
self
):
# See collector #1869 && #1926
from
AccessControl.AuthEncoding
import
pw_validate
USER_ID
=
'already_encrypted'
PASSWORD
=
'password'
uf
=
self
.
_makeOne
()
uf
.
encrypt_passwords
=
True
ENCRYPTED
=
uf
.
_encryptPassword
(
PASSWORD
)
uf
.
_doAddUser
(
USER_ID
,
ENCRYPTED
,
[],
[])
user
=
uf
.
getUserById
(
USER_ID
)
self
.
assertEqual
(
user
.
__
,
ENCRYPTED
)
self
.
failUnless
(
uf
.
_isPasswordEncrypted
(
user
.
__
))
self
.
failUnless
(
pw_validate
(
user
.
__
,
PASSWORD
))
def
test_suite
():
suite
=
unittest
.
TestSuite
()
suite
.
addTest
(
unittest
.
makeSuite
(
UserFolderTests
))
return
suite
src/AccessControl/tests/test_users.py
deleted
100644 → 0
View file @
ccc10355
##############################################################################
#
# 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.
#
##############################################################################
""" Unit tests for AccessControl.User
"""
import
unittest
class
BasicUserTests
(
unittest
.
TestCase
):
def
_getTargetClass
(
self
):
from
AccessControl.users
import
BasicUser
return
BasicUser
def
_makeOne
(
self
,
name
,
password
,
roles
,
domains
):
return
self
.
_getTargetClass
()(
name
,
password
,
roles
,
domains
)
def
_makeDerived
(
self
,
**
kw
):
class
Derived
(
self
.
_getTargetClass
()):
def
__init__
(
self
,
**
kw
):
self
.
name
=
'name'
self
.
password
=
'password'
self
.
roles
=
[
'Manager'
]
self
.
domains
=
[]
self
.
__dict__
.
update
(
kw
)
return
Derived
(
**
kw
)
def
test_ctor_is_abstract
(
self
):
# Subclasses must override __init__, and mustn't call the base version.
self
.
assertRaises
(
NotImplementedError
,
self
.
_makeOne
,
'name'
,
'password'
,
[
'Manager'
],
[])
def
test_abstract_methods
(
self
):
# Subclasses must override these methods.
derived
=
self
.
_makeDerived
()
self
.
assertRaises
(
NotImplementedError
,
derived
.
getUserName
)
self
.
assertRaises
(
NotImplementedError
,
derived
.
getId
)
self
.
assertRaises
(
NotImplementedError
,
derived
.
_getPassword
)
self
.
assertRaises
(
NotImplementedError
,
derived
.
getRoles
)
self
.
assertRaises
(
NotImplementedError
,
derived
.
getDomains
)
# TODO: def test_getRolesInContext (w/wo local, callable, aq)
# TODO: def test_authenticate (w/wo domains)
# TODO: def test_allowed (...)
# TODO: def test_has_role (w/wo str, context)
# TODO: def test_has_permission (w/wo str)
def
test___len__
(
self
):
derived
=
self
.
_makeDerived
()
self
.
assertEqual
(
len
(
derived
),
1
)
def
test___str__
(
self
):
derived
=
self
.
_makeDerived
(
getUserName
=
lambda
:
'phred'
)
self
.
assertEqual
(
str
(
derived
),
'phred'
)
def
test___repr__
(
self
):
derived
=
self
.
_makeDerived
(
getUserName
=
lambda
:
'phred'
)
self
.
assertEqual
(
repr
(
derived
),
"<Derived 'phred'>"
)
class
SimpleUserTests
(
unittest
.
TestCase
):
def
_getTargetClass
(
self
):
from
AccessControl.users
import
SimpleUser
return
SimpleUser
def
_makeOne
(
self
,
name
=
'admin'
,
password
=
'123'
,
roles
=
None
,
domains
=
None
):
if
roles
is
None
:
roles
=
[
'Manager'
]
if
domains
is
None
:
domains
=
[]
return
self
.
_getTargetClass
()(
name
,
password
,
roles
,
domains
)
def
test_overrides
(
self
):
simple
=
self
.
_makeOne
()
self
.
assertEqual
(
simple
.
getUserName
(),
'admin'
)
self
.
assertEqual
(
simple
.
getId
(),
'admin'
)
self
.
assertEqual
(
simple
.
_getPassword
(),
'123'
)
self
.
assertEqual
(
simple
.
getDomains
(),
())
def
test_getRoles_anonymous
(
self
):
simple
=
self
.
_makeOne
(
'Anonymous User'
,
roles
=
())
self
.
assertEqual
(
simple
.
getRoles
(),
())
def
test_getRoles_non_anonymous
(
self
):
simple
=
self
.
_makeOne
(
'phred'
,
roles
=
())
self
.
assertEqual
(
simple
.
getRoles
(),
(
'Authenticated'
,))
def
test___repr__
(
self
):
special
=
self
.
_makeOne
()
self
.
assertEqual
(
repr
(
special
),
"<SimpleUser 'admin'>"
)
class
SpecialUserTests
(
unittest
.
TestCase
):
def
_getTargetClass
(
self
):
from
AccessControl.users
import
SpecialUser
return
SpecialUser
def
_makeOne
(
self
,
name
=
'admin'
,
password
=
'123'
,
roles
=
None
,
domains
=
None
):
if
roles
is
None
:
roles
=
[
'Manager'
]
if
domains
is
None
:
domains
=
[]
return
self
.
_getTargetClass
()(
name
,
password
,
roles
,
domains
)
def
test_overrides
(
self
):
special
=
self
.
_makeOne
()
self
.
assertEqual
(
special
.
getUserName
(),
'admin'
)
self
.
assertEqual
(
special
.
getId
(),
None
)
self
.
assertEqual
(
special
.
_getPassword
(),
'123'
)
self
.
assertEqual
(
special
.
getDomains
(),
())
def
test___repr__
(
self
):
special
=
self
.
_makeOne
()
self
.
assertEqual
(
repr
(
special
),
"<SpecialUser 'admin'>"
)
class
UnrestrictedUserTests
(
unittest
.
TestCase
):
def
_getTargetClass
(
self
):
from
AccessControl.users
import
UnrestrictedUser
return
UnrestrictedUser
def
_makeOne
(
self
,
name
=
'admin'
,
password
=
'123'
,
roles
=
None
,
domains
=
None
):
if
roles
is
None
:
roles
=
[
'Manager'
]
if
domains
is
None
:
domains
=
[]
return
self
.
_getTargetClass
()(
name
,
password
,
roles
,
domains
)
def
test_allowed__what_not_even_god_should_do
(
self
):
from
AccessControl.PermissionRole
import
_what_not_even_god_should_do
unrestricted
=
self
.
_makeOne
()
self
.
failIf
(
unrestricted
.
allowed
(
self
,
_what_not_even_god_should_do
))
def
test_allowed_empty
(
self
):
unrestricted
=
self
.
_makeOne
()
self
.
failUnless
(
unrestricted
.
allowed
(
self
,
()))
def
test_allowed_other
(
self
):
unrestricted
=
self
.
_makeOne
()
self
.
failUnless
(
unrestricted
.
allowed
(
self
,
(
'Manager'
,)))
def
test_has_role_empty_no_object
(
self
):
unrestricted
=
self
.
_makeOne
()
self
.
failUnless
(
unrestricted
.
has_role
(()))
def
test_has_role_empty_w_object
(
self
):
unrestricted
=
self
.
_makeOne
()
self
.
failUnless
(
unrestricted
.
has_role
((),
self
))
def
test_has_role_other_no_object
(
self
):
unrestricted
=
self
.
_makeOne
()
self
.
failUnless
(
unrestricted
.
has_role
((
'Manager'
,)))
def
test_has_role_other_w_object
(
self
):
unrestricted
=
self
.
_makeOne
()
self
.
failUnless
(
unrestricted
.
has_role
((
'Manager'
,),
self
))
def
test___repr__
(
self
):
unrestricted
=
self
.
_makeOne
()
self
.
assertEqual
(
repr
(
unrestricted
),
"<UnrestrictedUser 'admin'>"
)
class
NullUnrestrictedUserTests
(
unittest
.
TestCase
):
def
_getTargetClass
(
self
):
from
AccessControl.users
import
NullUnrestrictedUser
return
NullUnrestrictedUser
def
_makeOne
(
self
):
return
self
.
_getTargetClass
()()
def
test_overrides
(
self
):
simple
=
self
.
_makeOne
()
self
.
assertEqual
(
simple
.
getUserName
(),
(
None
,
None
))
self
.
assertEqual
(
simple
.
getId
(),
None
)
self
.
assertEqual
(
simple
.
_getPassword
(),
(
None
,
None
))
self
.
assertEqual
(
simple
.
getRoles
(),
())
self
.
assertEqual
(
simple
.
getDomains
(),
())
def
test_getRolesInContext
(
self
):
null
=
self
.
_makeOne
()
self
.
assertEqual
(
null
.
getRolesInContext
(
self
),
())
def
test_authenticate
(
self
):
null
=
self
.
_makeOne
()
self
.
failIf
(
null
.
authenticate
(
'password'
,
{}))
def
test_allowed
(
self
):
null
=
self
.
_makeOne
()
self
.
failIf
(
null
.
allowed
(
self
,
()))
def
test_has_role
(
self
):
null
=
self
.
_makeOne
()
self
.
failIf
(
null
.
has_role
(
'Authenticated'
))
def
test_has_role_w_object
(
self
):
null
=
self
.
_makeOne
()
self
.
failIf
(
null
.
has_role
(
'Authenticated'
,
self
))
def
test_has_permission
(
self
):
null
=
self
.
_makeOne
()
self
.
failIf
(
null
.
has_permission
(
'View'
,
self
))
def
test___repr__
(
self
):
null
=
self
.
_makeOne
()
self
.
assertEqual
(
repr
(
null
),
"<NullUnrestrictedUser (None, None)>"
)
def
test___str__
(
self
):
# See https://bugs.launchpad.net/zope2/+bug/142563
null
=
self
.
_makeOne
()
self
.
assertEqual
(
str
(
null
),
"<NullUnrestrictedUser (None, None)>"
)
def
test_suite
():
suite
=
unittest
.
TestSuite
()
suite
.
addTest
(
unittest
.
makeSuite
(
BasicUserTests
))
suite
.
addTest
(
unittest
.
makeSuite
(
SimpleUserTests
))
suite
.
addTest
(
unittest
.
makeSuite
(
SpecialUserTests
))
suite
.
addTest
(
unittest
.
makeSuite
(
UnrestrictedUserTests
))
suite
.
addTest
(
unittest
.
makeSuite
(
NullUnrestrictedUserTests
))
return
suite
src/AccessControl/unauthorized.py
deleted
100644 → 0
View file @
ccc10355
##############################################################################
#
# 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
#
##############################################################################
"""Access control exceptions
"""
import
zExceptions
class
Unauthorized
(
zExceptions
.
Unauthorized
):
def
getValueName
(
self
):
v
=
self
.
value
n
=
getattr
(
v
,
'getId'
,
v
)
if
n
is
v
:
n
=
getattr
(
v
,
'id'
,
v
)
if
n
is
v
:
n
=
getattr
(
v
,
'__name__'
,
v
)
if
n
is
not
v
:
if
callable
(
n
):
try
:
n
=
n
()
except
TypeError
:
pass
return
n
c
=
getattr
(
v
,
'__class__'
,
type
(
v
))
c
=
getattr
(
c
,
'__name__'
,
'object'
)
return
"a particular %s"
%
c
src/AccessControl/userfolder.py
deleted
100644 → 0
View file @
ccc10355
##############################################################################
#
# 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.
#
##############################################################################
"""User folders.
"""
from
base64
import
decodestring
from
Acquisition
import
aq_base
from
Acquisition
import
aq_parent
from
Acquisition
import
Implicit
from
Persistence
import
Persistent
from
Persistence
import
PersistentMapping
from
zExceptions
import
BadRequest
from
zExceptions
import
Unauthorized
from
zope.interface
import
implements
from
AccessControl
import
AuthEncoding
from
AccessControl
import
ClassSecurityInfo
from
AccessControl.class_init
import
InitializeClass
from
AccessControl.interfaces
import
IStandardUserFolder
from
AccessControl.Permissions
import
manage_users
as
ManageUsers
from
AccessControl.rolemanager
import
DEFAULTMAXLISTUSERS
from
AccessControl.rolemanager
import
RoleManager
from
AccessControl.SecurityManagement
import
getSecurityManager
from
AccessControl.SecurityManagement
import
newSecurityManager
from
AccessControl.SecurityManagement
import
noSecurityManager
from
AccessControl.users
import
User
from
AccessControl.users
import
_remote_user_mode
from
AccessControl.users
import
emergency_user
from
AccessControl.users
import
nobody
from
AccessControl.users
import
addr_match
from
AccessControl.users
import
host_match
from
AccessControl.ZopeSecurityPolicy
import
_noroles
class
BasicUserFolder
(
Implicit
,
Persistent
,
RoleManager
):
"""Base class for UserFolder-like objects"""
meta_type
=
'User Folder'
id
=
'acl_users'
title
=
'User Folder'
isPrincipiaFolderish
=
1
isAUserFolder
=
1
maxlistusers
=
DEFAULTMAXLISTUSERS
encrypt_passwords
=
1
_remote_user_mode
=
_remote_user_mode
_domain_auth_mode
=
0
_emergency_user
=
emergency_user
_nobody
=
nobody
security
=
ClassSecurityInfo
()
security
.
declareProtected
(
ManageUsers
,
'getUserNames'
)
def
getUserNames
(
self
):
"""Return a list of usernames"""
raise
NotImplementedError
security
.
declareProtected
(
ManageUsers
,
'getUsers'
)
def
getUsers
(
self
):
"""Return a list of user objects"""
raise
NotImplementedError
security
.
declareProtected
(
ManageUsers
,
'getUser'
)
def
getUser
(
self
,
name
):
"""Return the named user object or None"""
raise
NotImplementedError
security
.
declareProtected
(
ManageUsers
,
'getUserById'
)
def
getUserById
(
self
,
id
,
default
=
None
):
"""Return the user corresponding to the given id.
"""
# The connection between getting by ID and by name is not a strong
# one
user
=
self
.
getUser
(
id
)
if
user
is
None
:
return
default
return
user
def
_doAddUser
(
self
,
name
,
password
,
roles
,
domains
,
**
kw
):
"""Create a new user. This should be implemented by subclasses to
do the actual adding of a user. The 'password' will be the
original input password, unencrypted. The implementation of this
method is responsible for performing any needed encryption."""
raise
NotImplementedError
def
_doChangeUser
(
self
,
name
,
password
,
roles
,
domains
,
**
kw
):
"""Modify an existing user. This should be implemented by subclasses
to make the actual changes to a user. The 'password' will be the
original input password, unencrypted. The implementation of this
method is responsible for performing any needed encryption."""
raise
NotImplementedError
def
_doDelUsers
(
self
,
names
):
"""Delete one or more users. This should be implemented by subclasses
to do the actual deleting of users."""
raise
NotImplementedError
def
identify
(
self
,
auth
):
if
auth
and
auth
.
lower
().
startswith
(
'basic '
):
try
:
name
,
password
=
tuple
(
decodestring
(
auth
.
split
(
' '
)[
-
1
]).
split
(
':'
,
1
))
except
:
raise
BadRequest
(
'Invalid authentication token'
)
return
name
,
password
else
:
return
None
,
None
def
authenticate
(
self
,
name
,
password
,
request
):
emergency
=
self
.
_emergency_user
if
name
is
None
:
return
None
if
emergency
and
name
==
emergency
.
getUserName
():
user
=
emergency
else
:
user
=
self
.
getUser
(
name
)
if
user
is
not
None
and
user
.
authenticate
(
password
,
request
):
return
user
else
:
return
None
def
authorize
(
self
,
user
,
accessed
,
container
,
name
,
value
,
roles
):
user
=
getattr
(
user
,
'aq_base'
,
user
).
__of__
(
self
)
newSecurityManager
(
None
,
user
)
security
=
getSecurityManager
()
try
:
try
:
# This is evil: we cannot pass _noroles directly because
# it is a special marker, and that special marker is not
# the same between the C and Python policy implementations.
# We __really__ need to stop using this marker pattern!
if
roles
is
_noroles
:
if
security
.
validate
(
accessed
,
container
,
name
,
value
):
return
1
else
:
if
security
.
validate
(
accessed
,
container
,
name
,
value
,
roles
):
return
1
except
:
noSecurityManager
()
raise
except
Unauthorized
:
pass
return
0
def
validate
(
self
,
request
,
auth
=
''
,
roles
=
_noroles
):
"""
this method performs identification, authentication, and
authorization
v is the object (value) we're validating access to
n is the name used to access the object
a is the object the object was accessed through
c is the physical container of the object
We allow the publishing machinery to defer to higher-level user
folders or to raise an unauthorized by returning None from this
method.
"""
v
=
request
[
'PUBLISHED'
]
# the published object
a
,
c
,
n
,
v
=
self
.
_getobcontext
(
v
,
request
)
# we need to continue to support this silly mode
# where if there is no auth info, but if a user in our
# database has no password and he has domain restrictions,
# return him as the authorized user.
if
not
auth
:
if
self
.
_domain_auth_mode
:
for
user
in
self
.
getUsers
():
if
user
.
getDomains
():
if
self
.
authenticate
(
user
.
getUserName
(),
''
,
request
):
if
self
.
authorize
(
user
,
a
,
c
,
n
,
v
,
roles
):
return
user
.
__of__
(
self
)
name
,
password
=
self
.
identify
(
auth
)
user
=
self
.
authenticate
(
name
,
password
,
request
)
# user will be None if we can't authenticate him or if we can't find
# his username in this user database.
emergency
=
self
.
_emergency_user
if
emergency
and
user
is
emergency
:
if
self
.
_isTop
():
# we do not need to authorize the emergency user against the
# published object.
return
emergency
.
__of__
(
self
)
else
:
# we're not the top-level user folder
return
None
elif
user
is
None
:
# either we didn't find the username, or the user's password
# was incorrect. try to authorize and return the anonymous user.
if
(
self
.
_isTop
()
and
self
.
authorize
(
self
.
_nobody
,
a
,
c
,
n
,
v
,
roles
)):
return
self
.
_nobody
.
__of__
(
self
)
else
:
# anonymous can't authorize or we're not top-level user folder
return
None
else
:
# We found a user, his password was correct, and the user
# wasn't the emergency user. We need to authorize the user
# against the published object.
if
self
.
authorize
(
user
,
a
,
c
,
n
,
v
,
roles
):
return
user
.
__of__
(
self
)
# That didn't work. Try to authorize the anonymous user.
elif
(
self
.
_isTop
()
and
self
.
authorize
(
self
.
_nobody
,
a
,
c
,
n
,
v
,
roles
)):
return
self
.
_nobody
.
__of__
(
self
)
else
:
# we can't authorize the user, and we either can't authorize
# nobody against the published object or we're not top-level
return
None
if
_remote_user_mode
:
def
validate
(
self
,
request
,
auth
=
''
,
roles
=
_noroles
):
v
=
request
[
'PUBLISHED'
]
a
,
c
,
n
,
v
=
self
.
_getobcontext
(
v
,
request
)
name
=
request
.
environ
.
get
(
'REMOTE_USER'
,
None
)
if
name
is
None
:
if
self
.
_domain_auth_mode
:
for
user
in
self
.
getUsers
():
if
user
.
getDomains
():
if
self
.
authenticate
(
user
.
getUserName
(),
''
,
request
):
if
self
.
authorize
(
user
,
a
,
c
,
n
,
v
,
roles
):
return
user
.
__of__
(
self
)
user
=
self
.
getUser
(
name
)
# user will be None if we can't find his username in this user
# database.
emergency
=
self
.
_emergency_user
if
emergency
and
name
==
emergency
.
getUserName
():
if
self
.
_isTop
():
# we do not need to authorize the emergency user against
#the published object.
return
emergency
.
__of__
(
self
)
else
:
# we're not the top-level user folder
return
None
elif
user
is
None
:
# we didn't find the username in this database
# try to authorize and return the anonymous user.
if
self
.
_isTop
()
and
self
.
authorize
(
self
.
_nobody
,
a
,
c
,
n
,
v
,
roles
):
return
self
.
_nobody
.
__of__
(
self
)
else
:
# anonymous can't authorize or we're not top-level user
# folder
return
None
else
:
# We found a user and the user wasn't the emergency user.
# We need to authorize the user against the published object.
if
self
.
authorize
(
user
,
a
,
c
,
n
,
v
,
roles
):
return
user
.
__of__
(
self
)
# That didn't work. Try to authorize the anonymous user.
elif
self
.
_isTop
()
and
self
.
authorize
(
self
.
_nobody
,
a
,
c
,
n
,
v
,
roles
):
return
self
.
_nobody
.
__of__
(
self
)
else
:
# we can't authorize the user, and we either can't
# authorize nobody against the published object or
# we're not top-level
return
None
def
_getobcontext
(
self
,
v
,
request
):
"""
v is the object (value) we're validating access to
n is the name used to access the object
a is the object the object was accessed through
c is the physical container of the object
"""
if
len
(
request
.
steps
)
==
0
:
# someone deleted root index_html
request
.
RESPONSE
.
notFoundError
(
'no default view (root default view'
' was probably deleted)'
)
n
=
request
.
steps
[
-
1
]
# default to accessed and container as v.__parent__
a
=
c
=
request
[
'PARENTS'
][
0
]
# try to find actual container
inner
=
getattr
(
v
,
'aq_inner'
,
v
)
innerparent
=
getattr
(
inner
,
'__parent__'
,
None
)
if
innerparent
is
not
None
:
# this is not a method, we needn't treat it specially
c
=
innerparent
elif
hasattr
(
v
,
'im_self'
):
# this is a method, we need to treat it specially
c
=
v
.
im_self
c
=
getattr
(
v
,
'aq_inner'
,
v
)
request_container
=
getattr
(
request
[
'PARENTS'
][
-
1
],
'__parent__'
,
[])
# if pub's __parent__ or container is the request container, it
# means pub was accessed from the root
if
a
is
request_container
:
a
=
request
[
'PARENTS'
][
-
1
]
if
c
is
request_container
:
c
=
request
[
'PARENTS'
][
-
1
]
return
a
,
c
,
n
,
v
def
_isTop
(
self
):
try
:
parent
=
aq_base
(
aq_parent
(
self
))
return
parent
.
isTopLevelPrincipiaApplicationObject
except
:
return
0
def
__len__
(
self
):
return
1
def
_isPasswordEncrypted
(
self
,
pw
):
return
AuthEncoding
.
is_encrypted
(
pw
)
def
_encryptPassword
(
self
,
pw
):
return
AuthEncoding
.
pw_encrypt
(
pw
,
'SSHA'
)
def
domainSpecValidate
(
self
,
spec
):
for
ob
in
spec
:
am
=
addr_match
(
ob
)
hm
=
host_match
(
ob
)
if
am
is
None
and
hm
is
None
:
return
0
return
1
security
.
declareProtected
(
ManageUsers
,
'user_names'
)
def
user_names
(
self
):
return
self
.
getUserNames
()
def
__creatable_by_emergency_user__
(
self
):
return
1
# Domain authentication support. This is a good candidate to
# become deprecated in future Zope versions.
security
.
declareProtected
(
ManageUsers
,
'setDomainAuthenticationMode'
)
def
setDomainAuthenticationMode
(
self
,
domain_auth_mode
):
"""Set the domain-based authentication mode. By default, this
mode is off due to the high overhead of the operation that
is incurred for all anonymous accesses. If you have the
'Manage Users' permission, you can call this method via
the web, passing a boolean value for domain_auth_mode to
turn this behavior on or off."""
v
=
self
.
_domain_auth_mode
=
domain_auth_mode
and
1
or
0
return
'Domain authentication mode set to %d'
%
v
def
domainAuthModeEnabled
(
self
):
""" returns true if domain auth mode is set to true"""
return
getattr
(
self
,
'_domain_auth_mode'
,
None
)
class
UserFolder
(
BasicUserFolder
):
"""Standard UserFolder object
A UserFolder holds User objects which contain information
about users including name, password domain, and roles.
UserFolders function chiefly to control access by authenticating
users and binding them to a collection of roles."""
implements
(
IStandardUserFolder
)
meta_type
=
'User Folder'
id
=
'acl_users'
title
=
'User Folder'
def
__init__
(
self
):
self
.
data
=
PersistentMapping
()
def
getUserNames
(
self
):
"""Return a list of usernames"""
names
=
self
.
data
.
keys
()
names
.
sort
()
return
names
def
getUsers
(
self
):
"""Return a list of user objects"""
data
=
self
.
data
names
=
data
.
keys
()
names
.
sort
()
return
[
data
[
n
]
for
n
in
names
]
def
getUser
(
self
,
name
):
"""Return the named user object or None"""
return
self
.
data
.
get
(
name
,
None
)
def
hasUsers
(
self
):
""" This is not a formal API method: it is used only to provide
a way for the quickstart page to determine if the default user
folder contains any users to provide instructions on how to
add a user for newbies. Using getUserNames or getUsers would have
posed a denial of service risk."""
return
not
not
len
(
self
.
data
)
def
_doAddUser
(
self
,
name
,
password
,
roles
,
domains
,
**
kw
):
"""Create a new user"""
if
password
is
not
None
and
self
.
encrypt_passwords
\
and
not
self
.
_isPasswordEncrypted
(
password
):
password
=
self
.
_encryptPassword
(
password
)
self
.
data
[
name
]
=
User
(
name
,
password
,
roles
,
domains
)
def
_doChangeUser
(
self
,
name
,
password
,
roles
,
domains
,
**
kw
):
user
=
self
.
data
[
name
]
if
password
is
not
None
:
if
(
self
.
encrypt_passwords
and
not
self
.
_isPasswordEncrypted
(
password
)):
password
=
self
.
_encryptPassword
(
password
)
user
.
__
=
password
user
.
roles
=
roles
user
.
domains
=
domains
def
_doDelUsers
(
self
,
names
):
for
name
in
names
:
del
self
.
data
[
name
]
InitializeClass
(
UserFolder
)
src/AccessControl/users.py
deleted
100644 → 0
View file @
ccc10355
##############################################################################
#
# 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.
#
##############################################################################
"""Access control package.
"""
import
os
import
re
import
socket
from
Acquisition
import
aq_parent
from
Acquisition
import
aq_inContextOf
from
Acquisition
import
Implicit
from
Persistence
import
Persistent
from
AccessControl
import
AuthEncoding
from
AccessControl
import
SpecialUsers
from
.PermissionRole
import
_what_not_even_god_should_do
from
.PermissionRole
import
rolesForPermissionOn
_marker
=
[]
class
BasicUser
(
Implicit
):
"""Base class for all User objects"""
# ----------------------------
# Public User object interface
# ----------------------------
# Maybe allow access to unprotected attributes. Note that this is
# temporary to avoid exposing information but without breaking
# everyone's current code. In the future the security will be
# clamped down and permission-protected here. Because there are a
# fair number of user object types out there, this method denies
# access to names that are private parts of the standard User
# interface or implementation only. The other approach (only
# allowing access to public names in the User interface) would
# probably break a lot of other User implementations with extended
# functionality that we cant anticipate from the base scaffolding.
def
__allow_access_to_unprotected_subobjects__
(
self
,
name
,
value
=
None
):
deny_names
=
(
'name'
,
'__'
,
'roles'
,
'domains'
,
'_getPassword'
,
'authenticate'
,
'_shared_roles'
)
if
name
in
deny_names
:
return
0
return
1
def
__init__
(
self
,
name
,
password
,
roles
,
domains
):
raise
NotImplementedError
def
getUserName
(
self
):
"""Return the username of a user"""
raise
NotImplementedError
def
getId
(
self
):
"""Get the ID of the user. The ID can be used, at least from
Python, to get the user from the user's
UserDatabase"""
return
self
.
getUserName
()
def
_getPassword
(
self
):
"""Return the password of the user."""
raise
NotImplementedError
def
getRoles
(
self
):
"""Return the list of roles assigned to a user."""
raise
NotImplementedError
def
getRolesInContext
(
self
,
object
):
"""Return the list of roles assigned to the user,
including local roles assigned in context of
the passed in object."""
userid
=
self
.
getId
()
roles
=
self
.
getRoles
()
local
=
{}
object
=
getattr
(
object
,
'aq_inner'
,
object
)
while
1
:
local_roles
=
getattr
(
object
,
'__ac_local_roles__'
,
None
)
if
local_roles
:
if
callable
(
local_roles
):
local_roles
=
local_roles
()
dict
=
local_roles
or
{}
for
r
in
dict
.
get
(
userid
,
[]):
local
[
r
]
=
1
inner
=
getattr
(
object
,
'aq_inner'
,
object
)
parent
=
getattr
(
inner
,
'__parent__'
,
None
)
if
parent
is
not
None
:
object
=
parent
continue
if
hasattr
(
object
,
'im_self'
):
object
=
object
.
im_self
object
=
getattr
(
object
,
'aq_inner'
,
object
)
continue
break
roles
=
list
(
roles
)
+
local
.
keys
()
return
roles
def
getDomains
(
self
):
"""Return the list of domain restrictions for a user"""
raise
NotImplementedError
# ------------------------------
# Internal User object interface
# ------------------------------
def
authenticate
(
self
,
password
,
request
):
passwrd
=
self
.
_getPassword
()
result
=
AuthEncoding
.
pw_validate
(
passwrd
,
password
)
domains
=
self
.
getDomains
()
if
domains
:
return
result
and
domainSpecMatch
(
domains
,
request
)
return
result
def
_shared_roles
(
self
,
parent
):
r
=
[]
while
1
:
if
hasattr
(
parent
,
'__roles__'
):
roles
=
parent
.
__roles__
if
roles
is
None
:
return
'Anonymous'
,
if
'Shared'
in
roles
:
roles
=
list
(
roles
)
roles
.
remove
(
'Shared'
)
r
=
r
+
roles
else
:
try
:
return
r
+
list
(
roles
)
except
:
return
r
if
getattr
(
parent
,
'__parent__'
,
None
)
is
not
None
:
while
hasattr
(
parent
.
aq_self
,
'aq_self'
):
parent
=
parent
.
aq_self
parent
=
aq_parent
(
parent
)
else
:
return
r
def
_check_context
(
self
,
object
):
# Check that 'object' exists in the acquisition context of
# the parent of the acl_users object containing this user,
# to prevent "stealing" access through acquisition tricks.
# Return true if in context, false if not or if context
# cannot be determined (object is not wrapped).
parent
=
getattr
(
self
,
'__parent__'
,
None
)
context
=
getattr
(
parent
,
'__parent__'
,
None
)
if
context
is
not
None
:
if
object
is
None
:
return
1
if
hasattr
(
object
,
'im_self'
):
# This is a method. Grab its self.
object
=
object
.
im_self
return
aq_inContextOf
(
object
,
context
,
1
)
# This is lame, but required to keep existing behavior.
return
1
def
allowed
(
self
,
object
,
object_roles
=
None
):
"""Check whether the user has access to object. The user must
have one of the roles in object_roles to allow access."""
if
object_roles
is
_what_not_even_god_should_do
:
return
0
# Short-circuit the common case of anonymous access.
if
object_roles
is
None
or
'Anonymous'
in
object_roles
:
return
1
# Provide short-cut access if object is protected by 'Authenticated'
# role and user is not nobody
if
'Authenticated'
in
object_roles
and
(
self
.
getUserName
()
!=
'Anonymous User'
):
if
self
.
_check_context
(
object
):
return
1
# Check for ancient role data up front, convert if found.
# This should almost never happen, and should probably be
# deprecated at some point.
if
'Shared'
in
object_roles
:
object_roles
=
self
.
_shared_roles
(
object
)
if
object_roles
is
None
or
'Anonymous'
in
object_roles
:
return
1
# Check for a role match with the normal roles given to
# the user, then with local roles only if necessary. We
# want to avoid as much overhead as possible.
user_roles
=
self
.
getRoles
()
for
role
in
object_roles
:
if
role
in
user_roles
:
if
self
.
_check_context
(
object
):
return
1
return
None
# Still have not found a match, so check local roles. We do
# this manually rather than call getRolesInContext so that
# we can incur only the overhead required to find a match.
inner_obj
=
getattr
(
object
,
'aq_inner'
,
object
)
userid
=
self
.
getId
()
while
1
:
local_roles
=
getattr
(
inner_obj
,
'__ac_local_roles__'
,
None
)
if
local_roles
:
if
callable
(
local_roles
):
local_roles
=
local_roles
()
dict
=
local_roles
or
{}
local_roles
=
dict
.
get
(
userid
,
[])
for
role
in
object_roles
:
if
role
in
local_roles
:
if
self
.
_check_context
(
object
):
return
1
return
0
inner
=
getattr
(
inner_obj
,
'aq_inner'
,
inner_obj
)
parent
=
getattr
(
inner
,
'__parent__'
,
None
)
if
parent
is
not
None
:
inner_obj
=
parent
continue
if
hasattr
(
inner_obj
,
'im_self'
):
inner_obj
=
inner_obj
.
im_self
inner_obj
=
getattr
(
inner_obj
,
'aq_inner'
,
inner_obj
)
continue
break
return
None
domains
=
[]
def
has_role
(
self
,
roles
,
object
=
None
):
"""Check to see if a user has a given role or roles."""
if
isinstance
(
roles
,
str
):
roles
=
[
roles
]
if
object
is
not
None
:
user_roles
=
self
.
getRolesInContext
(
object
)
else
:
# Global roles only...
user_roles
=
self
.
getRoles
()
for
role
in
roles
:
if
role
in
user_roles
:
return
1
return
0
def
has_permission
(
self
,
permission
,
object
):
"""Check to see if a user has a given permission on an object."""
roles
=
rolesForPermissionOn
(
permission
,
object
)
if
isinstance
(
roles
,
str
):
roles
=
[
roles
]
return
self
.
allowed
(
object
,
roles
)
def
__len__
(
self
):
return
1
def
__str__
(
self
):
return
self
.
getUserName
()
def
__repr__
(
self
):
return
'<%s %r>'
%
(
self
.
__class__
.
__name__
,
self
.
getUserName
())
class
SimpleUser
(
BasicUser
):
"""A very simple user implementation
that doesn't make a database commitment"""
def
__init__
(
self
,
name
,
password
,
roles
,
domains
):
self
.
name
=
name
self
.
__
=
password
self
.
roles
=
roles
self
.
domains
=
domains
def
getUserName
(
self
):
"""Return the username of a user"""
return
self
.
name
def
_getPassword
(
self
):
"""Return the password of the user."""
return
self
.
__
def
getRoles
(
self
):
"""Return the list of roles assigned to a user."""
if
self
.
name
==
'Anonymous User'
:
return
tuple
(
self
.
roles
)
else
:
return
tuple
(
self
.
roles
)
+
(
'Authenticated'
,
)
def
getDomains
(
self
):
"""Return the list of domain restrictions for a user"""
return
tuple
(
self
.
domains
)
class
SpecialUser
(
SimpleUser
):
"""Class for special users, like emergency user and nobody"""
def
getId
(
self
):
pass
class
User
(
SimpleUser
,
Persistent
):
"""Standard User object"""
class
UnrestrictedUser
(
SpecialUser
):
"""User that passes all security checks. Note, however, that modules
like Owner.py can still impose restrictions.
"""
def
allowed
(
self
,
parent
,
roles
=
None
):
return
roles
is
not
_what_not_even_god_should_do
def
has_role
(
self
,
roles
,
object
=
None
):
return
1
def
has_permission
(
self
,
permission
,
object
):
return
1
class
NullUnrestrictedUser
(
SpecialUser
):
"""User created if no emergency user exists. It is only around to
satisfy third party userfolder implementations that may
expect the emergency user to exist and to be able to call certain
methods on it (in other words, backward compatibility).
Note that when no emergency user is installed, this object that
exists in its place is more of an anti-superuser since you cannot
login as this user and it has no priveleges at all."""
__null_user__
=
1
def
__init__
(
self
):
pass
def
getUserName
(
self
):
# return an unspellable username
return
(
None
,
None
)
_getPassword
=
getUserName
def
getRoles
(
self
):
return
()
getDomains
=
getRoles
def
getRolesInContext
(
self
,
object
):
return
()
def
authenticate
(
self
,
password
,
request
):
return
0
def
allowed
(
self
,
parent
,
roles
=
None
):
return
0
def
has_role
(
self
,
roles
,
object
=
None
):
return
0
def
has_permission
(
self
,
permission
,
object
):
return
0
def
__str__
(
self
):
# See https://bugs.launchpad.net/zope2/+bug/142563
return
repr
(
self
)
def
readUserAccessFile
(
filename
):
'''Reads an access file from the instance home.
Returns name, password, domains, remote_user_mode.
'''
environ
=
os
.
environ
instancehome
=
environ
.
get
(
'INSTANCE_HOME'
,
None
)
if
not
instancehome
:
return
None
try
:
f
=
open
(
os
.
path
.
join
(
instancehome
,
filename
),
'r'
)
line
=
f
.
readline
()
f
.
close
()
except
IOError
:
return
None
if
line
:
data
=
line
.
strip
().
split
(
':'
)
remote_user_mode
=
not
data
[
1
]
try
:
ds
=
data
[
2
].
split
(
' '
)
except
:
ds
=
[]
return
data
[
0
],
data
[
1
],
ds
,
remote_user_mode
else
:
return
None
# Create emergency user.
_remote_user_mode
=
0
info
=
readUserAccessFile
(
'access'
)
if
info
:
_remote_user_mode
=
info
[
3
]
emergency_user
=
UnrestrictedUser
(
info
[
0
],
info
[
1
],
(
'manage'
,
),
info
[
2
])
else
:
emergency_user
=
NullUnrestrictedUser
()
del
info
nobody
=
SpecialUser
(
'Anonymous User'
,
''
,
(
'Anonymous'
,
),
[])
system
=
UnrestrictedUser
(
'System Processes'
,
''
,
(
'manage'
,
),
[])
# stuff these in a handier place for importing
SpecialUsers
.
nobody
=
nobody
SpecialUsers
.
system
=
system
SpecialUsers
.
emergency_user
=
emergency_user
# Note: use of the 'super' name is deprecated.
SpecialUsers
.
super
=
emergency_user
def
rolejoin
(
roles
,
other
):
dict
=
{}
for
role
in
roles
:
dict
[
role
]
=
1
for
role
in
other
:
dict
[
role
]
=
1
roles
=
dict
.
keys
()
roles
.
sort
()
return
roles
addr_match
=
re
.
compile
(
r'((\
d{
1,3}\
.){
1,3}\
*)|((
\d{1,3}\
.){
3}\
d{
1,3})'
).
match
host_match
=
re
.
compile
(
r'(([\
_
0-9a-zA-Z\
-]*
\.)*[0-9a-zA-Z\
-]*)
').match
def domainSpecMatch(spec, request):
# Fast exit for the match-all case
if len(spec) == 1 and spec[0] == '
*
':
return 1
host = request.get('
REMOTE_HOST
', '')
addr = request.getClientAddr()
if not host and not addr:
return 0
if not host:
try:
host=socket.gethostbyaddr(addr)[0]
except:
pass
if not addr:
try:
addr=socket.gethostbyname(host)
except:
pass
_host = host.split('
.
')
_addr = addr.split('
.
')
_hlen = len(_host)
for ob in spec:
sz = len(ob)
_ob = ob.split('
.
')
_sz = len(_ob)
mo = addr_match(ob)
if mo is not None:
if mo.end(0)==sz:
fail=0
for i in range(_sz):
a = _addr[i]
o = _ob[i]
if (o != a) and (o != '
*
'):
fail = 1
break
if fail:
continue
return 1
mo = host_match(ob)
if mo is not None:
if mo.end(0)==sz:
if _hlen < _sz:
continue
elif _hlen > _sz:
_item = _host[-_sz:]
else:
_item = _host
fail = 0
for i in range(_sz):
h = _item[i]
o = _ob[i]
if (o != h) and (o != '
*
'):
fail = 1
break
if fail:
continue
return 1
return 0
def absattr(attr):
if callable(attr):
return attr()
return attr
def reqattr(request, attr):
try:
return request[attr]
except:
return None
versions.cfg
View file @
d2b68599
...
@@ -4,6 +4,7 @@ versions = versions
...
@@ -4,6 +4,7 @@ versions = versions
[versions]
[versions]
# Zope2-specific
# Zope2-specific
Zope2 =
Zope2 =
AccessControl = 2.13.0
Acquisition = 2.13.3
Acquisition = 2.13.3
DateTime = 2.12.2
DateTime = 2.12.2
ExtensionClass = 2.13.2
ExtensionClass = 2.13.2
...
...
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