@@ -19,12 +19,13 @@ import (
1919
2020// IdTokenGrantParams are the parameters the IdTokenGrant method accepts
2121type 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"`
2829}
2930
3031func (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
167168 return apierrors .NewOAuthError ("invalid request" , "provider or client_id and issuer required" )
168169 }
169170
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+
170190 oidcProvider , skipNonceCheck , providerType , acceptableClientIDs , emailOptional , err := params .getProvider (ctx , config , r )
171191 if err != nil {
172192 return err
@@ -251,15 +271,21 @@ func (a *API) IdTokenGrant(ctx context.Context, w http.ResponseWriter, r *http.R
251271
252272 grantParams .FillGrantParams (r )
253273
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+ }
256278 }
257279
258280 if err := db .Transaction (func (tx * storage.Connection ) error {
259281 var user * models.User
260282 var terr error
261283
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+ }
263289 if terr != nil {
264290 return terr
265291 }
0 commit comments