fix: use checkMemberGroups for security group membership#1383
Open
damsleth wants to merge 1 commit into
Open
Conversation
Replace the paged /groups/{id}/members scan with a single
/users/{mail}/checkMemberGroups POST. The previous implementation
only read the first page (default 100 members), silently denying
legitimate members in larger security groups. checkMemberGroups
is O(1) and transitive, and the caller surface stays the same
(groupId, mail) -> Promise<boolean>.
Also add a debug() log on catch so operational failures (e.g.
missing Directory.Read.All / User.Read.All consent) are
diagnosable instead of silently returning false.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
MSGraphService.isUserMemberOfSecurityGroupwith a singlePOST /users/{mail}/checkMemberGroupscall. The previous implementation fetched only the first page of/groups/{id}/membersand scanned locally, silently denying legitimate members in groups larger than the default page size (~100).debug()log on catch so operational failures (permission/consent issues, transient Graph errors) are visible instead of returningfalsesilently.(groupId, mail) => Promise<boolean>.Graph permission requirement
checkMemberGroupsrequiresUser.Read.AllorDirectory.Read.Allapplication/delegated permission.MICROSOFT_SCOPESin.env.samplealready includesuser.read.all, so no scope change is required for standard deployments. If a tenant's app registration is missing that permission, the endpoint will 403 and the catch will log + return false (fail-closed, same as today). The added debug log makes this diagnosable.Files changed
server/services/msgraph/MSGraphService.ts- new implementation +debugimportserver/services/msgraph/MSGraphService.test.ts- new, stubs the Graph client and covers member/non-member/error/url-encoding pathsTest plan
npm run lintpassesnpm test- the four newisUserMemberOfSecurityGroupcases pass in isolation. Note: several pre-existing tests (ReportService.test.ts,passport/index.test.ts,timesheet/extensions.test.ts) fail compilation under ts-node withTS2694: Namespace 'global.Express' has no exported member 'User'on this worktree. This is unrelated to this change (reproduces on cleanorigin/dev) and appears to pre-date this PR; flagged here for awareness.Out of scope
checkSecurityGroupMembership.tscaller shape (separate plan).mail).