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
8e409efa
Commit
8e409efa
authored
Jul 30, 2009
by
Hanno Schlichting
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Moved ``Products/Five/security.py`` into the AccessControl package.
parent
9e193fa3
Changes
14
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
224 additions
and
194 deletions
+224
-194
doc/CHANGES.rst
doc/CHANGES.rst
+2
-0
src/AccessControl/permissions.zcml
src/AccessControl/permissions.zcml
+7
-0
src/AccessControl/security.py
src/AccessControl/security.py
+175
-0
src/Products/Five/browser/metaconfigure.py
src/Products/Five/browser/metaconfigure.py
+6
-5
src/Products/Five/browser/tests/test_menu.py
src/Products/Five/browser/tests/test_menu.py
+1
-1
src/Products/Five/browser/tests/test_zope3security.py
src/Products/Five/browser/tests/test_zope3security.py
+1
-1
src/Products/Five/form/metaconfigure.py
src/Products/Five/form/metaconfigure.py
+3
-1
src/Products/Five/metaconfigure.py
src/Products/Five/metaconfigure.py
+1
-1
src/Products/Five/permissions.zcml
src/Products/Five/permissions.zcml
+1
-8
src/Products/Five/security.py
src/Products/Five/security.py
+17
-162
src/Products/Five/tests/test_security.py
src/Products/Five/tests/test_security.py
+5
-5
src/Products/Five/viewlet/metaconfigure.py
src/Products/Five/viewlet/metaconfigure.py
+3
-8
src/Testing/ZopeTestCase/placeless.py
src/Testing/ZopeTestCase/placeless.py
+1
-1
src/Zope2/utilities/skel/etc/site.zcml
src/Zope2/utilities/skel/etc/site.zcml
+1
-1
No files found.
doc/CHANGES.rst
View file @
8e409efa
...
...
@@ -11,6 +11,8 @@ Trunk (unreleased)
Restructuring
+++++++++++++
- Moved ``Products/Five/security.py`` into the AccessControl package.
- Moved ``Products/Five/traversing.zcml`` directly into the configure.zcml.
- Moved zope.security-style permission registrations from Products.Five into
...
...
src/AccessControl/permissions.zcml
View file @
8e409efa
<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"
...
...
src/AccessControl/security.py
0 → 100644
View file @
8e409efa
##############################################################################
#
# Copyright (c) 2004-2009 Zope Corporation 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
_registeredPermissions
from
AccessControl.Permission
import
pname
import
Products
from
AccessControl.Permission
import
ApplicationDefaultPermissions
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
):
sec
=
{}
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.
"""
global
_registeredPermissions
# Zope 2 uses string, not unicode yet
zope2_permission
=
str
(
permission
.
title
)
roles
=
(
'Manager'
,)
if
not
_registeredPermissions
.
has_key
(
zope2_permission
):
_registeredPermissions
[
zope2_permission
]
=
1
Products
.
__ac_permissions__
+=
((
zope2_permission
,
(),
roles
,),)
mangled
=
pname
(
zope2_permission
)
setattr
(
ApplicationDefaultPermissions
,
mangled
,
roles
)
src/Products/Five/browser/metaconfigure.py
View file @
8e409efa
...
...
@@ -37,6 +37,12 @@ from zope.app.publisher.browser.viewmeta import providesCallable
from
zope.app.publisher.browser.viewmeta
import
_handle_menu
from
zope.app.publisher.browser.viewmeta
import
_handle_for
from
AccessControl.security
import
getSecurityInfo
from
AccessControl.security
import
protectClass
from
AccessControl.security
import
protectName
from
AccessControl.security
import
CheckerPrivateId
from
App.class_init
import
InitializeClass
from
Products.Five.browser
import
BrowserView
from
Products.Five.browser.resource
import
FileResourceFactory
from
Products.Five.browser.resource
import
ImageResourceFactory
...
...
@@ -44,12 +50,7 @@ from Products.Five.browser.resource import PageTemplateResourceFactory
from
Products.Five.browser.resource
import
DirectoryResourceFactory
from
Products.Five.browser.pagetemplatefile
import
ViewPageTemplateFile
from
Products.Five.metaclass
import
makeClass
from
Products.Five.security
import
getSecurityInfo
from
Products.Five.security
import
protectClass
from
Products.Five.security
import
protectName
from
Products.Five.security
import
CheckerPrivateId
from
App.class_init
import
InitializeClass
def
page
(
_context
,
name
,
permission
,
for_
,
layer
=
IDefaultBrowserLayer
,
template
=
None
,
class_
=
None
,
...
...
src/Products/Five/browser/tests/test_menu.py
View file @
8e409efa
...
...
@@ -30,7 +30,7 @@ def test_menu():
>>> zcml.load_config("permissions.zcml", AccessControl)
>>> zcml.load_config('menu.zcml', package=Products.Five.browser.tests)
>>> from
Products.Five
.security import newInteraction
>>> from
AccessControl
.security import newInteraction
>>> newInteraction()
Now for some actual testing... Let's look up the menu we registered:
...
...
src/Products/Five/browser/tests/test_zope3security.py
View file @
8e409efa
...
...
@@ -11,7 +11,7 @@ def test_check_permission():
... xmlns="http://namespaces.zope.org/zope"
... xmlns:browser="http://namespaces.zope.org/browser">
... <securityPolicy
... component="
Products.Five.security.Five
SecurityPolicy" />
... component="
AccessControl.security.
SecurityPolicy" />
... <configure package="Products.Five.browser.tests">
... <browser:page
... for="OFS.interfaces.IFolder"
...
...
src/Products/Five/form/metaconfigure.py
View file @
8e409efa
...
...
@@ -26,10 +26,12 @@ _ = MessageFactory('zope')
from
zope.app.publisher.browser.menumeta
import
menuItemDirective
from
zope.app.form.browser.metaconfigure
import
BaseFormDirective
from
zope.browser.interfaces
import
IAdding
from
zope.publisher.interfaces.browser
import
IDefaultBrowserLayer
from
AccessControl.security
import
protectClass
from
Products.Five.form
import
EditView
,
AddView
from
Products.Five.metaclass
import
makeClass
from
Products.Five.security
import
protectClass
from
Products.Five.browser.pagetemplatefile
import
ZopeTwoPageTemplateFile
from
Products.Five.browser.metaconfigure
import
makeClassForTemplate
...
...
src/Products/Five/metaconfigure.py
View file @
8e409efa
...
...
@@ -17,8 +17,8 @@ $Id$
"""
import
warnings
from
zope.security
import
metaconfigure
from
AccessControl.security
import
protectName
from
App.class_init
import
InitializeClass
from
Products.Five.security
import
protectName
class
ClassDirective
(
metaconfigure
.
ClassDirective
):
...
...
src/Products/Five/permissions.zcml
View file @
8e409efa
<configure xmlns="http://namespaces.zope.org/zope"
i18n_domain="Five">
<!-- 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"
/>
<include package="AccessControl" file="permissions.zcml" />
<permission
id="five.ManageSite"
title="Manage Five local sites"
/>
<include package="AccessControl" file="permissions.zcml" />
<!-- CMF Core Permissions -->
<permission
...
...
src/Products/Five/security.py
View file @
8e409efa
...
...
@@ -18,165 +18,20 @@ $Id$
from
zope.deferredimport
import
deprecated
deprecated
(
"Please import InitializeClass from App.class_init"
,
initializeClass
=
'App.class_init:InitializeClass'
,
)
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
_registeredPermissions
from
AccessControl.Permission
import
pname
import
Products
from
AccessControl.Permission
import
ApplicationDefaultPermissions
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
):
sec
=
{}
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 3 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
FiveSecurityPolicy
(
ParanoidSecurityPolicy
):
"""Security policy that bridges between Zope 3 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 3 to use Zope 2's checkPermission.
Zope 3 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 3 into using Zope 2's checker...
"""
if
getattr
(
thread_local
,
'interaction'
,
None
)
is
None
:
thread_local
.
interaction
=
FiveSecurityPolicy
()
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.
"""
global
_registeredPermissions
# Zope 2 uses string, not unicode yet
zope2_permission
=
str
(
permission
.
title
)
roles
=
(
'Manager'
,)
if
not
_registeredPermissions
.
has_key
(
zope2_permission
):
_registeredPermissions
[
zope2_permission
]
=
1
Products
.
__ac_permissions__
+=
((
zope2_permission
,
(),
roles
,),)
mangled
=
pname
(
zope2_permission
)
setattr
(
ApplicationDefaultPermissions
,
mangled
,
roles
)
initializeClass
=
'App.class_init:InitializeClass'
,
)
deprecated
(
"Please import from AccessControl.security"
,
CheckerPublicId
=
'AccessControl.security:CheckerPublicId'
,
CheckerPrivateId
=
'AccessControl.security:CheckerPrivateId'
,
getSecurityInfo
=
'AccessControl.security:getSecurityInfo'
,
clearSecurityInfo
=
'AccessControl.security:clearSecurityInfo'
,
checkPermission
=
'AccessControl.security:checkPermission'
,
FiveSecurityPolicy
=
'AccessControl.security:SecurityPolicy'
,
newInteraction
=
'AccessControl.security:newInteraction'
,
_getSecurity
=
'AccessControl.security:_getSecurity'
,
protectName
=
'AccessControl.security:protectName'
,
protectClass
=
'AccessControl.security:protectClass'
,
create_permission_from_permission_directive
=
\
'AccessControl.security:create_permission_from_permission_directive'
,
)
src/Products/Five/tests/test_security.py
View file @
8e409efa
...
...
@@ -151,7 +151,7 @@ def test_security_equivalence():
Before we end we should clean up after ourselves:
>>> from
Products.Five
.security import clearSecurityInfo
>>> from
AccessControl
.security import clearSecurityInfo
>>> clearSecurityInfo(Dummy1)
>>> clearSecurityInfo(Dummy2)
...
...
@@ -292,8 +292,8 @@ def test_checkPermission():
has the permission to access an object. The function delegates to
the security policy's checkPermission() method.
Five has the same function, Five.security.checkPermission, but in
a Zope2-compatible implementation. It too uses the currently
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.
...
...
@@ -310,7 +310,7 @@ def test_checkPermission():
a) zope2.Public (which should always be available to everyone)
>>> from
Products.Five
.security import checkPermission
>>> from
AccessControl
.security import checkPermission
>>> checkPermission('zope2.Public', self.folder)
True
...
...
@@ -342,7 +342,7 @@ def test_checkPermission():
>>> from zope.security.management import endInteraction
>>> endInteraction()
>>> from
Products.Five
.security import newInteraction
>>> from
AccessControl
.security import newInteraction
>>> newInteraction()
a) zope2.Public (which should always be available to everyone)
...
...
src/Products/Five/viewlet/metaconfigure.py
View file @
8e409efa
...
...
@@ -20,17 +20,15 @@ import os
from
zope.app.publisher.browser
import
viewmeta
from
zope.component
import
zcml
from
zope.configuration.exceptions
import
ConfigurationError
from
zope.interface
import
classImplements
from
zope.interface
import
implements
from
zope.interface
import
Interface
from
zope.browser.interfaces
import
IBrowserView
from
zope.publisher.interfaces.browser
import
IDefaultBrowserLayer
from
zope.viewlet
import
interfaces
from
AccessControl.security
import
protectClass
from
AccessControl.security
import
protectName
from
App.class_init
import
InitializeClass
from
App.special_dtml
import
DTMLFile
from
Products.Five.security
import
protectClass
from
Products.Five.security
import
protectName
from
Products.Five.viewlet
import
manager
from
Products.Five.viewlet
import
viewlet
...
...
@@ -157,9 +155,6 @@ def viewletDirective(
new_class
=
type
(
class_
.
__name__
,
(
class_
,
viewlet
.
SimpleAttributeViewlet
),
cdict
)
if
hasattr
(
class_
,
'__implements__'
):
classImplements
(
new_class
,
IBrowserPublisher
)
else
:
# Create a new class for the viewlet template alone.
new_class
=
viewlet
.
SimpleViewletClass
(
template
,
name
=
name
,
...
...
src/Testing/ZopeTestCase/placeless.py
View file @
8e409efa
...
...
@@ -19,8 +19,8 @@ from zope.component.testing import PlacelessSetup as CAPlacelessSetup
from
zope.component.eventtesting
import
PlacelessSetup
as
EventPlacelessSetup
from
zope.container.testing
import
PlacelessSetup
as
ContainerPlacelessSetup
from
zope.i18n.testing
import
PlacelessSetup
as
I18nPlacelessSetup
from
zope.security.management
import
newInteraction
from
zope.security.testing
import
addCheckerPublic
from
AccessControl.security
import
newInteraction
class
PlacelessSetup
(
CAPlacelessSetup
,
...
...
src/Zope2/utilities/skel/etc/site.zcml
View file @
8e409efa
...
...
@@ -21,6 +21,6 @@
<securityPolicy
component="
Products.Five.security.Five
SecurityPolicy" />
component="
AccessControl.security.
SecurityPolicy" />
</configure>
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