// Create makes a new Admin account with a given email and pwhash. func Create(d db.DB, email, pwhash string) (util.Key, error) { var none util.Key adminJSON, err := db.GetByKey(d, emails, []byte(email)) switch { case err != nil: return none, err case len(adminJSON) != 0: return none, errors.AlreadyExistsf("admin for email %s:", email) } hash, salt := util.HashedAndSalt(pwhash, time.Now().String()) seed := time.Now().String() key := util.SaltedHash(string(hash), seed) adm := &Admin{ Email: email, Salt: salt, Hash: hash, Key: key, } if err := db.StoreKeyValue(d, admins, []byte(key), adm); err != nil { return none, err } return key, db.StoreKeyValue(d, emails, []byte(email), adm) }
func Valid(d db.DB, email string, key util.Key) error { userBytes, err := db.GetByKey(d, SessionKeys, []byte(email)) if err != nil { return err } if len(userBytes) == 0 { return errors.UserNotFoundf("user %q not logged in", email) } var login Login err = json.Unmarshal(userBytes, &login) if err != nil { return err } if login.Key == key { t := time.Now() if t.Before(login.Timeout) { err = db.StoreKeyValue(d, SessionKeys, b(email), Login{key, t.Add(GetTimeout())}) return nil } return errors.NotValidf("user %q timed out", email) } return fmt.Errorf("bad key %q for user %q", key, email) }
func LoginUser(d db.DB, email, pwhash string) (util.Key, error) { // Get the hash and password for the email. // util.CheckHashedPw(pw, salt, hash) // if ok, then log in. userBytes, err := db.GetByKey(d, Users, []byte(email)) if err != nil { return "", err } if len(userBytes) == 0 { return "", fmt.Errorf("no user for email %q", email) } var u User err = json.Unmarshal(userBytes, &u) if err != nil { return "", err } ok := util.CheckHashedPw(pwhash, u.Salt, u.Hash) if !ok { return "", fmt.Errorf("invalid password") } key := util.SaltedHash(pwhash, time.Now().String()) timeout := time.Now().Add(GetTimeout()) err = db.StoreKeyValue(d, SessionKeys, b(email), Login{key, timeout}) if err != nil { return "", err } return key, nil }
func ValidLogin(d db.DB, email string, key util.Key) error { login, err := GetLogin(d, email) if err != nil { return errors.NotValidf("could not get login for email %q", email) } if login.Key == key { t := time.Now() if t.Before(login.Timeout) { err = db.StoreKeyValue(d, LoginKeys, []byte(email), Login{key, t.Add(GetTimeout())}) return nil } return errors.NotValidf("user %q timed out", email) } return errors.NotValidf("bad key %q for user %q", key, email) }
func CreateUser(d db.DB, email, pwhash string) error { userBytes, err := db.GetByKey(d, Users, []byte(email)) if err != nil { return err } if len(userBytes) != 0 { return errors.AlreadyExistsf("user for email %q", email) } seed := time.Now().String() hash, salt := util.HashedAndSalt(pwhash, seed) return db.StoreKeyValue(d, Users, b(email), User{ Email: email, Salt: salt, Hash: hash, }) }
func LoginUser(d db.DB, email, pwhash string) (util.Key, error) { if err := CheckUser(d, email, pwhash); err != nil { return "", err } key := util.SaltedHash(pwhash, time.Now().String()) timeout := time.Now().Add(GetTimeout()) err := db.StoreKeyValue( d, LoginKeys, []byte(email), Login{key, timeout}, ) if err != nil { return "", err } return key, nil }