cartography 0.110.0rc2__py3-none-any.whl → 0.111.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of cartography might be problematic. Click here for more details.
- cartography/_version.py +16 -3
- cartography/cli.py +46 -0
- cartography/config.py +16 -0
- cartography/data/indexes.cypher +0 -2
- cartography/data/jobs/analysis/keycloak_inheritance.json +30 -0
- cartography/graph/querybuilder.py +70 -0
- cartography/intel/aws/apigateway.py +113 -4
- cartography/intel/aws/ec2/vpc.py +140 -124
- cartography/intel/aws/eventbridge.py +73 -0
- cartography/intel/github/repos.py +28 -12
- cartography/intel/github/util.py +12 -0
- cartography/intel/keycloak/__init__.py +153 -0
- cartography/intel/keycloak/authenticationexecutions.py +322 -0
- cartography/intel/keycloak/authenticationflows.py +77 -0
- cartography/intel/keycloak/clients.py +187 -0
- cartography/intel/keycloak/groups.py +126 -0
- cartography/intel/keycloak/identityproviders.py +94 -0
- cartography/intel/keycloak/organizations.py +163 -0
- cartography/intel/keycloak/realms.py +61 -0
- cartography/intel/keycloak/roles.py +202 -0
- cartography/intel/keycloak/scopes.py +73 -0
- cartography/intel/keycloak/users.py +70 -0
- cartography/intel/keycloak/util.py +47 -0
- cartography/models/aws/apigateway/apigatewaydeployment.py +74 -0
- cartography/models/aws/ec2/vpc.py +46 -0
- cartography/models/aws/ec2/vpc_cidr.py +102 -0
- cartography/models/aws/eventbridge/target.py +71 -0
- cartography/models/keycloak/__init__.py +0 -0
- cartography/models/keycloak/authenticationexecution.py +160 -0
- cartography/models/keycloak/authenticationflow.py +54 -0
- cartography/models/keycloak/client.py +177 -0
- cartography/models/keycloak/group.py +101 -0
- cartography/models/keycloak/identityprovider.py +89 -0
- cartography/models/keycloak/organization.py +116 -0
- cartography/models/keycloak/organizationdomain.py +73 -0
- cartography/models/keycloak/realm.py +173 -0
- cartography/models/keycloak/role.py +126 -0
- cartography/models/keycloak/scope.py +73 -0
- cartography/models/keycloak/user.py +51 -0
- cartography/models/tailscale/device.py +1 -0
- cartography/sync.py +2 -0
- cartography/util.py +8 -0
- {cartography-0.110.0rc2.dist-info → cartography-0.111.0.dist-info}/METADATA +2 -1
- {cartography-0.110.0rc2.dist-info → cartography-0.111.0.dist-info}/RECORD +53 -25
- cartography/data/jobs/cleanup/aws_import_vpc_cleanup.json +0 -23
- /cartography/models/aws/{__init__.py → apigateway/__init__.py} +0 -0
- /cartography/models/aws/{apigateway.py → apigateway/apigateway.py} +0 -0
- /cartography/models/aws/{apigatewaycertificate.py → apigateway/apigatewaycertificate.py} +0 -0
- /cartography/models/aws/{apigatewayresource.py → apigateway/apigatewayresource.py} +0 -0
- /cartography/models/aws/{apigatewaystage.py → apigateway/apigatewaystage.py} +0 -0
- {cartography-0.110.0rc2.dist-info → cartography-0.111.0.dist-info}/WHEEL +0 -0
- {cartography-0.110.0rc2.dist-info → cartography-0.111.0.dist-info}/entry_points.txt +0 -0
- {cartography-0.110.0rc2.dist-info → cartography-0.111.0.dist-info}/licenses/LICENSE +0 -0
- {cartography-0.110.0rc2.dist-info → cartography-0.111.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
from typing import Generator
|
|
3
|
+
|
|
4
|
+
import requests
|
|
5
|
+
|
|
6
|
+
# Connect and read timeouts of 60 seconds each; see https://requests.readthedocs.io/en/master/user/advanced/#timeouts
|
|
7
|
+
_TIMEOUT = (60, 60)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def get_paginated(
|
|
11
|
+
api_session: requests.Session,
|
|
12
|
+
endpoint: str,
|
|
13
|
+
items_per_page: int = 100,
|
|
14
|
+
params: dict[str, Any] | None = None,
|
|
15
|
+
) -> Generator[dict[str, Any], None, None]:
|
|
16
|
+
"""Fetch paginated results from a REST API endpoint.
|
|
17
|
+
|
|
18
|
+
This function handles pagination by making multiple requests to the API
|
|
19
|
+
until all pages of results have been retrieved.
|
|
20
|
+
|
|
21
|
+
Args:
|
|
22
|
+
api_session (requests.Session): The requests session to use for making API calls.
|
|
23
|
+
endpoint (str): The API endpoint to fetch data from.
|
|
24
|
+
items_per_page (int, optional): The number of items to retrieve per page. Defaults to 100.
|
|
25
|
+
params (dict[str, Any] | None, optional): Additional query parameters to include in the request. Defaults to None.
|
|
26
|
+
|
|
27
|
+
Yields:
|
|
28
|
+
Generator[dict[str, Any], None, None]: A generator that yields the individual items from the paginated response.
|
|
29
|
+
"""
|
|
30
|
+
has_more = True
|
|
31
|
+
offset = 0
|
|
32
|
+
while has_more:
|
|
33
|
+
if params is None:
|
|
34
|
+
payload = {}
|
|
35
|
+
else:
|
|
36
|
+
payload = params.copy()
|
|
37
|
+
payload["first"] = offset
|
|
38
|
+
payload["max"] = items_per_page
|
|
39
|
+
req = api_session.get(endpoint, params=payload, timeout=_TIMEOUT)
|
|
40
|
+
req.raise_for_status()
|
|
41
|
+
data = req.json()
|
|
42
|
+
if not data:
|
|
43
|
+
break
|
|
44
|
+
yield from data
|
|
45
|
+
if len(data) < items_per_page:
|
|
46
|
+
has_more = False
|
|
47
|
+
offset += len(data)
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
|
|
3
|
+
from cartography.models.core.common import PropertyRef
|
|
4
|
+
from cartography.models.core.nodes import CartographyNodeProperties
|
|
5
|
+
from cartography.models.core.nodes import CartographyNodeSchema
|
|
6
|
+
from cartography.models.core.relationships import CartographyRelProperties
|
|
7
|
+
from cartography.models.core.relationships import CartographyRelSchema
|
|
8
|
+
from cartography.models.core.relationships import LinkDirection
|
|
9
|
+
from cartography.models.core.relationships import make_target_node_matcher
|
|
10
|
+
from cartography.models.core.relationships import OtherRelationships
|
|
11
|
+
from cartography.models.core.relationships import TargetNodeMatcher
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@dataclass(frozen=True)
|
|
15
|
+
class APIGatewayDeploymentNodeProperties(CartographyNodeProperties):
|
|
16
|
+
id: PropertyRef = PropertyRef("id")
|
|
17
|
+
arn: PropertyRef = PropertyRef("id", extra_index=True)
|
|
18
|
+
description: PropertyRef = PropertyRef("description")
|
|
19
|
+
region: PropertyRef = PropertyRef("region", set_in_kwargs=True)
|
|
20
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@dataclass(frozen=True)
|
|
24
|
+
class APIGatewayDeploymentToAWSAccountRelRelProperties(CartographyRelProperties):
|
|
25
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@dataclass(frozen=True)
|
|
29
|
+
# (:APIGatewayDeployment)<-[:RESOURCE]-(:AWSAccount)
|
|
30
|
+
class APIGatewayDeploymentToAWSAccountRel(CartographyRelSchema):
|
|
31
|
+
target_node_label: str = "AWSAccount"
|
|
32
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
33
|
+
{"id": PropertyRef("AWS_ID", set_in_kwargs=True)},
|
|
34
|
+
)
|
|
35
|
+
direction: LinkDirection = LinkDirection.INWARD
|
|
36
|
+
rel_label: str = "RESOURCE"
|
|
37
|
+
properties: APIGatewayDeploymentToAWSAccountRelRelProperties = (
|
|
38
|
+
APIGatewayDeploymentToAWSAccountRelRelProperties()
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
@dataclass(frozen=True)
|
|
43
|
+
class APIGatewayDeploymentToRestAPIRelRelProperties(CartographyRelProperties):
|
|
44
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
@dataclass(frozen=True)
|
|
48
|
+
# (:APIGatewayDeployment)<-[:HAS_DEPLOYMENT]-(:APIGatewayRestAPI)
|
|
49
|
+
class APIGatewayDeploymentToRestAPIRel(CartographyRelSchema):
|
|
50
|
+
target_node_label: str = "APIGatewayRestAPI"
|
|
51
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
52
|
+
{"id": PropertyRef("api_id")},
|
|
53
|
+
)
|
|
54
|
+
direction: LinkDirection = LinkDirection.INWARD
|
|
55
|
+
rel_label: str = "HAS_DEPLOYMENT"
|
|
56
|
+
properties: APIGatewayDeploymentToRestAPIRelRelProperties = (
|
|
57
|
+
APIGatewayDeploymentToRestAPIRelRelProperties()
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
@dataclass(frozen=True)
|
|
62
|
+
class APIGatewayDeploymentSchema(CartographyNodeSchema):
|
|
63
|
+
label: str = "APIGatewayDeployment"
|
|
64
|
+
properties: APIGatewayDeploymentNodeProperties = (
|
|
65
|
+
APIGatewayDeploymentNodeProperties()
|
|
66
|
+
)
|
|
67
|
+
sub_resource_relationship: APIGatewayDeploymentToAWSAccountRel = (
|
|
68
|
+
APIGatewayDeploymentToAWSAccountRel()
|
|
69
|
+
)
|
|
70
|
+
other_relationships: OtherRelationships = OtherRelationships(
|
|
71
|
+
[
|
|
72
|
+
APIGatewayDeploymentToRestAPIRel(),
|
|
73
|
+
]
|
|
74
|
+
)
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
|
|
3
|
+
from cartography.models.core.common import PropertyRef
|
|
4
|
+
from cartography.models.core.nodes import CartographyNodeProperties
|
|
5
|
+
from cartography.models.core.nodes import CartographyNodeSchema
|
|
6
|
+
from cartography.models.core.relationships import CartographyRelProperties
|
|
7
|
+
from cartography.models.core.relationships import CartographyRelSchema
|
|
8
|
+
from cartography.models.core.relationships import LinkDirection
|
|
9
|
+
from cartography.models.core.relationships import make_target_node_matcher
|
|
10
|
+
from cartography.models.core.relationships import TargetNodeMatcher
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@dataclass(frozen=True)
|
|
14
|
+
class VPCNodeProperties(CartographyNodeProperties):
|
|
15
|
+
id: PropertyRef = PropertyRef("VpcId")
|
|
16
|
+
vpcid: PropertyRef = PropertyRef("VpcId", extra_index=True)
|
|
17
|
+
primary_cidr_block: PropertyRef = PropertyRef("PrimaryCIDRBlock")
|
|
18
|
+
instance_tenancy: PropertyRef = PropertyRef("InstanceTenancy")
|
|
19
|
+
state: PropertyRef = PropertyRef("State")
|
|
20
|
+
is_default: PropertyRef = PropertyRef("IsDefault")
|
|
21
|
+
dhcp_options_id: PropertyRef = PropertyRef("DhcpOptionsId")
|
|
22
|
+
region: PropertyRef = PropertyRef("Region", set_in_kwargs=True)
|
|
23
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@dataclass(frozen=True)
|
|
27
|
+
class VPCToAWSAccountRelProperties(CartographyRelProperties):
|
|
28
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
@dataclass(frozen=True)
|
|
32
|
+
class VPCToAWSAccountRel(CartographyRelSchema):
|
|
33
|
+
target_node_label: str = "AWSAccount"
|
|
34
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
35
|
+
{"id": PropertyRef("AWS_ID", set_in_kwargs=True)}
|
|
36
|
+
)
|
|
37
|
+
direction: LinkDirection = LinkDirection.INWARD
|
|
38
|
+
rel_label: str = "RESOURCE"
|
|
39
|
+
properties: VPCToAWSAccountRelProperties = VPCToAWSAccountRelProperties()
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
@dataclass(frozen=True)
|
|
43
|
+
class AWSVpcSchema(CartographyNodeSchema):
|
|
44
|
+
label: str = "AWSVpc"
|
|
45
|
+
properties: VPCNodeProperties = VPCNodeProperties()
|
|
46
|
+
sub_resource_relationship: VPCToAWSAccountRel = VPCToAWSAccountRel()
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
|
|
3
|
+
from cartography.models.core.common import PropertyRef
|
|
4
|
+
from cartography.models.core.nodes import CartographyNodeProperties
|
|
5
|
+
from cartography.models.core.nodes import CartographyNodeSchema
|
|
6
|
+
from cartography.models.core.nodes import ExtraNodeLabels
|
|
7
|
+
from cartography.models.core.relationships import CartographyRelProperties
|
|
8
|
+
from cartography.models.core.relationships import CartographyRelSchema
|
|
9
|
+
from cartography.models.core.relationships import LinkDirection
|
|
10
|
+
from cartography.models.core.relationships import make_target_node_matcher
|
|
11
|
+
from cartography.models.core.relationships import OtherRelationships
|
|
12
|
+
from cartography.models.core.relationships import TargetNodeMatcher
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@dataclass(frozen=True)
|
|
16
|
+
class AWSIPv4CidrBlockNodeProperties(CartographyNodeProperties):
|
|
17
|
+
id: PropertyRef = PropertyRef("Id")
|
|
18
|
+
vpcid: PropertyRef = PropertyRef("VpcId")
|
|
19
|
+
association_id: PropertyRef = PropertyRef("AssociationId")
|
|
20
|
+
cidr_block: PropertyRef = PropertyRef("CidrBlock")
|
|
21
|
+
block_state: PropertyRef = PropertyRef("BlockState")
|
|
22
|
+
block_state_message: PropertyRef = PropertyRef("BlockStateMessage")
|
|
23
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@dataclass(frozen=True)
|
|
27
|
+
class AWSIPv4CidrBlockToAWSVpcRelProperties(CartographyRelProperties):
|
|
28
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
@dataclass(frozen=True)
|
|
32
|
+
class AWSIPv4CidrBlockToAWSVpcRel(CartographyRelSchema):
|
|
33
|
+
target_node_label: str = "AWSVpc"
|
|
34
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
35
|
+
{"id": PropertyRef("VpcId")}
|
|
36
|
+
)
|
|
37
|
+
direction: LinkDirection = LinkDirection.INWARD
|
|
38
|
+
rel_label: str = "BLOCK_ASSOCIATION"
|
|
39
|
+
properties: AWSIPv4CidrBlockToAWSVpcRelProperties = (
|
|
40
|
+
AWSIPv4CidrBlockToAWSVpcRelProperties()
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
@dataclass(frozen=True)
|
|
45
|
+
class AWSIPv4CidrBlockSchema(CartographyNodeSchema):
|
|
46
|
+
"""
|
|
47
|
+
There is no sub-resource relationship here because a
|
|
48
|
+
CIDR block can be associated with more than one account
|
|
49
|
+
and it doesn't make sense to scope it to one.
|
|
50
|
+
"""
|
|
51
|
+
|
|
52
|
+
label: str = "AWSCidrBlock"
|
|
53
|
+
properties: AWSIPv4CidrBlockNodeProperties = AWSIPv4CidrBlockNodeProperties()
|
|
54
|
+
other_relationships: OtherRelationships = OtherRelationships(
|
|
55
|
+
[AWSIPv4CidrBlockToAWSVpcRel()]
|
|
56
|
+
)
|
|
57
|
+
extra_node_labels: ExtraNodeLabels = ExtraNodeLabels(["AWSIpv4CidrBlock"])
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
@dataclass(frozen=True)
|
|
61
|
+
class AWSIPv6CidrBlockNodeProperties(CartographyNodeProperties):
|
|
62
|
+
id: PropertyRef = PropertyRef("Id")
|
|
63
|
+
vpcid: PropertyRef = PropertyRef("VpcId")
|
|
64
|
+
association_id: PropertyRef = PropertyRef("AssociationId")
|
|
65
|
+
cidr_block: PropertyRef = PropertyRef("CidrBlock")
|
|
66
|
+
block_state: PropertyRef = PropertyRef("BlockState")
|
|
67
|
+
block_state_message: PropertyRef = PropertyRef("BlockStateMessage")
|
|
68
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
@dataclass(frozen=True)
|
|
72
|
+
class AWSIPv6CidrBlockToAWSVpcRelProperties(CartographyRelProperties):
|
|
73
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
@dataclass(frozen=True)
|
|
77
|
+
class AWSIPv6CidrBlockToAWSVpcRel(CartographyRelSchema):
|
|
78
|
+
target_node_label: str = "AWSVpc"
|
|
79
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
80
|
+
{"id": PropertyRef("VpcId")}
|
|
81
|
+
)
|
|
82
|
+
direction: LinkDirection = LinkDirection.INWARD
|
|
83
|
+
rel_label: str = "BLOCK_ASSOCIATION"
|
|
84
|
+
properties: AWSIPv6CidrBlockToAWSVpcRelProperties = (
|
|
85
|
+
AWSIPv6CidrBlockToAWSVpcRelProperties()
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
@dataclass(frozen=True)
|
|
90
|
+
class AWSIPv6CidrBlockSchema(CartographyNodeSchema):
|
|
91
|
+
"""
|
|
92
|
+
There is no sub-resource relationship here because a
|
|
93
|
+
CIDR block can be associated with more than one account
|
|
94
|
+
and it doesn't make sense to scope it to one.
|
|
95
|
+
"""
|
|
96
|
+
|
|
97
|
+
label: str = "AWSCidrBlock"
|
|
98
|
+
properties: AWSIPv6CidrBlockNodeProperties = AWSIPv6CidrBlockNodeProperties()
|
|
99
|
+
other_relationships: OtherRelationships = OtherRelationships(
|
|
100
|
+
[AWSIPv6CidrBlockToAWSVpcRel()]
|
|
101
|
+
)
|
|
102
|
+
extra_node_labels: ExtraNodeLabels = ExtraNodeLabels(["AWSIpv6CidrBlock"])
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
|
|
3
|
+
from cartography.models.core.common import PropertyRef
|
|
4
|
+
from cartography.models.core.nodes import CartographyNodeProperties
|
|
5
|
+
from cartography.models.core.nodes import CartographyNodeSchema
|
|
6
|
+
from cartography.models.core.relationships import CartographyRelProperties
|
|
7
|
+
from cartography.models.core.relationships import CartographyRelSchema
|
|
8
|
+
from cartography.models.core.relationships import LinkDirection
|
|
9
|
+
from cartography.models.core.relationships import make_target_node_matcher
|
|
10
|
+
from cartography.models.core.relationships import OtherRelationships
|
|
11
|
+
from cartography.models.core.relationships import TargetNodeMatcher
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@dataclass(frozen=True)
|
|
15
|
+
class EventBridgeTargetNodeProperties(CartographyNodeProperties):
|
|
16
|
+
id: PropertyRef = PropertyRef("Id")
|
|
17
|
+
arn: PropertyRef = PropertyRef("Arn", extra_index=True)
|
|
18
|
+
rule_arn: PropertyRef = PropertyRef("RuleArn")
|
|
19
|
+
role_arn: PropertyRef = PropertyRef("RoleArn")
|
|
20
|
+
region: PropertyRef = PropertyRef("Region", set_in_kwargs=True)
|
|
21
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@dataclass(frozen=True)
|
|
25
|
+
class EventBridgeTargetToAwsAccountRelProperties(CartographyRelProperties):
|
|
26
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@dataclass(frozen=True)
|
|
30
|
+
class EventBridgeTargetToAWSAccountRel(CartographyRelSchema):
|
|
31
|
+
target_node_label: str = "AWSAccount"
|
|
32
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
33
|
+
{"id": PropertyRef("AWS_ID", set_in_kwargs=True)},
|
|
34
|
+
)
|
|
35
|
+
direction: LinkDirection = LinkDirection.INWARD
|
|
36
|
+
rel_label: str = "RESOURCE"
|
|
37
|
+
properties: EventBridgeTargetToAwsAccountRelProperties = (
|
|
38
|
+
EventBridgeTargetToAwsAccountRelProperties()
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
@dataclass(frozen=True)
|
|
43
|
+
class EventBridgeTargetToEventBridgeRuleRelProperties(CartographyRelProperties):
|
|
44
|
+
lastupdated: PropertyRef = PropertyRef("lastupdated", set_in_kwargs=True)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
@dataclass(frozen=True)
|
|
48
|
+
class EventBridgeTargetToEventBridgeRuleRel(CartographyRelSchema):
|
|
49
|
+
target_node_label: str = "EventBridgeRule"
|
|
50
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
51
|
+
{"arn": PropertyRef("RuleArn")},
|
|
52
|
+
)
|
|
53
|
+
direction: LinkDirection = LinkDirection.OUTWARD
|
|
54
|
+
rel_label: str = "LINKED_TO_RULE"
|
|
55
|
+
properties: EventBridgeTargetToEventBridgeRuleRelProperties = (
|
|
56
|
+
EventBridgeTargetToEventBridgeRuleRelProperties()
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
@dataclass(frozen=True)
|
|
61
|
+
class EventBridgeTargetSchema(CartographyNodeSchema):
|
|
62
|
+
label: str = "EventBridgeTarget"
|
|
63
|
+
properties: EventBridgeTargetNodeProperties = EventBridgeTargetNodeProperties()
|
|
64
|
+
sub_resource_relationship: EventBridgeTargetToAWSAccountRel = (
|
|
65
|
+
EventBridgeTargetToAWSAccountRel()
|
|
66
|
+
)
|
|
67
|
+
other_relationships: OtherRelationships = OtherRelationships(
|
|
68
|
+
[
|
|
69
|
+
EventBridgeTargetToEventBridgeRuleRel(),
|
|
70
|
+
]
|
|
71
|
+
)
|
|
File without changes
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
|
|
3
|
+
from cartography.models.core.common import PropertyRef
|
|
4
|
+
from cartography.models.core.nodes import CartographyNodeProperties
|
|
5
|
+
from cartography.models.core.nodes import CartographyNodeSchema
|
|
6
|
+
from cartography.models.core.relationships import CartographyRelProperties
|
|
7
|
+
from cartography.models.core.relationships import CartographyRelSchema
|
|
8
|
+
from cartography.models.core.relationships import LinkDirection
|
|
9
|
+
from cartography.models.core.relationships import make_source_node_matcher
|
|
10
|
+
from cartography.models.core.relationships import make_target_node_matcher
|
|
11
|
+
from cartography.models.core.relationships import OtherRelationships
|
|
12
|
+
from cartography.models.core.relationships import SourceNodeMatcher
|
|
13
|
+
from cartography.models.core.relationships import TargetNodeMatcher
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@dataclass(frozen=True)
|
|
17
|
+
class KeycloakAuthenticationExecutionNodeProperties(CartographyNodeProperties):
|
|
18
|
+
id: PropertyRef = PropertyRef("id")
|
|
19
|
+
display_name: PropertyRef = PropertyRef("displayName")
|
|
20
|
+
requirement: PropertyRef = PropertyRef("requirement")
|
|
21
|
+
description: PropertyRef = PropertyRef("description")
|
|
22
|
+
configurable: PropertyRef = PropertyRef("configurable")
|
|
23
|
+
authentication_flow: PropertyRef = PropertyRef("authenticationFlow")
|
|
24
|
+
provider_id: PropertyRef = PropertyRef("providerId")
|
|
25
|
+
flow_id: PropertyRef = PropertyRef("flowId")
|
|
26
|
+
level: PropertyRef = PropertyRef("level")
|
|
27
|
+
index: PropertyRef = PropertyRef("index")
|
|
28
|
+
priority: PropertyRef = PropertyRef("priority")
|
|
29
|
+
is_terminal_step: PropertyRef = PropertyRef("is_terminal_step")
|
|
30
|
+
lastupdated: PropertyRef = PropertyRef("LASTUPDATED", set_in_kwargs=True)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
@dataclass(frozen=True)
|
|
34
|
+
class KeycloakAuthenticationExecutionToRealmRelProperties(CartographyRelProperties):
|
|
35
|
+
lastupdated: PropertyRef = PropertyRef("LASTUPDATED", set_in_kwargs=True)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
@dataclass(frozen=True)
|
|
39
|
+
# (:KeycloakAuthenticationExecution)<-[:RESOURCE]-(:KeycloakRealm)
|
|
40
|
+
class KeycloakAuthenticationExecutionToRealmRel(CartographyRelSchema):
|
|
41
|
+
target_node_label: str = "KeycloakRealm"
|
|
42
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
43
|
+
{"name": PropertyRef("REALM", set_in_kwargs=True)},
|
|
44
|
+
)
|
|
45
|
+
direction: LinkDirection = LinkDirection.INWARD
|
|
46
|
+
rel_label: str = "RESOURCE"
|
|
47
|
+
properties: KeycloakAuthenticationExecutionToRealmRelProperties = (
|
|
48
|
+
KeycloakAuthenticationExecutionToRealmRelProperties()
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
@dataclass(frozen=True)
|
|
53
|
+
class ExecutionToFlowRelProperties(CartographyRelProperties):
|
|
54
|
+
lastupdated: PropertyRef = PropertyRef("LASTUPDATED", set_in_kwargs=True)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
@dataclass(frozen=True)
|
|
58
|
+
# (:KeycloakAuthenticationExecution)<-[:HAS_STEP]-(:KeycloakAuthenticationFlow)
|
|
59
|
+
class ExecutionToFlowRel(CartographyRelSchema):
|
|
60
|
+
target_node_label: str = "KeycloakAuthenticationFlow"
|
|
61
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
62
|
+
{
|
|
63
|
+
"alias": PropertyRef("_parent_flow"),
|
|
64
|
+
"realm": PropertyRef("REALM", set_in_kwargs=True),
|
|
65
|
+
},
|
|
66
|
+
)
|
|
67
|
+
direction: LinkDirection = LinkDirection.INWARD
|
|
68
|
+
rel_label: str = "HAS_STEP"
|
|
69
|
+
properties: ExecutionToFlowRelProperties = ExecutionToFlowRelProperties()
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
@dataclass(frozen=True)
|
|
73
|
+
class ExecutionToExecutionRelProperties(CartographyRelProperties):
|
|
74
|
+
lastupdated: PropertyRef = PropertyRef("LASTUPDATED", set_in_kwargs=True)
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
@dataclass(frozen=True)
|
|
78
|
+
# (:KeycloakAuthenticationExecution)<-[:HAS_STEP]-(:KeycloakAuthenticationExecution)
|
|
79
|
+
class ExecutionToExecutionRel(CartographyRelSchema):
|
|
80
|
+
target_node_label: str = "KeycloakAuthenticationExecution"
|
|
81
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
82
|
+
{"id": PropertyRef("_parent_subflow")},
|
|
83
|
+
)
|
|
84
|
+
direction: LinkDirection = LinkDirection.INWARD
|
|
85
|
+
rel_label: str = "HAS_STEP"
|
|
86
|
+
properties: ExecutionToExecutionRelProperties = ExecutionToExecutionRelProperties()
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
@dataclass(frozen=True)
|
|
90
|
+
class KeycloakAuthenticationExecutionSchema(CartographyNodeSchema):
|
|
91
|
+
label: str = "KeycloakAuthenticationExecution"
|
|
92
|
+
properties: KeycloakAuthenticationExecutionNodeProperties = (
|
|
93
|
+
KeycloakAuthenticationExecutionNodeProperties()
|
|
94
|
+
)
|
|
95
|
+
sub_resource_relationship: KeycloakAuthenticationExecutionToRealmRel = (
|
|
96
|
+
KeycloakAuthenticationExecutionToRealmRel()
|
|
97
|
+
)
|
|
98
|
+
other_relationships: OtherRelationships = OtherRelationships(
|
|
99
|
+
[ExecutionToFlowRel(), ExecutionToExecutionRel()]
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
# The following relationships are MatchLinks, they are used to modelize all the possible flows
|
|
104
|
+
@dataclass(frozen=True)
|
|
105
|
+
class ExecutionToExecutionStepRelProperties(CartographyRelProperties):
|
|
106
|
+
lastupdated: PropertyRef = PropertyRef("LASTUPDATED", set_in_kwargs=True)
|
|
107
|
+
# Mandatory fields for MatchLinks
|
|
108
|
+
_sub_resource_label: PropertyRef = PropertyRef(
|
|
109
|
+
"_sub_resource_label", set_in_kwargs=True
|
|
110
|
+
)
|
|
111
|
+
_sub_resource_id: PropertyRef = PropertyRef("_sub_resource_id", set_in_kwargs=True)
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
@dataclass(frozen=True)
|
|
115
|
+
# (:KeycloakAuthenticationExecution)-[:NEXT_STEP]->(:KeycloakAuthenticationExecution)
|
|
116
|
+
class ExecutionToExecutionMatchLink(CartographyRelSchema):
|
|
117
|
+
source_node_label: str = "KeycloakAuthenticationExecution"
|
|
118
|
+
source_node_matcher: SourceNodeMatcher = make_source_node_matcher(
|
|
119
|
+
{"id": PropertyRef("source")},
|
|
120
|
+
)
|
|
121
|
+
target_node_label: str = "KeycloakAuthenticationExecution"
|
|
122
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
123
|
+
{"id": PropertyRef("target")},
|
|
124
|
+
)
|
|
125
|
+
direction: LinkDirection = LinkDirection.OUTWARD
|
|
126
|
+
rel_label: str = "NEXT_STEP"
|
|
127
|
+
properties: ExecutionToExecutionStepRelProperties = (
|
|
128
|
+
ExecutionToExecutionStepRelProperties()
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
@dataclass(frozen=True)
|
|
133
|
+
class ExecutionToFlowStepRelProperties(CartographyRelProperties):
|
|
134
|
+
lastupdated: PropertyRef = PropertyRef("LASTUPDATED", set_in_kwargs=True)
|
|
135
|
+
# Mandatory fields for MatchLinks
|
|
136
|
+
_sub_resource_label: PropertyRef = PropertyRef(
|
|
137
|
+
"_sub_resource_label", set_in_kwargs=True
|
|
138
|
+
)
|
|
139
|
+
_sub_resource_id: PropertyRef = PropertyRef("_sub_resource_id", set_in_kwargs=True)
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
@dataclass(frozen=True)
|
|
143
|
+
# (:KeycloakAuthenticationFlow)-[:NEXT_STEP]->(:KeycloakAuthenticationExecution)
|
|
144
|
+
class ExecutionToFlowMatchLink(CartographyRelSchema):
|
|
145
|
+
source_node_label: str = "KeycloakAuthenticationExecution"
|
|
146
|
+
source_node_matcher: SourceNodeMatcher = make_source_node_matcher(
|
|
147
|
+
{"id": PropertyRef("execution_id")},
|
|
148
|
+
)
|
|
149
|
+
target_node_label: str = "KeycloakAuthenticationFlow"
|
|
150
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
151
|
+
{
|
|
152
|
+
"alias": PropertyRef("flow_name"),
|
|
153
|
+
"realm": PropertyRef(
|
|
154
|
+
"realm"
|
|
155
|
+
), # We need to pass the realm to match the flow correctly as aliases can be shared across realms
|
|
156
|
+
},
|
|
157
|
+
)
|
|
158
|
+
direction: LinkDirection = LinkDirection.INWARD
|
|
159
|
+
rel_label: str = "NEXT_STEP"
|
|
160
|
+
properties: ExecutionToFlowStepRelProperties = ExecutionToFlowStepRelProperties()
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
|
|
3
|
+
from cartography.models.core.common import PropertyRef
|
|
4
|
+
from cartography.models.core.nodes import CartographyNodeProperties
|
|
5
|
+
from cartography.models.core.nodes import CartographyNodeSchema
|
|
6
|
+
from cartography.models.core.relationships import CartographyRelProperties
|
|
7
|
+
from cartography.models.core.relationships import CartographyRelSchema
|
|
8
|
+
from cartography.models.core.relationships import LinkDirection
|
|
9
|
+
from cartography.models.core.relationships import make_target_node_matcher
|
|
10
|
+
from cartography.models.core.relationships import TargetNodeMatcher
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@dataclass(frozen=True)
|
|
14
|
+
class KeycloakAuthenticationFlowNodeProperties(CartographyNodeProperties):
|
|
15
|
+
id: PropertyRef = PropertyRef("id")
|
|
16
|
+
alias: PropertyRef = PropertyRef("alias", extra_index=True)
|
|
17
|
+
description: PropertyRef = PropertyRef("description")
|
|
18
|
+
provider_id: PropertyRef = PropertyRef("providerId")
|
|
19
|
+
top_level: PropertyRef = PropertyRef("topLevel")
|
|
20
|
+
built_in: PropertyRef = PropertyRef("builtIn")
|
|
21
|
+
lastupdated: PropertyRef = PropertyRef("LASTUPDATED", set_in_kwargs=True)
|
|
22
|
+
# We need to store the realm name because authentication flows are often referenced by name
|
|
23
|
+
# and not by id, so we need to be able to find the authentication flows by name (that is not unique across realms)
|
|
24
|
+
realm: PropertyRef = PropertyRef("REALM", set_in_kwargs=True, extra_index=True)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@dataclass(frozen=True)
|
|
28
|
+
class KeycloakAuthenticationFlowToRealmRelProperties(CartographyRelProperties):
|
|
29
|
+
lastupdated: PropertyRef = PropertyRef("LASTUPDATED", set_in_kwargs=True)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
@dataclass(frozen=True)
|
|
33
|
+
# (:KeycloakAuthenticationFlow)<-[:RESOURCE]-(:KeycloakRealm)
|
|
34
|
+
class KeycloakAuthenticationFlowToRealmRel(CartographyRelSchema):
|
|
35
|
+
target_node_label: str = "KeycloakRealm"
|
|
36
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
37
|
+
{"name": PropertyRef("REALM", set_in_kwargs=True)},
|
|
38
|
+
)
|
|
39
|
+
direction: LinkDirection = LinkDirection.INWARD
|
|
40
|
+
rel_label: str = "RESOURCE"
|
|
41
|
+
properties: KeycloakAuthenticationFlowToRealmRelProperties = (
|
|
42
|
+
KeycloakAuthenticationFlowToRealmRelProperties()
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
@dataclass(frozen=True)
|
|
47
|
+
class KeycloakAuthenticationFlowSchema(CartographyNodeSchema):
|
|
48
|
+
label: str = "KeycloakAuthenticationFlow"
|
|
49
|
+
properties: KeycloakAuthenticationFlowNodeProperties = (
|
|
50
|
+
KeycloakAuthenticationFlowNodeProperties()
|
|
51
|
+
)
|
|
52
|
+
sub_resource_relationship: KeycloakAuthenticationFlowToRealmRel = (
|
|
53
|
+
KeycloakAuthenticationFlowToRealmRel()
|
|
54
|
+
)
|