3
from keystone.backends.api import BaseTenantAPI
4
from keystone.common import exception
7
from .base import BaseLdapAPI
10
class RoleAPI(BaseLdapAPI, BaseTenantAPI):
11
DEFAULT_TREE_DN = 'ou=Groups,dc=example,dc=com'
12
options_name = 'role_tree_dn'
13
object_class = 'keystoneRole'
15
attribute_mapping = {'desc': 'description', 'service_id': 'serviceId'}
18
def _create_ref(role_id, tenant_id, user_id):
19
role_id = '' if role_id is None else str(role_id)
20
tenant_id = '' if tenant_id is None else str(tenant_id)
21
user_id = '' if user_id is None else str(user_id)
22
return '%d-%d-%s%s%s' % (len(role_id), len(tenant_id),
23
role_id, tenant_id, user_id)
26
def _explode_ref(role_ref):
27
a = role_ref.split('-', 2)
29
len_tenant = int(a[1])
30
role_id = a[2][:len_role]
31
role_id = None if len(role_id) == 0 else str(role_id)
32
tenant_id = a[2][len_role:len_tenant + len_role]
33
tenant_id = None if len(tenant_id) == 0 else str(tenant_id)
34
user_id = a[2][len_tenant + len_role:]
35
user_id = None if len(user_id) == 0 else str(user_id)
36
return role_id, tenant_id, user_id
38
def _subrole_id_to_dn(self, role_id, tenant_id):
40
return self._id_to_dn(role_id)
42
return "cn=%s,%s" % (ldap.dn.escape_dn_chars(role_id),
43
self.api.tenant._id_to_dn(tenant_id))
45
def add_user(self, role_id, user_id, tenant_id=None):
46
user = self.api.user.get(user_id)
48
raise exception.NotFound("User %s not found" % (user_id,))
49
role_dn = self._subrole_id_to_dn(role_id, tenant_id)
50
conn = self.api.get_connection()
51
user_dn = self.api.user._id_to_dn(user_id)
53
conn.modify_s(role_dn, [(ldap.MOD_ADD, 'member', user_dn)])
54
except ldap.TYPE_OR_VALUE_EXISTS:
55
raise exception.Duplicate(
56
"User %s already has role %s in tenant %s" % (user_id,
58
except ldap.NO_SUCH_OBJECT:
59
if tenant_id is None or self.get(role_id) is None:
60
raise exception.NotFound("Role %s not found" % (role_id,))
62
tenant_dn = self.api.tenant._id_to_dn(tenant_id)
66
('objectClass', 'keystoneTenantRole'),
68
('keystoneRole', self._id_to_dn(role_id)),
70
conn.add_s(role_dn, attrs)
71
return models.UserRoleAssociation(
72
id=self._create_ref(role_id, tenant_id, user_id),
73
role_id=role_id, user_id=user_id, tenant_id=tenant_id)
75
def get_by_service(self, service_id):
76
roles = self.get_all('(serviceId=%s)' % \
77
(ldap.filter.escape_filter_chars(service_id),))
86
def get_role_assignments(self, tenant_id):
87
conn = self.api.get_connection()
88
query = '(objectClass=keystoneTenantRole)'
89
tenant_dn = self.api.tenant._id_to_dn(tenant_id)
91
roles = conn.search_s(tenant_dn, ldap.SCOPE_ONELEVEL, query)
92
except ldap.NO_SUCH_OBJECT:
95
for role_dn, attrs in roles:
97
user_dns = attrs['member']
100
for user_dn in user_dns:
101
user_id = ldap.dn.str2dn(user_dn)[0][0][1]
102
role_id = ldap.dn.str2dn(role_dn)[0][0][1]
103
res.append(models.UserRoleAssociation(
104
id=self._create_ref(role_id, tenant_id, user_id),
107
tenant_id=tenant_id))
110
def ref_get_all_global_roles(self, user_id):
111
user_dn = self.api.user._id_to_dn(user_id)
112
roles = self.get_all('(member=%s)' % (user_dn,))
113
return [models.UserRoleAssociation(
114
id=self._create_ref(role.id, None, user_id),
116
user_id=user_id) for role in roles]
118
def ref_get_all_tenant_roles(self, user_id, tenant_id=None):
119
conn = self.api.get_connection()
120
user_dn = self.api.user._id_to_dn(user_id)
121
query = '(&(objectClass=keystoneTenantRole)(member=%s))' % (user_dn,)
122
if tenant_id is not None:
123
tenant_dn = self.api.tenant._id_to_dn(tenant_id)
125
roles = conn.search_s(tenant_dn, ldap.SCOPE_ONELEVEL, query)
126
except ldap.NO_SUCH_OBJECT:
129
for role_dn, _ in roles:
130
role_id = ldap.dn.str2dn(role_dn)[0][0][1]
131
res.append(models.UserRoleAssociation(
132
id=self._create_ref(role_id, tenant_id, user_id),
135
tenant_id=tenant_id))
139
roles = conn.search_s(self.api.tenant.tree_dn,
140
ldap.SCOPE_SUBTREE, query)
141
except ldap.NO_SUCH_OBJECT:
144
for role_dn, _ in roles:
145
role_id = ldap.dn.str2dn(role_dn)[0][0][1]
146
tenant_id = ldap.dn.str2dn(role_dn)[1][0][1]
147
res.append(models.UserRoleAssociation(
148
id=self._create_ref(role_id, tenant_id, user_id),
151
tenant_id=tenant_id))
154
def ref_get(self, id):
155
role_id, tenant_id, user_id = self._explode_ref(id)
156
user_dn = self.api.user._id_to_dn(user_id)
157
role_dn = self._subrole_id_to_dn(role_id, tenant_id)
158
query = '(&(objectClass=keystoneTenantRole)(member=%s))' % (user_dn,)
160
res = search_s(role_dn, ldap.SCOPE_BASE, query)
161
except ldap.NO_SUCH_OBJECT:
165
return models.UserRoleAssociation(id=id, role_id=role_id,
166
tenant_id=tenant_id, user_id=user_id)
168
def ref_delete(self, id):
169
role_id, tenant_id, user_id = self._explode_ref(id)
170
user_dn = self.api.user._id_to_dn(user_id)
171
role_dn = self._subrole_id_to_dn(role_id, tenant_id)
172
conn = self.api.get_connection()
174
conn.modify_s(role_dn, [(ldap.MOD_DELETE, 'member', [user_dn])])
175
except ldap.NO_SUCH_ATTRIBUTE:
176
raise exception.NotFound("No such user in role")
178
def ref_get_page(self, marker, limit, user_id):
179
all_roles = self.ref_get_all_global_roles(user_id)
180
for tenant in self.api.tenant.get_all():
181
all_roles += self.ref_get_all_tenant_roles(user_id, tenant.id)
182
return self._get_page(marker, limit, all_roles)
184
def ref_get_page_markers(self, user_id, marker, limit):
185
all_roles = self.ref_get_all_global_roles(user_id)
186
for tenant in self.api.tenant.get_all():
187
all_roles += self.ref_get_all_tenant_roles(user_id, tenant.id)
188
return self._get_page_markers(marker, limit, all_roles)
190
def ref_get_by_role(self, id):
191
role_dn = self._id_to_dn(id)
193
roles = self.get_all('(keystoneRole=%s)' % (role_dn,))
194
except ldap.NO_SUCH_OBJECT:
197
for role_dn, attrs in roles:
199
user_dns = attrs['member']
200
tenant_dns = attrs['tenant']
203
for user_dn in user_dns:
204
user_id = ldap.dn.str2dn(user_dn)[0][0][1]
206
if tenant_dns != None:
207
for tenant_dn in tenant_dns:
208
tenant_id = ldap.dn.str2dn(tenant_dn)[0][0][1]
209
role_id = ldap.dn.str2dn(role_dn)[0][0][1]
210
res.append(models.UserRoleAssociation(
211
id=self._create_ref(role_id, tenant_id, user_id),
214
tenant_id=tenant_id))