Skip to content

Commit 7f2ab39

Browse files
authored
IFC-1305 Clean up permission identifier custom GraphQL code (#8330)
1 parent f2a87b9 commit 7f2ab39

File tree

10 files changed

+95
-50
lines changed

10 files changed

+95
-50
lines changed

backend/infrahub/core/manager.py

Lines changed: 1 addition & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,10 @@
33
from copy import copy
44
from typing import TYPE_CHECKING, Any, Iterable, Literal, TypeVar, overload
55

6-
from infrahub_sdk.utils import deep_merge_dict, is_valid_uuid
6+
from infrahub_sdk.utils import is_valid_uuid
77

88
from infrahub.core.constants import (
99
SYSTEM_USER_ID,
10-
InfrahubKind,
1110
MetadataOptions,
1211
RelationshipCardinality,
1312
RelationshipDirection,
@@ -188,23 +187,6 @@ async def query(
188187
await query.execute(db=db)
189188
node_ids = query.get_node_ids()
190189

191-
if (
192-
fields
193-
and "identifier" in fields
194-
and node_schema.kind
195-
in [
196-
InfrahubKind.BASEPERMISSION,
197-
InfrahubKind.GLOBALPERMISSION,
198-
InfrahubKind.OBJECTPERMISSION,
199-
]
200-
):
201-
# This is a workaround to ensure we are querying the right fields for permissions
202-
# The identifier for permissions needs the same fields as the display label
203-
schema_branch = db.schema.get_schema_branch(name=branch.name)
204-
display_label_fields = schema_branch.generate_fields_for_display_label(name=node_schema.kind)
205-
if display_label_fields:
206-
deep_merge_dict(dicta=fields, dictb=display_label_fields)
207-
208190
response = await cls.get_many(
209191
ids=node_ids,
210192
fields=fields,
@@ -331,20 +313,6 @@ async def query_peers(
331313
if not peers_info:
332314
return []
333315

334-
if fields and "identifier" in fields:
335-
# This is a workaround to ensure we are querying the right fields for permissions
336-
# The identifier for permissions needs the same fields as the display label
337-
peer_schema = schema.get_peer_schema(db=db, branch=branch)
338-
if peer_schema.kind in [
339-
InfrahubKind.BASEPERMISSION,
340-
InfrahubKind.GLOBALPERMISSION,
341-
InfrahubKind.OBJECTPERMISSION,
342-
]:
343-
schema_branch = db.schema.get_schema_branch(name=branch.name)
344-
display_label_fields = schema_branch.generate_fields_for_display_label(name=peer_schema.kind)
345-
if display_label_fields:
346-
deep_merge_dict(dicta=fields, dictb=display_label_fields)
347-
348316
if fetch_peers:
349317
peer_ids = [peer.peer_id for peer in peers_info]
350318
peer_nodes = await cls.get_many(

backend/infrahub/core/schema/definitions/core/permission.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@
3434
read_only=True,
3535
optional=True,
3636
allow_override=AllowOverrideType.NONE,
37-
deprecation="Use permission display_label instead",
3837
),
3938
],
4039
relationships=[

backend/infrahub/graphql/queries/account.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ async def resolve_account_tokens(
7272

7373
class AccountGlobalPermissionNode(ObjectType):
7474
id = Field(String, required=True)
75+
display_label = Field(String, required=True)
7576
description = Field(String, required=False)
7677
name = Field(String, required=True)
7778
action = Field(String, required=True)
@@ -81,6 +82,7 @@ class AccountGlobalPermissionNode(ObjectType):
8182

8283
class AccountObjectPermissionNode(ObjectType):
8384
id = Field(String, required=True)
85+
display_label = Field(String, required=True)
8486
description = Field(String, required=False)
8587
namespace = Field(String, required=True)
8688
name = Field(String, required=True)
@@ -131,6 +133,7 @@ async def resolve_account_permissions(
131133
{
132134
"node": {
133135
"id": obj.id,
136+
"display_label": str(obj),
134137
"description": obj.description,
135138
"action": obj.action,
136139
"decision": obj.decision,
@@ -146,6 +149,7 @@ async def resolve_account_permissions(
146149
{
147150
"node": {
148151
"id": obj.id,
152+
"display_label": str(obj),
149153
"description": obj.description,
150154
"namespace": obj.namespace,
151155
"name": obj.name,

backend/tests/component/graphql/test_core_account.py

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,15 @@ async def test_permissions(
5959
global_permissions {
6060
edges {
6161
node {
62+
display_label
6263
identifier
6364
}
6465
}
6566
}
6667
object_permissions {
6768
edges {
6869
node {
70+
display_label
6971
identifier
7072
}
7173
}
@@ -83,19 +85,44 @@ async def test_permissions(
8385

8486
assert result.errors is None
8587
assert result.data
86-
perms = [edge["node"]["identifier"] for edge in result.data["InfrahubPermissions"]["global_permissions"]["edges"]]
87-
assert perms == [
88-
str(GlobalPermission(action=GlobalPermissions.SUPER_ADMIN.value, decision=PermissionDecision.ALLOW_ALL.value))
88+
perm_display_labels = [
89+
edge["node"]["display_label"] for edge in result.data["InfrahubPermissions"]["global_permissions"]["edges"]
8990
]
90-
91-
perms = [edge["node"]["identifier"] for edge in result.data["InfrahubPermissions"]["object_permissions"]["edges"]]
92-
assert perms == [
93-
str(
94-
ObjectPermission(
95-
namespace="*", name="*", action=PermissionAction.ANY.value, decision=PermissionDecision.ALLOW_ALL.value
91+
perm_identifiers = [
92+
edge["node"]["identifier"] for edge in result.data["InfrahubPermissions"]["global_permissions"]["edges"]
93+
]
94+
assert (
95+
perm_display_labels
96+
== perm_identifiers
97+
== [
98+
str(
99+
GlobalPermission(
100+
action=GlobalPermissions.SUPER_ADMIN.value, decision=PermissionDecision.ALLOW_ALL.value
101+
)
96102
)
97-
)
103+
]
104+
)
105+
106+
perm_display_labels = [
107+
edge["node"]["display_label"] for edge in result.data["InfrahubPermissions"]["object_permissions"]["edges"]
98108
]
109+
perm_identifiers = [
110+
edge["node"]["identifier"] for edge in result.data["InfrahubPermissions"]["object_permissions"]["edges"]
111+
]
112+
assert (
113+
perm_display_labels
114+
== perm_identifiers
115+
== [
116+
str(
117+
ObjectPermission(
118+
namespace="*",
119+
name="*",
120+
action=PermissionAction.ANY.value,
121+
decision=PermissionDecision.ALLOW_ALL.value,
122+
)
123+
)
124+
]
125+
)
99126

100127
gql_params = await prepare_graphql_params(
101128
db=db,

frontend/app/src/shared/api/graphql/graphql-env.d.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44
export type introspection_types = {
55
'AccountGlobalPermissionEdge': { kind: 'OBJECT'; name: 'AccountGlobalPermissionEdge'; fields: { 'node': { name: 'node'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'OBJECT'; name: 'AccountGlobalPermissionNode'; ofType: null; }; } }; }; };
66
'AccountGlobalPermissionEdges': { kind: 'OBJECT'; name: 'AccountGlobalPermissionEdges'; fields: { 'count': { name: 'count'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'Int'; ofType: null; }; } }; 'edges': { name: 'edges'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'OBJECT'; name: 'AccountGlobalPermissionEdge'; ofType: null; }; }; }; } }; }; };
7-
'AccountGlobalPermissionNode': { kind: 'OBJECT'; name: 'AccountGlobalPermissionNode'; fields: { 'action': { name: 'action'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; } }; 'decision': { name: 'decision'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; } }; 'description': { name: 'description'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'id': { name: 'id'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; } }; 'identifier': { name: 'identifier'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; } }; 'name': { name: 'name'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; } }; }; };
7+
'AccountGlobalPermissionNode': { kind: 'OBJECT'; name: 'AccountGlobalPermissionNode'; fields: { 'action': { name: 'action'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; } }; 'decision': { name: 'decision'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; } }; 'description': { name: 'description'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'display_label': { name: 'display_label'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; } }; 'id': { name: 'id'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; } }; 'identifier': { name: 'identifier'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; } }; 'name': { name: 'name'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; } }; }; };
88
'AccountObjectPermissionEdge': { kind: 'OBJECT'; name: 'AccountObjectPermissionEdge'; fields: { 'node': { name: 'node'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'OBJECT'; name: 'AccountObjectPermissionNode'; ofType: null; }; } }; }; };
99
'AccountObjectPermissionEdges': { kind: 'OBJECT'; name: 'AccountObjectPermissionEdges'; fields: { 'count': { name: 'count'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'Int'; ofType: null; }; } }; 'edges': { name: 'edges'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'OBJECT'; name: 'AccountObjectPermissionEdge'; ofType: null; }; }; }; } }; }; };
10-
'AccountObjectPermissionNode': { kind: 'OBJECT'; name: 'AccountObjectPermissionNode'; fields: { 'action': { name: 'action'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; } }; 'decision': { name: 'decision'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; } }; 'description': { name: 'description'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'id': { name: 'id'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; } }; 'identifier': { name: 'identifier'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; } }; 'name': { name: 'name'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; } }; 'namespace': { name: 'namespace'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; } }; }; };
10+
'AccountObjectPermissionNode': { kind: 'OBJECT'; name: 'AccountObjectPermissionNode'; fields: { 'action': { name: 'action'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; } }; 'decision': { name: 'decision'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; } }; 'description': { name: 'description'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'display_label': { name: 'display_label'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; } }; 'id': { name: 'id'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; } }; 'identifier': { name: 'identifier'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; } }; 'name': { name: 'name'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; } }; 'namespace': { name: 'namespace'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; } }; }; };
1111
'AccountPermissionsEdges': { kind: 'OBJECT'; name: 'AccountPermissionsEdges'; fields: { 'global_permissions': { name: 'global_permissions'; type: { kind: 'OBJECT'; name: 'AccountGlobalPermissionEdges'; ofType: null; } }; 'object_permissions': { name: 'object_permissions'; type: { kind: 'OBJECT'; name: 'AccountObjectPermissionEdges'; ofType: null; } }; }; };
1212
'AccountTokenEdge': { kind: 'OBJECT'; name: 'AccountTokenEdge'; fields: { 'node': { name: 'node'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'OBJECT'; name: 'AccountTokenNode'; ofType: null; }; } }; }; };
1313
'AccountTokenEdges': { kind: 'OBJECT'; name: 'AccountTokenEdges'; fields: { 'count': { name: 'count'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'Int'; ofType: null; }; } }; 'edges': { name: 'edges'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'OBJECT'; name: 'AccountTokenEdge'; ofType: null; }; }; }; } }; }; };

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "infrahub-server"
3-
version = "1.7.4"
3+
version = "1.8.0b0"
44
description = "Infrahub is taking a new approach to Infrastructure Management by providing a new generation of datastore to organize and control all the data that defines how an infrastructure should run."
55
authors = [{ name = "OpsMill", email = "info@opsmill.com" }]
66
requires-python = ">=3.12,<3.15"

python_testcontainers/pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "infrahub-testcontainers"
3-
version = "1.7.4"
3+
version = "1.8.0b0"
44
requires-python = ">=3.10"
55

66
description = "Testcontainers instance for Infrahub to easily build integration tests"

python_testcontainers/uv.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

schema/schema.graphql

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ type AccountGlobalPermissionNode {
1111
action: String!
1212
decision: String!
1313
description: String
14+
display_label: String!
1415
id: String!
1516
identifier: String!
1617
name: String!
@@ -29,6 +30,7 @@ type AccountObjectPermissionNode {
2930
action: String!
3031
decision: String!
3132
description: String
33+
display_label: String!
3234
id: String!
3335
identifier: String!
3436
name: String!

0 commit comments

Comments
 (0)