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 }