145 lines
3.6 KiB
Go
145 lines
3.6 KiB
Go
package datamysql
|
|
|
|
import (
|
|
"database/sql"
|
|
"fmt"
|
|
|
|
"bitbucket.org/nemt/nemt-portal-api/domain/entity"
|
|
"bitbucket.org/nemt/nemt-portal-api/infra/errors"
|
|
uuid "github.com/satori/go.uuid"
|
|
)
|
|
|
|
// rideRepo maps methods to database
|
|
type passwordResetRepo struct {
|
|
conn executor
|
|
}
|
|
|
|
func newPasswordResetRepo(conn executor) *passwordResetRepo {
|
|
return &passwordResetRepo{
|
|
conn: conn,
|
|
}
|
|
}
|
|
|
|
func (c *passwordResetRepo) getQuery() string {
|
|
const (
|
|
query = `SELECT
|
|
a.password_reset_id,
|
|
a.password_reset_uuid,
|
|
a.user_id,
|
|
b.user_uuid,
|
|
a.token,
|
|
a.create_date,
|
|
a.expire_date,
|
|
(IFNULL(a.used, b'0') = b'1') used,
|
|
(IFNULL(a.opened, b'0') = b'1') opened
|
|
FROM
|
|
tab_password_reset a
|
|
INNER JOIN tab_user b
|
|
ON a.user_id = b.user_id`
|
|
)
|
|
|
|
return query
|
|
}
|
|
|
|
// parseSet parses a result set result to an entity array
|
|
func (c *passwordResetRepo) parseSet(rows *sql.Rows, err error) ([]entity.PasswordReset, error) {
|
|
if err != nil {
|
|
return nil, errors.Wrap(err)
|
|
}
|
|
result := make([]entity.PasswordReset, 0)
|
|
for rows.Next() {
|
|
entity, err := c.parseEntity(rows)
|
|
if err != nil {
|
|
return nil, errors.Wrap(err)
|
|
}
|
|
result = append(result, entity)
|
|
}
|
|
return result, nil
|
|
}
|
|
|
|
// parseEntity parses a result to an entity
|
|
func (c *passwordResetRepo) parseEntity(row scanner) (retVal entity.PasswordReset, err error) {
|
|
err = row.Scan(
|
|
&retVal.ID, &retVal.UUID, &retVal.User.ID, &retVal.User.UUID, &retVal.Token, &retVal.Created, &retVal.Expires, &retVal.Used, &retVal.Opened)
|
|
|
|
return retVal, errors.Wrap(err)
|
|
}
|
|
|
|
func (c *passwordResetRepo) GetAll() ([]entity.PasswordReset, error) {
|
|
return c.parseSet(c.conn.Query(c.getQuery()))
|
|
}
|
|
|
|
func (c *passwordResetRepo) CreatePasswordResetEntry(passwordResetEntry entity.PasswordReset) (entity.PasswordReset, error) {
|
|
const (
|
|
insertQuery = `INSERT INTO tab_password_reset(password_reset_uuid, user_id, token, expire_date, used, opened) VALUES(?, ?, ?, ?, 0, 0);`
|
|
)
|
|
|
|
retVal := passwordResetEntry
|
|
guid, _ := uuid.NewV4()
|
|
|
|
userRepo := newUserRepo(c.conn)
|
|
|
|
fullUser, err := userRepo.GetByEmail(passwordResetEntry.User.Email)
|
|
if err != nil {
|
|
return retVal, err
|
|
}
|
|
|
|
if fullUser.Email != passwordResetEntry.User.Email {
|
|
return retVal, fmt.Errorf("User not found")
|
|
}
|
|
|
|
results, err := c.conn.Exec(insertQuery, guid, fullUser.ID, passwordResetEntry.Token, passwordResetEntry.Expires)
|
|
if err != nil {
|
|
return retVal, err
|
|
}
|
|
|
|
retVal.ID, err = results.LastInsertId()
|
|
if err != nil {
|
|
return retVal, err
|
|
}
|
|
|
|
return c.GetByID(retVal.ID)
|
|
}
|
|
|
|
func (c *passwordResetRepo) GetByID(ID int64) (entity.PasswordReset, error) {
|
|
return c.parseEntity(c.conn.QueryRow(c.getQuery()+" WHERE a.password_reset_id = ?; ", ID))
|
|
}
|
|
|
|
func (c *passwordResetRepo) GetByToken(token string) (entity.PasswordReset, error) {
|
|
return c.parseEntity(c.conn.QueryRow(c.getQuery()+" WHERE a.token = ? AND a.used = 0; ", token))
|
|
}
|
|
|
|
func (c *passwordResetRepo) SetTokenOpened(token string) error {
|
|
const (
|
|
query = `UPDATE tab_password_reset a
|
|
SET a.opened = 1
|
|
WHERE a.token = ? AND a.used = 0 AND a.expire_date > CURRENT_TIMESTAMP`
|
|
)
|
|
|
|
result, err := c.conn.Exec(query, token)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if updateCount, err := result.RowsAffected(); err != nil || updateCount == 0 {
|
|
return fmt.Errorf("Invalid token")
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (c *passwordResetRepo) SetTokenUsed(token string) error {
|
|
const (
|
|
query = `UPDATE tab_password_reset a
|
|
SET a.opened = 1,
|
|
a.used = 1
|
|
WHERE a.token = ? AND a.used = 0`
|
|
)
|
|
|
|
if _, err := c.conn.Exec(query, token); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|