From a323e62a48fbe2dda3635405a4294da4629fbab6 Mon Sep 17 00:00:00 2001 From: Ryan Waldheim Date: Tue, 26 May 2026 15:00:04 -0700 Subject: [PATCH 1/4] Add accessGroupObjs field to User --- models.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/models.py b/models.py index 6932204..320c03e 100644 --- a/models.py +++ b/models.py @@ -303,6 +303,11 @@ def groups(self, info) -> List[str]: if not grps: return [] return [ x["name"] for x in grps] + + @strawberry.field + def accessGroupObjs(self, info) -> List['AccessGroup']: + return info.context.db.find_access_groups({"members": self.username}) + @strawberry.field def storages(self, info) -> List[UserStorage]: storages = list(info.context.db.collection("user_storage_allocation").find({"username": self.username})) From 792bfcbed74a1e8695831f5542d6715a9adf4974 Mon Sep 17 00:00:00 2001 From: Ryan Waldheim Date: Wed, 27 May 2026 09:31:02 -0700 Subject: [PATCH 2/4] members -> users --- models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/models.py b/models.py index 320c03e..9dd362e 100644 --- a/models.py +++ b/models.py @@ -306,7 +306,7 @@ def groups(self, info) -> List[str]: @strawberry.field def accessGroupObjs(self, info) -> List['AccessGroup']: - return info.context.db.find_access_groups({"members": self.username}) + return info.context.db.find_access_groups({"users": self.username}) @strawberry.field def storages(self, info) -> List[UserStorage]: From d3a6c9040a5a45927e9a588dc64baf207e32b498 Mon Sep 17 00:00:00 2001 From: Ryan Waldheim Date: Wed, 27 May 2026 09:47:27 -0700 Subject: [PATCH 3/4] parse access groups from Repo within User --- models.py | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/models.py b/models.py index 9dd362e..f07897c 100644 --- a/models.py +++ b/models.py @@ -306,7 +306,30 @@ def groups(self, info) -> List[str]: @strawberry.field def accessGroupObjs(self, info) -> List['AccessGroup']: - return info.context.db.find_access_groups({"users": self.username}) + """ + Return all POSIX group objects (with gidnumber, name, etc.) for this user, + by scanning all repos where the user is a member and extracting features with gidnumber. + """ + repos = info.context.db.collection("repos").find({ + "$or": [ + {"users": self.username}, + {"leaders": self.username}, + {"principal": self.username} + ] + }) + groups = [] + for repo in repos: + features = repo.get("features", {}) + for feature_name, feature in features.items(): + if isinstance(feature, dict) and "gidnumber" in feature: + groups.append(AccessGroup( + gidnumber=feature["gidnumber"], + name=feature.get("name", feature_name), + repoid=repo.get("_id"), + state=feature.get("state"), + members=repo.get("users", []) + )) + return groups @strawberry.field def storages(self, info) -> List[UserStorage]: From b25bbe929ec4180b937db086855d8ad75dfa058a Mon Sep 17 00:00:00 2001 From: Ryan Waldheim Date: Wed, 27 May 2026 09:55:15 -0700 Subject: [PATCH 4/4] correctly parse mongo db posixgroup schema --- models.py | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/models.py b/models.py index f07897c..0f5d5c4 100644 --- a/models.py +++ b/models.py @@ -308,8 +308,9 @@ def groups(self, info) -> List[str]: def accessGroupObjs(self, info) -> List['AccessGroup']: """ Return all POSIX group objects (with gidnumber, name, etc.) for this user, - by scanning all repos where the user is a member and extracting features with gidnumber. + by scanning all repos where the user is a member and extracting group info from posixgroup feature options. """ + import json repos = info.context.db.collection("repos").find({ "$or": [ {"users": self.username}, @@ -320,15 +321,24 @@ def accessGroupObjs(self, info) -> List['AccessGroup']: groups = [] for repo in repos: features = repo.get("features", {}) - for feature_name, feature in features.items(): - if isinstance(feature, dict) and "gidnumber" in feature: - groups.append(AccessGroup( - gidnumber=feature["gidnumber"], - name=feature.get("name", feature_name), - repoid=repo.get("_id"), - state=feature.get("state"), - members=repo.get("users", []) - )) + posixgroup = features.get("posixgroup") + if posixgroup and isinstance(posixgroup, dict): + options = posixgroup.get("options", []) + for opt in options: + try: + parsed = json.loads(opt) if isinstance(opt, str) else opt + gid = parsed.get("gidNumber") + name = parsed.get("name") + if gid is not None: + groups.append(AccessGroup( + gidnumber=int(gid), + name=name or repo.get("name"), + repoid=repo.get("_id"), + state=posixgroup.get("state"), + members=repo.get("users", []) + )) + except Exception: + continue return groups @strawberry.field