Skip to content

Commit 1002f93

Browse files
authored
fix: prevent affiliations for project-registry member organizations (#4321)
Signed-off-by: Yeganathan S <63534555+skwowet@users.noreply.github.com>
1 parent 8a6db20 commit 1002f93

2 files changed

Lines changed: 125 additions & 29 deletions

File tree

services/apps/git_integration/src/crowdgit/database/crud.py

Lines changed: 90 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -720,6 +720,20 @@ async def find_many_organization_ids_by_identities(identities: list[dict]) -> li
720720
return results
721721

722722

723+
async def fetch_organizations(org_ids: list[str]) -> list[dict]:
724+
if not org_ids:
725+
return []
726+
727+
return await query(
728+
"""
729+
SELECT id, "isAffiliationBlocked"
730+
FROM organizations
731+
WHERE id = ANY($1::uuid[])
732+
""",
733+
(org_ids,),
734+
)
735+
736+
723737
async def fetch_member_organizations(member_ids: list[str]) -> list[dict]:
724738
if not member_ids:
725739
return []
@@ -751,9 +765,9 @@ async def fetch_segment_affiliations(member_ids: list[str], segment_id: str) ->
751765
)
752766

753767

754-
async def insert_member_organizations(rows: list[dict]) -> None:
768+
async def insert_member_organizations(rows: list[dict]) -> list[dict]:
755769
if not rows:
756-
return
770+
return []
757771

758772
undated_rows: list[tuple] = []
759773
open_ended_rows: list[tuple] = []
@@ -767,8 +781,10 @@ async def insert_member_organizations(rows: list[dict]) -> None:
767781
row.get("date_end"),
768782
row["source"],
769783
)
784+
770785
date_start = row.get("date_start")
771786
date_end = row.get("date_end")
787+
772788
if date_start is None and date_end is None:
773789
undated_rows.append(params)
774790
elif date_end is None:
@@ -787,41 +803,91 @@ async def insert_member_organizations(rows: list[dict]) -> None:
787803
"createdAt",
788804
"updatedAt"
789805
)
790-
VALUES ($1, $2, $3, $4, NULL, $5, NOW(), NOW())
791806
"""
792807

793-
if undated_rows:
794-
sql = (
795-
insert_sql
796-
+ """
808+
returning_sql = """
809+
RETURNING id, "memberId", "organizationId"
810+
"""
811+
812+
buckets = [
813+
(
814+
undated_rows,
815+
"""
797816
ON CONFLICT ("memberId", "organizationId")
798817
WHERE ("dateStart" IS NULL AND "dateEnd" IS NULL AND "deletedAt" IS NULL)
799818
DO NOTHING
800-
"""
801-
)
802-
await executemany(sql, undated_rows)
803-
804-
if open_ended_rows:
805-
sql = (
806-
insert_sql
807-
+ """
819+
""",
820+
),
821+
(
822+
open_ended_rows,
823+
"""
808824
ON CONFLICT ("memberId", "organizationId", "dateStart")
809825
WHERE ("dateEnd" IS NULL AND "deletedAt" IS NULL)
810826
DO NOTHING
811-
"""
812-
)
813-
await executemany(sql, open_ended_rows)
814-
815-
if dated_rows:
816-
sql = (
817-
insert_sql
818-
+ """
827+
""",
828+
),
829+
(
830+
dated_rows,
831+
"""
819832
ON CONFLICT ("memberId", "organizationId", "dateStart", "dateEnd")
820833
WHERE ("deletedAt" IS NULL)
821834
DO NOTHING
835+
""",
836+
),
837+
]
838+
839+
created_rows: list[dict] = []
840+
841+
for bucket_rows, conflict_sql in buckets:
842+
if not bucket_rows:
843+
continue
844+
845+
values_parts: list[str] = []
846+
params: list = []
847+
param_index = 1
848+
849+
for member_id, organization_id, date_start, date_end, source in bucket_rows:
850+
values_parts.append(
851+
f"(${param_index}, ${param_index + 1}, ${param_index + 2}, "
852+
f"${param_index + 3}, NULL, ${param_index + 4}, NOW(), NOW())"
853+
)
854+
params.extend([member_id, organization_id, date_start, date_end, source])
855+
param_index += 5
856+
857+
created_rows.extend(
858+
await query(
859+
insert_sql + f" VALUES {', '.join(values_parts)}" + conflict_sql + returning_sql,
860+
tuple(params),
861+
)
862+
)
863+
864+
return created_rows
865+
866+
867+
async def insert_member_organization_affiliation_overrides(rows: list[dict]) -> None:
868+
if not rows:
869+
return
870+
871+
await executemany(
822872
"""
873+
INSERT INTO "memberOrganizationAffiliationOverrides"(
874+
id,
875+
"memberId",
876+
"memberOrganizationId",
877+
"allowAffiliation"
823878
)
824-
await executemany(sql, dated_rows)
879+
VALUES (gen_random_uuid(), $1, $2, $3)
880+
ON CONFLICT ("memberId", "memberOrganizationId") DO NOTHING
881+
""",
882+
[
883+
(
884+
row["member_id"],
885+
row["member_organization_id"],
886+
row["allow_affiliation"],
887+
)
888+
for row in rows
889+
],
890+
)
825891

826892

827893
async def insert_member_segment_affiliations(rows: list[dict]) -> None:

services/apps/git_integration/src/crowdgit/services/affiliation/affiliation_service.py

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,12 @@
1111

1212
from crowdgit.database.crud import (
1313
fetch_member_organizations,
14+
fetch_organizations,
1415
fetch_segment_affiliations,
1516
find_many_member_ids_by_identities,
1617
find_many_organization_ids_by_identities,
1718
get_repo_affiliation_registry,
19+
insert_member_organization_affiliation_overrides,
1820
insert_member_organizations,
1921
insert_member_segment_affiliations,
2022
save_service_execution,
@@ -870,6 +872,16 @@ async def apply_affiliations(
870872
else:
871873
segment_affiliations_by_member.setdefault(member_id, []).append(row)
872874

875+
blocked_org_ids: set[str] = set()
876+
if resolved_stints:
877+
org_ids = list({organization_id for _, organization_id, _ in resolved_stints})
878+
organizations = await fetch_organizations(org_ids)
879+
blocked_org_ids = {
880+
str(organization["id"])
881+
for organization in organizations
882+
if organization["isAffiliationBlocked"]
883+
}
884+
873885
mo_inserts: list[dict] = []
874886
msa_inserts: list[dict] = []
875887

@@ -896,10 +908,14 @@ async def apply_affiliations(
896908
}
897909
)
898910

899-
if not self.has_existing_stint(
900-
existing_msas, organization_id, date_start, date_end
901-
) and not self.is_blocked_by_deleted_row(
902-
deleted_msas, organization_id, date_start, date_end
911+
if (
912+
str(organization_id) not in blocked_org_ids
913+
and not self.has_existing_stint(
914+
existing_msas, organization_id, date_start, date_end
915+
)
916+
and not self.is_blocked_by_deleted_row(
917+
deleted_msas, organization_id, date_start, date_end
918+
)
903919
):
904920
msa_inserts.append(
905921
{
@@ -911,7 +927,21 @@ async def apply_affiliations(
911927
}
912928
)
913929

914-
await insert_member_organizations(mo_inserts)
930+
created_member_organizations = await insert_member_organizations(mo_inserts)
931+
932+
if blocked_org_ids:
933+
override_rows = [
934+
{
935+
"member_id": mo["memberId"],
936+
"member_organization_id": mo["id"],
937+
"allow_affiliation": False,
938+
}
939+
for mo in created_member_organizations
940+
if str(mo["organizationId"]) in blocked_org_ids
941+
]
942+
if override_rows:
943+
await insert_member_organization_affiliation_overrides(override_rows)
944+
915945
await insert_member_segment_affiliations(msa_inserts)
916946

917947
async def process_affiliations(

0 commit comments

Comments
 (0)