Skip to content

Commit 606ef60

Browse files
committed
fix dupliactes in fetch roles
1 parent 647080a commit 606ef60

1 file changed

Lines changed: 36 additions & 56 deletions

File tree

  • wavefront/server/modules/user_management_module/user_management_module/controllers

wavefront/server/modules/user_management_module/user_management_module/controllers/access_controller.py

Lines changed: 36 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -268,75 +268,55 @@ async def get_role(
268268
content=response_formatter.buildErrorResponse('Access denied'),
269269
)
270270
item_to_select = select_item.split(',') if select_item else []
271-
valid_columns = []
272271
for item in item_to_select:
273-
if not getattr(Role, item):
272+
if not hasattr(Role, item):
274273
return JSONResponse(
275274
status_code=status.HTTP_400_BAD_REQUEST,
276275
content=response_formatter.buildErrorResponse(
277276
error=f'Invalid column {item}'
278277
),
279278
)
280-
valid_columns.append(getattr(Role, item))
281279

282-
search_filter = None
280+
# Roles having at least one resource in the requested scopes. The IN-subquery
281+
# keeps the outer query join-free, so each role is returned exactly once.
282+
filters = [
283+
Role.id.in_(
284+
select(RoleResource.role_id)
285+
.join(Resource, Resource.id == RoleResource.resource_id)
286+
.where(Resource.scope.in_(scopes))
287+
)
288+
]
283289
if search and search.strip():
284290
term = f'%{search.strip()}%'
285-
search_filter = or_(Role.name.ilike(term), Role.description.ilike(term))
291+
filters.append(or_(Role.name.ilike(term), Role.description.ilike(term)))
286292

287293
async with role_repository.session() as session:
288-
if valid_columns:
289-
statement = select(Role).options(selectinload(Role.resources))
290-
count_statement = select(func.count()).select_from(Role)
291-
if search_filter is not None:
292-
statement = statement.where(search_filter)
293-
count_statement = count_statement.where(search_filter)
294-
295-
total = (await session.execute(count_statement)).scalar() or 0
296-
297-
statement = statement.offset(offset)
298-
if limit is not None:
299-
statement = statement.limit(limit)
300-
result = await session.execute(statement)
301-
roles = result.scalars().unique().all()
302-
data = []
303-
for role in roles:
304-
role_dict = {}
305-
for col in item_to_select:
306-
if col == 'resources':
307-
role_dict[col] = [
308-
resource.to_dict() for resource in role.resources
309-
]
310-
else:
311-
role_dict[col] = str(getattr(role, col))
312-
data.append(role_dict)
313-
else:
314-
statement = (
315-
select(Role)
316-
.join(RoleResource, Role.id == RoleResource.role_id)
317-
.join(Resource, Resource.id == RoleResource.resource_id)
318-
.where(Resource.scope.in_(scopes))
319-
.distinct()
294+
total = (
295+
await session.execute(
296+
select(func.count()).select_from(Role).where(*filters)
320297
)
321-
count_statement = (
322-
select(func.count(func.distinct(Role.id)))
323-
.select_from(Role)
324-
.join(RoleResource, Role.id == RoleResource.role_id)
325-
.join(Resource, Resource.id == RoleResource.resource_id)
326-
.where(Resource.scope.in_(scopes))
327-
)
328-
if search_filter is not None:
329-
statement = statement.where(search_filter)
330-
count_statement = count_statement.where(search_filter)
331-
332-
total = (await session.execute(count_statement)).scalar() or 0
333-
334-
statement = statement.offset(offset)
335-
if limit is not None:
336-
statement = statement.limit(limit)
337-
result: Result = await session.execute(statement)
338-
roles = result.scalars().unique().all()
339-
298+
).scalar() or 0
299+
300+
statement = select(Role).where(*filters)
301+
if 'resources' in item_to_select:
302+
statement = statement.options(selectinload(Role.resources))
303+
statement = statement.offset(offset)
304+
if limit is not None:
305+
statement = statement.limit(limit)
306+
307+
roles = (await session.execute(statement)).scalars().all()
308+
309+
if item_to_select:
310+
data = [
311+
{
312+
col: [resource.to_dict() for resource in role.resources]
313+
if col == 'resources'
314+
else str(getattr(role, col))
315+
for col in item_to_select
316+
}
317+
for role in roles
318+
]
319+
else:
340320
data = [role.to_dict() for role in roles]
341321

342322
return JSONResponse(

0 commit comments

Comments
 (0)