scsusers/auth.go

103 lines
2.7 KiB
Go

package scsusers
import (
"fmt"
"log"
"strconv"
"strings"
"time"
"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 {
rc, ok := u.Get("recoverycode")
if !ok {
log.Println("No recovery code")
return false
}
log.Printf("Checking against recovery code %s", rc)
if bcrypt.CompareHashAndPassword([]byte(rc), []byte(password)) != nil {
log.Printf("scsusers.Login: Failed password for " + username)
return false
}
tmp, ok := u.Get("recoverytime")
if !ok {
log.Printf("scsusers.Login: recoverytime missing " + username)
return false
}
rt, _ := strconv.ParseInt(tmp, 10, 64)
if time.Now().Unix() > rt {
log.Printf("scsusers.Login: recovery time expired")
return false
}
u.SetPassword([]byte(rc))
u.Delete("recoverycode")
u.Delete("recoverytime")
}
log.Printf("User %s logged in\n", username)
return true
}
func (u *UserData) SetPassword(newcrypt []byte) bool {
q := fmt.Sprintf("update %s_users set password=? where id=? limit 1", c.TablePrefix)
_, err := c.db.Exec(q, newcrypt, u.UserID)
if err != nil {
log.Printf("scsusers.SetPassword: update failed for %s: %s\n", u.Username, err.Error())
return false
}
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
}
return u.SetPassword(newcrypt)
}
func (u *UserData) Suspend() bool {
var hash string
u.Set("status", "inactive")
q := fmt.Sprintf("select password from %s_users where id=? limit 1", c.TablePrefix)
err := c.db.Get(&hash, q, u.UserID)
if err != nil {
return false
}
if strings.HasPrefix(hash, "*") {
return true
}
newhash := "*" + hash
q = fmt.Sprintf("update %s_users set password=? where id=?", c.TablePrefix)
_, err = c.db.Exec(q, newhash, u.UserID)
return err == nil
}
func (u *UserData) Unsuspend() bool {
var hash string
u.Set("status", "active")
q := fmt.Sprintf("select password from %s_users where id=? limit 1", c.TablePrefix)
err := c.db.Get(&hash, q, u.UserID)
if err != nil {
return false
}
if !strings.HasPrefix(hash, "*") {
return true
}
newhash := strings.TrimPrefix(hash, "*")
q = fmt.Sprintf("update %s_users set password=? where id=?", c.TablePrefix)
_, err = c.db.Exec(q, newhash, u.UserID)
return err == nil
}