Skip to content

Commit b3e4587

Browse files
committed
Fix conflicting permissions resolver.
1 parent 7ec6b48 commit b3e4587

File tree

3 files changed

+65
-1
lines changed

3 files changed

+65
-1
lines changed

backend/infrahub/graphql/manager.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
default_resolver,
4949
descendants_resolver,
5050
many_relationship_resolver,
51+
parent_field_name_resolver,
5152
single_relationship_resolver,
5253
)
5354
from .schema import InfrahubBaseMutation, InfrahubBaseQuery
@@ -886,7 +887,9 @@ def generate_graphql_paginated_object(
886887
}
887888

888889
if isinstance(schema, (NodeSchema, GenericSchema)):
889-
main_attrs["permissions"] = graphene.Field(PaginatedObjectPermission, required=True)
890+
main_attrs["permissions"] = graphene.Field(
891+
PaginatedObjectPermission, required=True, resolver=parent_field_name_resolver
892+
)
890893

891894
graphql_paginated_object = type(object_name, (InfrahubObject,), main_attrs)
892895

backend/infrahub/graphql/resolver.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,15 @@ async def default_resolver(*args: Any, **kwargs) -> dict | list[dict] | None:
118118
return await objs[0].to_graphql(db=db, fields=fields, related_node_ids=context.related_node_ids)
119119

120120

121+
async def parent_field_name_resolver(parent: dict[str, dict], info: GraphQLResolveInfo) -> dict:
122+
"""This resolver gets used when we know that the parent resolver has already gathered the required information.
123+
124+
An example of this is the permissions field at the top level within default_paginated_list_resolver()
125+
"""
126+
127+
return parent[info.field_name]
128+
129+
121130
async def default_paginated_list_resolver(
122131
root: dict, # pylint: disable=unused-argument
123132
info: GraphQLResolveInfo,

backend/tests/unit/graphql/queries/test_list_permissions.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,31 @@
6363
"""
6464

6565

66+
QUERY_ACCOUNT_ROLE = """
67+
query {
68+
CoreAccountRole {
69+
edges {
70+
node {
71+
display_label
72+
}
73+
}
74+
permissions {
75+
count
76+
edges {
77+
node {
78+
kind
79+
create
80+
update
81+
delete
82+
view
83+
}
84+
}
85+
}
86+
}
87+
}
88+
"""
89+
90+
6691
class TestObjectPermissions:
6792
async def test_setup(
6893
self,
@@ -231,6 +256,33 @@ async def test_first_account_list_permissions_for_generics(
231256
}
232257
} in result.data["CoreGenericRepository"]["permissions"]["edges"]
233258

259+
async def test_first_account_account_role(
260+
self, db: InfrahubDatabase, permissions_helper: PermissionsHelper
261+
) -> None:
262+
"""In the main branch the first account doesn't have the permission to make changes, but it has in the other branches"""
263+
session = AccountSession(
264+
authenticated=True, account_id=permissions_helper.first.id, session_id=str(uuid4()), auth_type=AuthType.JWT
265+
)
266+
gql_params = prepare_graphql_params(
267+
db=db, include_mutation=True, branch=permissions_helper.default_branch, account_session=session
268+
)
269+
270+
result = await graphql(schema=gql_params.schema, source=QUERY_ACCOUNT_ROLE, context_value=gql_params.context)
271+
272+
assert not result.errors
273+
assert result.data
274+
assert result.data["CoreAccountRole"]["permissions"]["count"] == 1
275+
assert result.data["CoreAccountRole"]["permissions"]["edges"][0] == {
276+
"node": {
277+
"kind": "CoreAccountRole",
278+
"create": PermissionDecision.ALLOW_OTHER.name,
279+
"update": PermissionDecision.ALLOW_OTHER.name,
280+
"delete": PermissionDecision.ALLOW_OTHER.name,
281+
"view": PermissionDecision.ALLOW_ALL.name,
282+
}
283+
}
284+
assert result.data["CoreAccountRole"]["edges"][0]["node"]["display_label"] == "admin"
285+
234286

235287
QUERY_TAGS_ATTR = """
236288
query {

0 commit comments

Comments
 (0)