Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
fixup comments
  • Loading branch information
Emyrk committed May 7, 2025
commit e0b8af3903e718e17dc3643603f6f8f936513d77
2 changes: 1 addition & 1 deletion coderd/coderd.go
Original file line number Diff line number Diff line change
Expand Up @@ -1076,7 +1076,7 @@ func New(options *Options) *API {

r.Group(func(r chi.Router) {
r.Use(
httpmw.ExtractOrganizationMemberParam(options.Database, api.HTTPAuth.Authorize),
httpmw.ExtractOrganizationMemberParam(options.Database),
)
r.Delete("/", api.deleteOrganizationMember)
r.Put("/roles", api.putMemberRoles)
Expand Down
17 changes: 12 additions & 5 deletions coderd/httpmw/organizationparam.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,12 +118,12 @@ type OrganizationMember struct {

// ExtractOrganizationMemberParam grabs a user membership from the "organization" and "user" URL parameter.
// This middleware requires the ExtractUser and ExtractOrganization middleware higher in the stack
func ExtractOrganizationMemberParam(db database.Store, auth func(r *http.Request, action policy.Action, object rbac.Objecter) bool) func(http.Handler) http.Handler {
func ExtractOrganizationMemberParam(db database.Store) func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
ctx := r.Context()
organization := OrganizationParam(r)
_, members, done := ExtractOrganizationMember(ctx, auth, rw, r, db, organization.ID)
_, members, done := ExtractOrganizationMember(ctx, nil, rw, r, db, organization.ID)
if done {
return
}
Expand Down Expand Up @@ -194,12 +194,12 @@ func ExtractOrganizationMember(ctx context.Context, auth func(r *http.Request, a
return nil, nil, true
}

if auth(r, policy.ActionRead, user) {
if auth != nil && auth(r, policy.ActionRead, user) {
return &user, organizationMembers, true
}

// If the user cannot be read and 0 memberships exist, throw a 404 to not
// leak the user existance.
// leak the user existence.
if len(organizationMembers) == 0 {
httpapi.ResourceNotFound(rw)
return nil, nil, true
Expand All @@ -209,7 +209,11 @@ func ExtractOrganizationMember(ctx context.Context, auth func(r *http.Request, a
}

type OrganizationMembers struct {
User *database.User
// User is `nil` if the caller is not allowed access to the site wide
// user object.
User *database.User
// Memberships can only be length 0 if `user != nil`. If `user == nil`, then
// memberships will be at least length 1.
Memberships []OrganizationMember
}

Expand All @@ -226,6 +230,9 @@ func (om OrganizationMembers) UserID() uuid.UUID {

// ExtractOrganizationMembersParam grabs all user organization memberships.
// Only requires the "user" URL parameter.
//
// Use this if you want to grab as much information for a user as you can.
// From an organization context, site wide user information might not available.
func ExtractOrganizationMembersParam(db database.Store, auth func(r *http.Request, action policy.Action, object rbac.Objecter) bool) func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
Expand Down
14 changes: 6 additions & 8 deletions coderd/httpmw/organizationparam_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,9 +131,7 @@ func TestOrganizationParam(t *testing.T) {
}),
httpmw.ExtractUserParam(db),
httpmw.ExtractOrganizationParam(db),
httpmw.ExtractOrganizationMemberParam(db, func(r *http.Request, _ policy.Action, _ rbac.Objecter) bool {
return true
}),
httpmw.ExtractOrganizationMemberParam(db),
)
rtr.Get("/", nil)
rtr.ServeHTTP(rw, r)
Expand Down Expand Up @@ -170,11 +168,10 @@ func TestOrganizationParam(t *testing.T) {
}),
httpmw.ExtractOrganizationParam(db),
httpmw.ExtractUserParam(db),
httpmw.ExtractOrganizationMemberParam(db, func(r *http.Request, _ policy.Action, _ rbac.Objecter) bool {
return true
}),
httpmw.ExtractOrganizationMemberParam(db),
httpmw.ExtractOrganizationMembersParam(db, func(r *http.Request, _ policy.Action, _ rbac.Objecter) bool {
return true
// Assume the caller cannot read the member
return false
}),
)
rtr.Get("/", func(rw http.ResponseWriter, r *http.Request) {
Expand Down Expand Up @@ -202,7 +199,8 @@ func TestOrganizationParam(t *testing.T) {

orgMems := httpmw.OrganizationMembersParam(r)
assert.NotZero(t, orgMems)
assert.Equal(t, orgMem.UserID, orgMems[0].UserID)
assert.Equal(t, orgMem.UserID, orgMems.Memberships[0].UserID)
assert.Nil(t, orgMems.User, "user data should not be available, hard coded false authorize")
})

// Try by ID
Expand Down