go: save,verify a bcrypt hash of the passwd
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
5a3ce50bb2
commit
a2c17693c6
@ -38,7 +38,7 @@ var (
|
||||
{Name: "id", Type: field.TypeUUID, Unique: true},
|
||||
{Name: "username", Type: field.TypeString, Unique: true},
|
||||
{Name: "email", Type: field.TypeString, Unique: true},
|
||||
{Name: "password", Type: field.TypeString},
|
||||
{Name: "password", Type: field.TypeBytes},
|
||||
{Name: "is_admin", Type: field.TypeBool, Default: false},
|
||||
{Name: "is_active", Type: field.TypeBool, Default: true},
|
||||
{Name: "created_at", Type: field.TypeTime},
|
||||
|
@ -1178,7 +1178,7 @@ type UserMutation struct {
|
||||
id *uuid.UUID
|
||||
username *string
|
||||
email *string
|
||||
password *string
|
||||
password *[]byte
|
||||
is_admin *bool
|
||||
is_active *bool
|
||||
created_at *time.Time
|
||||
@ -1366,12 +1366,12 @@ func (m *UserMutation) ResetEmail() {
|
||||
}
|
||||
|
||||
// SetPassword sets the "password" field.
|
||||
func (m *UserMutation) SetPassword(s string) {
|
||||
m.password = &s
|
||||
func (m *UserMutation) SetPassword(b []byte) {
|
||||
m.password = &b
|
||||
}
|
||||
|
||||
// Password returns the value of the "password" field in the mutation.
|
||||
func (m *UserMutation) Password() (r string, exists bool) {
|
||||
func (m *UserMutation) Password() (r []byte, exists bool) {
|
||||
v := m.password
|
||||
if v == nil {
|
||||
return
|
||||
@ -1382,7 +1382,7 @@ func (m *UserMutation) Password() (r string, exists bool) {
|
||||
// OldPassword returns the old "password" field's value of the User entity.
|
||||
// If the User object wasn't provided to the builder, the object is fetched from the database.
|
||||
// An error is returned if the mutation operation is not UpdateOne, or the database query fails.
|
||||
func (m *UserMutation) OldPassword(ctx context.Context) (v string, err error) {
|
||||
func (m *UserMutation) OldPassword(ctx context.Context) (v []byte, err error) {
|
||||
if !m.op.Is(OpUpdateOne) {
|
||||
return v, errors.New("OldPassword is only allowed on UpdateOne operations")
|
||||
}
|
||||
@ -1670,7 +1670,7 @@ func (m *UserMutation) SetField(name string, value ent.Value) error {
|
||||
m.SetEmail(v)
|
||||
return nil
|
||||
case user.FieldPassword:
|
||||
v, ok := value.(string)
|
||||
v, ok := value.([]byte)
|
||||
if !ok {
|
||||
return fmt.Errorf("unexpected type %T for field %s", value, name)
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ func init() {
|
||||
// userDescPassword is the schema descriptor for password field.
|
||||
userDescPassword := userFields[3].Descriptor()
|
||||
// user.PasswordValidator is a validator for the "password" field. It is called by the builders before save.
|
||||
user.PasswordValidator = userDescPassword.Validators[0].(func(string) error)
|
||||
user.PasswordValidator = userDescPassword.Validators[0].(func([]byte) error)
|
||||
// userDescIsAdmin is the schema descriptor for is_admin field.
|
||||
userDescIsAdmin := userFields[4].Descriptor()
|
||||
// user.DefaultIsAdmin holds the default value on creation for the is_admin field.
|
||||
|
@ -26,7 +26,7 @@ func (User) Fields() []ent.Field {
|
||||
field.String("email").
|
||||
NotEmpty().
|
||||
Unique(),
|
||||
field.String("password").
|
||||
field.Bytes("password").
|
||||
Sensitive().
|
||||
NotEmpty(),
|
||||
field.Bool("is_admin").
|
||||
|
12
ent/user.go
12
ent/user.go
@ -22,7 +22,7 @@ type User struct {
|
||||
// Email holds the value of the "email" field.
|
||||
Email string `json:"email,omitempty"`
|
||||
// Password holds the value of the "password" field.
|
||||
Password string `json:"-"`
|
||||
Password []byte `json:"-"`
|
||||
// IsAdmin holds the value of the "is_admin" field.
|
||||
IsAdmin bool `json:"is_admin,omitempty"`
|
||||
// IsActive holds the value of the "is_active" field.
|
||||
@ -38,9 +38,11 @@ func (*User) scanValues(columns []string) ([]any, error) {
|
||||
values := make([]any, len(columns))
|
||||
for i := range columns {
|
||||
switch columns[i] {
|
||||
case user.FieldPassword:
|
||||
values[i] = new([]byte)
|
||||
case user.FieldIsAdmin, user.FieldIsActive:
|
||||
values[i] = new(sql.NullBool)
|
||||
case user.FieldUsername, user.FieldEmail, user.FieldPassword:
|
||||
case user.FieldUsername, user.FieldEmail:
|
||||
values[i] = new(sql.NullString)
|
||||
case user.FieldCreatedAt, user.FieldUpdatedAt:
|
||||
values[i] = new(sql.NullTime)
|
||||
@ -80,10 +82,10 @@ func (u *User) assignValues(columns []string, values []any) error {
|
||||
u.Email = value.String
|
||||
}
|
||||
case user.FieldPassword:
|
||||
if value, ok := values[i].(*sql.NullString); !ok {
|
||||
if value, ok := values[i].(*[]byte); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field password", values[i])
|
||||
} else if value.Valid {
|
||||
u.Password = value.String
|
||||
} else if value != nil {
|
||||
u.Password = *value
|
||||
}
|
||||
case user.FieldIsAdmin:
|
||||
if value, ok := values[i].(*sql.NullBool); !ok {
|
||||
|
@ -59,7 +59,7 @@ var (
|
||||
// EmailValidator is a validator for the "email" field. It is called by the builders before save.
|
||||
EmailValidator func(string) error
|
||||
// PasswordValidator is a validator for the "password" field. It is called by the builders before save.
|
||||
PasswordValidator func(string) error
|
||||
PasswordValidator func([]byte) error
|
||||
// DefaultIsAdmin holds the default value on creation for the "is_admin" field.
|
||||
DefaultIsAdmin bool
|
||||
// DefaultIsActive holds the default value on creation for the "is_active" field.
|
||||
|
@ -66,7 +66,7 @@ func Email(v string) predicate.User {
|
||||
}
|
||||
|
||||
// Password applies equality check predicate on the "password" field. It's identical to PasswordEQ.
|
||||
func Password(v string) predicate.User {
|
||||
func Password(v []byte) predicate.User {
|
||||
return predicate.User(sql.FieldEQ(FieldPassword, v))
|
||||
}
|
||||
|
||||
@ -221,70 +221,45 @@ func EmailContainsFold(v string) predicate.User {
|
||||
}
|
||||
|
||||
// PasswordEQ applies the EQ predicate on the "password" field.
|
||||
func PasswordEQ(v string) predicate.User {
|
||||
func PasswordEQ(v []byte) predicate.User {
|
||||
return predicate.User(sql.FieldEQ(FieldPassword, v))
|
||||
}
|
||||
|
||||
// PasswordNEQ applies the NEQ predicate on the "password" field.
|
||||
func PasswordNEQ(v string) predicate.User {
|
||||
func PasswordNEQ(v []byte) predicate.User {
|
||||
return predicate.User(sql.FieldNEQ(FieldPassword, v))
|
||||
}
|
||||
|
||||
// PasswordIn applies the In predicate on the "password" field.
|
||||
func PasswordIn(vs ...string) predicate.User {
|
||||
func PasswordIn(vs ...[]byte) predicate.User {
|
||||
return predicate.User(sql.FieldIn(FieldPassword, vs...))
|
||||
}
|
||||
|
||||
// PasswordNotIn applies the NotIn predicate on the "password" field.
|
||||
func PasswordNotIn(vs ...string) predicate.User {
|
||||
func PasswordNotIn(vs ...[]byte) predicate.User {
|
||||
return predicate.User(sql.FieldNotIn(FieldPassword, vs...))
|
||||
}
|
||||
|
||||
// PasswordGT applies the GT predicate on the "password" field.
|
||||
func PasswordGT(v string) predicate.User {
|
||||
func PasswordGT(v []byte) predicate.User {
|
||||
return predicate.User(sql.FieldGT(FieldPassword, v))
|
||||
}
|
||||
|
||||
// PasswordGTE applies the GTE predicate on the "password" field.
|
||||
func PasswordGTE(v string) predicate.User {
|
||||
func PasswordGTE(v []byte) predicate.User {
|
||||
return predicate.User(sql.FieldGTE(FieldPassword, v))
|
||||
}
|
||||
|
||||
// PasswordLT applies the LT predicate on the "password" field.
|
||||
func PasswordLT(v string) predicate.User {
|
||||
func PasswordLT(v []byte) predicate.User {
|
||||
return predicate.User(sql.FieldLT(FieldPassword, v))
|
||||
}
|
||||
|
||||
// PasswordLTE applies the LTE predicate on the "password" field.
|
||||
func PasswordLTE(v string) predicate.User {
|
||||
func PasswordLTE(v []byte) predicate.User {
|
||||
return predicate.User(sql.FieldLTE(FieldPassword, v))
|
||||
}
|
||||
|
||||
// PasswordContains applies the Contains predicate on the "password" field.
|
||||
func PasswordContains(v string) predicate.User {
|
||||
return predicate.User(sql.FieldContains(FieldPassword, v))
|
||||
}
|
||||
|
||||
// PasswordHasPrefix applies the HasPrefix predicate on the "password" field.
|
||||
func PasswordHasPrefix(v string) predicate.User {
|
||||
return predicate.User(sql.FieldHasPrefix(FieldPassword, v))
|
||||
}
|
||||
|
||||
// PasswordHasSuffix applies the HasSuffix predicate on the "password" field.
|
||||
func PasswordHasSuffix(v string) predicate.User {
|
||||
return predicate.User(sql.FieldHasSuffix(FieldPassword, v))
|
||||
}
|
||||
|
||||
// PasswordEqualFold applies the EqualFold predicate on the "password" field.
|
||||
func PasswordEqualFold(v string) predicate.User {
|
||||
return predicate.User(sql.FieldEqualFold(FieldPassword, v))
|
||||
}
|
||||
|
||||
// PasswordContainsFold applies the ContainsFold predicate on the "password" field.
|
||||
func PasswordContainsFold(v string) predicate.User {
|
||||
return predicate.User(sql.FieldContainsFold(FieldPassword, v))
|
||||
}
|
||||
|
||||
// IsAdminEQ applies the EQ predicate on the "is_admin" field.
|
||||
func IsAdminEQ(v bool) predicate.User {
|
||||
return predicate.User(sql.FieldEQ(FieldIsAdmin, v))
|
||||
|
@ -34,8 +34,8 @@ func (uc *UserCreate) SetEmail(s string) *UserCreate {
|
||||
}
|
||||
|
||||
// SetPassword sets the "password" field.
|
||||
func (uc *UserCreate) SetPassword(s string) *UserCreate {
|
||||
uc.mutation.SetPassword(s)
|
||||
func (uc *UserCreate) SetPassword(b []byte) *UserCreate {
|
||||
uc.mutation.SetPassword(b)
|
||||
return uc
|
||||
}
|
||||
|
||||
@ -248,7 +248,7 @@ func (uc *UserCreate) createSpec() (*User, *sqlgraph.CreateSpec) {
|
||||
_node.Email = value
|
||||
}
|
||||
if value, ok := uc.mutation.Password(); ok {
|
||||
_spec.SetField(user.FieldPassword, field.TypeString, value)
|
||||
_spec.SetField(user.FieldPassword, field.TypeBytes, value)
|
||||
_node.Password = value
|
||||
}
|
||||
if value, ok := uc.mutation.IsAdmin(); ok {
|
||||
|
@ -41,8 +41,8 @@ func (uu *UserUpdate) SetEmail(s string) *UserUpdate {
|
||||
}
|
||||
|
||||
// SetPassword sets the "password" field.
|
||||
func (uu *UserUpdate) SetPassword(s string) *UserUpdate {
|
||||
uu.mutation.SetPassword(s)
|
||||
func (uu *UserUpdate) SetPassword(b []byte) *UserUpdate {
|
||||
uu.mutation.SetPassword(b)
|
||||
return uu
|
||||
}
|
||||
|
||||
@ -160,7 +160,7 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
||||
_spec.SetField(user.FieldEmail, field.TypeString, value)
|
||||
}
|
||||
if value, ok := uu.mutation.Password(); ok {
|
||||
_spec.SetField(user.FieldPassword, field.TypeString, value)
|
||||
_spec.SetField(user.FieldPassword, field.TypeBytes, value)
|
||||
}
|
||||
if value, ok := uu.mutation.IsAdmin(); ok {
|
||||
_spec.SetField(user.FieldIsAdmin, field.TypeBool, value)
|
||||
@ -204,8 +204,8 @@ func (uuo *UserUpdateOne) SetEmail(s string) *UserUpdateOne {
|
||||
}
|
||||
|
||||
// SetPassword sets the "password" field.
|
||||
func (uuo *UserUpdateOne) SetPassword(s string) *UserUpdateOne {
|
||||
uuo.mutation.SetPassword(s)
|
||||
func (uuo *UserUpdateOne) SetPassword(b []byte) *UserUpdateOne {
|
||||
uuo.mutation.SetPassword(b)
|
||||
return uuo
|
||||
}
|
||||
|
||||
@ -353,7 +353,7 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (_node *User, err error)
|
||||
_spec.SetField(user.FieldEmail, field.TypeString, value)
|
||||
}
|
||||
if value, ok := uuo.mutation.Password(); ok {
|
||||
_spec.SetField(user.FieldPassword, field.TypeString, value)
|
||||
_spec.SetField(user.FieldPassword, field.TypeBytes, value)
|
||||
}
|
||||
if value, ok := uuo.mutation.IsAdmin(); ok {
|
||||
_spec.SetField(user.FieldIsAdmin, field.TypeBool, value)
|
||||
|
@ -11,6 +11,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"git.dotya.ml/mirre-mt/pcmt/ent"
|
||||
passwd "git.dotya.ml/mirre-mt/pcmt/modules/password"
|
||||
moduser "git.dotya.ml/mirre-mt/pcmt/modules/user"
|
||||
"github.com/gorilla/sessions"
|
||||
"github.com/labstack/echo-contrib/session"
|
||||
@ -200,7 +201,7 @@ func SigninPost(client *ent.Client) echo.HandlerFunc {
|
||||
if usr, err := moduser.QueryUser(ctx, client, username); err == nil {
|
||||
log.Info("queried user:", &usr.ID)
|
||||
|
||||
if usr.Password != password {
|
||||
if !passwd.Compare(usr.Password, password) {
|
||||
log.Warn("wrong user credentials, redirecting to /signin")
|
||||
|
||||
return c.Redirect(http.StatusFound, "/signin")
|
||||
|
@ -7,6 +7,7 @@ import (
|
||||
|
||||
"git.dotya.ml/mirre-mt/pcmt/ent"
|
||||
"git.dotya.ml/mirre-mt/pcmt/ent/user"
|
||||
passwd "git.dotya.ml/mirre-mt/pcmt/modules/password"
|
||||
"git.dotya.ml/mirre-mt/pcmt/slogging"
|
||||
)
|
||||
|
||||
@ -14,13 +15,18 @@ import (
|
||||
func CreateUser(ctx context.Context, client *ent.Client, email, username, password string) (*ent.User, error) {
|
||||
log := ctx.Value(CtxKey{}).(*slogging.Logger)
|
||||
|
||||
digest, err := passwd.GetHash(password)
|
||||
if err != nil {
|
||||
log.Errorf("error hashing passoword: %s", err)
|
||||
return nil, errors.New("could not hash password")
|
||||
}
|
||||
|
||||
u, err := client.User.
|
||||
Create().
|
||||
SetEmail(email).
|
||||
SetUsername(username).
|
||||
SetPassword(password).
|
||||
SetPassword(digest).
|
||||
Save(ctx)
|
||||
// TODO: saving cleartext password, rework!
|
||||
if err != nil {
|
||||
log.Infof("error querying user: %q", err)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user