-
Notifications
You must be signed in to change notification settings - Fork 126
/
config_auth.go
155 lines (136 loc) · 6.23 KB
/
config_auth.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
package evergreen
import (
"context"
"github.com/evergreen-ci/utility"
"github.com/mongodb/anser/bsonutil"
"github.com/mongodb/grip"
"github.com/pkg/errors"
"go.mongodb.org/mongo-driver/bson"
)
// AuthUser configures a user for our Naive authentication setup.
type AuthUser struct {
Username string `bson:"username" json:"username" yaml:"username"`
DisplayName string `bson:"display_name" json:"display_name" yaml:"display_name"`
Password string `bson:"password" json:"password" yaml:"password"`
Email string `bson:"email" json:"email" yaml:"email"`
}
var (
AuthOktaKey = bsonutil.MustHaveTag(AuthConfig{}, "Okta")
AuthGithubKey = bsonutil.MustHaveTag(AuthConfig{}, "Github")
AuthNaiveKey = bsonutil.MustHaveTag(AuthConfig{}, "Naive")
AuthMultiKey = bsonutil.MustHaveTag(AuthConfig{}, "Multi")
authPreferredTypeKey = bsonutil.MustHaveTag(AuthConfig{}, "PreferredType")
authBackgroundReauthMinutesKey = bsonutil.MustHaveTag(AuthConfig{}, "BackgroundReauthMinutes")
AuthAllowServiceUsersKey = bsonutil.MustHaveTag(AuthConfig{}, "AllowServiceUsers")
)
// NaiveAuthConfig contains a list of AuthUsers from the settings file.
type NaiveAuthConfig struct {
Users []AuthUser `bson:"users" json:"users" yaml:"users"`
}
type OktaConfig struct {
ClientID string `bson:"client_id" json:"client_id" yaml:"client_id"`
ClientSecret string `bson:"client_secret" json:"client_secret" yaml:"client_secret"`
Issuer string `bson:"issuer" json:"issuer" yaml:"issuer"`
Scopes []string `bson:"scopes" json:"scopes" yaml:"scopes"`
UserGroup string `bson:"user_group" json:"user_group" yaml:"user_group"`
ExpireAfterMinutes int `bson:"expire_after_minutes" json:"expire_after_minutes" yaml:"expire_after_minutes"`
}
// GithubAuthConfig contains settings for interacting with Github Authentication
// including the ClientID, ClientSecret and CallbackUri which are given when
// registering the application Furthermore,
type GithubAuthConfig struct {
AppId int64 `bson:"app_id" json:"app_id" yaml:"app_id"`
ClientId string `bson:"client_id" json:"client_id" yaml:"client_id"`
ClientSecret string `bson:"client_secret" json:"client_secret" yaml:"client_secret"`
DefaultOwner string `bson:"default_owner" json:"default_owner" yaml:"default_owner"`
DefaultRepo string `bson:"default_repo" json:"default_repo" yaml:"default_repo"`
Organization string `bson:"organization" json:"organization" yaml:"organization"`
Users []string `bson:"users" json:"users" yaml:"users"`
}
// MultiAuthConfig contains settings for using multiple authentication
// mechanisms.
type MultiAuthConfig struct {
ReadWrite []string `bson:"read_write" json:"read_write" yaml:"read_write"`
ReadOnly []string `bson:"read_only" json:"read_only" yaml:"read_only"`
}
// IsZero checks if the configuration is populated or not.
func (c *MultiAuthConfig) IsZero() bool {
return len(c.ReadWrite) == 0 && len(c.ReadOnly) == 0
}
// AuthConfig contains the settings for the various auth managers.
type AuthConfig struct {
Okta *OktaConfig `bson:"okta,omitempty" json:"okta" yaml:"okta"`
Naive *NaiveAuthConfig `bson:"naive,omitempty" json:"naive" yaml:"naive"`
Github *GithubAuthConfig `bson:"github,omitempty" json:"github" yaml:"github"`
Multi *MultiAuthConfig `bson:"multi" json:"multi" yaml:"multi"`
AllowServiceUsers bool `bson:"allow_service_users" json:"allow_service_users" yaml:"allow_service_users"`
PreferredType string `bson:"preferred_type,omitempty" json:"preferred_type" yaml:"preferred_type"`
BackgroundReauthMinutes int `bson:"background_reauth_minutes" json:"background_reauth_minutes" yaml:"background_reauth_minutes"`
}
func (c *AuthConfig) SectionId() string { return "auth" }
func (c *AuthConfig) Get(ctx context.Context) error {
return getConfigSection(ctx, c)
}
func (c *AuthConfig) Set(ctx context.Context) error {
return errors.Wrapf(setConfigSection(ctx, c.SectionId(), bson.M{
"$set": bson.M{
AuthOktaKey: c.Okta,
AuthNaiveKey: c.Naive,
AuthGithubKey: c.Github,
AuthMultiKey: c.Multi,
authPreferredTypeKey: c.PreferredType,
authBackgroundReauthMinutesKey: c.BackgroundReauthMinutes,
AuthAllowServiceUsersKey: c.AllowServiceUsers,
}}), "updating config section '%s'", c.SectionId(),
)
}
func (c *AuthConfig) checkDuplicateUsers() error {
catcher := grip.NewBasicCatcher()
var usernames []string
if c.Naive != nil {
for _, u := range c.Naive.Users {
usernames = append(usernames, u.Username)
}
}
used := map[string]bool{}
for _, name := range usernames {
catcher.AddWhen(used[name], errors.Errorf("duplicate user '%s' in list", name))
used[name] = true
}
return catcher.Resolve()
}
func (c *AuthConfig) ValidateAndDefault() error {
catcher := grip.NewSimpleCatcher()
catcher.ErrorfWhen(!utility.StringSliceContains([]string{
"",
AuthOktaKey,
AuthNaiveKey,
AuthGithubKey,
AuthMultiKey}, c.PreferredType), "invalid auth type '%s'", c.PreferredType)
if c.Naive == nil && c.Github == nil && c.Okta == nil && c.Multi == nil {
catcher.Add(errors.New("must specify one form of authentication"))
}
catcher.Add(c.checkDuplicateUsers())
if c.Multi != nil {
seen := map[string]bool{}
kinds := append([]string{}, c.Multi.ReadWrite...)
kinds = append(kinds, c.Multi.ReadOnly...)
for _, kind := range kinds {
// Check that settings exist for the user manager.
switch kind {
case AuthOktaKey:
catcher.NewWhen(c.Okta == nil, "Okta settings cannot be empty if using in multi auth")
case AuthGithubKey:
catcher.NewWhen(c.Github == nil, "GitHub settings cannot be empty if using in multi auth")
case AuthNaiveKey:
catcher.NewWhen(c.Naive == nil, "Naive settings cannot be empty if using in multi auth")
default:
catcher.Errorf("unrecognized auth mechanism '%s'", kind)
}
// Check for duplicate user managers.
catcher.ErrorfWhen(seen[kind], "duplicate auth mechanism '%s' in multi auth", kind)
seen[kind] = true
}
}
return catcher.Resolve()
}