1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
##############################################################################
#
# Copyright (c) 2004 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 related configuration fields.
"""
__docformat__ = 'restructuredtext'
from zope.configuration.fields import GlobalObject
from zope.configuration.fields import MessageID
from zope.interface import Interface
from zope.schema import Id
from zope.schema.interfaces import IFromUnicode
from zope.security._compat import implementer_if_needed
from zope.security.permission import checkPermission
from zope.security.management import setSecurityPolicy
from zope.security.interfaces import PUBLIC_PERMISSION_NAME as zope_Public
@implementer_if_needed(IFromUnicode)
class Permission(Id):
r"""This field describes a permission.
"""
def fromUnicode(self, value):
u = super(Permission, self).fromUnicode(value)
map = getattr(self.context, 'permission_mapping', {})
return map.get(u, u)
def _validate(self, value):
super(Permission, self)._validate(value)
if value != zope_Public:
self.context.action(
discriminator=None,
callable=checkPermission,
args=(None, value),
# Delay execution till end. This is an
# optimization. We don't want to intersperse utility
# lookup, done when checking permissions, with utility
# definitions. Utility lookup is expensive after
# utility definition, as extensive caches have to be
# rebuilt.
order=9999999,
)
class ISecurityPolicyDirective(Interface):
"""Defines the security policy that will be used for Zope."""
component = GlobalObject(
title=u"Component",
description=u"Pointer to the object that will handle the security.",
required=True)
def securityPolicy(_context, component):
_context.action(
discriminator='defaultPolicy',
callable=setSecurityPolicy,
args=(component,)
)
class IPermissionDirective(Interface):
"""Define a new security object."""
id = Id(
title=u"ID",
description=u"ID as which this object will be known and used.",
required=True)
title = MessageID(
title=u"Title",
description=u"Provides a title for the object.",
required=True)
description = MessageID(
title=u"Description",
description=u"Provides a description for the object.",
required=False)
def permission(_context, id, title, description=u''):
from zope.security.interfaces import IPermission
from zope.security.permission import Permission
from zope.component.zcml import utility
permission = Permission(id, title, description)
utility(_context, IPermission, permission, name=id)
class IRedefinePermission(Interface):
"""Define a permission to replace another permission."""
from_ = Permission(
title=u"Original permission",
description=u"Original permission ID to redefine.",
required=True)
to = Permission(
title=u"Substituted permission",
description=u"Substituted permission ID.",
required=True)
def redefinePermission(_context, from_, to):
_context = _context.context
# check if context has any permission mappings yet
if not hasattr(_context, 'permission_mapping'):
_context.permission_mapping = {}
_context.permission_mapping[from_] = to
|