github.com/Azareal/Gosora@v0.0.0-20210729070923-553e66b59003/common/email_store.go (about)

     1  package common
     2  
     3  import (
     4  	"database/sql"
     5  
     6  	qgen "github.com/Azareal/Gosora/query_gen"
     7  )
     8  
     9  var Emails EmailStore
    10  
    11  type Email struct {
    12  	UserID    int
    13  	Email     string
    14  	Validated bool
    15  	Primary   bool
    16  	Token     string
    17  }
    18  
    19  type EmailStore interface {
    20  	// TODO: Add an autoincrement key
    21  	Get(u *User, email string) (Email, error)
    22  	GetEmailsByUser(u *User) (emails []Email, err error)
    23  	Add(uid int, email, token string) error
    24  	Delete(uid int, email string) error
    25  	VerifyEmail(email string) error
    26  }
    27  
    28  type DefaultEmailStore struct {
    29  	get             *sql.Stmt
    30  	getEmailsByUser *sql.Stmt
    31  	add             *sql.Stmt
    32  	delete          *sql.Stmt
    33  	verifyEmail     *sql.Stmt
    34  }
    35  
    36  func NewDefaultEmailStore(acc *qgen.Accumulator) (*DefaultEmailStore, error) {
    37  	e := "emails"
    38  	return &DefaultEmailStore{
    39  		get:             acc.Select(e).Columns("email,validated,token").Where("uid=? AND email=?").Prepare(),
    40  		getEmailsByUser: acc.Select(e).Columns("email,validated,token").Where("uid=?").Prepare(),
    41  		add:             acc.Insert(e).Columns("uid,email,validated,token").Fields("?,?,?,?").Prepare(),
    42  		delete:          acc.Delete(e).Where("uid=? AND email=?").Prepare(),
    43  
    44  		// Need to fix this: Empty string isn't working, it gets set to 1 instead x.x -- Has this been fixed?
    45  		verifyEmail: acc.Update(e).Set("validated=1,token=''").Where("email=?").Prepare(),
    46  	}, acc.FirstError()
    47  }
    48  
    49  func (s *DefaultEmailStore) Get(user *User, email string) (Email, error) {
    50  	e := Email{UserID: user.ID, Primary: email != "" && user.Email == email}
    51  	err := s.get.QueryRow(user.ID, email).Scan(&e.Email, &e.Validated, &e.Token)
    52  	return e, err
    53  }
    54  
    55  func (s *DefaultEmailStore) GetEmailsByUser(user *User) (emails []Email, err error) {
    56  	e := Email{UserID: user.ID}
    57  	rows, err := s.getEmailsByUser.Query(user.ID)
    58  	if err != nil {
    59  		return emails, err
    60  	}
    61  	defer rows.Close()
    62  	for rows.Next() {
    63  		err := rows.Scan(&e.Email, &e.Validated, &e.Token)
    64  		if err != nil {
    65  			return emails, err
    66  		}
    67  		if e.Email == user.Email {
    68  			e.Primary = true
    69  		}
    70  		emails = append(emails, e)
    71  	}
    72  	return emails, rows.Err()
    73  }
    74  
    75  func (s *DefaultEmailStore) Add(uid int, email, token string) error {
    76  	email = CanonEmail(SanitiseSingleLine(email))
    77  	_, err := s.add.Exec(uid, email, 0, token)
    78  	return err
    79  }
    80  
    81  func (s *DefaultEmailStore) Delete(uid int, email string) error {
    82  	_, err := s.delete.Exec(uid, email)
    83  	return err
    84  }
    85  
    86  func (s *DefaultEmailStore) VerifyEmail(email string) error {
    87  	email = CanonEmail(SanitiseSingleLine(email))
    88  	_, err := s.verifyEmail.Exec(email)
    89  	return err
    90  }