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:
Steven Masley
2024-08-23 16:23:51 -05:00
committed by GitHub
parent af125c3795
commit c8eacc6df7
28 changed files with 597 additions and 367 deletions

View File

@ -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})
})
}