feat: implement SetProjectMemberRole RPC#1481
Conversation
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add handler, service, and authorization for atomically changing a user's role in a project. Enforces minimum-owner constraint. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
📝 WalkthroughSummary by CodeRabbit
WalkthroughAdds a server-side RPC and service flow to set a project member's role: new ProjectService.SetMemberRole handler and API surface, Service.SetMemberRole implementation with role validation and policy CRUD, roleService dependency wiring, multiple mock additions/updates, new error values, an authorization check, and a Makefile PROTON_COMMIT update. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~40 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 2✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 5
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
core/project/service_test.go (1)
23-35:⚠️ Potential issue | 🟠 MajorAdd direct unit tests for
SetMemberRolebehavior (currently missing).This update wires new dependencies, but the new project-member role mutation path is not covered here. Please add focused tests for role validation, non-member handling, and last-owner protection to reduce regression risk in the new RPC path.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 56252940-859b-4c10-83dd-9b50d88a457e
⛔ Files ignored due to path filters (3)
proto/v1beta1/frontier.pb.gois excluded by!**/*.pb.go,!proto/**proto/v1beta1/frontier.pb.validate.gois excluded by!proto/**proto/v1beta1/frontierv1beta1connect/frontier.connect.gois excluded by!proto/**
📒 Files selected for processing (12)
Makefilecmd/serve.gocore/project/errors.gocore/project/mocks/policy_service.gocore/project/mocks/role_service.gocore/project/service.gocore/project/service_test.gointernal/api/v1beta1connect/errors.gointernal/api/v1beta1connect/interfaces.gointernal/api/v1beta1connect/mocks/project_service.gointernal/api/v1beta1connect/project.gopkg/server/connect_interceptors/authorization.go
…berRole Project access can come from org-level permissions, so we don't enforce minimum-owner constraint or require existing membership at project level. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Pull Request Test Coverage Report for Build 23633134429Details
💛 - Coveralls |
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…emberRole Each principal type has its own field in the request (user_id, service_user_id, group_id). Validation checks that the principal exists and belongs to the org that owns the project. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (1)
core/project/service.go (1)
360-363:⚠️ Potential issue | 🟠 MajorThe last-owner invariant is gone.
Demoting the only direct owner now succeeds and leaves the project with zero project-scoped owners. That regresses the owner-constraint behavior this RPC is supposed to preserve; if org-level fallback is intentionally replacing that invariant, the contract/tests need to change too.
Also applies to: 377-390
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 7a3f72ab-6cdf-4e25-beb2-3c66806bc560
📒 Files selected for processing (3)
core/project/errors.gocore/project/service.gointernal/api/v1beta1connect/project.go
🚧 Files skipped from review as they are similar to previous changes (2)
- core/project/errors.go
- internal/api/v1beta1connect/project.go
…ate ID fields Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
12 test cases covering: - validation errors (project/user/serviceuser/group not found) - invalid principal type - org membership check - role validation (not found, wrong scope) - success with no existing policies (add member) - success replacing existing policies (role change) - service user and group principal types Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
♻️ Duplicate comments (1)
core/project/service.go (1)
362-402:⚠️ Potential issue | 🟠 MajorUse the resolved project ID (
prj.ID) consistently.Lines 380 and 396 use the raw
projectIDparameter instead ofprj.ID. Sinces.Get()at line 366 resolves both UUIDs and names, passing a project name will cause the policy filter and create operations to use the name string instead of the canonical UUID.🐛 Proposed fix
existingPolicies, err := s.policyService.List(ctx, policy.Filter{ - ProjectID: projectID, + ProjectID: prj.ID, PrincipalID: principalID, PrincipalType: principalType, }) @@ _, err = s.policyService.Create(ctx, policy.Policy{ RoleID: newRoleID, - ResourceID: projectID, + ResourceID: prj.ID, ResourceType: schema.ProjectNamespace, PrincipalID: principalID, PrincipalType: principalType, })
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: c2d62ec5-29b5-4805-9f36-2c26ab203e72
⛔ Files ignored due to path filters (2)
proto/v1beta1/frontier.pb.gois excluded by!**/*.pb.go,!proto/**proto/v1beta1/frontier.pb.validate.gois excluded by!proto/**
📒 Files selected for processing (9)
Makefilecore/project/errors.gocore/project/mocks/group_service.gocore/project/mocks/serviceuser_service.gocore/project/service.gocore/project/service_test.gointernal/api/v1beta1connect/interfaces.gointernal/api/v1beta1connect/mocks/project_service.gointernal/api/v1beta1connect/project.go
🚧 Files skipped from review as they are similar to previous changes (3)
- Makefile
- internal/api/v1beta1connect/project.go
- core/project/errors.go
Summary
SetProjectMemberRoleRPC for atomic role assignment on project membersupdatepermission on the projectCloses #1461 (partially -
RemoveProjectMemberwill be a separate PR)Proton PR: raystack/proton#456
Test plan
updatepermission🤖 Generated with Claude Code