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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
|
# Copyright 2011 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
"""Base class to implement the Launchpad security policy."""
__metaclass__ = type
__all__ = [
'AnonymousAuthorization',
'AuthorizationBase',
'DelegatedAuthorization',
]
from itertools import (
izip,
repeat,
)
from zope.component import queryAdapter
from zope.interface import implements
from zope.security.permission import checkPermission
from lp.app.interfaces.security import IAuthorization
from lp.registry.interfaces.person import IPerson
from lp.registry.interfaces.role import IPersonRoles
class AuthorizationBase:
implements(IAuthorization)
permission = None
usedfor = None
def __init__(self, obj):
self.obj = obj
def checkUnauthenticated(self):
"""See `IAuthorization.checkUnauthenticated`.
:return: True or False.
"""
return False
def checkAuthenticated(self, user):
"""Return True if the given person has the given permission.
This method is implemented by security adapters that have not
been updated to work in terms of IAccount.
:return: True or False.
"""
return False
def checkPermissionIsRegistered(self, obj, permission):
"""Pass through to checkPermission.
To be replaced during testing.
"""
return checkPermission(obj, permission)
def forwardCheckAuthenticated(self, user,
obj=None, permission=None):
"""Forward request to another security adapter.
Find a matching adapter and call checkAuthenticated on it. Intended
to be used in checkAuthenticated.
:param user: The IRolesPerson object that was passed in.
:param obj: The object to check the permission for. If None, use
the same object as this adapter.
:param permission: The permission to check. If None, use the same
permission as this adapter.
:return: True or False.
"""
assert obj is not None or permission is not None, (
"Please specify either an object or permission to forward to.")
if obj is None:
obj = self.obj
if permission is None:
permission = self.permission
# This will raise ValueError if the permission doesn't exist.
self.checkPermissionIsRegistered(obj, permission)
next_adapter = queryAdapter(obj, IAuthorization, permission)
if next_adapter is None:
return False
else:
return next_adapter.checkAuthenticated(user)
def checkAccountAuthenticated(self, account):
"""See `IAuthorization.checkAccountAuthenticated`.
:return: True or False.
"""
# For backward compatibility, delegate to one of
# checkAuthenticated() or checkUnauthenticated().
person = IPerson(account, None)
if person is None:
return self.checkUnauthenticated()
else:
return self.checkAuthenticated(IPersonRoles(person))
class AnonymousAuthorization(AuthorizationBase):
"""Allow any authenticated and unauthenticated user access."""
permission = 'launchpad.View'
def checkUnauthenticated(self):
"""Any unauthorized user can see this object."""
return True
def checkAuthenticated(self, user):
"""Any authorized user can see this object."""
return True
class DelegatedAuthorization(AuthorizationBase):
def __init__(self, obj, forwarded_object=None, permission=None):
super(DelegatedAuthorization, self).__init__(obj)
self.forwarded_object = forwarded_object
if permission is not None:
self.permission = permission
def iter_objects(self):
"""Iterator of objects used for authentication checking.
If an object is provided when the class is instantiated, it will be
used. Otherwise this method must be overridden to provide the objects
to be used.
"""
if self.forwarded_object is None:
raise ValueError(
"Either set forwarded_object or override iter_objects.")
yield self.forwarded_object
def checkAuthenticated(self, user):
"""See `IAuthorization`."""
return izip(self.iter_objects(), repeat(self.permission))
def checkUnauthenticated(self):
"""See `IAuthorization`."""
return izip(self.iter_objects(), repeat(self.permission))
|