mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
chore!: allow CreateUser to accept multiple organizations (#14383)
* chore: allow CreateUser to accept multiple organizations In a multi-org deployment, it makes more sense to allow for multiple org memberships to be assigned at create. The legacy param will still be honored. * Handle sdk deprecation better by maintaining cli functions
This commit is contained in:
@@ -757,11 +757,11 @@ func TestGroup(t *testing.T) {
|
||||
require.Contains(t, group.Members, user2.ReducedUser)
|
||||
|
||||
// cannot explicitly set a dormant user status so must create a new user
|
||||
anotherUser, err := userAdminClient.CreateUser(ctx, codersdk.CreateUserRequest{
|
||||
Email: "coder@coder.com",
|
||||
Username: "coder",
|
||||
Password: "SomeStrongPassword!",
|
||||
OrganizationID: user.OrganizationID,
|
||||
anotherUser, err := userAdminClient.CreateUserWithOrgs(ctx, codersdk.CreateUserRequestWithOrgs{
|
||||
Email: "coder@coder.com",
|
||||
Username: "coder",
|
||||
Password: "SomeStrongPassword!",
|
||||
OrganizationIDs: []uuid.UUID{user.OrganizationID},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
|
||||
@@ -228,11 +228,11 @@ func (api *API) scimPostUser(rw http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
//nolint:gocritic // needed for SCIM
|
||||
dbUser, _, err = api.AGPL.CreateUser(dbauthz.AsSystemRestricted(ctx), api.Database, agpl.CreateUserRequest{
|
||||
CreateUserRequest: codersdk.CreateUserRequest{
|
||||
Username: sUser.UserName,
|
||||
Email: email,
|
||||
OrganizationID: defaultOrganization.ID,
|
||||
dbUser, err = api.AGPL.CreateUser(dbauthz.AsSystemRestricted(ctx), api.Database, agpl.CreateUserRequest{
|
||||
CreateUserRequestWithOrgs: codersdk.CreateUserRequestWithOrgs{
|
||||
Username: sUser.UserName,
|
||||
Email: email,
|
||||
OrganizationIDs: []uuid.UUID{defaultOrganization.ID},
|
||||
},
|
||||
LoginType: database.LoginTypeOIDC,
|
||||
// Do not send notifications to user admins as SCIM endpoint might be called sequentially to all users.
|
||||
|
||||
@@ -717,7 +717,7 @@ func TestEnterpriseUserLogin(t *testing.T) {
|
||||
Name: customRole.Name,
|
||||
OrganizationID: owner.OrganizationID,
|
||||
},
|
||||
}, func(r *codersdk.CreateUserRequest) {
|
||||
}, func(r *codersdk.CreateUserRequestWithOrgs) {
|
||||
r.Password = "SomeSecurePassword!"
|
||||
r.UserLoginType = codersdk.LoginTypePassword
|
||||
})
|
||||
@@ -752,7 +752,7 @@ func TestEnterpriseUserLogin(t *testing.T) {
|
||||
},
|
||||
})
|
||||
|
||||
anotherClient, anotherUser := coderdtest.CreateAnotherUserMutators(t, ownerClient, owner.OrganizationID, nil, func(r *codersdk.CreateUserRequest) {
|
||||
anotherClient, anotherUser := coderdtest.CreateAnotherUserMutators(t, ownerClient, owner.OrganizationID, nil, func(r *codersdk.CreateUserRequestWithOrgs) {
|
||||
r.Password = "SomeSecurePassword!"
|
||||
r.UserLoginType = codersdk.LoginTypePassword
|
||||
})
|
||||
|
||||
@@ -7,7 +7,6 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/coder/coder/v2/coderd/coderdtest"
|
||||
@@ -509,11 +508,11 @@ func TestEnterprisePostUser(t *testing.T) {
|
||||
request.Name = "another"
|
||||
})
|
||||
|
||||
_, err := notInOrg.CreateUser(ctx, codersdk.CreateUserRequest{
|
||||
Email: "some@domain.com",
|
||||
Username: "anotheruser",
|
||||
Password: "SomeSecurePassword!",
|
||||
OrganizationID: org.ID,
|
||||
_, err := notInOrg.CreateUserWithOrgs(ctx, codersdk.CreateUserRequestWithOrgs{
|
||||
Email: "some@domain.com",
|
||||
Username: "anotheruser",
|
||||
Password: "SomeSecurePassword!",
|
||||
OrganizationIDs: []uuid.UUID{org.ID},
|
||||
})
|
||||
var apiErr *codersdk.Error
|
||||
require.ErrorAs(t, err, &apiErr)
|
||||
@@ -543,11 +542,11 @@ func TestEnterprisePostUser(t *testing.T) {
|
||||
|
||||
org := coderdenttest.CreateOrganization(t, other, coderdenttest.CreateOrganizationOptions{})
|
||||
|
||||
_, err := notInOrg.CreateUser(ctx, codersdk.CreateUserRequest{
|
||||
Email: "some@domain.com",
|
||||
Username: "anotheruser",
|
||||
Password: "SomeSecurePassword!",
|
||||
OrganizationID: org.ID,
|
||||
_, err := notInOrg.CreateUserWithOrgs(ctx, codersdk.CreateUserRequestWithOrgs{
|
||||
Email: "some@domain.com",
|
||||
Username: "anotheruser",
|
||||
Password: "SomeSecurePassword!",
|
||||
OrganizationIDs: []uuid.UUID{org.ID},
|
||||
})
|
||||
var apiErr *codersdk.Error
|
||||
require.ErrorAs(t, err, &apiErr)
|
||||
@@ -559,7 +558,7 @@ func TestEnterprisePostUser(t *testing.T) {
|
||||
dv := coderdtest.DeploymentValues(t)
|
||||
dv.Experiments = []string{string(codersdk.ExperimentMultiOrganization)}
|
||||
|
||||
client, firstUser := coderdenttest.New(t, &coderdenttest.Options{
|
||||
client, _ := coderdenttest.New(t, &coderdenttest.Options{
|
||||
Options: &coderdtest.Options{
|
||||
DeploymentValues: dv,
|
||||
},
|
||||
@@ -578,14 +577,53 @@ func TestEnterprisePostUser(t *testing.T) {
|
||||
|
||||
// nolint:gocritic // intentional using the owner.
|
||||
// Manually making a user with the request instead of the coderdtest util
|
||||
user, err := client.CreateUser(ctx, codersdk.CreateUserRequest{
|
||||
_, err := client.CreateUserWithOrgs(ctx, codersdk.CreateUserRequestWithOrgs{
|
||||
Email: "another@user.org",
|
||||
Username: "someone-else",
|
||||
Password: "SomeSecurePassword!",
|
||||
})
|
||||
require.ErrorContains(t, err, "No organization specified")
|
||||
})
|
||||
|
||||
t.Run("MultipleOrganizations", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
dv := coderdtest.DeploymentValues(t)
|
||||
dv.Experiments = []string{string(codersdk.ExperimentMultiOrganization)}
|
||||
|
||||
client, _ := coderdenttest.New(t, &coderdenttest.Options{
|
||||
Options: &coderdtest.Options{
|
||||
DeploymentValues: dv,
|
||||
},
|
||||
LicenseOptions: &coderdenttest.LicenseOptions{
|
||||
Features: license.Features{
|
||||
codersdk.FeatureMultipleOrganizations: 1,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
// Add an extra org to assign member into
|
||||
second := coderdenttest.CreateOrganization(t, client, coderdenttest.CreateOrganizationOptions{})
|
||||
third := coderdenttest.CreateOrganization(t, client, coderdenttest.CreateOrganizationOptions{})
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
|
||||
defer cancel()
|
||||
|
||||
// nolint:gocritic // intentional using the owner.
|
||||
// Manually making a user with the request instead of the coderdtest util
|
||||
user, err := client.CreateUserWithOrgs(ctx, codersdk.CreateUserRequestWithOrgs{
|
||||
Email: "another@user.org",
|
||||
Username: "someone-else",
|
||||
Password: "SomeSecurePassword!",
|
||||
OrganizationIDs: []uuid.UUID{
|
||||
second.ID,
|
||||
third.ID,
|
||||
},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Len(t, user.OrganizationIDs, 1)
|
||||
assert.Equal(t, firstUser.OrganizationID, user.OrganizationIDs[0])
|
||||
memberedOrgs, err := client.OrganizationsByUser(ctx, user.ID.String())
|
||||
require.NoError(t, err)
|
||||
require.Len(t, memberedOrgs, 2)
|
||||
require.ElementsMatch(t, []uuid.UUID{second.ID, third.ID}, []uuid.UUID{memberedOrgs[0].ID, memberedOrgs[1].ID})
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user