openhound-github 0.13.1__py3-none-any.whl → 0.14.2.dev2__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.
openhound_github/graph.py CHANGED
@@ -4,6 +4,9 @@ from openhound.core.models.entries_dataclass import EdgeProperties
4
4
  from openhound.core.models.entries_dataclass import Node as BaseNode
5
5
  from openhound.core.models.entries_dataclass import NodeProperties as BaseProperties
6
6
 
7
+ GITHUB_SOURCE_KIND = "GitHub"
8
+ SAML_SOURCE_KIND = "SAML"
9
+
7
10
 
8
11
  @dataclass
9
12
  class GHNodeProperties(BaseProperties):
@@ -22,6 +25,13 @@ class GHNode(BaseNode):
22
25
  # Use GitHub's native node_id as the OpenGraph node id so edges can
23
26
  # reference nodes by the same identifier used during collection.
24
27
  self.id = self.properties.node_id
28
+ source_kind = (
29
+ SAML_SOURCE_KIND
30
+ if any(kind.startswith("SAML_") for kind in self.kinds)
31
+ else GITHUB_SOURCE_KIND
32
+ )
33
+ if source_kind not in self.kinds:
34
+ self.kinds.append(source_kind)
25
35
 
26
36
 
27
37
  @dataclass
openhound_github/main.py CHANGED
@@ -8,7 +8,7 @@ from openhound.core.preproc import PreProcContext
8
8
  from .lookup import GithubLookup
9
9
  from .transforms import transforms
10
10
 
11
- app = OpenHound("github", source_kind="GitHub", help="OpenGraph collector for GitHub")
11
+ app = OpenHound("github", help="OpenGraph collector for GitHub")
12
12
 
13
13
 
14
14
  @app.collect()
@@ -15,6 +15,7 @@ class GHOrganizationProperties(GHNodeProperties):
15
15
  """Organization-specific properties and accordion panel queries.
16
16
 
17
17
  Attributes:
18
+ database_id: The organization's numeric GitHub database ID used in immutable OIDC subjects.
18
19
  login: The organization's login handle (URL slug).
19
20
  org_name: The organization's display name (from the `name` field in the GitHub API).
20
21
  description: The organization's description.
@@ -88,6 +89,7 @@ class GHOrganizationProperties(GHNodeProperties):
88
89
  collected: The collected property.
89
90
  """
90
91
 
92
+ database_id: int | None = None
91
93
  login: str | None = None
92
94
  org_name: str | None = None
93
95
  description: str | None = None
@@ -176,6 +178,7 @@ class Organization(BaseAsset):
176
178
 
177
179
  node_id: str
178
180
  login: str
181
+ database_id: int | None = None
179
182
  name: str | None = None
180
183
  description: str | None = None
181
184
  company: str | None = None
@@ -245,6 +248,7 @@ class Organization(BaseAsset):
245
248
  name=self.login,
246
249
  displayname=self.name or self.login,
247
250
  node_id=oid,
251
+ database_id=self.database_id,
248
252
  login=self.login,
249
253
  org_name=self.name or "",
250
254
  description=self.description,
@@ -18,6 +18,7 @@ class GHRepositoryProperties(GHNodeProperties):
18
18
 
19
19
  Attributes:
20
20
  collected: Collected/generated by OpenHound
21
+ database_id: The repository's numeric GitHub database ID used in immutable OIDC subjects.
21
22
  full_name: The fully qualified name (e.g., `org/repo`).
22
23
  private: Whether the repository is private.
23
24
  html_url: URL to the repository on GitHub.
@@ -37,7 +38,8 @@ class GHRepositoryProperties(GHNodeProperties):
37
38
  open_issues: Number of open issues (includes pull requests).
38
39
  watchers: Number of watchers.
39
40
  owner_name: The login of the repository owner.
40
- owner_id: The owner id property.
41
+ owner_id: The opaque GraphQL node ID of the repository owner.
42
+ owner_database_id: The numeric GitHub database ID of the repository owner used in immutable OIDC subjects.
41
43
  environment_name: The name of the environment (GitHub organization).
42
44
  actions_enabled: Whether GitHub Actions is enabled for this repository.
43
45
  self_hosted_runners_enabled: Whether the repository may use self-hosted runners.
@@ -70,6 +72,7 @@ class GHRepositoryProperties(GHNodeProperties):
70
72
  collected: bool = True
71
73
 
72
74
  # TODO: Check owner_node_id
75
+ database_id: int | None = None
73
76
  full_name: str | None = None
74
77
  private: bool | None = None
75
78
  html_url: str | None = None
@@ -90,6 +93,7 @@ class GHRepositoryProperties(GHNodeProperties):
90
93
  watchers: int | None = None
91
94
  owner_name: str | None = None
92
95
  owner_id: str | None = None
96
+ owner_database_id: int | None = None
93
97
  environment_name: str | None = None
94
98
  actions_enabled: bool | None = None
95
99
  self_hosted_runners_enabled: bool | None = None
@@ -201,6 +205,7 @@ class Repository(BaseAsset):
201
205
  node_id: str
202
206
  name: str
203
207
  full_name: str
208
+ database_id: int | None = None
204
209
 
205
210
  private: bool
206
211
  owner: Owner
@@ -238,6 +243,10 @@ class Repository(BaseAsset):
238
243
  def owner_name(self) -> str:
239
244
  return self.owner.login
240
245
 
246
+ @property
247
+ def owner_database_id(self) -> int:
248
+ return self.owner.id
249
+
241
250
  @property
242
251
  def as_node(self) -> GHNode:
243
252
  rid = self.node_id
@@ -255,6 +264,7 @@ class Repository(BaseAsset):
255
264
  name=self.name,
256
265
  displayname=self.full_name,
257
266
  node_id=rid,
267
+ database_id=self.database_id,
258
268
  full_name=self.full_name,
259
269
  private=self.private,
260
270
  html_url=self.html_url,
@@ -275,6 +285,7 @@ class Repository(BaseAsset):
275
285
  watchers=self.watchers,
276
286
  owner_name=self.owner_name or "",
277
287
  owner_id=self.owner_id or "",
288
+ owner_database_id=self.owner_database_id,
278
289
  environment_name=self.org_login,
279
290
  environmentid=self.org_node_id,
280
291
  actions_enabled=self.actions_enabled,
@@ -23,6 +23,8 @@ from openhound_github.kinds import nodes as nk
23
23
  from openhound_github.main import app
24
24
  from openhound_github.models.saml_helpers import detect_foreign_idp
25
25
 
26
+ SCIM_SOURCE_KIND = "SCIM"
27
+
26
28
 
27
29
  def scim_organization_id(scope_node_id: str) -> str:
28
30
  return f"SCIM_Organization_{scope_node_id}"
@@ -40,7 +42,6 @@ class ScimNodeProperties(NodeProperties):
40
42
  profile_url: str | None = None
41
43
  enterprise: str | None = None
42
44
  organization: str | None = None
43
- source_kind: str | None = None
44
45
 
45
46
 
46
47
  @dataclass
@@ -48,7 +49,8 @@ class ScimNode(Node):
48
49
  id: str
49
50
 
50
51
  def __post_init__(self):
51
- return None
52
+ if SCIM_SOURCE_KIND not in self.kinds:
53
+ self.kinds.append(SCIM_SOURCE_KIND)
52
54
 
53
55
 
54
56
  class Name(BaseModel):
@@ -128,7 +130,6 @@ class ScimOrganization(ScimScopeAsset):
128
130
  environmentid=self.scope_node_id,
129
131
  enterprise=self.enterprise_slug,
130
132
  organization=self.org_login,
131
- source_kind="GitHub",
132
133
  ),
133
134
  )
134
135
 
@@ -210,7 +211,6 @@ class ScimUser(ScimScopeAsset):
210
211
  profile_url=self.meta.location if self.meta else None,
211
212
  enterprise=self.enterprise_slug,
212
213
  organization=self.org_login,
213
- source_kind="GitHub",
214
214
  ),
215
215
  )
216
216
 
@@ -306,7 +306,6 @@ class ScimGroup(ScimScopeAsset):
306
306
  external_id=self.external_id,
307
307
  enterprise=self.enterprise_slug,
308
308
  organization=self.org_login,
309
- source_kind="GitHub",
310
309
  ),
311
310
  )
312
311
 
@@ -510,6 +510,7 @@ def organizations(ctx: SourceContext):
510
510
  org_data["can_approve_pull_request_reviews"] = workflow_perms.get(
511
511
  "can_approve_pull_request_reviews"
512
512
  )
513
+ org_data["database_id"] = org_data.get("id")
513
514
  org_data["github_deployment_type"] = ctx.deployment_type
514
515
  org_data["ghes_version"] = ctx.ghes_version
515
516
 
@@ -1008,6 +1009,7 @@ def repositories(ctx: SourceContext):
1008
1009
  )
1009
1010
  yield {
1010
1011
  **repo,
1012
+ "database_id": repo.get("id"),
1011
1013
  "actions_enabled": actions_enabled,
1012
1014
  "self_hosted_runners_enabled": self_hosted_runners_enabled,
1013
1015
  "org_login": org_name,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: openhound-github
3
- Version: 0.13.1
3
+ Version: 0.14.2.dev2
4
4
  Summary: Github collector for OpenHound
5
5
  Author-email: "jdreijer@specterops.io" <jdreijer@specterops.io>, Jared Atkinson <jatkinson@specterops.io>
6
6
  License-File: LICENSE.md
@@ -2,11 +2,11 @@ openhound_github/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,
2
2
  openhound_github/auth.py,sha256=fO0vEdpJIEHXUgF6rP_sZf_k7gMTa9jMFbZbKBw38Dg,10106
3
3
  openhound_github/github_rest_client.py,sha256=WnrUIbkHFEepAZSdIAFBeyeSkoumbWT_FiPjBZsoyqk,115
4
4
  openhound_github/github_retry.py,sha256=j4VJ-VWLE-s-PO9wPRPVkRkJdv4SCOR3HWvaywzsUJk,1325
5
- openhound_github/graph.py,sha256=xBY_qhBO1j3H6eGuN4LcElqiltlPBdMsfnn_2vw6pt8,997
5
+ openhound_github/graph.py,sha256=7PApox9Uk88xav9ilwYDa1fLv0FBduuENRPDiudUgv0,1306
6
6
  openhound_github/graphql.py,sha256=QQpom5MHAu4Yw153mifxOI5N_Ou_GvJ7eRlbCN7XW5g,10796
7
7
  openhound_github/helpers.py,sha256=xQmYyzVpG73lebbyhUdT73EAi2YPk9_s4d_Korqh054,16149
8
8
  openhound_github/lookup.py,sha256=6TxoW9FYNpZpir0ncH40uULRo80_WBozibpbObDS4_k,47436
9
- openhound_github/main.py,sha256=S84-jN1WWZ5KL_C0bVleGk0mIFs2s5vDOhrevtdZaGY,4015
9
+ openhound_github/main.py,sha256=5DWn8LyKtsA2Yktm6RQzsGOiJbrPgn0ESRe3KBsrOzM,3993
10
10
  openhound_github/runner_ids.py,sha256=rlAi0Fz2xUMcb4s7YQGqL2csHVaLdZP-vMxDpoPgHo8,478
11
11
  openhound_github/source.py,sha256=kSr8OiDd3q1UaEr2Uo358hd9W-_e1_PDU13QoUQtwBg,17878
12
12
  openhound_github/transforms.py,sha256=qXagoTMMnQ6CjSI-XVf_HcXAsqZKJTns5ZW9KOz-ffY,22945
@@ -39,7 +39,7 @@ openhound_github/models/env_variable.py,sha256=ccIZg0LyBmvCDehPeANRF3ZstEU1ldr77
39
39
  openhound_github/models/environment.py,sha256=iiFGYsRu33FXPf5WuerJ1QXthcWZoDxwmE0DpboWLZU,25022
40
40
  openhound_github/models/environment_branch_policy.py,sha256=j6RWZ4WRqCEgGVfMuwOYc7Lo0zNdCZrBpu7hhV58Ul0,6843
41
41
  openhound_github/models/external_identity.py,sha256=DE9ieDuUerwIuiE20V8Pn1vRs2sUs6-vklqx-H2-wM4,11106
42
- openhound_github/models/org.py,sha256=EyaQD0eNMkM9giPeUubaVyzPQymAlhrOWjfApmUtaLE,19947
42
+ openhound_github/models/org.py,sha256=cGO4JsaooozBSb65QJ4c6DwSUT4IwsQokB2RVwySPeA,20163
43
43
  openhound_github/models/org_role.py,sha256=Qf8IlQgRZQPyHy3IgRPX859L9-UgtEJ2rm5Bk48t3UY,14890
44
44
  openhound_github/models/org_role_member.py,sha256=OM2N2xtZd0uC2T7U6lh5TbDo7HZLt-jn92dr80lwksI,1368
45
45
  openhound_github/models/org_role_team.py,sha256=Q6_OQUHw1GkFBI0ZQq5lTYZB-s8METE7dbTFXwrx4AM,1438
@@ -51,7 +51,7 @@ openhound_github/models/personal_access_token_access.py,sha256=U16xNR31CeMvxIhof
51
51
  openhound_github/models/personal_access_token_request.py,sha256=KtGzREwQIJ6mMAYE0n7p3VDCLMHkVC5elCI4m3-Q0N8,5740
52
52
  openhound_github/models/projected_enterprise_team.py,sha256=3z-rC4h2iPbBkrWr1-GJG_dUqe2diCHgg8ZAbywTuBg,2070
53
53
  openhound_github/models/repo_role_assignment.py,sha256=8i-utvyyJE311rIiUvSUq2WmX50dcw8otiljqrbsomw,4022
54
- openhound_github/models/repository.py,sha256=yIJz-VH9dMTYtniDsHw9VF2fg1K82vgtUiGkLPIVFW4,14445
54
+ openhound_github/models/repository.py,sha256=3VXd01I__er52zFxQ57NXSQVFreuK7KdWlYD9JJWPEg,14986
55
55
  openhound_github/models/repository_role.py,sha256=YYxO6sSul2QuSvZUy81sjpAMi1KdzJr8QHQ0_l_QbfU,35740
56
56
  openhound_github/models/repository_secret.py,sha256=0D5StsOM09H7hjUSKwUjuZLBcjlbRljxeO9sIldWKdQ,3940
57
57
  openhound_github/models/repository_variable.py,sha256=Ad_PiC7fRN4aICngQ4vlIKZVGJNmfn0GJqvUXiHUj94,3747
@@ -61,7 +61,7 @@ openhound_github/models/saml_helpers.py,sha256=9YUckYOI_LkZ4pQfc559_enk2-mIR9Zhf
61
61
  openhound_github/models/saml_issuer.py,sha256=335ra0YiHZhI7kwAuAdSnZSxxUP_Q1DY-iaagGM8s_0,4089
62
62
  openhound_github/models/saml_provider.py,sha256=4jDEDqN_ZVncQglPIfOr1Lfxczlc1NkhZvHxzeAAOuI,5202
63
63
  openhound_github/models/saml_service_provider.py,sha256=FqD1jpAwANC_HTc1D90x1d6q3CbzF06aEN5fTcmx6iM,4712
64
- openhound_github/models/scim_user.py,sha256=37_pRB7_WQHNfNNt0udiuK7JIZ1JaRzHB_1aAnT8rrY,11657
64
+ openhound_github/models/scim_user.py,sha256=YqqVElZxOMYT2ZytpWW58QaMCV1VZaYzso7r_3h00Rs,11610
65
65
  openhound_github/models/secret_scanning_alert.py,sha256=nElFrnrqzjm9uMmkvRs1-_eQxAAbTGfnCzKQYjB3Ib4,9330
66
66
  openhound_github/models/team.py,sha256=l9ZT3DBzAHE9DbYRHcus3nI7iUM45-Ef_DiTm5i1pzU,8385
67
67
  openhound_github/models/team_member.py,sha256=YgSvClbaVGsPQW0rMeXRWWb1aRYfzCa4GxnjmihcSig,1668
@@ -73,10 +73,10 @@ openhound_github/models/workflow_reference.py,sha256=Vfk3biAtkVHTz796GWf-J9TQj1T
73
73
  openhound_github/models/workflow_step.py,sha256=GZ1ggZXVWojuKl7iXdHcpJUfNXRRjx1Sypp3qPFjEmI,10748
74
74
  openhound_github/resources/__init__.py,sha256=jGuYogLtrEsUP3neBw41YZeC1yAOV3tDIzJCA8ZQgUo,101
75
75
  openhound_github/resources/enterprise.py,sha256=qDdctdmg2nACGlUmgBEnE-zV7Yebov_MEunAHJxiX1U,34749
76
- openhound_github/resources/organization.py,sha256=F5WR0qCuuwqqDsAqgOXE8AURhetCqZhX8x0uFZCo3Ak,89653
76
+ openhound_github/resources/organization.py,sha256=fVmPxA5GYiVs4im5262X76RMJ_32MXTe0RdBOmxGTk4,89765
77
77
  openhound_github/extension.yaml,sha256=iqEqiG14paSzaH7xISg7oy9PviLGHSMvEYOallBpKw0,706
78
- openhound_github-0.13.1.dist-info/METADATA,sha256=xBJ3gens3BeuSezEE7JpaL_1Pi_YgINpC8bgvdYmYXQ,6361
79
- openhound_github-0.13.1.dist-info/WHEEL,sha256=zOwg4jB6zX2kU910N-cMawjivD6tO8NEWvE12je1bVk,87
80
- openhound_github-0.13.1.dist-info/entry_points.txt,sha256=dn_0GC3hAM9jAcn81NhGSZK_vQtKEazxGRfXcaNJQsA,55
81
- openhound_github-0.13.1.dist-info/licenses/LICENSE.md,sha256=hl-6dfjqiqdl-iWur-TsJegvxJxByg2rZ7DmjsVZ1pI,10802
82
- openhound_github-0.13.1.dist-info/RECORD,,
78
+ openhound_github-0.14.2.dev2.dist-info/METADATA,sha256=oygwwuxk6C-5r25xpCtJrUXDGa3Lxp_2q_ZNYcziHyc,6366
79
+ openhound_github-0.14.2.dev2.dist-info/WHEEL,sha256=zOwg4jB6zX2kU910N-cMawjivD6tO8NEWvE12je1bVk,87
80
+ openhound_github-0.14.2.dev2.dist-info/entry_points.txt,sha256=dn_0GC3hAM9jAcn81NhGSZK_vQtKEazxGRfXcaNJQsA,55
81
+ openhound_github-0.14.2.dev2.dist-info/licenses/LICENSE.md,sha256=hl-6dfjqiqdl-iWur-TsJegvxJxByg2rZ7DmjsVZ1pI,10802
82
+ openhound_github-0.14.2.dev2.dist-info/RECORD,,