Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bids 3175/data access user creation #661

Merged
merged 7 commits into from
Aug 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions backend/pkg/api/data_access/dummy.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,12 +137,6 @@ func (d *DummyService) UpdatePasswordResetTime(ctx context.Context, userId uint6
return nil
}

func (d *DummyService) GetEmailConfirmationHash(ctx context.Context, userId uint64) (string, error) {
r := ""
err := commonFakeData(&r)
return r, err
}

func (d *DummyService) UpdateEmailConfirmationHash(ctx context.Context, userId uint64, email, confirmationHash string) error {
return nil
}
Expand Down
107 changes: 82 additions & 25 deletions backend/pkg/api/data_access/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ type UserRepository interface {
IsPasswordResetAllowed(ctx context.Context, userId uint64) (bool, error)
UpdateEmailConfirmationTime(ctx context.Context, userId uint64) error
UpdatePasswordResetTime(ctx context.Context, userId uint64) error
GetEmailConfirmationHash(ctx context.Context, userId uint64) (string, error)
UpdateEmailConfirmationHash(ctx context.Context, userId uint64, email, confirmationHash string) error
UpdatePasswordResetHash(ctx context.Context, userId uint64, passwordHash string) error
GetUserCredentialInfo(ctx context.Context, userId uint64) (*t.UserCredentialInfo, error)
Expand All @@ -37,43 +36,86 @@ type UserRepository interface {
}

func (d *DataAccessService) GetUserByEmail(ctx context.Context, email string) (uint64, error) {
// TODO @DATA-ACCESS i quickly hacked this together, maybe improve
result := uint64(0)
err := d.userReader.GetContext(ctx, &result, `SELECT id FROM users WHERE email = $1 LIMIT 1`, email)
err := d.userReader.GetContext(ctx, &result, `SELECT id FROM users WHERE email = $1`, email)
if errors.Is(err, sql.ErrNoRows) {
return 0, fmt.Errorf("%w: user not found", ErrNotFound)
}
return result, err
}

func (d *DataAccessService) CreateUser(ctx context.Context, email, password string) (uint64, error) {
// TODO @DATA-ACCESS
// (password is already hashed)
return d.dummy.CreateUser(ctx, email, password)
var result uint64

apiKey, err := utils.GenerateRandomAPIKey()
if err != nil {
return 0, err
}

err = d.userWriter.GetContext(ctx, &result, `
INSERT INTO users (password, email, register_ts, api_key)
VALUES ($1, $2, NOW(), $3)
RETURNING id`,
password, email, apiKey,
)

return result, err
}

func (d *DataAccessService) RemoveUser(ctx context.Context, userId uint64) error {
// TODO @DATA-ACCESS
return d.dummy.RemoveUser(ctx, userId)
_, err := d.userWriter.ExecContext(ctx, "DELETE FROM users WHERE id = $1", userId)
return err
}

func (d *DataAccessService) UpdateUserEmail(ctx context.Context, userId uint64) error {
// TODO @DATA-ACCESS
// Called after user clicked link for email confirmations + changes, so:
// set user_confirmed true, set email (from email_change_to_value), update stripe email
// set email_confirmed true, set email (from email_change_to_value), update stripe email
// unset email_confirmation_hash
return d.dummy.UpdateUserEmail(ctx, userId)

_, err := d.userWriter.ExecContext(ctx, `
UPDATE users
SET
email = email_change_to_value,
email_change_to_value = NULL,
email_confirmed = true,
email_confirmation_hash = NULL,
stripe_email_pending = true
WHERE id = $1
`, userId)

return err
}

func (d *DataAccessService) UpdateUserPassword(ctx context.Context, userId uint64, password string) error {
// TODO @DATA-ACCESS
// (password is already hashed)
return d.dummy.UpdateUserPassword(ctx, userId, password)

_, err := d.userWriter.ExecContext(ctx, `
UPDATE users
SET
password = $1,
password_reset_hash = NULL
WHERE id = $2
`, password, userId)

return err
}

func (d *DataAccessService) GetEmailConfirmationTime(ctx context.Context, userId uint64) (time.Time, error) {
// TODO @DATA-ACCESS
return d.dummy.GetEmailConfirmationTime(ctx, userId)
result := time.Time{}

var queryResult sql.NullTime
err := d.userReader.GetContext(ctx, &queryResult, `
SELECT
email_confirmation_ts
FROM users
WHERE id = $1`, userId)

if queryResult.Valid {
result = queryResult.Time
}

return result, err
}

func (d *DataAccessService) GetPasswordResetTime(ctx context.Context, userId uint64) (time.Time, error) {
Expand All @@ -82,8 +124,14 @@ func (d *DataAccessService) GetPasswordResetTime(ctx context.Context, userId uin
}

func (d *DataAccessService) UpdateEmailConfirmationTime(ctx context.Context, userId uint64) error {
// TODO @DATA-ACCESS
return d.dummy.UpdateEmailConfirmationTime(ctx, userId)
_, err := d.userWriter.ExecContext(ctx, `
UPDATE users
SET
email_confirmation_ts = NOW()
WHERE id = $1
`, userId)

return err
}

func (d *DataAccessService) IsPasswordResetAllowed(ctx context.Context, userId uint64) (bool, error) {
Expand All @@ -95,14 +143,16 @@ func (d *DataAccessService) UpdatePasswordResetTime(ctx context.Context, userId
return d.dummy.UpdatePasswordResetTime(ctx, userId)
}

func (d *DataAccessService) GetEmailConfirmationHash(ctx context.Context, userId uint64) (string, error) {
// TODO @DATA-ACCESS
return d.dummy.GetEmailConfirmationHash(ctx, userId)
}

func (d *DataAccessService) UpdateEmailConfirmationHash(ctx context.Context, userId uint64, email, confirmationHash string) error {
// TODO @DATA-ACCESS
return d.dummy.UpdateEmailConfirmationHash(ctx, userId, email, confirmationHash)
_, err := d.userWriter.ExecContext(ctx, `
UPDATE users
SET
email_confirmation_hash = $1,
email_change_to_value = $2
WHERE id = $3
`, confirmationHash, email, userId)

return err
}

func (d *DataAccessService) UpdatePasswordResetHash(ctx context.Context, userId uint64, confirmationHash string) error {
Expand Down Expand Up @@ -154,8 +204,15 @@ func (d *DataAccessService) GetUserIdByApiKey(ctx context.Context, apiKey string
}

func (d *DataAccessService) GetUserIdByConfirmationHash(ctx context.Context, hash string) (uint64, error) {
// TODO @DATA-ACCESS
return d.dummy.GetUserIdByConfirmationHash(ctx, hash)
var result uint64

err := d.userReader.GetContext(ctx, &result, `
SELECT
id
FROM users
WHERE email_confirmation_hash = $1`, hash)

return result, err
}

func (d *DataAccessService) GetUserIdByResetHash(ctx context.Context, hash string) (uint64, error) {
Expand Down
Loading