(tx *storage.Connection, r *http.Request, userData *provider.UserProvidedData, providerType string, emailOptional bool)
| 290 | } |
| 291 | |
| 292 | func (a *API) createAccountFromExternalIdentity(tx *storage.Connection, r *http.Request, userData *provider.UserProvidedData, providerType string, emailOptional bool) (models.AccountLinkingDecision, *models.User, error) { |
| 293 | ctx := r.Context() |
| 294 | aud := a.requestAud(ctx, r) |
| 295 | config := a.config |
| 296 | |
| 297 | var user *models.User |
| 298 | var identity *models.Identity |
| 299 | var identityData map[string]interface{} |
| 300 | if userData.Metadata != nil { |
| 301 | identityData = structs.Map(userData.Metadata) |
| 302 | } |
| 303 | |
| 304 | decision, terr := models.DetermineAccountLinking(tx, config, userData.Emails, aud, providerType, userData.Metadata.Subject) |
| 305 | if terr != nil { |
| 306 | return 0, nil, terr |
| 307 | } |
| 308 | |
| 309 | switch decision.Decision { |
| 310 | case models.LinkAccount: |
| 311 | user = decision.User |
| 312 | |
| 313 | if identity, terr = a.createNewIdentity(tx, user, providerType, identityData); terr != nil { |
| 314 | return 0, nil, terr |
| 315 | } |
| 316 | |
| 317 | if terr = user.UpdateUserMetaData(tx, identityData); terr != nil { |
| 318 | return 0, nil, terr |
| 319 | } |
| 320 | |
| 321 | if terr = user.UpdateAppMetaDataProviders(tx); terr != nil { |
| 322 | return 0, nil, terr |
| 323 | } |
| 324 | |
| 325 | case models.CreateAccount: |
| 326 | if config.DisableSignup { |
| 327 | return 0, nil, apierrors.NewUnprocessableEntityError(apierrors.ErrorCodeSignupDisabled, "Signups not allowed for this instance") |
| 328 | } |
| 329 | |
| 330 | params := &SignupParams{ |
| 331 | Provider: providerType, |
| 332 | Email: decision.CandidateEmail.Email, |
| 333 | Aud: aud, |
| 334 | Data: identityData, |
| 335 | } |
| 336 | |
| 337 | // This is a little bit of a hack. Let me explain: When |
| 338 | // is_sso_user == true, it allows there to be different user |
| 339 | // rows with the same email address. Initially it was added to |
| 340 | // support SSO accounts, but at this point renaming the column |
| 341 | // or adding a new one requires re-indexing the table which is |
| 342 | // expensive and introduces a potentially unnecessary API |
| 343 | // surface change. It therefore set to true for other linking |
| 344 | // domains, not just SSO ones. This enables different linking |
| 345 | // domains to co-exist, such as when using |
| 346 | // GOTRUE_EXPERIMENTAL_PROVIDERS_WITH_OWN_LINKING_DOMAIN="provider_a,provider_b". |
| 347 | isSSOUser := decision.LinkingDomain != "default" |
| 348 | |
| 349 | // because params above sets no password, this method is not |
no test coverage detected