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

feat: add group mapping option for group sync#6705

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
bpmct merged 2 commits intomainfromcolin/group-mapping
Mar 21, 2023
Merged
Show file tree
Hide file tree
Changes fromall commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletionscli/server.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -796,6 +796,7 @@ flags, and YAML configuration. The precedence is as follows:
AllowSignups: cfg.OIDC.AllowSignups.Value(),
UsernameField: cfg.OIDC.UsernameField.String(),
GroupField: cfg.OIDC.GroupField.String(),
GroupMapping: cfg.OIDC.GroupMapping.Value,
SignInText: cfg.OIDC.SignInText.String(),
IconURL: cfg.OIDC.IconURL.String(),
IgnoreEmailVerified: cfg.OIDC.IgnoreEmailVerified.Value(),
Expand Down
3 changes: 3 additions & 0 deletionscoderd/apidoc/docs.go
View file
Open in desktop

Some generated files are not rendered by default. Learn more abouthow customized files appear on GitHub.

3 changes: 3 additions & 0 deletionscoderd/apidoc/swagger.json
View file
Open in desktop

Some generated files are not rendered by default. Learn more abouthow customized files appear on GitHub.

7 changes: 6 additions & 1 deletioncoderd/coderd.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -223,7 +223,12 @@ func New(options *Options) *API {
options.SSHConfig.HostnamePrefix = "coder."
}
if options.SetUserGroups == nil {
options.SetUserGroups = func(context.Context, database.Store, uuid.UUID, []string) error { return nil }
options.SetUserGroups = func(ctx context.Context, _ database.Store, id uuid.UUID, groups []string) error {
options.Logger.Warn(ctx, "attempted to assign OIDC groups without enterprise license",
slog.F("id", id), slog.F("groups", groups),
)
return nil
}
}
if options.TemplateScheduleStore == nil {
options.TemplateScheduleStore = schedule.NewAGPLTemplateScheduleStore()
Expand Down
9 changes: 9 additions & 0 deletionscoderd/userauth.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -481,6 +481,10 @@ type OIDCConfig struct {
// groups. If the group field is the empty string, then no group updates
// will ever come from the OIDC provider.
GroupField string
// GroupMapping controls how groups returned by the OIDC provider get mapped
// to groups within Coder.
// map[oidcGroupName]coderGroupName
GroupMapping map[string]string
// SignInText is the text to display on the OIDC login button
SignInText string
// IconURL points to the URL of an icon to display on the OIDC login button
Expand DownExpand Up@@ -651,6 +655,11 @@ func (api *API) userOIDC(rw http.ResponseWriter, r *http.Request) {
})
return
}

if mappedGroup, ok := api.OIDCConfig.GroupMapping[group]; ok {
group = mappedGroup
}

groups = append(groups, group)
}
} else {
Expand Down
36 changes: 23 additions & 13 deletionscodersdk/deployment.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -4,7 +4,6 @@ import (
"context"
"encoding/json"
"flag"
"fmt"
"math"
"net/http"
"os"
Expand DownExpand Up@@ -199,7 +198,7 @@ func ParseSSHConfigOption(opt string) (key string, value string, err error) {
return r == ' ' || r == '='
})
if idx == -1 {
return "", "",fmt.Errorf("invalid config-ssh option %q", opt)
return "", "",xerrors.Errorf("invalid config-ssh option %q", opt)
}
return opt[:idx], opt[idx+1:], nil
}
Expand DownExpand Up@@ -248,17 +247,18 @@ type OAuth2GithubConfig struct {
}

type OIDCConfig struct {
AllowSignups clibase.Bool `json:"allow_signups" typescript:",notnull"`
ClientID clibase.String `json:"client_id" typescript:",notnull"`
ClientSecret clibase.String `json:"client_secret" typescript:",notnull"`
EmailDomain clibase.Strings `json:"email_domain" typescript:",notnull"`
IssuerURL clibase.String `json:"issuer_url" typescript:",notnull"`
Scopes clibase.Strings `json:"scopes" typescript:",notnull"`
IgnoreEmailVerified clibase.Bool `json:"ignore_email_verified" typescript:",notnull"`
UsernameField clibase.String `json:"username_field" typescript:",notnull"`
GroupField clibase.String `json:"groups_field" typescript:",notnull"`
SignInText clibase.String `json:"sign_in_text" typescript:",notnull"`
IconURL clibase.URL `json:"icon_url" typescript:",notnull"`
AllowSignups clibase.Bool `json:"allow_signups" typescript:",notnull"`
ClientID clibase.String `json:"client_id" typescript:",notnull"`
ClientSecret clibase.String `json:"client_secret" typescript:",notnull"`
EmailDomain clibase.Strings `json:"email_domain" typescript:",notnull"`
IssuerURL clibase.String `json:"issuer_url" typescript:",notnull"`
Scopes clibase.Strings `json:"scopes" typescript:",notnull"`
IgnoreEmailVerified clibase.Bool `json:"ignore_email_verified" typescript:",notnull"`
UsernameField clibase.String `json:"username_field" typescript:",notnull"`
GroupField clibase.String `json:"groups_field" typescript:",notnull"`
GroupMapping clibase.Struct[map[string]string] `json:"group_mapping" typescript:",notnull"`
SignInText clibase.String `json:"sign_in_text" typescript:",notnull"`
IconURL clibase.URL `json:"icon_url" typescript:",notnull"`
}

type TelemetryConfig struct {
Expand DownExpand Up@@ -875,6 +875,16 @@ when required by your organization's security policy.`,
Group: &deploymentGroupOIDC,
YAML: "groupField",
},
{
Name: "OIDC Group Mapping",
Description: "A map of OIDC group IDs and the group in Coder it should map to. This is useful for when OIDC providers only return group IDs.",
Flag: "oidc-group-mapping",
Env: "OIDC_GROUP_MAPPING",
Default: "{}",
Value: &c.OIDC.GroupMapping,
Group: &deploymentGroupOIDC,
YAML: "groupMapping",
},
{
Name: "OpenID Connect sign in text",
Description: "The text to show on the OpenID Connect sign in button",
Expand Down
16 changes: 16 additions & 0 deletionsdocs/admin/auth.md
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -197,4 +197,20 @@ CODER_OIDC_SCOPES=openid,profile,email,groups
On login, users will automatically be assigned to groups that have matching
names in Coder and removed from groups that the user no longer belongs to.

For cases when an OIDC provider only returns group IDs ([Azure AD][azure-gids])
or you want to have different group names in Coder than in your OIDC provider,
you can configure mapping between the two.

```console
# as an environment variable
CODER_OIDC_GROUP_MAPPING='{"myOIDCGroupID": "myCoderGroupName"}'
# as a flag
--oidc-group-mapping '{"myOIDCGroupID": "myCoderGroupName"}'
```

From the example above, users that belong to the `myOIDCGroupID` group in your
OIDC provider will be added to the `myCoderGroupName` group in Coder.

> **Note:** Groups are only updated on login.

[azure-gids]: https://github.com/MicrosoftDocs/azure-docs/issues/59766#issuecomment-664387195
1 change: 1 addition & 0 deletionsdocs/api/general.md
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -234,6 +234,7 @@ curl -X GET http://coder-server:8080/api/v2/deployment/config \
"client_id": "string",
"client_secret": "string",
"email_domain": ["string"],
"group_mapping": {},
"groups_field": "string",
"icon_url": {
"forceQuery": true,
Expand Down
4 changes: 4 additions & 0 deletionsdocs/api/schemas.md
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -1766,6 +1766,7 @@ CreateParameterRequest is a structure used to create a new parameter value for a
"client_id": "string",
"client_secret": "string",
"email_domain": ["string"],
"group_mapping": {},
"groups_field": "string",
"icon_url": {
"forceQuery": true,
Expand DownExpand Up@@ -2110,6 +2111,7 @@ CreateParameterRequest is a structure used to create a new parameter value for a
"client_id": "string",
"client_secret": "string",
"email_domain": ["string"],
"group_mapping": {},
"groups_field": "string",
"icon_url": {
"forceQuery": true,
Expand DownExpand Up@@ -2771,6 +2773,7 @@ CreateParameterRequest is a structure used to create a new parameter value for a
"client_id": "string",
"client_secret": "string",
"email_domain": ["string"],
"group_mapping": {},
"groups_field": "string",
"icon_url": {
"forceQuery": true,
Expand DownExpand Up@@ -2801,6 +2804,7 @@ CreateParameterRequest is a structure used to create a new parameter value for a
| `client_id` | string | false | | |
| `client_secret` | string | false | | |
| `email_domain` | array of string | false | | |
| `group_mapping` | object | false | | |
| `groups_field` | string | false | | |
| `icon_url` | [clibase.URL](#clibaseurl) | false | | |
| `ignore_email_verified` | boolean | false | | |
Expand Down
45 changes: 45 additions & 0 deletionsenterprise/coderd/userauth_test.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -67,6 +67,51 @@ func TestUserOIDC(t *testing.T) {
require.NoError(t, err)
require.Len(t, group.Members, 1)
})
t.Run("AssignsMapped", func(t *testing.T) {
t.Parallel()

ctx, _ := testutil.Context(t)
conf := coderdtest.NewOIDCConfig(t, "")

oidcGroupName := "pingpong"
coderGroupName := "bingbong"
Comment on lines +76 to +77
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

classic

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

classic


config := conf.OIDCConfig(t, jwt.MapClaims{}, func(cfg *coderd.OIDCConfig) {
cfg.GroupMapping = map[string]string{oidcGroupName: coderGroupName}
})
config.AllowSignups = true

client := coderdenttest.New(t, &coderdenttest.Options{
Options: &coderdtest.Options{
OIDCConfig: config,
},
})
_ = coderdtest.CreateFirstUser(t, client)
coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{
AllFeatures: true,
})

admin, err := client.User(ctx, "me")
require.NoError(t, err)
require.Len(t, admin.OrganizationIDs, 1)

group, err := client.CreateGroup(ctx, admin.OrganizationIDs[0], codersdk.CreateGroupRequest{
Name: coderGroupName,
})
require.NoError(t, err)
require.Len(t, group.Members, 0)

resp := oidcCallback(t, client, conf.EncodeClaims(t, jwt.MapClaims{
"email": "colin@coder.com",
"groups": []string{oidcGroupName},
}))
assert.Equal(t, http.StatusTemporaryRedirect, resp.StatusCode)

group, err = client.Group(ctx, group.ID)
require.NoError(t, err)
require.Len(t, group.Members, 1)
})

t.Run("AddThenRemove", func(t *testing.T) {
t.Parallel()

Expand Down
4 changes: 0 additions & 4 deletionsgo.sum
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -376,10 +376,6 @@ github.com/coder/retry v1.3.1-0.20230210155434-e90a2e1e091d h1:09JG37IgTB6n3ouX9
github.com/coder/retry v1.3.1-0.20230210155434-e90a2e1e091d/go.mod h1:r+1J5i/989wt6CUeNSuvFKKA9hHuKKPMxdzDbTuvwwk=
github.com/coder/ssh v0.0.0-20220811105153-fcea99919338 h1:tN5GKFT68YLVzJoA8AHuiMNJ0qlhoD3pGN3JY9gxSko=
github.com/coder/ssh v0.0.0-20220811105153-fcea99919338/go.mod h1:ZSS+CUoKHDrqVakTfTWUlKSr9MtMFkC4UvtQKD7O914=
github.com/coder/tailscale v1.1.1-0.20230314023417-d9efcc0ac972 h1:193YGsJz8hc4yxqAclE36paKl+9CQ6KGLgdleIguCVE=
github.com/coder/tailscale v1.1.1-0.20230314023417-d9efcc0ac972/go.mod h1:jpg+77g19FpXL43U1VoIqoSg1K/Vh5CVxycGldQ8KhA=
github.com/coder/tailscale v1.1.1-0.20230321164649-3362540e3026 h1:6YnWw08eQEGc/7KyweGWP8urOb9TDlo6S35ZqNm8qsQ=
github.com/coder/tailscale v1.1.1-0.20230321164649-3362540e3026/go.mod h1:jpg+77g19FpXL43U1VoIqoSg1K/Vh5CVxycGldQ8KhA=
github.com/coder/tailscale v1.1.1-0.20230321171725-fed359a0cafa h1:EjRGgTz7BUECmbV8jHTi1/rKdDjJESGSlm1Jp7evvCQ=
github.com/coder/tailscale v1.1.1-0.20230321171725-fed359a0cafa/go.mod h1:jpg+77g19FpXL43U1VoIqoSg1K/Vh5CVxycGldQ8KhA=
github.com/coder/terraform-provider-coder v0.6.20 h1:bVyITX9JlbnGzKzTj0qi/JziUCGqD2DiN3cXaWyDcxE=
Expand Down
3 changes: 3 additions & 0 deletionssite/src/api/typesGenerated.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -507,6 +507,9 @@ export interface OIDCConfig {
readonly ignore_email_verified: boolean
readonly username_field: string
readonly groups_field: string
// Named type "github.com/coder/coder/cli/clibase.Struct[map[string]string]" unknown, using "any"
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- External type
readonly group_mapping: any
readonly sign_in_text: string
readonly icon_url: string
}
Expand Down

[8]ページ先頭

©2009-2025 Movatter.jp