From d96adad56f5d80cae3bc7d43c18f8548fb2189d0 Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Tue, 17 Sep 2024 14:08:33 -0500 Subject: [PATCH] chore: add cli command to fetch group sync settings as json (#14694) * chore: add cli command to fetch group sync settings as json --- cli/organization.go | 1 + cli/organizationsettings.go | 209 ++++++++++++++++++ cli/root.go | 6 +- .../coder_organizations_--help.golden | 13 +- ...coder_organizations_settings_--help.golden | 15 ++ ...r_organizations_settings_set_--help.golden | 17 ++ ...izations_settings_set_--help_--help.golden | 17 ++ ..._organizations_settings_show_--help.golden | 17 ++ ...zations_settings_show_--help_--help.golden | 17 ++ docs/manifest.json | 35 +++ docs/reference/cli/organizations.md | 13 +- docs/reference/cli/organizations_settings.md | 22 ++ .../cli/organizations_settings_set.md | 26 +++ .../organizations_settings_set_group-sync.md | 15 ++ .../organizations_settings_set_role-sync.md | 15 ++ .../cli/organizations_settings_show.md | 26 +++ .../organizations_settings_show_group-sync.md | 15 ++ .../organizations_settings_show_role-sync.md | 15 ++ enterprise/cli/organizationsettings_test.go | 130 +++++++++++ enterprise/coderd/idpsync.go | 15 ++ 20 files changed, 626 insertions(+), 13 deletions(-) create mode 100644 cli/organizationsettings.go create mode 100644 cli/testdata/coder_organizations_settings_--help.golden create mode 100644 cli/testdata/coder_organizations_settings_set_--help.golden create mode 100644 cli/testdata/coder_organizations_settings_set_--help_--help.golden create mode 100644 cli/testdata/coder_organizations_settings_show_--help.golden create mode 100644 cli/testdata/coder_organizations_settings_show_--help_--help.golden create mode 100644 docs/reference/cli/organizations_settings.md create mode 100644 docs/reference/cli/organizations_settings_set.md create mode 100644 docs/reference/cli/organizations_settings_set_group-sync.md create mode 100644 docs/reference/cli/organizations_settings_set_role-sync.md create mode 100644 docs/reference/cli/organizations_settings_show.md create mode 100644 docs/reference/cli/organizations_settings_show_group-sync.md create mode 100644 docs/reference/cli/organizations_settings_show_role-sync.md create mode 100644 enterprise/cli/organizationsettings_test.go diff --git a/cli/organization.go b/cli/organization.go index 0f83d9b117..941219a0a6 100644 --- a/cli/organization.go +++ b/cli/organization.go @@ -26,6 +26,7 @@ func (r *RootCmd) organizations() *serpent.Command { r.createOrganization(), r.organizationMembers(orgContext), r.organizationRoles(orgContext), + r.organizationSettings(orgContext), }, } diff --git a/cli/organizationsettings.go b/cli/organizationsettings.go new file mode 100644 index 0000000000..c4422c8d37 --- /dev/null +++ b/cli/organizationsettings.go @@ -0,0 +1,209 @@ +package cli + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + + "github.com/google/uuid" + "golang.org/x/xerrors" + + "github.com/coder/coder/v2/codersdk" + "github.com/coder/serpent" +) + +func (r *RootCmd) organizationSettings(orgContext *OrganizationContext) *serpent.Command { + settings := []organizationSetting{ + { + Name: "group-sync", + Aliases: []string{"groupsync"}, + Short: "Group sync settings to sync groups from an IdP.", + Patch: func(ctx context.Context, cli *codersdk.Client, org uuid.UUID, input json.RawMessage) (any, error) { + var req codersdk.GroupSyncSettings + err := json.Unmarshal(input, &req) + if err != nil { + return nil, xerrors.Errorf("unmarshalling group sync settings: %w", err) + } + return cli.PatchGroupIDPSyncSettings(ctx, org.String(), req) + }, + Fetch: func(ctx context.Context, cli *codersdk.Client, org uuid.UUID) (any, error) { + return cli.GroupIDPSyncSettings(ctx, org.String()) + }, + }, + { + Name: "role-sync", + Aliases: []string{"rolesync"}, + Short: "Role sync settings to sync organization roles from an IdP.", + Patch: func(ctx context.Context, cli *codersdk.Client, org uuid.UUID, input json.RawMessage) (any, error) { + var req codersdk.RoleSyncSettings + err := json.Unmarshal(input, &req) + if err != nil { + return nil, xerrors.Errorf("unmarshalling role sync settings: %w", err) + } + return cli.PatchRoleIDPSyncSettings(ctx, org.String(), req) + }, + Fetch: func(ctx context.Context, cli *codersdk.Client, org uuid.UUID) (any, error) { + return cli.RoleIDPSyncSettings(ctx, org.String()) + }, + }, + } + cmd := &serpent.Command{ + Use: "settings", + Short: "Manage organization settings.", + Aliases: []string{"setting"}, + Handler: func(inv *serpent.Invocation) error { + return inv.Command.HelpHandler(inv) + }, + Children: []*serpent.Command{ + r.printOrganizationSetting(orgContext, settings), + r.setOrganizationSettings(orgContext, settings), + }, + } + return cmd +} + +type organizationSetting struct { + Name string + Aliases []string + Short string + Patch func(ctx context.Context, cli *codersdk.Client, org uuid.UUID, input json.RawMessage) (any, error) + Fetch func(ctx context.Context, cli *codersdk.Client, org uuid.UUID) (any, error) +} + +func (r *RootCmd) setOrganizationSettings(orgContext *OrganizationContext, settings []organizationSetting) *serpent.Command { + client := new(codersdk.Client) + cmd := &serpent.Command{ + Use: "set", + Short: "Update specified organization setting.", + Long: FormatExamples( + Example{ + Description: "Update group sync settings.", + Command: "coder organization settings set groupsync < input.json", + }, + ), + Options: []serpent.Option{}, + Middleware: serpent.Chain( + serpent.RequireNArgs(0), + r.InitClient(client), + ), + Handler: func(inv *serpent.Invocation) error { + return inv.Command.HelpHandler(inv) + }, + } + + for _, set := range settings { + set := set + patch := set.Patch + cmd.Children = append(cmd.Children, &serpent.Command{ + Use: set.Name, + Aliases: set.Aliases, + Short: set.Short, + Options: []serpent.Option{}, + Middleware: serpent.Chain( + serpent.RequireNArgs(0), + r.InitClient(client), + ), + Handler: func(inv *serpent.Invocation) error { + ctx := inv.Context() + org, err := orgContext.Selected(inv, client) + if err != nil { + return err + } + + // Read in the json + inputData, err := io.ReadAll(inv.Stdin) + if err != nil { + return xerrors.Errorf("reading stdin: %w", err) + } + + output, err := patch(ctx, client, org.ID, inputData) + if err != nil { + return xerrors.Errorf("patching %q: %w", set.Name, err) + } + + settingJSON, err := json.Marshal(output) + if err != nil { + return fmt.Errorf("failed to marshal organization setting %s: %w", inv.Args[0], err) + } + + var dst bytes.Buffer + err = json.Indent(&dst, settingJSON, "", "\t") + if err != nil { + return fmt.Errorf("failed to indent organization setting as json %s: %w", inv.Args[0], err) + } + + _, err = fmt.Fprintln(inv.Stdout, dst.String()) + return err + }, + }) + } + + return cmd +} + +func (r *RootCmd) printOrganizationSetting(orgContext *OrganizationContext, settings []organizationSetting) *serpent.Command { + client := new(codersdk.Client) + cmd := &serpent.Command{ + Use: "show", + Short: "Outputs specified organization setting.", + Long: FormatExamples( + Example{ + Description: "Output group sync settings.", + Command: "coder organization settings show groupsync", + }, + ), + Options: []serpent.Option{}, + Middleware: serpent.Chain( + serpent.RequireNArgs(0), + r.InitClient(client), + ), + Handler: func(inv *serpent.Invocation) error { + return inv.Command.HelpHandler(inv) + }, + } + + for _, set := range settings { + set := set + fetch := set.Fetch + cmd.Children = append(cmd.Children, &serpent.Command{ + Use: set.Name, + Aliases: set.Aliases, + Short: set.Short, + Options: []serpent.Option{}, + Middleware: serpent.Chain( + serpent.RequireNArgs(0), + r.InitClient(client), + ), + Handler: func(inv *serpent.Invocation) error { + ctx := inv.Context() + org, err := orgContext.Selected(inv, client) + if err != nil { + return err + } + + output, err := fetch(ctx, client, org.ID) + if err != nil { + return xerrors.Errorf("patching %q: %w", set.Name, err) + } + + settingJSON, err := json.Marshal(output) + if err != nil { + return fmt.Errorf("failed to marshal organization setting %s: %w", inv.Args[0], err) + } + + var dst bytes.Buffer + err = json.Indent(&dst, settingJSON, "", "\t") + if err != nil { + return fmt.Errorf("failed to indent organization setting as json %s: %w", inv.Args[0], err) + } + + _, err = fmt.Fprintln(inv.Stdout, dst.String()) + return err + }, + }) + } + + return cmd +} diff --git a/cli/root.go b/cli/root.go index 4945ecdd16..87a4f4b422 100644 --- a/cli/root.go +++ b/cli/root.go @@ -29,6 +29,7 @@ import ( "golang.org/x/mod/semver" "golang.org/x/xerrors" + "github.com/coder/coder/v2/coderd/database/db2sdk" "github.com/coder/pretty" "github.com/coder/coder/v2/buildinfo" @@ -657,7 +658,10 @@ func (o *OrganizationContext) Selected(inv *serpent.Invocation, client *codersdk } // No org selected, and we are more than 1? Return an error. - return codersdk.Organization{}, xerrors.Errorf("Must select an organization with --org=.") + validOrgs := db2sdk.List(orgs, func(org codersdk.Organization) string { + return fmt.Sprintf("%q", org.Name) + }) + return codersdk.Organization{}, xerrors.Errorf("Must select an organization with --org=. Choose from: %s", strings.Join(validOrgs, ", ")) } func splitNamedWorkspace(identifier string) (owner string, workspaceName string, err error) { diff --git a/cli/testdata/coder_organizations_--help.golden b/cli/testdata/coder_organizations_--help.golden index e246b9f856..5b06825e39 100644 --- a/cli/testdata/coder_organizations_--help.golden +++ b/cli/testdata/coder_organizations_--help.golden @@ -8,12 +8,13 @@ USAGE: Aliases: organization, org, orgs SUBCOMMANDS: - create Create a new organization. - members Manage organization members - roles Manage organization roles. - show Show the organization. Using "selected" will show the selected - organization from the "--org" flag. Using "me" will show all - organizations you are a member of. + create Create a new organization. + members Manage organization members + roles Manage organization roles. + settings Manage organization settings. + show Show the organization. Using "selected" will show the selected + organization from the "--org" flag. Using "me" will show all + organizations you are a member of. OPTIONS: -O, --org string, $CODER_ORGANIZATION diff --git a/cli/testdata/coder_organizations_settings_--help.golden b/cli/testdata/coder_organizations_settings_--help.golden new file mode 100644 index 0000000000..39597c1f2f --- /dev/null +++ b/cli/testdata/coder_organizations_settings_--help.golden @@ -0,0 +1,15 @@ +coder v0.0.0-devel + +USAGE: + coder organizations settings + + Manage organization settings. + + Aliases: setting + +SUBCOMMANDS: + set Update specified organization setting. + show Outputs specified organization setting. + +——— +Run `coder --help` for a list of global options. diff --git a/cli/testdata/coder_organizations_settings_set_--help.golden b/cli/testdata/coder_organizations_settings_set_--help.golden new file mode 100644 index 0000000000..e86ceddf73 --- /dev/null +++ b/cli/testdata/coder_organizations_settings_set_--help.golden @@ -0,0 +1,17 @@ +coder v0.0.0-devel + +USAGE: + coder organizations settings set + + Update specified organization setting. + + - Update group sync settings.: + + $ coder organization settings set groupsync < input.json + +SUBCOMMANDS: + group-sync Group sync settings to sync groups from an IdP. + role-sync Role sync settings to sync organization roles from an IdP. + +——— +Run `coder --help` for a list of global options. diff --git a/cli/testdata/coder_organizations_settings_set_--help_--help.golden b/cli/testdata/coder_organizations_settings_set_--help_--help.golden new file mode 100644 index 0000000000..e86ceddf73 --- /dev/null +++ b/cli/testdata/coder_organizations_settings_set_--help_--help.golden @@ -0,0 +1,17 @@ +coder v0.0.0-devel + +USAGE: + coder organizations settings set + + Update specified organization setting. + + - Update group sync settings.: + + $ coder organization settings set groupsync < input.json + +SUBCOMMANDS: + group-sync Group sync settings to sync groups from an IdP. + role-sync Role sync settings to sync organization roles from an IdP. + +——— +Run `coder --help` for a list of global options. diff --git a/cli/testdata/coder_organizations_settings_show_--help.golden b/cli/testdata/coder_organizations_settings_show_--help.golden new file mode 100644 index 0000000000..ee575a0fd0 --- /dev/null +++ b/cli/testdata/coder_organizations_settings_show_--help.golden @@ -0,0 +1,17 @@ +coder v0.0.0-devel + +USAGE: + coder organizations settings show + + Outputs specified organization setting. + + - Output group sync settings.: + + $ coder organization settings show groupsync + +SUBCOMMANDS: + group-sync Group sync settings to sync groups from an IdP. + role-sync Role sync settings to sync organization roles from an IdP. + +——— +Run `coder --help` for a list of global options. diff --git a/cli/testdata/coder_organizations_settings_show_--help_--help.golden b/cli/testdata/coder_organizations_settings_show_--help_--help.golden new file mode 100644 index 0000000000..ee575a0fd0 --- /dev/null +++ b/cli/testdata/coder_organizations_settings_show_--help_--help.golden @@ -0,0 +1,17 @@ +coder v0.0.0-devel + +USAGE: + coder organizations settings show + + Outputs specified organization setting. + + - Output group sync settings.: + + $ coder organization settings show groupsync + +SUBCOMMANDS: + group-sync Group sync settings to sync groups from an IdP. + role-sync Role sync settings to sync organization roles from an IdP. + +——— +Run `coder --help` for a list of global options. diff --git a/docs/manifest.json b/docs/manifest.json index 75ee5e6e81..7d9c422b28 100644 --- a/docs/manifest.json +++ b/docs/manifest.json @@ -857,6 +857,41 @@ "description": "Show role(s)", "path": "reference/cli/organizations_roles_show.md" }, + { + "title": "organizations settings", + "description": "Manage organization settings.", + "path": "reference/cli/organizations_settings.md" + }, + { + "title": "organizations settings set", + "description": "Update specified organization setting.", + "path": "reference/cli/organizations_settings_set.md" + }, + { + "title": "organizations settings set group-sync", + "description": "Group sync settings to sync groups from an IdP.", + "path": "reference/cli/organizations_settings_set_group-sync.md" + }, + { + "title": "organizations settings set role-sync", + "description": "Role sync settings to sync organization roles from an IdP.", + "path": "reference/cli/organizations_settings_set_role-sync.md" + }, + { + "title": "organizations settings show", + "description": "Outputs specified organization setting.", + "path": "reference/cli/organizations_settings_show.md" + }, + { + "title": "organizations settings show group-sync", + "description": "Group sync settings to sync groups from an IdP.", + "path": "reference/cli/organizations_settings_show_group-sync.md" + }, + { + "title": "organizations settings show role-sync", + "description": "Role sync settings to sync organization roles from an IdP.", + "path": "reference/cli/organizations_settings_show_role-sync.md" + }, { "title": "organizations show", "description": "Show the organization. Using \"selected\" will show the selected organization from the \"--org\" flag. Using \"me\" will show all organizations you are a member of.", diff --git a/docs/reference/cli/organizations.md b/docs/reference/cli/organizations.md index 8257048960..1fbd076425 100644 --- a/docs/reference/cli/organizations.md +++ b/docs/reference/cli/organizations.md @@ -18,12 +18,13 @@ coder organizations [flags] [subcommand] ## Subcommands -| Name | Purpose | -| -------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [show](./organizations_show.md) | Show the organization. Using "selected" will show the selected organization from the "--org" flag. Using "me" will show all organizations you are a member of. | -| [create](./organizations_create.md) | Create a new organization. | -| [members](./organizations_members.md) | Manage organization members | -| [roles](./organizations_roles.md) | Manage organization roles. | +| Name | Purpose | +| ---------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [show](./organizations_show.md) | Show the organization. Using "selected" will show the selected organization from the "--org" flag. Using "me" will show all organizations you are a member of. | +| [create](./organizations_create.md) | Create a new organization. | +| [members](./organizations_members.md) | Manage organization members | +| [roles](./organizations_roles.md) | Manage organization roles. | +| [settings](./organizations_settings.md) | Manage organization settings. | ## Options diff --git a/docs/reference/cli/organizations_settings.md b/docs/reference/cli/organizations_settings.md new file mode 100644 index 0000000000..15093c984f --- /dev/null +++ b/docs/reference/cli/organizations_settings.md @@ -0,0 +1,22 @@ + + +# organizations settings + +Manage organization settings. + +Aliases: + +- setting + +## Usage + +```console +coder organizations settings +``` + +## Subcommands + +| Name | Purpose | +| ----------------------------------------------------- | --------------------------------------- | +| [show](./organizations_settings_show.md) | Outputs specified organization setting. | +| [set](./organizations_settings_set.md) | Update specified organization setting. | diff --git a/docs/reference/cli/organizations_settings_set.md b/docs/reference/cli/organizations_settings_set.md new file mode 100644 index 0000000000..b4fd819184 --- /dev/null +++ b/docs/reference/cli/organizations_settings_set.md @@ -0,0 +1,26 @@ + + +# organizations settings set + +Update specified organization setting. + +## Usage + +```console +coder organizations settings set +``` + +## Description + +```console + - Update group sync settings.: + + $ coder organization settings set groupsync < input.json +``` + +## Subcommands + +| Name | Purpose | +| --------------------------------------------------------------------- | ---------------------------------------------------------- | +| [group-sync](./organizations_settings_set_group-sync.md) | Group sync settings to sync groups from an IdP. | +| [role-sync](./organizations_settings_set_role-sync.md) | Role sync settings to sync organization roles from an IdP. | diff --git a/docs/reference/cli/organizations_settings_set_group-sync.md b/docs/reference/cli/organizations_settings_set_group-sync.md new file mode 100644 index 0000000000..f60a456771 --- /dev/null +++ b/docs/reference/cli/organizations_settings_set_group-sync.md @@ -0,0 +1,15 @@ + + +# organizations settings set group-sync + +Group sync settings to sync groups from an IdP. + +Aliases: + +- groupsync + +## Usage + +```console +coder organizations settings set group-sync +``` diff --git a/docs/reference/cli/organizations_settings_set_role-sync.md b/docs/reference/cli/organizations_settings_set_role-sync.md new file mode 100644 index 0000000000..40203b21f7 --- /dev/null +++ b/docs/reference/cli/organizations_settings_set_role-sync.md @@ -0,0 +1,15 @@ + + +# organizations settings set role-sync + +Role sync settings to sync organization roles from an IdP. + +Aliases: + +- rolesync + +## Usage + +```console +coder organizations settings set role-sync +``` diff --git a/docs/reference/cli/organizations_settings_show.md b/docs/reference/cli/organizations_settings_show.md new file mode 100644 index 0000000000..651f0a6f19 --- /dev/null +++ b/docs/reference/cli/organizations_settings_show.md @@ -0,0 +1,26 @@ + + +# organizations settings show + +Outputs specified organization setting. + +## Usage + +```console +coder organizations settings show +``` + +## Description + +```console + - Output group sync settings.: + + $ coder organization settings show groupsync +``` + +## Subcommands + +| Name | Purpose | +| ---------------------------------------------------------------------- | ---------------------------------------------------------- | +| [group-sync](./organizations_settings_show_group-sync.md) | Group sync settings to sync groups from an IdP. | +| [role-sync](./organizations_settings_show_role-sync.md) | Role sync settings to sync organization roles from an IdP. | diff --git a/docs/reference/cli/organizations_settings_show_group-sync.md b/docs/reference/cli/organizations_settings_show_group-sync.md new file mode 100644 index 0000000000..6ae796d117 --- /dev/null +++ b/docs/reference/cli/organizations_settings_show_group-sync.md @@ -0,0 +1,15 @@ + + +# organizations settings show group-sync + +Group sync settings to sync groups from an IdP. + +Aliases: + +- groupsync + +## Usage + +```console +coder organizations settings show group-sync +``` diff --git a/docs/reference/cli/organizations_settings_show_role-sync.md b/docs/reference/cli/organizations_settings_show_role-sync.md new file mode 100644 index 0000000000..8a32c13851 --- /dev/null +++ b/docs/reference/cli/organizations_settings_show_role-sync.md @@ -0,0 +1,15 @@ + + +# organizations settings show role-sync + +Role sync settings to sync organization roles from an IdP. + +Aliases: + +- rolesync + +## Usage + +```console +coder organizations settings show role-sync +``` diff --git a/enterprise/cli/organizationsettings_test.go b/enterprise/cli/organizationsettings_test.go new file mode 100644 index 0000000000..44438a6fb0 --- /dev/null +++ b/enterprise/cli/organizationsettings_test.go @@ -0,0 +1,130 @@ +package cli_test + +import ( + "bytes" + "encoding/json" + "regexp" + "testing" + + "github.com/google/uuid" + "github.com/stretchr/testify/require" + + "github.com/coder/coder/v2/cli/clitest" + "github.com/coder/coder/v2/coderd/coderdtest" + "github.com/coder/coder/v2/coderd/rbac" + "github.com/coder/coder/v2/codersdk" + "github.com/coder/coder/v2/enterprise/coderd/coderdenttest" + "github.com/coder/coder/v2/enterprise/coderd/license" + "github.com/coder/coder/v2/testutil" +) + +func TestUpdateGroupSync(t *testing.T) { + t.Parallel() + + t.Run("OK", func(t *testing.T) { + t.Parallel() + + dv := coderdtest.DeploymentValues(t) + dv.Experiments = []string{string(codersdk.ExperimentMultiOrganization)} + + owner, first := coderdenttest.New(t, &coderdenttest.Options{ + Options: &coderdtest.Options{ + DeploymentValues: dv, + }, + LicenseOptions: &coderdenttest.LicenseOptions{ + Features: license.Features{ + codersdk.FeatureMultipleOrganizations: 1, + }, + }, + }) + + ctx := testutil.Context(t, testutil.WaitLong) + inv, root := clitest.New(t, "organization", "settings", "set", "groupsync") + //nolint:gocritic // Using the owner, testing the cli not perms + clitest.SetupConfig(t, owner, root) + + expectedSettings := codersdk.GroupSyncSettings{ + Field: "groups", + Mapping: map[string][]uuid.UUID{ + "test": {first.OrganizationID}, + }, + RegexFilter: regexp.MustCompile("^foo"), + AutoCreateMissing: true, + LegacyNameMapping: nil, + } + expectedData, err := json.Marshal(expectedSettings) + require.NoError(t, err) + + buf := new(bytes.Buffer) + inv.Stdout = buf + inv.Stdin = bytes.NewBuffer(expectedData) + err = inv.WithContext(ctx).Run() + require.NoError(t, err) + require.JSONEq(t, string(expectedData), buf.String()) + + // Now read it back + inv, root = clitest.New(t, "organization", "settings", "show", "groupsync") + //nolint:gocritic // Using the owner, testing the cli not perms + clitest.SetupConfig(t, owner, root) + + buf = new(bytes.Buffer) + inv.Stdout = buf + err = inv.WithContext(ctx).Run() + require.NoError(t, err) + require.JSONEq(t, string(expectedData), buf.String()) + }) +} + +func TestUpdateRoleSync(t *testing.T) { + t.Parallel() + + t.Run("OK", func(t *testing.T) { + t.Parallel() + + dv := coderdtest.DeploymentValues(t) + dv.Experiments = []string{string(codersdk.ExperimentMultiOrganization)} + + owner, _ := coderdenttest.New(t, &coderdenttest.Options{ + Options: &coderdtest.Options{ + DeploymentValues: dv, + }, + LicenseOptions: &coderdenttest.LicenseOptions{ + Features: license.Features{ + codersdk.FeatureMultipleOrganizations: 1, + }, + }, + }) + + ctx := testutil.Context(t, testutil.WaitLong) + inv, root := clitest.New(t, "organization", "settings", "set", "rolesync") + //nolint:gocritic // Using the owner, testing the cli not perms + clitest.SetupConfig(t, owner, root) + + expectedSettings := codersdk.RoleSyncSettings{ + Field: "roles", + Mapping: map[string][]string{ + "test": {rbac.RoleOrgAdmin()}, + }, + } + expectedData, err := json.Marshal(expectedSettings) + require.NoError(t, err) + + buf := new(bytes.Buffer) + inv.Stdout = buf + inv.Stdin = bytes.NewBuffer(expectedData) + err = inv.WithContext(ctx).Run() + require.NoError(t, err) + require.JSONEq(t, string(expectedData), buf.String()) + + // Now read it back + inv, root = clitest.New(t, "organization", "settings", "show", "rolesync") + //nolint:gocritic // Using the owner, testing the cli not perms + clitest.SetupConfig(t, owner, root) + + buf = new(bytes.Buffer) + inv.Stdout = buf + err = inv.WithContext(ctx).Run() + require.NoError(t, err) + require.JSONEq(t, string(expectedData), buf.String()) + }) +} diff --git a/enterprise/coderd/idpsync.go b/enterprise/coderd/idpsync.go index f5b3b6f013..096209ffe8 100644 --- a/enterprise/coderd/idpsync.go +++ b/enterprise/coderd/idpsync.go @@ -9,6 +9,7 @@ import ( "github.com/coder/coder/v2/coderd/idpsync" "github.com/coder/coder/v2/coderd/rbac" "github.com/coder/coder/v2/coderd/rbac/policy" + "github.com/coder/coder/v2/codersdk" ) // @Summary Get group IdP Sync settings by organization @@ -61,6 +62,20 @@ func (api *API) patchGroupIDPSyncSettings(rw http.ResponseWriter, r *http.Reques return } + if len(req.LegacyNameMapping) > 0 { + httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{ + Message: "Unexpected field 'legacy_group_name_mapping'. Field not allowed, set to null or remove it.", + Detail: "legacy_group_name_mapping is deprecated, use mapping instead", + Validations: []codersdk.ValidationError{ + { + Field: "legacy_group_name_mapping", + Detail: "field is not allowed", + }, + }, + }) + return + } + //nolint:gocritic // Requires system context to update runtime config sysCtx := dbauthz.AsSystemRestricted(ctx) err := api.IDPSync.UpdateGroupSettings(sysCtx, org.ID, api.Database, req)