package scsusers import ( "fmt" "log" "strconv" "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) }