@@ -38,11 +38,15 @@ const (
38
38
spEntityIDKey = "spConfig.spEntityId"
39
39
callbackURIKey = "spConfig.callbackUri"
40
40
41
- clientIDKey = "clientId"
42
- issuerKey = "issuer"
41
+ clientIDKey = "clientId"
42
+ clientSecretKey = "clientSecret"
43
+ issuerKey = "issuer"
43
44
44
45
displayNameKey = "displayName"
45
46
enabledKey = "enabled"
47
+
48
+ idTokenResponseTypeKey = "responseType.idToken"
49
+ codeResponseTypeKey = "responseType.code"
46
50
)
47
51
48
52
type nestedMap map [string ]interface {}
@@ -113,11 +117,14 @@ func buildMask(data map[string]interface{}) []string {
113
117
// OIDCProviderConfig is the OIDC auth provider configuration.
114
118
// See https://openid.net/specs/openid-connect-core-1_0-final.html.
115
119
type OIDCProviderConfig struct {
116
- ID string
117
- DisplayName string
118
- Enabled bool
119
- ClientID string
120
- Issuer string
120
+ ID string
121
+ DisplayName string
122
+ Enabled bool
123
+ ClientID string
124
+ Issuer string
125
+ ClientSecret string
126
+ CodeResponseType bool
127
+ IDTokenResponseType bool
121
128
}
122
129
123
130
// OIDCProviderConfigToCreate represents the options used to create a new OIDCProviderConfig.
@@ -152,6 +159,27 @@ func (config *OIDCProviderConfigToCreate) Enabled(enabled bool) *OIDCProviderCon
152
159
return config .set (enabledKey , enabled )
153
160
}
154
161
162
+ // ClientSecret sets the client secret for the new provider.
163
+ // This is required for the code flow.
164
+ func (config * OIDCProviderConfigToCreate ) ClientSecret (secret string ) * OIDCProviderConfigToCreate {
165
+ return config .set (clientSecretKey , secret )
166
+ }
167
+
168
+ // IDTokenResponseType sets whether to enable the ID token response flow for the new provider.
169
+ // By default, this is enabled if no response type is specified.
170
+ // Having both the code and ID token response flows is currently not supported.
171
+ func (config * OIDCProviderConfigToCreate ) IDTokenResponseType (enabled bool ) * OIDCProviderConfigToCreate {
172
+ return config .set (idTokenResponseTypeKey , enabled )
173
+ }
174
+
175
+ // CodeResponseType sets whether to enable the code response flow for the new provider.
176
+ // By default, this is not enabled if no response type is specified.
177
+ // A client secret must be set for this response type.
178
+ // Having both the code and ID token response flows is currently not supported.
179
+ func (config * OIDCProviderConfigToCreate ) CodeResponseType (enabled bool ) * OIDCProviderConfigToCreate {
180
+ return config .set (codeResponseTypeKey , enabled )
181
+ }
182
+
155
183
func (config * OIDCProviderConfigToCreate ) set (key string , value interface {}) * OIDCProviderConfigToCreate {
156
184
if config .params == nil {
157
185
config .params = make (nestedMap )
@@ -180,6 +208,19 @@ func (config *OIDCProviderConfigToCreate) buildRequest() (nestedMap, string, err
180
208
return nil , "" , fmt .Errorf ("failed to parse Issuer: %v" , err )
181
209
}
182
210
211
+ if val , ok := config .params .Get (codeResponseTypeKey ); ok && val .(bool ) {
212
+ if val , ok := config .params .GetString (clientSecretKey ); ! ok || val == "" {
213
+ return nil , "" , errors .New ("Client Secret must not be empty for Code Response Type" )
214
+ }
215
+ if val , ok := config .params .Get (idTokenResponseTypeKey ); ok && val .(bool ) {
216
+ return nil , "" , errors .New ("Only one response type may be chosen" )
217
+ }
218
+ } else if ok && ! val .(bool ) {
219
+ if val , ok := config .params .Get (idTokenResponseTypeKey ); ok && ! val .(bool ) {
220
+ return nil , "" , errors .New ("At least one response type must be returned" )
221
+ }
222
+ }
223
+
183
224
return config .params , config .id , nil
184
225
}
185
226
@@ -213,6 +254,27 @@ func (config *OIDCProviderConfigToUpdate) Enabled(enabled bool) *OIDCProviderCon
213
254
return config .set (enabledKey , enabled )
214
255
}
215
256
257
+ // ClientSecret sets the client secret for the provider.
258
+ // This is required for the code flow.
259
+ func (config * OIDCProviderConfigToUpdate ) ClientSecret (secret string ) * OIDCProviderConfigToUpdate {
260
+ return config .set (clientSecretKey , secret )
261
+ }
262
+
263
+ // IDTokenResponseType sets whether to enable the ID token response flow for the provider.
264
+ // By default, this is enabled if no response type is specified.
265
+ // Having both the code and ID token response flows is currently not supported.
266
+ func (config * OIDCProviderConfigToUpdate ) IDTokenResponseType (enabled bool ) * OIDCProviderConfigToUpdate {
267
+ return config .set (idTokenResponseTypeKey , enabled )
268
+ }
269
+
270
+ // CodeResponseType sets whether to enable the code response flow for the new provider.
271
+ // By default, this is not enabled if no response type is specified.
272
+ // A client secret must be set for this response type.
273
+ // Having both the code and ID token response flows is currently not supported.
274
+ func (config * OIDCProviderConfigToUpdate ) CodeResponseType (enabled bool ) * OIDCProviderConfigToUpdate {
275
+ return config .set (codeResponseTypeKey , enabled )
276
+ }
277
+
216
278
func (config * OIDCProviderConfigToUpdate ) set (key string , value interface {}) * OIDCProviderConfigToUpdate {
217
279
if config .params == nil {
218
280
config .params = make (nestedMap )
@@ -240,6 +302,19 @@ func (config *OIDCProviderConfigToUpdate) buildRequest() (nestedMap, error) {
240
302
}
241
303
}
242
304
305
+ if val , ok := config .params .Get (codeResponseTypeKey ); ok && val .(bool ) {
306
+ if val , ok := config .params .GetString (clientSecretKey ); ! ok || val == "" {
307
+ return nil , errors .New ("Client Secret must not be empty for Code Response Type" )
308
+ }
309
+ if val , ok := config .params .Get (idTokenResponseTypeKey ); ok && val .(bool ) {
310
+ return nil , errors .New ("Only one response type may be chosen" )
311
+ }
312
+ } else if ok && ! val .(bool ) {
313
+ if val , ok := config .params .Get (idTokenResponseTypeKey ); ok && ! val .(bool ) {
314
+ return nil , errors .New ("At least one response type must be returned" )
315
+ }
316
+ }
317
+
243
318
return config .params , nil
244
319
}
245
320
@@ -826,20 +901,30 @@ func (c *baseClient) makeRequest(
826
901
}
827
902
828
903
type oidcProviderConfigDAO struct {
829
- Name string `json:"name"`
830
- ClientID string `json:"clientId"`
831
- Issuer string `json:"issuer"`
832
- DisplayName string `json:"displayName"`
833
- Enabled bool `json:"enabled"`
904
+ Name string `json:"name"`
905
+ ClientID string `json:"clientId"`
906
+ Issuer string `json:"issuer"`
907
+ DisplayName string `json:"displayName"`
908
+ Enabled bool `json:"enabled"`
909
+ ClientSecret string `json:"clientSecret"`
910
+ ResponseType oidcProviderResponseType `json:"responseType"`
911
+ }
912
+
913
+ type oidcProviderResponseType struct {
914
+ Code bool `json:"code"`
915
+ IDToken bool `json:"idToken"`
834
916
}
835
917
836
918
func (dao * oidcProviderConfigDAO ) toOIDCProviderConfig () * OIDCProviderConfig {
837
919
return & OIDCProviderConfig {
838
- ID : extractResourceID (dao .Name ),
839
- DisplayName : dao .DisplayName ,
840
- Enabled : dao .Enabled ,
841
- ClientID : dao .ClientID ,
842
- Issuer : dao .Issuer ,
920
+ ID : extractResourceID (dao .Name ),
921
+ DisplayName : dao .DisplayName ,
922
+ Enabled : dao .Enabled ,
923
+ ClientID : dao .ClientID ,
924
+ Issuer : dao .Issuer ,
925
+ ClientSecret : dao .ClientSecret ,
926
+ CodeResponseType : dao .ResponseType .Code ,
927
+ IDTokenResponseType : dao .ResponseType .IDToken ,
843
928
}
844
929
}
845
930
0 commit comments