summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Manuel <nilslice@gmail.com>2017-01-02 21:57:53 -0800
committerSteve Manuel <nilslice@gmail.com>2017-01-02 21:57:53 -0800
commitc1d9ac15acdc9ea2f389cfcd8eee2ac7db291f87 (patch)
tree316c4a0c854dca1a089573daf44cc0098a643ed2
parent2ed96b15af39aaeb43ed56c7c9ef6535f31a6d96 (diff)
update codebase where previous deps were used
-rw-r--r--system/admin/handlers.go39
-rw-r--r--system/admin/user/auth.go101
-rw-r--r--system/db/user.go6
3 files changed, 108 insertions, 38 deletions
diff --git a/system/admin/handlers.go b/system/admin/handlers.go
index 3d0cf16..0fb025c 100644
--- a/system/admin/handlers.go
+++ b/system/admin/handlers.go
@@ -74,7 +74,12 @@ func initHandler(res http.ResponseWriter, req *http.Request) {
// create and save admin user
email := strings.ToLower(req.FormValue("email"))
password := req.FormValue("password")
- usr := user.NewUser(email, password)
+ usr, err := user.New(email, password)
+ if err != nil {
+ log.Println(err)
+ res.WriteHeader(http.StatusInternalServerError)
+ return
+ }
_, err = db.SetUser(usr)
if err != nil {
@@ -227,7 +232,12 @@ func configUsersHandler(res http.ResponseWriter, req *http.Request) {
return
}
- usr := user.NewUser(email, password)
+ usr, err := user.New(email, password)
+ if err != nil {
+ log.Println(err)
+ res.WriteHeader(http.StatusInternalServerError)
+ return
+ }
_, err = db.SetUser(usr)
if err != nil {
@@ -301,9 +311,19 @@ func configUsersEditHandler(res http.ResponseWriter, req *http.Request) {
newPassword := req.PostFormValue("new_password")
var updatedUser *user.User
if newPassword != "" {
- updatedUser = user.NewUser(email, newPassword)
+ updatedUser, err = user.New(email, newPassword)
+ if err != nil {
+ log.Println(err)
+ res.WriteHeader(http.StatusInternalServerError)
+ return
+ }
} else {
- updatedUser = user.NewUser(email, password)
+ updatedUser, err = user.New(email, password)
+ if err != nil {
+ log.Println(err)
+ res.WriteHeader(http.StatusInternalServerError)
+ return
+ }
}
// set the ID to the same ID as current user
@@ -676,7 +696,6 @@ func recoveryKeyHandler(res http.ResponseWriter, req *http.Request) {
if key != actual {
log.Println("Bad recovery key submitted:", key)
- log.Println("Actual:", actual)
res.WriteHeader(http.StatusBadRequest)
res.Write([]byte("Error, please go back and try again."))
@@ -712,7 +731,15 @@ func recoveryKeyHandler(res http.ResponseWriter, req *http.Request) {
return
}
- update := user.NewUser(email, password)
+ update, err := user.New(email, password)
+ if err != nil {
+ log.Println(err)
+
+ res.WriteHeader(http.StatusInternalServerError)
+ res.Write([]byte("Error, please go back and try again."))
+ return
+ }
+
update.ID = usr.ID
err = db.UpdateUser(usr, update)
diff --git a/system/admin/user/auth.go b/system/admin/user/auth.go
index 3ff2b2b..76c4804 100644
--- a/system/admin/user/auth.go
+++ b/system/admin/user/auth.go
@@ -1,11 +1,15 @@
package user
import (
+ "bytes"
+ crand "crypto/rand"
"encoding/base64"
+ "log"
+ mrand "math/rand"
"net/http"
+ "time"
"github.com/nilslice/jwt"
- "github.com/nilslice/rand"
"golang.org/x/crypto/bcrypt"
)
@@ -17,10 +21,21 @@ type User struct {
Salt string `json:"salt"`
}
-// NewUser creates a user
-func NewUser(email, password string) *User {
- salt := salt128()
- hash := encryptPassword([]byte(password), salt)
+var (
+ r = mrand.New(mrand.NewSource(time.Now().Unix()))
+)
+
+// New creates a user
+func New(email, password string) (*User, error) {
+ salt, err := randSalt()
+ if err != nil {
+ return nil, err
+ }
+
+ hash, err := hashPassword([]byte(password), salt)
+ if err != nil {
+ return nil, err
+ }
user := &User{
Email: email,
@@ -28,7 +43,7 @@ func NewUser(email, password string) *User {
Salt: base64.StdEncoding.EncodeToString(salt),
}
- return user
+ return user, nil
}
// Auth is HTTP middleware to ensure the request has proper token credentials
@@ -63,42 +78,68 @@ func IsUser(usr *User, password string) bool {
return false
}
- err = comparePassword([]byte(usr.Hash), []byte(password), salt)
+ err = checkPassword([]byte(usr.Hash), []byte(password), salt)
if err != nil {
+ log.Println("Error checking password:", err)
return false
}
return true
}
-// The following functions are from github.com/sluu99/um -----------------------
+// randSalt generates 16 * 8 bits of data for a random salt
+func randSalt() ([]byte, error) {
+ buf := make([]byte, 16)
+ count := len(buf)
+ n, err := crand.Read(buf)
+ if err != nil {
+ return nil, err
+ }
-// salt128 generates 128 bits of random data.
-func salt128() []byte {
- x := make([]byte, 16)
- rand.Read(x)
- return x
-}
+ if n != count || err != nil {
+ for count > 0 {
+ count--
+ buf[count] = byte(r.Int31n(256))
+ }
+ }
-// makePassword makes the actual password from the plain password and salt
-func makePassword(plainPw, salt []byte) []byte {
- password := make([]byte, 0, len(plainPw)+len(salt))
- password = append(password, salt...)
- password = append(password, plainPw...)
- return password
+ return buf, nil
}
-// encryptPassword uses bcrypt to encrypt a password and salt combination.
-// It returns the encrypted password in hex form.
-func encryptPassword(plainPw, salt []byte) []byte {
- hash, _ := bcrypt.GenerateFromPassword(makePassword(plainPw, salt), 10)
- return hash
+// saltPassword combines the salt and password provided
+func saltPassword(password, salt []byte) ([]byte, error) {
+ salted := &bytes.Buffer{}
+ _, err := salted.Write(append(salt, password...))
+ if err != nil {
+ return nil, err
+ }
+
+ return salted.Bytes(), nil
}
-// comparePassword compares a hash with the plain password and the salt.
-// The function returns nil on success or an error on failure.
-func comparePassword(hash, plainPw, salt []byte) error {
- return bcrypt.CompareHashAndPassword(hash, makePassword(plainPw, salt))
+// hashPassword encrypts the salted password using bcrypt
+func hashPassword(password, salt []byte) ([]byte, error) {
+ salted, err := saltPassword(password, salt)
+ if err != nil {
+ return nil, err
+ }
+
+ hash, err := bcrypt.GenerateFromPassword(salted, 10)
+ if err != nil {
+ return nil, err
+ }
+
+ return hash, nil
}
-// End code from github.com/sluu99/um ------------------------------------------
+// checkPassword compares the hash with the salted password. A nil return means
+// the password is correct, but an error could mean either the password is not
+// correct, or the salt process failed - indicated in logs
+func checkPassword(hash, password, salt []byte) error {
+ salted, err := saltPassword(password, salt)
+ if err != nil {
+ return err
+ }
+
+ return bcrypt.CompareHashAndPassword(hash, salted)
+}
diff --git a/system/db/user.go b/system/db/user.go
index 1b15a82..02fda95 100644
--- a/system/db/user.go
+++ b/system/db/user.go
@@ -5,13 +5,14 @@ import (
"encoding/json"
"errors"
"fmt"
+ "math/rand"
"net/http"
+ "time"
"github.com/ponzu-cms/ponzu/system/admin/user"
"github.com/boltdb/bolt"
"github.com/nilslice/jwt"
- "github.com/nilslice/rand"
)
// ErrUserExists is used for the db to report to admin user of existing user
@@ -198,7 +199,8 @@ func CurrentUser(req *http.Request) ([]byte, error) {
// SetRecoveryKey generates and saves a random secret key to verify an email
// address submitted in order to recover/reset an account password
func SetRecoveryKey(email string) (string, error) {
- key := fmt.Sprintf("%d", rand.Int63())
+ r := rand.New(rand.NewSource(time.Now().Unix()))
+ key := fmt.Sprintf("%d", r.Int63())
err := store.Update(func(tx *bolt.Tx) error {
b, err := tx.CreateBucketIfNotExists([]byte("__recoveryKeys"))