CreateAuth Creates a new authentication object If a User is attached to auth, then the auth object is linked to an existing user. Otherwise a new user object is created. On success, the auth.ID is set to the new authentication ID.
(ctx context.Context, auth *wtf.Auth)
| 74 | // |
| 75 | // On success, the auth.ID is set to the new authentication ID. |
| 76 | func (s *AuthService) CreateAuth(ctx context.Context, auth *wtf.Auth) error { |
| 77 | tx, err := s.db.BeginTx(ctx, nil) |
| 78 | if err != nil { |
| 79 | return err |
| 80 | } |
| 81 | defer tx.Rollback() |
| 82 | |
| 83 | // Check to see if the auth already exists for the given source. |
| 84 | if other, err := findAuthBySourceID(ctx, tx, auth.Source, auth.SourceID); err == nil { |
| 85 | // If an auth already exists for the source user, update with the new tokens. |
| 86 | if other, err = updateAuth(ctx, tx, other.ID, auth.AccessToken, auth.RefreshToken, auth.Expiry); err != nil { |
| 87 | return fmt.Errorf("cannot update auth: id=%d err=%w", other.ID, err) |
| 88 | } else if err := attachAuthAssociations(ctx, tx, other); err != nil { |
| 89 | return err |
| 90 | } |
| 91 | |
| 92 | // Copy found auth back to the caller's arg & return. |
| 93 | *auth = *other |
| 94 | return tx.Commit() |
| 95 | } else if wtf.ErrorCode(err) != wtf.ENOTFOUND { |
| 96 | return fmt.Errorf("canot find auth by source user: %w", err) |
| 97 | } |
| 98 | |
| 99 | // Check if auth has a new user object passed in. It is considered "new" if |
| 100 | // the caller doesn't know the database ID for the user. |
| 101 | if auth.UserID == 0 && auth.User != nil { |
| 102 | // Look up the user by email address. If no user can be found then |
| 103 | // create a new user with the auth.User object passed in. |
| 104 | if user, err := findUserByEmail(ctx, tx, auth.User.Email); err == nil { // user exists |
| 105 | auth.User = user |
| 106 | } else if wtf.ErrorCode(err) == wtf.ENOTFOUND { // user does not exist |
| 107 | if err := createUser(ctx, tx, auth.User); err != nil { |
| 108 | return fmt.Errorf("cannot create user: %w", err) |
| 109 | } |
| 110 | } else { |
| 111 | return fmt.Errorf("cannot find user by email: %w", err) |
| 112 | } |
| 113 | |
| 114 | // Assign the created/found user ID back to the auth object. |
| 115 | auth.UserID = auth.User.ID |
| 116 | } |
| 117 | |
| 118 | // Create new auth object & attach associated user. |
| 119 | if err := createAuth(ctx, tx, auth); err != nil { |
| 120 | return err |
| 121 | } else if err := attachAuthAssociations(ctx, tx, auth); err != nil { |
| 122 | return err |
| 123 | } |
| 124 | return tx.Commit() |
| 125 | } |
| 126 | |
| 127 | // DeleteAuth permanently deletes an authentication object from the system by ID. |
| 128 | // The parent user object is not removed. |