MapyWeb/db/auth.go

114 lines
2.8 KiB
Go

package db
import (
"errors"
"time"
pgsql "github.com/fergusstrange/embedded-postgres"
"github.com/jmoiron/sqlx"
_ "github.com/lib/pq"
"github.com/rs/zerolog/log"
)
var (
db *sqlx.DB
postgres *pgsql.EmbeddedPostgres
)
// User represents a mapy user.
type User struct {
ID int64 `db:"id"`
Username string `db:"username"`
Password string `db:"password"`
Creation time.Time `db:"creation"`
LastLogin time.Time `db:"last_login"`
LastIP string `db:"last_ip"`
Ban int `db:"ban"`
Admin int `db:"admin"`
Gender int `db:"gender"`
}
func getUser(username string) (u *User, err error) {
u = new(User)
if err = db.Get(u, "SELECT * FROM accounts WHERE username=$1", username); err != nil {
return nil, err
}
return u, nil
}
// UserExists queries our database for a user using the given username and returns true if it exists, false if it does not.
func UserExists(username string) bool {
u := new(User)
if err := db.Get(u, "SELECT id FROM accounts WHERE username=$1", username); err != nil {
return false
}
return true
}
// EmailTaken queries our database for a user using the given email address and returns true if the email is taken, false if it is not.
func EmailTaken(email string) bool {
u := new(User)
if err := db.Get(u, "SELECT id FROM accounts WHERE email=$1", email); err == nil {
return true
}
return false
}
// AttemptWebLogin checks the given credentials for validity and returns a User and an error.
func AttemptWebLogin(username, password, ipaddr, useragent string) (*User, error) {
var (
u *User
err error
good = false
)
defer func() {
// TODO: make bitcask max value size larger because this 000 is gonna get huge
// to log invalid users
if u == nil {
u = &User{ID: 000}
}
if err := authlog.newAttempt(int(u.ID), ipaddr, useragent, Web, good); err != nil {
println(err.Error())
log.Error().Err(err).Msg("failed_login")
}
}()
if u, err = getUser(username); err != nil {
return u, err
}
if !CheckPasswordHash(password, u.Password) {
return nil, errors.New("invalid password")
}
good = true
return u, nil
}
// RegisterNewUser registers a new mapyweb user
func RegisterNewUser(username, password, ipaddr string, gender int, admin bool) error {
hashed, err := HashPassword(password)
if err != nil {
return err
}
if !CheckPasswordHash(password, hashed) {
return errors.New("FAILED PASSWORD HASHING")
}
u := &User{
Username: username,
Password: hashed,
Creation: time.Now(),
LastLogin: time.Now(),
LastIP: ipaddr,
Ban: 0,
Gender: gender,
}
if admin {
u.Admin = 1
} else {
u.Admin = 0
}
_, err = db.NamedExec(`INSERT INTO accounts (username, password, creation, last_login, last_ip, ban, admin, gender)
VALUES (:username, :password, :creation, :last_login, :last_ip, 0, :admin, :gender);`, u)
return err
}