mirror of
https://github.com/acaloiaro/newsbox
synced 2026-07-21 18:29:15 +00:00
118 lines
4.5 KiB
Go
118 lines
4.5 KiB
Go
package models
|
|
|
|
import (
|
|
"encoding/json"
|
|
"log"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/gobuffalo/nulls"
|
|
"github.com/gobuffalo/pop/v6"
|
|
"github.com/gobuffalo/validate/v3"
|
|
"github.com/gobuffalo/validate/v3/validators"
|
|
"github.com/gofrs/uuid"
|
|
"github.com/pkg/errors"
|
|
"golang.org/x/crypto/bcrypt"
|
|
)
|
|
|
|
// User is a generated model from buffalo-auth, it serves as the base for username/password authentication.
|
|
type User struct {
|
|
ID uuid.UUID `json:"id" db:"id"`
|
|
Name string `json:"name" db:"name" form:"name"`
|
|
Username string `json:"username" db:"username" form:"username"`
|
|
Email nulls.String `json:"email" db:"email" form:"email"`
|
|
PasswordHash string `json:"password_hash" db:"password_hash"`
|
|
Provider string `json:"provider" db:"provider"`
|
|
ProviderID string `json:"provider_id" db:"provider_id"`
|
|
Password string `json:"-" db:"-" form:"password"`
|
|
PasswordConfirmation string `json:"-" db:"-" form:"password_confirmation"`
|
|
CreatedAt time.Time `json:"created_at" db:"created_at"`
|
|
UpdatedAt time.Time `json:"updated_at" db:"updated_at"`
|
|
EmailVerification UserEmailVerification `has_one:"user_email_verification" fk_id:"owner_id"`
|
|
Preferences UserPreference `has_one:"user_preference" fk_id:"owner_id" form:"preferences"`
|
|
}
|
|
|
|
// Create wraps up the pattern of encrypting the password and
|
|
// running validations. Useful when writing tests.
|
|
func (u *User) Create(tx *pop.Connection) (*validate.Errors, error) {
|
|
emailStr := u.Email.Interface().(string)
|
|
u.Email = nulls.NewString(strings.ToLower(emailStr))
|
|
ph, err := bcrypt.GenerateFromPassword([]byte(u.Password), bcrypt.DefaultCost)
|
|
if err != nil {
|
|
return validate.NewErrors(), errors.WithStack(err)
|
|
}
|
|
u.PasswordHash = string(ph)
|
|
return tx.ValidateAndCreate(u)
|
|
}
|
|
|
|
// String is not required by pop and may be deleted
|
|
func (u User) String() string {
|
|
ju, _ := json.Marshal(u)
|
|
return string(ju)
|
|
}
|
|
|
|
// Users is not required by pop and may be deleted
|
|
type Users []User
|
|
|
|
// String is not required by pop and may be deleted
|
|
func (u Users) String() string {
|
|
ju, _ := json.Marshal(u)
|
|
return string(ju)
|
|
}
|
|
|
|
// Validate gets run every time you call a "pop.Validate*" (pop.ValidateAndSave, pop.ValidateAndCreate, pop.ValidateAndUpdate) method.
|
|
// This method is not required and may be deleted.
|
|
func (u *User) Validate(tx *pop.Connection) (*validate.Errors, error) {
|
|
var err error
|
|
return validate.Validate(
|
|
&validators.EmailIsPresent{Field: u.Email.Interface().(string), Name: "Email", Message: "Not a valid email address"},
|
|
&validators.FuncValidator{
|
|
Field: u.Email.Interface().(string),
|
|
Name: "Email",
|
|
Message: "%s is already taken",
|
|
Fn: func() bool {
|
|
var b bool
|
|
q := tx.Where("email = ?", u.Email)
|
|
if u.ID != uuid.Nil {
|
|
q = q.Where("id != ?", u.ID)
|
|
}
|
|
b, err = q.Exists(u)
|
|
if err != nil {
|
|
return false
|
|
}
|
|
return !b
|
|
},
|
|
},
|
|
), err
|
|
}
|
|
|
|
// ValidateCreate gets run every time you call "pop.ValidateAndCreate" method.
|
|
// This method is not required and may be deleted.
|
|
func (u *User) ValidateCreate(tx *pop.Connection) (*validate.Errors, error) {
|
|
var err error
|
|
return validate.Validate(
|
|
&validators.StringIsPresent{Field: u.Password, Name: "Password"},
|
|
&validators.StringsMatch{Name: "Password", Field: u.Password, Field2: u.PasswordConfirmation, Message: "Password does not match confirmation"},
|
|
), err
|
|
}
|
|
|
|
// ValidateUpdate gets run every time you call "pop.ValidateAndUpdate" method.
|
|
// This method is not required and may be deleted.
|
|
func (u *User) ValidateUpdate(tx *pop.Connection) (*validate.Errors, error) {
|
|
log.Println(u.Preferences)
|
|
if u.Password != "" || u.PasswordConfirmation != "" {
|
|
ph, err := bcrypt.GenerateFromPassword([]byte(u.Password), bcrypt.DefaultCost)
|
|
if err != nil {
|
|
return validate.NewErrors(), errors.WithStack(err)
|
|
}
|
|
u.PasswordHash = string(ph)
|
|
|
|
return validate.Validate(
|
|
&validators.StringIsPresent{Field: u.Password, Name: "Password", Message: "Password must not be empty"},
|
|
&validators.StringIsPresent{Field: u.PasswordConfirmation, Name: "PasswordConfirmation", Message: "Confirmation must be present"},
|
|
&validators.StringsMatch{Name: "Password", Field: u.Password, Field2: u.PasswordConfirmation, Message: "Password does not match confirmation"},
|
|
), nil
|
|
}
|
|
|
|
return validate.NewErrors(), nil
|
|
}
|