Files
old-svijetlastrana/data/datamysql/passwordreset.go
2018-06-01 16:46:46 +02:00

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
}