Skip to content

Commit f857add

Browse files
authored
feat: load membership from header (#1654)
Signed-off-by: Miguel Martinez <[email protected]>
1 parent 1d40e44 commit f857add

File tree

4 files changed

+92
-9
lines changed

4 files changed

+92
-9
lines changed

app/controlplane/internal/usercontext/currentorganization_middleware.go

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,23 @@ func WithCurrentOrganizationMiddleware(userUseCase biz.UserOrgFinder, logger *lo
3636
return handler(ctx, req)
3737
}
3838

39-
var err error
40-
ctx, err = setCurrentOrganization(ctx, u, userUseCase, logger)
39+
orgName, err := getOrganizationName(ctx)
4140
if err != nil {
42-
return nil, fmt.Errorf("error setting current org: %w", err)
41+
return nil, fmt.Errorf("error getting organization name: %w", err)
42+
}
43+
44+
if orgName != "" {
45+
ctx, err = setCurrentOrganizationFromHeader(ctx, u, orgName, userUseCase)
46+
if err != nil {
47+
return nil, fmt.Errorf("error setting current org: %w", err)
48+
}
49+
} else {
50+
// If no organization name is provided, we use the DB to find the current organization
51+
// DEPRECATED: in favor of header based org selection
52+
ctx, err = setCurrentOrganizationFromDB(ctx, u, userUseCase, logger)
53+
if err != nil {
54+
return nil, fmt.Errorf("error setting current org: %w", err)
55+
}
4356
}
4457

4558
org := entities.CurrentOrg(ctx)
@@ -54,8 +67,19 @@ func WithCurrentOrganizationMiddleware(userUseCase biz.UserOrgFinder, logger *lo
5467
}
5568
}
5669

70+
func setCurrentOrganizationFromHeader(ctx context.Context, user *entities.User, orgName string, userUC biz.UserOrgFinder) (context.Context, error) {
71+
membership, err := userUC.MembershipInOrg(ctx, user.ID, orgName)
72+
if err != nil {
73+
return nil, fmt.Errorf("failed to find membership: %w", err)
74+
}
75+
76+
ctx = entities.WithCurrentOrg(ctx, &entities.Org{Name: membership.Org.Name, ID: membership.Org.ID, CreatedAt: membership.CreatedAt})
77+
// Set the authorization subject that will be used to check the policies
78+
return WithAuthzSubject(ctx, string(membership.Role)), nil
79+
}
80+
5781
// Find the current membership of the user and sets it on the context
58-
func setCurrentOrganization(ctx context.Context, user *entities.User, userUC biz.UserOrgFinder, logger *log.Helper) (context.Context, error) {
82+
func setCurrentOrganizationFromDB(ctx context.Context, user *entities.User, userUC biz.UserOrgFinder, logger *log.Helper) (context.Context, error) {
5983
// We load the current organization
6084
membership, err := userUC.CurrentMembership(ctx, user.ID)
6185
if err != nil {

app/controlplane/internal/usercontext/usercontext.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,13 @@ func GetRawToken(ctx context.Context) (string, error) {
3636
}
3737
return auths[1], nil
3838
}
39+
40+
func getOrganizationName(ctx context.Context) (string, error) {
41+
const OrganizationHeader = "Chainloop-Organization"
42+
header, ok := transport.FromServerContext(ctx)
43+
if ok {
44+
return header.RequestHeader().Get(OrganizationHeader), nil
45+
}
46+
47+
return "", nil
48+
}

app/controlplane/pkg/biz/mocks/UserOrgFinder.go

Lines changed: 42 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/controlplane/pkg/biz/user.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ type UserRepo interface {
4646
type UserOrgFinder interface {
4747
FindByID(ctx context.Context, userID string) (*User, error)
4848
CurrentMembership(ctx context.Context, userID string) (*Membership, error)
49+
MembershipInOrg(ctx context.Context, userID string, orgName string) (*Membership, error)
4950
}
5051

5152
type UserUseCase struct {
@@ -159,6 +160,17 @@ func (uc *UserUseCase) FindByID(ctx context.Context, userID string) (*User, erro
159160
return uc.userRepo.FindByID(ctx, userUUID)
160161
}
161162

163+
func (uc *UserUseCase) MembershipInOrg(ctx context.Context, userID string, orgName string) (*Membership, error) {
164+
m, err := uc.membershipUseCase.FindByOrgNameAndUser(ctx, orgName, userID)
165+
if err != nil {
166+
return nil, fmt.Errorf("failed to find membership: %w", err)
167+
} else if m == nil {
168+
return nil, NewErrNotFound("user does not have this org associated")
169+
}
170+
171+
return m, nil
172+
}
173+
162174
// Find the membership associated with the user that's marked as current
163175
// If none is selected, it will pick the first one and set it as current
164176
func (uc *UserUseCase) CurrentMembership(ctx context.Context, userID string) (*Membership, error) {

0 commit comments

Comments
 (0)