@@ -19,12 +19,13 @@ import (
19
19
20
20
// IdTokenGrantParams are the parameters the IdTokenGrant method accepts
21
21
type IdTokenGrantParams struct {
22
- IdToken string `json:"id_token"`
23
- AccessToken string `json:"access_token"`
24
- Nonce string `json:"nonce"`
25
- Provider string `json:"provider"`
26
- ClientID string `json:"client_id"`
27
- Issuer string `json:"issuer"`
22
+ IdToken string `json:"id_token"`
23
+ AccessToken string `json:"access_token"`
24
+ Nonce string `json:"nonce"`
25
+ Provider string `json:"provider"`
26
+ ClientID string `json:"client_id"`
27
+ Issuer string `json:"issuer"`
28
+ LinkIdentity bool `json:"link_identity"`
28
29
}
29
30
30
31
func (p * IdTokenGrantParams ) getProvider (ctx context.Context , config * conf.GlobalConfiguration , r * http.Request ) (* oidc.Provider , bool , string , []string , bool , error ) {
@@ -167,6 +168,25 @@ func (a *API) IdTokenGrant(ctx context.Context, w http.ResponseWriter, r *http.R
167
168
return apierrors .NewOAuthError ("invalid request" , "provider or client_id and issuer required" )
168
169
}
169
170
171
+ if params .LinkIdentity {
172
+ if r .Header .Get ("Authorization" ) == "" {
173
+ return apierrors .NewOAuthError ("invalid request" , "Linking requires a valid user access token in Authorization" )
174
+ }
175
+
176
+ requireAuthCtx , err := a .requireAuthentication (w , r )
177
+ if err != nil {
178
+ return err
179
+ }
180
+
181
+ targetUser := getUser (requireAuthCtx )
182
+ if targetUser == nil {
183
+ return apierrors .NewOAuthError ("invalid request" , "Linking requires a valid user authentication" )
184
+ }
185
+
186
+ // set it so linkIdentityToUser works below
187
+ ctx = withTargetUser (ctx , targetUser )
188
+ }
189
+
170
190
oidcProvider , skipNonceCheck , providerType , acceptableClientIDs , emailOptional , err := params .getProvider (ctx , config , r )
171
191
if err != nil {
172
192
return err
@@ -251,15 +271,21 @@ func (a *API) IdTokenGrant(ctx context.Context, w http.ResponseWriter, r *http.R
251
271
252
272
grantParams .FillGrantParams (r )
253
273
254
- if err := a .triggerBeforeUserCreatedExternal (r , db , userData , providerType ); err != nil {
255
- return err
274
+ if ! params .LinkIdentity {
275
+ if err := a .triggerBeforeUserCreatedExternal (r , db , userData , providerType ); err != nil {
276
+ return err
277
+ }
256
278
}
257
279
258
280
if err := db .Transaction (func (tx * storage.Connection ) error {
259
281
var user * models.User
260
282
var terr error
261
283
262
- user , terr = a .createAccountFromExternalIdentity (tx , r , userData , providerType , emailOptional )
284
+ if params .LinkIdentity {
285
+ user , terr = a .linkIdentityToUser (r , ctx , tx , userData , providerType )
286
+ } else {
287
+ user , terr = a .createAccountFromExternalIdentity (tx , r , userData , providerType , emailOptional )
288
+ }
263
289
if terr != nil {
264
290
return terr
265
291
}
0 commit comments