validate 2fa. more cleanups

This commit is contained in:
Your Name 2023-09-26 16:45:19 -04:00
parent f3cc9cdeed
commit b042b4dbc9
5 changed files with 127 additions and 163 deletions

24
2fa.go
View File

@ -5,6 +5,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"math/big" "math/big"
"strconv"
"time" "time"
) )
@ -17,7 +18,29 @@ func generate2fa() string {
} }
func Validate2FA(u *UserData, challenge string) bool { func Validate2FA(u *UserData, challenge string) bool {
defer func() {
u.Delete("2fa")
u.Delete("2faexpires")
}()
v, ok := u.Get("2fa") v, ok := u.Get("2fa")
if !ok {
return false
}
exp, ok := u.Get("2faexpires")
if !ok {
return false
}
tmp, err := strconv.ParseInt(exp, 10, 64)
if err != nil {
return false
}
if int64(time.Now().Unix()) > tmp {
return false
}
return ok && v == challenge return ok && v == challenge
} }
@ -41,4 +64,3 @@ func Send2FA(u *UserData) error {
return Send2faEmail(email, fullname, code) return Send2faEmail(email, fullname, code)
} }

41
auth.go Normal file
View File

@ -0,0 +1,41 @@
package scsusers
import (
"fmt"
"log"
"golang.org/x/crypto/bcrypt"
)
func Login(username, password string) bool {
u, ok := Get(username)
if !ok {
return false
}
if bcrypt.CompareHashAndPassword([]byte(u.Password), []byte(password)) != nil {
log.Printf("scsusers.Login: Failed password for " + username)
return false
}
log.Printf("User %s logged in\n", username)
return true
}
func (u *UserData) ChangePassword(oldpass, newpass string) bool {
if bcrypt.CompareHashAndPassword([]byte(u.Password), []byte(oldpass)) != nil {
log.Printf("scsusers.ChangePassword: Failed password for %s\n", u.Username)
return false
}
newcrypt, err := bcrypt.GenerateFromPassword([]byte(newpass), 10)
if err != nil {
log.Printf("scsusers.ChangePassword: generate: %s", err.Error())
return false
}
q := fmt.Sprintf("update %s_auth set password=? where userid=?", c.TablePrefix)
_, err = c.db.Exec(q, newcrypt, u.UserID)
if err != nil {
log.Printf("scsusers.ChangePassword: update failed for %s: %s\n", u.Username, err.Error())
return false
}
return true
}

149
main.go
View File

@ -2,7 +2,6 @@ package scsusers
import ( import (
"database/sql" "database/sql"
"encoding/json"
"fmt" "fmt"
"html/template" "html/template"
"log" "log"
@ -119,7 +118,6 @@ func NewUser() *UserData {
} }
func Get(username string) (*UserData, bool) { func Get(username string) (*UserData, bool) {
u := NewUser() u := NewUser()
q := fmt.Sprintf("select username, password, id from %s_auth where username=?", c.TablePrefix) q := fmt.Sprintf("select username, password, id from %s_auth where username=?", c.TablePrefix)
err := c.db.Get(u, q, username) err := c.db.Get(u, q, username)
@ -145,39 +143,6 @@ func Get(username string) (*UserData, bool) {
return u, true return u, true
} }
func Login(username, password string) bool {
u, ok := Get(username)
if !ok {
return false
}
if bcrypt.CompareHashAndPassword([]byte(u.Password), []byte(password)) != nil {
log.Printf("scsusers.Login: Failed password for " + username)
return false
}
log.Printf("User %s logged in\n", username)
return true
}
func (u *UserData) ChangePassword(oldpass, newpass string) bool {
if bcrypt.CompareHashAndPassword([]byte(u.Password), []byte(oldpass)) != nil {
log.Printf("scsusers.ChangePassword: Failed password for %s\n", u.Username)
return false
}
newcrypt, err := bcrypt.GenerateFromPassword([]byte(newpass), 10)
if err != nil {
log.Printf("scsusers.ChangePassword: generate: %s", err.Error())
return false
}
q := fmt.Sprintf("update %s_auth set password=? where userid=?", c.TablePrefix)
_, err = c.db.Exec(q, newcrypt, u.UserID)
if err != nil {
log.Printf("scsusers.ChangePassword: update failed for %s: %s\n", u.Username, err.Error())
return false
}
return true
}
func GetUserid(username string) int64 { func GetUserid(username string) int64 {
var i int64 var i int64
username = strings.ToLower(username) username = strings.ToLower(username)
@ -190,117 +155,3 @@ func GetUserid(username string) int64 {
} }
return i return i
} }
func (u *UserData) Get(key string) (string, bool) {
tmp, ok := u.Meta[key]
return tmp.Value, ok
}
func (u *UserData) Set(key, value string) error {
tmp, ok := u.Meta[key]
if ok {
_, err := c.db.Query(fmt.Sprintf("delete from %s_meta where id=?", c.TablePrefix), tmp.ID)
if err != nil {
log.Printf("scsauth: set: delete: %s", err.Error())
return err
}
}
var insertid int64
err := c.db.Get(&insertid, fmt.Sprintf("insert into %s_meta (userid, meta_key, meta_value) VALUES (?,?,?) returning id", c.TablePrefix), u.UserID, key, value)
if err != nil {
log.Printf("scsauth: set: insert: %s", err.Error())
return err
}
var m metadata
m.Key = key
m.Value = value
m.ID = insertid
u.Meta[key] = m
return nil
}
func SaveUser(username string, d UserData) bool {
username = strings.ToLower(username)
q := fmt.Sprintf("update %s_userdata set data=? where username = ?", c.TablePrefix)
j, err := json.Marshal(d)
if err != nil {
log.Printf("scsusers.SaveUser: json.Marshal failed for username %s : %s\n", username, err.Error())
return false
}
_, err = c.db.Exec(q, username, j)
if err != nil {
log.Printf("scsusers.SaveUser: db.Exec failed for username %s : %s\n", username, err.Error())
return false
}
return true
}
type Metadata struct {
MetaKey string `db:"meta_key"`
MetaValue string `db:"meta_value"`
}
func GetAllMeta(username string) map[string]string {
meta := make(map[string]string)
username = strings.ToLower(username)
q := fmt.Sprintf(`select meta_key, meta_value
from %s_user_metadata where
user_id=(select userid from %s_auth where username = ?)`,
c.TablePrefix, c.TablePrefix)
rows, err := c.db.Queryx(q, username)
if err != nil && err != sql.ErrNoRows {
log.Printf("scsusers.GetAllMeta: %s: %s\n", username, err.Error())
return meta
}
var m Metadata
for rows.Next() {
err = rows.StructScan(&m)
if err != nil {
log.Printf("scsusers.GetAllMeta: StructScan: %s: %s\n", username, err.Error())
return meta
}
meta[m.MetaKey] = m.MetaValue
}
return meta
}
func GetMeta(username string, metakey string) string {
var v string
username = strings.ToLower(username)
q := fmt.Sprintf(`select meta_value from %s_user_metadata where
user_id=(select userid from %s_auth where username = ?) AND meta_key=?`, c.TablePrefix, c.TablePrefix)
err := c.db.Get(&v, q, username, metakey)
if err != nil && err != sql.ErrNoRows {
log.Printf("scsusers.GetMeta: %s - %s - %s\n", username, metakey, err.Error())
}
if v == "" {
// get default user
err := c.db.Get(&v, q, "//default//", metakey)
if err != nil && err != sql.ErrNoRows {
log.Printf("scsusers.GetMeta: %s - %s - %s\n", username, metakey, err.Error())
}
}
return v
}
func SetMeta(username string, metakey string, metavalue string) {
var err error
username = strings.ToLower(username)
if metavalue == "" {
q := fmt.Sprintf(`delete from %s_user_metadata where user_id=(select userid from %s_auth where username = ?) AND meta_key=?`,
c.TablePrefix, c.TablePrefix)
_, err = c.db.Exec(q, username, metakey)
} else {
q := fmt.Sprintf(`insert into %s_user_metadata (user_id, meta_key, meta_value) VALUES
((select userid from %s_auth where username = ?), ?, ?)`, c.TablePrefix, c.TablePrefix)
_, err = c.db.Exec(q, username, metakey, metavalue)
}
if err != nil {
log.Printf("scsusers.SetMeta: %s %s %s %s\n", username, metakey, metavalue, err.Error())
}
}

50
meta.go Normal file
View File

@ -0,0 +1,50 @@
package scsusers
import (
"fmt"
"log"
)
type Metadata struct {
MetaKey string `db:"meta_key"`
MetaValue string `db:"meta_value"`
}
func (u *UserData) Get(key string) (string, bool) {
tmp, ok := u.Meta[key]
return tmp.Value, ok
}
func (u *UserData) Delete(key string) {
tmp, ok := u.Meta[key]
if ok {
_, err := c.db.Query(fmt.Sprintf("delete from %s_meta where id=?", c.TablePrefix), tmp.ID)
if err != nil {
log.Printf("scsauth: set: delete: %s", err.Error())
}
}
}
func (u *UserData) Set(key, value string) error {
tmp, ok := u.Meta[key]
if ok {
_, err := c.db.Query(fmt.Sprintf("delete from %s_meta where id=?", c.TablePrefix), tmp.ID)
if err != nil {
log.Printf("scsauth: set: delete: %s", err.Error())
return err
}
}
var insertid int64
err := c.db.Get(&insertid, fmt.Sprintf("insert into %s_meta (userid, meta_key, meta_value) VALUES (?,?,?) returning id", c.TablePrefix), u.UserID, key, value)
if err != nil {
log.Printf("scsauth: set: insert: %s", err.Error())
return err
}
var m metadata
m.Key = key
m.Value = value
m.ID = insertid
u.Meta[key] = m
return nil
}