Skip to content

Commit 25827d0

Browse files
For Role Requests, filter owners for Role search in the API (#252)
1 parent 8327347 commit 25827d0

File tree

6 files changed

+43
-6
lines changed

6 files changed

+43
-6
lines changed

api/swagger.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2455,6 +2455,12 @@
24552455
"name": "q",
24562456
"required": false,
24572457
"type": "string"
2458+
},
2459+
{
2460+
"in": "query",
2461+
"name": "owner_id",
2462+
"required": false,
2463+
"type": "string"
24582464
}
24592465
],
24602466
"responses": {

api/views/resources/role.py

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,15 @@
77
from api.apispec import FlaskApiSpecDecorators
88
from api.authorization import AuthorizationHelpers
99
from api.extensions import db
10-
from api.models import AppGroup, OktaGroup, OktaGroupTagMap, OktaUserGroupMember, RoleGroup, RoleGroupMap
10+
from api.models import AppGroup, OktaGroup, OktaGroupTagMap, OktaUser, OktaUserGroupMember, RoleGroup, RoleGroupMap
1111
from api.operations import ModifyRoleGroups
1212
from api.operations.constraints import CheckForReason, CheckForSelfAdd
1313
from api.pagination import paginate
1414
from api.views.schemas import (
1515
RoleGroupSchema,
1616
RoleMemberSchema,
1717
RolePaginationSchema,
18-
SearchPaginationRequestSchema,
18+
SearchRolePaginationRequestSchema,
1919
)
2020

2121
ALL_GROUP_TYPES = with_polymorphic(OktaGroup, [AppGroup, RoleGroup], flat=True)
@@ -238,13 +238,38 @@ def put(self, role_id: str) -> ResponseReturnValue:
238238

239239

240240
class RoleList(MethodResource):
241-
@FlaskApiSpecDecorators.request_schema(SearchPaginationRequestSchema, location="query")
241+
@FlaskApiSpecDecorators.request_schema(SearchRolePaginationRequestSchema, location="query")
242242
@FlaskApiSpecDecorators.response_schema(RolePaginationSchema)
243243
def get(self) -> ResponseReturnValue:
244-
search_args = SearchPaginationRequestSchema().load(request.args)
244+
search_args = SearchRolePaginationRequestSchema().load(request.args)
245245

246246
query = RoleGroup.query.filter(RoleGroup.deleted_at.is_(None)).order_by(func.lower(RoleGroup.name))
247247

248+
if "owner_id" in search_args:
249+
owner_id = search_args["owner_id"]
250+
if owner_id == "@me":
251+
owner_id = g.current_user_id
252+
owner = (
253+
OktaUser.query.filter(db.or_(OktaUser.id == owner_id, OktaUser.email.ilike(owner_id)))
254+
.order_by(nullsfirst(OktaUser.deleted_at.desc()))
255+
.first_or_404()
256+
)
257+
owner_group_ownerships = (
258+
OktaUserGroupMember.query.filter(OktaUserGroupMember.user_id == owner.id)
259+
.filter(OktaUserGroupMember.is_owner.is_(True))
260+
.filter(
261+
db.or_(
262+
OktaUserGroupMember.ended_at.is_(None),
263+
OktaUserGroupMember.ended_at > db.func.now(),
264+
)
265+
)
266+
)
267+
query = query.filter(
268+
RoleGroup.id.in_(
269+
[o.group_id for o in owner_group_ownerships.with_entities(OktaUserGroupMember.group_id).all()]
270+
),
271+
)
272+
248273
# Implement basic search with the "q" url parameter
249274
if "q" in search_args and len(search_args["q"]) > 0:
250275
like_search = f"%{search_args['q']}%"

api/views/schemas/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
SearchGroupPaginationRequestSchema,
3434
SearchGroupRoleAuditPaginationRequestSchema,
3535
SearchPaginationRequestSchema,
36+
SearchRolePaginationRequestSchema,
3637
SearchRoleRequestPaginationRequestSchema,
3738
SearchUserGroupAuditPaginationRequestSchema,
3839
TagPaginationSchema,
@@ -76,6 +77,7 @@
7677
"SearchGroupPaginationRequestSchema",
7778
"SearchGroupRoleAuditPaginationRequestSchema",
7879
"SearchPaginationRequestSchema",
80+
"SearchRolePaginationRequestSchema",
7981
"SearchRoleRequestPaginationRequestSchema",
8082
"SearchUserGroupAuditPaginationRequestSchema",
8183
"TagPaginationSchema",

api/views/schemas/pagination.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ class SearchGroupPaginationRequestSchema(SearchPaginationRequestSchema):
2626
managed = fields.Boolean(load_only=True)
2727

2828

29+
class SearchRolePaginationRequestSchema(SearchPaginationRequestSchema):
30+
owner_id = fields.String(load_only=True)
31+
32+
2933
class AuditOrderBy(Enum):
3034
moniker = 1 # Enum has a field called "name", so we can't use that
3135
created_at = 2

src/api/apiComponents.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -845,6 +845,7 @@ export type GetRolesQueryParams = {
845845
page?: number;
846846
per_page?: number;
847847
q?: string;
848+
owner_id?: string;
848849
};
849850

850851
export type GetRolesError = Fetcher.ErrorWrapper<{

src/pages/role_requests/Create.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -209,11 +209,10 @@ function CreateRequestContainer(props: CreateRequestContainerProps) {
209209
page: 0,
210210
per_page: 10,
211211
q: roleSearchInput,
212+
owner_id: '@me',
212213
},
213214
});
214215
let roleSearchOptions = roleSearchData?.results ?? [];
215-
// Filter to only show roles owned by the current user
216-
roleSearchOptions = roleSearchOptions.filter((group) => ownedGroups.includes(group.id ?? ''));
217216

218217
const {data: groupSearchData} = useGetGroups({
219218
queryParams: {

0 commit comments

Comments
 (0)