Skip to content

Commit e2681d7

Browse files
committed
fix(scim): ensure scim users aren't created with their own org
1 parent 0b15b1b commit e2681d7

File tree

2 files changed

+58
-17
lines changed

2 files changed

+58
-17
lines changed

coderd/users.go

Lines changed: 40 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,8 @@ func (api *API) postFirstUser(rw http.ResponseWriter, r *http.Request) {
128128
// Create an org for the first user.
129129
OrganizationID: uuid.Nil,
130130
},
131-
LoginType: database.LoginTypePassword,
131+
CreateOrganization: true,
132+
LoginType: database.LoginTypePassword,
132133
})
133134
if err != nil {
134135
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
@@ -313,19 +314,38 @@ func (api *API) postUser(rw http.ResponseWriter, r *http.Request) {
313314
return
314315
}
315316

316-
_, err = api.Database.GetOrganizationByID(ctx, req.OrganizationID)
317-
if httpapi.Is404Error(err) {
318-
httpapi.Write(ctx, rw, http.StatusNotFound, codersdk.Response{
319-
Message: fmt.Sprintf("Organization does not exist with the provided id %q.", req.OrganizationID),
320-
})
321-
return
322-
}
323-
if err != nil {
324-
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
325-
Message: "Internal error fetching organization.",
326-
Detail: err.Error(),
327-
})
328-
return
317+
if req.OrganizationID != uuid.Nil {
318+
_, err := api.Database.GetOrganizationByID(ctx, req.OrganizationID)
319+
if err != nil {
320+
if httpapi.Is404Error(err) {
321+
httpapi.Write(ctx, rw, http.StatusNotFound, codersdk.Response{
322+
Message: fmt.Sprintf("Organization does not exist with the provided id %q.", req.OrganizationID),
323+
})
324+
return
325+
}
326+
327+
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
328+
Message: "Internal error fetching organization.",
329+
Detail: err.Error(),
330+
})
331+
return
332+
}
333+
} else {
334+
organizations, err := api.Database.GetOrganizations(ctx)
335+
if err != nil {
336+
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
337+
Message: "Internal error fetching user.",
338+
Detail: err.Error(),
339+
})
340+
return
341+
}
342+
343+
if len(organizations) > 0 {
344+
// Add the user to the first organization. Once multi-organization
345+
// support is added, we should enable a configuration map of user
346+
// email to organization.
347+
req.OrganizationID = organizations[0].ID
348+
}
329349
}
330350

331351
err = userpassword.Validate(req.Password)
@@ -955,7 +975,8 @@ func (api *API) organizationByUserAndName(rw http.ResponseWriter, r *http.Reques
955975

956976
type CreateUserRequest struct {
957977
codersdk.CreateUserRequest
958-
LoginType database.LoginType
978+
CreateOrganization bool
979+
LoginType database.LoginType
959980
}
960981

961982
func (api *API) CreateUser(ctx context.Context, store database.Store, req CreateUserRequest) (database.User, uuid.UUID, error) {
@@ -964,6 +985,10 @@ func (api *API) CreateUser(ctx context.Context, store database.Store, req Create
964985
orgRoles := make([]string, 0)
965986
// If no organization is provided, create a new one for the user.
966987
if req.OrganizationID == uuid.Nil {
988+
if !req.CreateOrganization {
989+
return xerrors.Errorf("organization ID must be provided")
990+
}
991+
967992
organization, err := tx.InsertOrganization(ctx, database.InsertOrganizationParams{
968993
ID: uuid.New(),
969994
Name: req.Username,

enterprise/coderd/scim.go

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,11 +156,27 @@ func (api *API) scimPostUser(rw http.ResponseWriter, r *http.Request) {
156156
return
157157
}
158158

159+
var organizationID uuid.UUID
160+
//nolint:gocritic
161+
organizations, err := api.Database.GetOrganizations(dbauthz.AsSystemRestricted(ctx))
162+
if err != nil {
163+
_ = handlerutil.WriteError(rw, err)
164+
return
165+
}
166+
167+
if len(organizations) > 0 {
168+
// Add the user to the first organization. Once multi-organization
169+
// support is added, we should enable a configuration map of user
170+
// email to organization.
171+
organizationID = organizations[0].ID
172+
}
173+
159174
//nolint:gocritic // needed for SCIM
160175
user, _, err := api.AGPL.CreateUser(dbauthz.AsSystemRestricted(ctx), api.Database, agpl.CreateUserRequest{
161176
CreateUserRequest: codersdk.CreateUserRequest{
162-
Username: sUser.UserName,
163-
Email: email,
177+
Username: sUser.UserName,
178+
Email: email,
179+
OrganizationID: organizationID,
164180
},
165181
LoginType: database.LoginTypeOIDC,
166182
})

0 commit comments

Comments
 (0)