2021-09-20 10:36:20 +00:00
|
|
|
package db
|
2021-09-20 01:24:43 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
pgsql "github.com/fergusstrange/embedded-postgres"
|
|
|
|
"github.com/jmoiron/sqlx"
|
|
|
|
_ "github.com/lib/pq"
|
2021-09-20 03:31:47 +00:00
|
|
|
"github.com/rs/zerolog/log"
|
2021-09-20 01:24:43 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
|
|
|
db *sqlx.DB
|
|
|
|
postgres *pgsql.EmbeddedPostgres
|
|
|
|
)
|
|
|
|
|
|
|
|
// User represents a mapy user.
|
|
|
|
type User struct {
|
2021-09-20 03:31:47 +00:00
|
|
|
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"`
|
2021-09-20 01:24:43 +00:00
|
|
|
}
|
|
|
|
|
2021-09-20 03:31:47 +00:00
|
|
|
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 {
|
2021-09-20 01:24:43 +00:00
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return u, nil
|
|
|
|
}
|
|
|
|
|
2021-09-20 10:36:20 +00:00
|
|
|
// 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
|
|
|
|
}
|
|
|
|
|
2021-09-20 01:24:43 +00:00
|
|
|
// 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
|
|
|
|
)
|
2021-09-20 10:36:20 +00:00
|
|
|
|
2021-09-20 01:24:43 +00:00
|
|
|
defer func() {
|
2021-09-20 10:36:20 +00:00
|
|
|
// TODO: make bitcask max value size larger because this 000 is gonna get huge
|
2021-09-20 03:31:47 +00:00
|
|
|
// to log invalid users
|
|
|
|
if u == nil {
|
|
|
|
u = &User{ID: 000}
|
|
|
|
}
|
2021-09-20 10:36:20 +00:00
|
|
|
if err := authlog.newAttempt(int(u.ID), ipaddr, useragent, Web, good); err != nil {
|
2021-09-20 03:31:47 +00:00
|
|
|
println(err.Error())
|
|
|
|
log.Error().Err(err).Msg("failed_login")
|
2021-09-20 01:24:43 +00:00
|
|
|
}
|
|
|
|
}()
|
2021-09-20 10:36:20 +00:00
|
|
|
|
2021-09-20 01:24:43 +00:00
|
|
|
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
|
|
|
|
}
|
2021-09-20 03:31:47 +00:00
|
|
|
if !CheckPasswordHash(password, hashed) {
|
|
|
|
return errors.New("FAILED PASSWORD HASHING")
|
|
|
|
}
|
2021-09-20 01:24:43 +00:00
|
|
|
u := &User{
|
2021-09-20 03:31:47 +00:00
|
|
|
Username: username,
|
|
|
|
Password: hashed,
|
|
|
|
Creation: time.Now(),
|
|
|
|
LastLogin: time.Now(),
|
|
|
|
LastIP: ipaddr,
|
|
|
|
Ban: 0,
|
|
|
|
Gender: gender,
|
2021-09-20 01:24:43 +00:00
|
|
|
}
|
|
|
|
if admin {
|
|
|
|
u.Admin = 1
|
|
|
|
} else {
|
|
|
|
u.Admin = 0
|
|
|
|
}
|
2021-09-20 03:31:47 +00:00
|
|
|
_, 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)
|
2021-09-20 01:24:43 +00:00
|
|
|
return err
|
|
|
|
}
|