Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit0abd55e

Browse files
committed
fix(scim): ensure scim users aren't created with their own org
1 parent0b15b1b commit0abd55e

File tree

8 files changed

+91
-22
lines changed

8 files changed

+91
-22
lines changed

‎coderd/apidoc/docs.go

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

‎coderd/apidoc/swagger.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

‎coderd/userauth.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -921,7 +921,8 @@ func (api *API) oauthLogin(r *http.Request, params oauthLoginParams) (*http.Cook
921921
Username:params.Username,
922922
OrganizationID:organizationID,
923923
},
924-
LoginType:params.LoginType,
924+
CreateOrganization:len(organizations)==0,
925+
LoginType:params.LoginType,
925926
})
926927
iferr!=nil {
927928
returnxerrors.Errorf("create user: %w",err)

‎coderd/users.go

Lines changed: 43 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
iferr!=nil {
134135
httpapi.Write(ctx,rw,http.StatusInternalServerError, codersdk.Response{
@@ -313,19 +314,41 @@ func (api *API) postUser(rw http.ResponseWriter, r *http.Request) {
313314
return
314315
}
315316

316-
_,err=api.Database.GetOrganizationByID(ctx,req.OrganizationID)
317-
ifhttpapi.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-
iferr!=nil {
324-
httpapi.Write(ctx,rw,http.StatusInternalServerError, codersdk.Response{
325-
Message:"Internal error fetching organization.",
326-
Detail:err.Error(),
327-
})
328-
return
317+
ifreq.OrganizationID!=uuid.Nil {
318+
// If an organization was provided, make sure it exists.
319+
_,err:=api.Database.GetOrganizationByID(ctx,req.OrganizationID)
320+
iferr!=nil {
321+
ifhttpapi.Is404Error(err) {
322+
httpapi.Write(ctx,rw,http.StatusNotFound, codersdk.Response{
323+
Message:fmt.Sprintf("Organization does not exist with the provided id %q.",req.OrganizationID),
324+
})
325+
return
326+
}
327+
328+
httpapi.Write(ctx,rw,http.StatusInternalServerError, codersdk.Response{
329+
Message:"Internal error fetching organization.",
330+
Detail:err.Error(),
331+
})
332+
return
333+
}
334+
}else {
335+
// If no organization is provided, add the user to the first
336+
// organization.
337+
organizations,err:=api.Database.GetOrganizations(ctx)
338+
iferr!=nil {
339+
httpapi.Write(ctx,rw,http.StatusInternalServerError, codersdk.Response{
340+
Message:"Internal error fetching user.",
341+
Detail:err.Error(),
342+
})
343+
return
344+
}
345+
346+
iflen(organizations)>0 {
347+
// Add the user to the first organization. Once multi-organization
348+
// support is added, we should enable a configuration map of user
349+
// email to organization.
350+
req.OrganizationID=organizations[0].ID
351+
}
329352
}
330353

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

956979
typeCreateUserRequeststruct {
957980
codersdk.CreateUserRequest
958-
LoginType database.LoginType
981+
CreateOrganizationbool
982+
LoginType database.LoginType
959983
}
960984

961985
func (api*API)CreateUser(ctx context.Context,store database.Store,reqCreateUserRequest) (database.User, uuid.UUID,error) {
@@ -964,6 +988,10 @@ func (api *API) CreateUser(ctx context.Context, store database.Store, req Create
964988
orgRoles:=make([]string,0)
965989
// If no organization is provided, create a new one for the user.
966990
ifreq.OrganizationID==uuid.Nil {
991+
if!req.CreateOrganization {
992+
returnxerrors.Errorf("organization ID must be provided")
993+
}
994+
967995
organization,err:=tx.InsertOrganization(ctx, database.InsertOrganizationParams{
968996
ID:uuid.New(),
969997
Name:req.Username,

‎coderd/users_test.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,31 @@ func TestPostUsers(t *testing.T) {
478478
require.Equal(t,http.StatusNotFound,apiErr.StatusCode())
479479
})
480480

481+
t.Run("CreateWithoutOrg",func(t*testing.T) {
482+
t.Parallel()
483+
auditor:=audit.NewMock()
484+
client:=coderdtest.New(t,&coderdtest.Options{Auditor:auditor})
485+
numLogs:=len(auditor.AuditLogs())
486+
487+
_=coderdtest.CreateFirstUser(t,client)
488+
numLogs++// add an audit log for user create
489+
numLogs++// add an audit log for login
490+
491+
ctx,cancel:=context.WithTimeout(context.Background(),testutil.WaitLong)
492+
defercancel()
493+
494+
_,err:=client.CreateUser(ctx, codersdk.CreateUserRequest{
495+
Email:"another@user.org",
496+
Username:"someone-else",
497+
Password:"SomeSecurePassword!",
498+
})
499+
require.NoError(t,err)
500+
501+
require.Len(t,auditor.AuditLogs(),numLogs)
502+
require.Equal(t,database.AuditActionCreate,auditor.AuditLogs()[numLogs-1].Action)
503+
require.Equal(t,database.AuditActionLogin,auditor.AuditLogs()[numLogs-2].Action)
504+
})
505+
481506
t.Run("Create",func(t*testing.T) {
482507
t.Parallel()
483508
auditor:=audit.NewMock()

‎codersdk/users.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ type CreateUserRequest struct {
6969
Emailstring`json:"email" validate:"required,email" format:"email"`
7070
Usernamestring`json:"username" validate:"required,username"`
7171
Passwordstring`json:"password" validate:"required"`
72-
OrganizationID uuid.UUID`json:"organization_id" validate:"required" format:"uuid"`
72+
OrganizationID uuid.UUID`json:"organization_id" validate:"" format:"uuid"`
7373
}
7474

7575
typeUpdateUserProfileRequeststruct {

‎docs/api/schemas.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1564,7 +1564,7 @@ CreateParameterRequest is a structure used to create a new parameter value for a
15641564
| Name| Type| Required| Restrictions| Description|
15651565
| -----------------| ------| --------| ------------| -----------|
15661566
|`email`| string| true|||
1567-
|`organization_id`| string|true|||
1567+
|`organization_id`| string|false|||
15681568
|`password`| string| true|||
15691569
|`username`| string| true|||
15701570

‎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+
varorganizationID uuid.UUID
160+
//nolint:gocritic
161+
organizations,err:=api.Database.GetOrganizations(dbauthz.AsSystemRestricted(ctx))
162+
iferr!=nil {
163+
_=handlerutil.WriteError(rw,err)
164+
return
165+
}
166+
167+
iflen(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)

[8]ページ先頭

©2009-2025 Movatter.jp