Skip to content

Commit 18ce59d

Browse files
authored
Merge pull request #362 from TeskaLabs/feature/limit-credentials-list-by-tenant
Fix searching credentials with multiple filters
2 parents a92661d + fbc03aa commit 18ce59d

File tree

3 files changed

+25
-7
lines changed

3 files changed

+25
-7
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
## v24.06
44

55
### Pre-releases
6+
- `v24.06-alpha14`
67
- `v24.06-alpha13`
78
- `v24.06-alpha12`
89
- `v24.06-alpha11`
@@ -25,6 +26,7 @@
2526
- Disable special characters in tenant ID (#349, `v24.06-alpha6`)
2627

2728
### Fix
29+
- Fix searching credentials with multiple filters (#362, `v24.06-alpha14`)
2830
- Better TOTP error responses (#352, `v24.06-alpha10`)
2931
- Fix resource editability (#355, `v24.06-alpha9`)
3032
- Make FIDO MDS request non-blocking using TaskService (#354, `v24.06-alpha8`)

seacatauth/credentials/handler.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,8 +195,10 @@ async def list_credentials(self, request):
195195
mode = request.query.get("m", "default")
196196
if mode == "role":
197197
search.AdvancedFilter["role"] = request.query.get("f")
198+
search.SimpleFilter = None
198199
elif mode == "tenant":
199200
search.AdvancedFilter["tenant"] = request.query.get("f")
201+
search.SimpleFilter = None
200202
elif mode == "default":
201203
search.SimpleFilter = request.query.get("f")
202204

@@ -215,6 +217,7 @@ async def list_credentials(self, request):
215217
return asab.web.rest.json_response(request, {
216218
"data": result["data"],
217219
"count": result["count"],
220+
"result": "OK",
218221
})
219222

220223

seacatauth/credentials/service.py

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ async def list(self, session: SessionAdapter, search_params: generic.SearchParam
206206
List credentials that are members of currently authorized tenants.
207207
Global_search lists all credentials, regardless of tenants, but this requires superuser authorization.
208208
"""
209+
# TODO: Searching with filters is very inefficient and needs serious optimization
209210
if len(search_params.AdvancedFilter) > 1:
210211
raise asab.exceptions.ValidationError("No more than one advanced filter at a time is supported.")
211212

@@ -260,8 +261,7 @@ async def list(self, session: SessionAdapter, search_params: generic.SearchParam
260261
estimated_count = None
261262
if searched_roles:
262263
role_svc = self.App.get_service("seacatauth.RoleService")
263-
assignments = await role_svc.list_role_assignments(
264-
role_id=searched_roles, page=search_params.Page, limit=search_params.ItemsPerPage)
264+
assignments = await role_svc.list_role_assignments(role_id=searched_roles)
265265
if filtered_cids is None:
266266
filtered_cids = set(a["c"] for a in assignments["data"])
267267
estimated_count = assignments["count"]
@@ -271,8 +271,7 @@ async def list(self, session: SessionAdapter, search_params: generic.SearchParam
271271
if searched_tenants:
272272
tenant_svc = self.App.get_service("seacatauth.TenantService")
273273
provider = tenant_svc.get_provider()
274-
assignments = await provider.list_tenant_assignments(
275-
searched_tenants, page=search_params.Page, limit=search_params.ItemsPerPage)
274+
assignments = await provider.list_tenant_assignments(searched_tenants)
276275
if filtered_cids is None:
277276
filtered_cids = set(a["c"] for a in assignments["data"])
278277
estimated_count = assignments["count"]
@@ -285,20 +284,34 @@ async def list(self, session: SessionAdapter, search_params: generic.SearchParam
285284
return {"count": 0, "data": []}
286285

287286
credentials = []
288-
total_count = estimated_count
287+
filtered_cids = sorted(filtered_cids)
289288

289+
offset = search_params.Page * search_params.ItemsPerPage
290290
for cid in filtered_cids:
291291
_, provider_id, _ = cid.split(":", 2)
292292
try:
293293
provider = self.CredentialProviders[provider_id]
294-
credentials.append(await provider.get(cid))
294+
cred_data = await provider.get(cid)
295295
except KeyError:
296296
L.info("Found an assignment of nonexisting credentials", struct_data={
297297
"cid": cid, "role_ids": searched_roles, "tenant_ids": searched_tenants})
298+
continue
299+
if not search_params.SimpleFilter or (
300+
cred_data.get("username", "").startswith(search_params.SimpleFilter)
301+
or cred_data.get("email", "").startswith(search_params.SimpleFilter)
302+
):
303+
if offset > 0:
304+
# Skip until offset is reached
305+
offset -= 1
306+
continue
307+
credentials.append(cred_data)
308+
if len(credentials) >= search_params.ItemsPerPage:
309+
# Page is full
310+
break
298311

299312
return {
300313
"data": credentials,
301-
"count": total_count,
314+
"count": estimated_count,
302315
}
303316

304317
# Search without external filters

0 commit comments

Comments
 (0)