Skip to content

Commit 2371153

Browse files
authored
feat: add endpoint for partial updates to org sync mapping (#16316)
1 parent f651ab9 commit 2371153

File tree

17 files changed

+595
-11
lines changed

17 files changed

+595
-11
lines changed

coderd/apidoc/docs.go

Lines changed: 76 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/apidoc/swagger.json

Lines changed: 70 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/idpsync/idpsync.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import (
2626
type IDPSync interface {
2727
OrganizationSyncEntitled() bool
2828
OrganizationSyncSettings(ctx context.Context, db database.Store) (*OrganizationSyncSettings, error)
29-
UpdateOrganizationSettings(ctx context.Context, db database.Store, settings OrganizationSyncSettings) error
29+
UpdateOrganizationSyncSettings(ctx context.Context, db database.Store, settings OrganizationSyncSettings) error
3030
// OrganizationSyncEnabled returns true if all OIDC users are assigned
3131
// to organizations via org sync settings.
3232
// This is used to know when to disable manual org membership assignment.
@@ -70,6 +70,9 @@ type IDPSync interface {
7070
SyncRoles(ctx context.Context, db database.Store, user database.User, params RoleParams) error
7171
}
7272

73+
// AGPLIDPSync implements the IDPSync interface
74+
var _ IDPSync = AGPLIDPSync{}
75+
7376
// AGPLIDPSync is the configuration for syncing user information from an external
7477
// IDP. All related code to syncing user information should be in this package.
7578
type AGPLIDPSync struct {

coderd/idpsync/organization.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ func (AGPLIDPSync) OrganizationSyncEnabled(_ context.Context, _ database.Store)
3434
return false
3535
}
3636

37-
func (s AGPLIDPSync) UpdateOrganizationSettings(ctx context.Context, db database.Store, settings OrganizationSyncSettings) error {
37+
func (s AGPLIDPSync) UpdateOrganizationSyncSettings(ctx context.Context, db database.Store, settings OrganizationSyncSettings) error {
3838
rlv := s.Manager.Resolver(db)
3939
err := s.SyncSettings.Organization.SetRuntimeValue(ctx, rlv, &settings)
4040
if err != nil {

coderd/runtimeconfig/resolver.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ import (
1212
"github.com/coder/coder/v2/coderd/database"
1313
)
1414

15+
// NoopResolver implements the Resolver interface
16+
var _ Resolver = &NoopResolver{}
17+
1518
// NoopResolver is a useful test device.
1619
type NoopResolver struct{}
1720

@@ -31,6 +34,9 @@ func (NoopResolver) DeleteRuntimeConfig(context.Context, string) error {
3134
return ErrEntryNotFound
3235
}
3336

37+
// StoreResolver implements the Resolver interface
38+
var _ Resolver = &StoreResolver{}
39+
3440
// StoreResolver uses the database as the underlying store for runtime settings.
3541
type StoreResolver struct {
3642
db Store

coderd/telemetry/telemetry_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,7 @@ func TestTelemetry(t *testing.T) {
295295
org, err := db.GetDefaultOrganization(ctx)
296296
require.NoError(t, err)
297297
sync := idpsync.NewAGPLSync(testutil.Logger(t), runtimeconfig.NewManager(), idpsync.DeploymentSyncSettings{})
298-
err = sync.UpdateOrganizationSettings(ctx, db, idpsync.OrganizationSyncSettings{
298+
err = sync.UpdateOrganizationSyncSettings(ctx, db, idpsync.OrganizationSyncSettings{
299299
Field: "organizations",
300300
Mapping: map[string][]uuid.UUID{
301301
"first": {org.ID},

codersdk/idpsync.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,13 @@ import (
1212
"golang.org/x/xerrors"
1313
)
1414

15+
type IDPSyncMapping[ResourceIdType uuid.UUID | string] struct {
16+
// The IdP claim the user has
17+
Given string
18+
// The ID of the Coder resource the user should be added to
19+
Gets ResourceIdType
20+
}
21+
1522
type GroupSyncSettings struct {
1623
// Field is the name of the claim field that specifies what groups a user
1724
// should be in. If empty, no groups will be synced.
@@ -137,6 +144,26 @@ func (c *Client) PatchOrganizationIDPSyncSettings(ctx context.Context, req Organ
137144
return resp, json.NewDecoder(res.Body).Decode(&resp)
138145
}
139146

147+
// If the same mapping is present in both Add and Remove, Remove will take presidence.
148+
type PatchOrganizationIDPSyncMappingRequest struct {
149+
Add []IDPSyncMapping[uuid.UUID]
150+
Remove []IDPSyncMapping[uuid.UUID]
151+
}
152+
153+
func (c *Client) PatchOrganizationIDPSyncMapping(ctx context.Context, req PatchOrganizationIDPSyncMappingRequest) (OrganizationSyncSettings, error) {
154+
res, err := c.Request(ctx, http.MethodPatch, "/api/v2/settings/idpsync/organization/mapping", req)
155+
if err != nil {
156+
return OrganizationSyncSettings{}, xerrors.Errorf("make request: %w", err)
157+
}
158+
defer res.Body.Close()
159+
160+
if res.StatusCode != http.StatusOK {
161+
return OrganizationSyncSettings{}, ReadBodyAsError(res)
162+
}
163+
var resp OrganizationSyncSettings
164+
return resp, json.NewDecoder(res.Body).Decode(&resp)
165+
}
166+
140167
func (c *Client) GetAvailableIDPSyncFields(ctx context.Context) ([]string, error) {
141168
res, err := c.Request(ctx, http.MethodGet, "/api/v2/settings/idpsync/available-fields", nil)
142169
if err != nil {

docs/reference/api/enterprise.md

Lines changed: 66 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/reference/api/schemas.md

Lines changed: 30 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy