From 40cd2ae837658433253f1ed100b28a09331c05e6 Mon Sep 17 00:00:00 2001 From: Jordan Date: Thu, 6 Feb 2014 10:49:53 -0600 Subject: [PATCH] Cleaned up some errors Implemented using db.* helpers (ie GetUser) Implemented ChangePassword (not reachable from UI currently) Fixed angular issue in settings.html template --- auth/auth.go | 60 +++++++++++++++++------------------------ controllers/api.go | 24 +++++++---------- controllers/route.go | 4 +-- db/db.go | 11 ++++++-- static/css/main.css | 4 +++ templates/settings.html | 40 ++++++++++++++++----------- templates/users.html | 4 ++- 7 files changed, 77 insertions(+), 70 deletions(-) diff --git a/auth/auth.go b/auth/auth.go index 191edbed..561b6f86 100644 --- a/auth/auth.go +++ b/auth/auth.go @@ -1,9 +1,7 @@ package auth import ( - "database/sql" "encoding/gob" - "errors" "fmt" "io" "net/http" @@ -27,24 +25,20 @@ var Store = sessions.NewCookieStore( []byte(securecookie.GenerateRandomKey(64)), //Signing key []byte(securecookie.GenerateRandomKey(32))) -var ErrUsernameTaken = errors.New("Username already taken") - // Login attempts to login the user given a request. func Login(r *http.Request) (bool, error) { username, password := r.FormValue("username"), r.FormValue("password") session, _ := Store.Get(r, "gophish") - u := models.User{} - err := db.Conn.SelectOne(&u, "SELECT * FROM Users WHERE username=?", username) - if err == sql.ErrNoRows { + u, err := db.GetUserByUsername(username) + if err != db.ErrUsernameTaken { //Return false, but don't return an error - return false, nil - } else if err != nil { return false, err } //If we've made it here, we should have a valid user stored in u //Let's check the password err = bcrypt.CompareHashAndPassword([]byte(u.Hash), []byte(password)) if err != nil { + fmt.Println("Error in comparing hash and password") ctx.Set(r, "user", nil) //Return false, but don't return an error return false, nil @@ -57,10 +51,9 @@ func Login(r *http.Request) (bool, error) { // Register attempts to register the user given a request. func Register(r *http.Request) (bool, error) { username, password := r.FormValue("username"), r.FormValue("password") - u := models.User{} - err := db.Conn.SelectOne(&u, "SELECT * FROM Users WHERE username=?", username) - if err != sql.ErrNoRows { - return false, ErrUsernameTaken + u, err := db.GetUserByUsername(username) + if err != nil { + return false, err } //If we've made it here, we should have a valid username given //Let's create the password hash @@ -78,31 +71,28 @@ func Register(r *http.Request) (bool, error) { return true, nil } -// GetUserById returns the user that the given id corresponds to. If no user is found, an -// error is thrown. -func GetUserById(id int64) (models.User, error) { - u := models.User{} - err := db.Conn.SelectOne(&u, "SELECT id, username, api_key FROM Users WHERE id=?", id) - if err != nil { - return u, err - } - return u, nil -} - -// GetUserByAPIKey returns the user that the given API Key corresponds to. If no user is found, an -// error is thrown. -func GetUserByAPIKey(key []byte) (models.User, error) { - u := models.User{} - err := db.Conn.SelectOne(&u, "SELECT id, username, api_key FROM Users WHERE apikey=?", key) - if err != nil { - return u, err - } - return u, nil -} - func GenerateSecureKey() string { // Inspired from gorilla/securecookie k := make([]byte, 32) io.ReadFull(rand.Reader, k) return fmt.Sprintf("%x", k) } + +func ChangePassword(u *models.User, c string, n string) bool { + // Check the current password + err := bcrypt.CompareHashAndPassword([]byte(u.Hash), []byte(c)) + if err != nil { + return false + } else { + // Generate the new hash + h, err := bcrypt.GenerateFromPassword([]byte(n), bcrypt.DefaultCost) + if err != nil { + return false + } + u.Hash = string(h) + if err = db.PutUser(u); err != nil { + return false + } + return true + } +} diff --git a/controllers/api.go b/controllers/api.go index de9cf3a0..27ea2c34 100644 --- a/controllers/api.go +++ b/controllers/api.go @@ -10,7 +10,6 @@ import ( ctx "github.com/gorilla/context" "github.com/gorilla/mux" - "github.com/gorilla/sessions" "github.com/jordan-wright/gophish/auth" "github.com/jordan-wright/gophish/db" "github.com/jordan-wright/gophish/models" @@ -37,13 +36,12 @@ func API_Reset(w http.ResponseWriter, r *http.Request) { case r.Method == "POST": u := ctx.Get(r, "user").(models.User) u.APIKey = auth.GenerateSecureKey() - db.Conn.Exec("UPDATE users SET api_key=? WHERE id=?", u.APIKey, u.Id) - session := ctx.Get(r, "session").(*sessions.Session) - session.AddFlash(models.Flash{ - Type: "success", - Message: "API Key Successfully Reset", - }) - session.Save(r, w) + err := db.PutUser(&u) + if err != nil { + Flash(w, r, "danger", "Error resetting API Key") + } else { + Flash(w, r, "success", "API Key Successfully Reset") + } http.Redirect(w, r, "/settings", 302) } } @@ -53,8 +51,7 @@ func API_Reset(w http.ResponseWriter, r *http.Request) { func API_Campaigns(w http.ResponseWriter, r *http.Request) { switch { case r.Method == "GET": - cs := []models.Campaign{} - _, err := db.Conn.Select(&cs, "SELECT c.id, name, created_date, completed_date, status, template FROM campaigns c, users u WHERE c.uid=u.id AND u.api_key=?", ctx.Get(r, "api_key")) + cs, err := db.GetCampaigns(ctx.Get(r, "api_key")) if err != nil { fmt.Println(err) } @@ -96,14 +93,11 @@ func API_Campaigns(w http.ResponseWriter, r *http.Request) { // valid, API_Campaigns_Id returns null. func API_Campaigns_Id(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) - id, err := strconv.ParseInt(vars["id"], 0, 64) - if checkError(err, w, "Invalid Int") { - return - } + id, _ := strconv.ParseInt(vars["id"], 0, 64) switch { case r.Method == "GET": c := models.Campaign{} - err := db.Conn.SelectOne(&c, "SELECT campaigns.id, name, created_date, completed_date, status, template FROM campaigns, users WHERE campaigns.uid=users.id AND campaigns.id =? AND users.api_key=?", id, ctx.Get(r, "api_key")) + c, err := db.GetCampaign(id, ctx.Get(r, "api_key")) if checkError(err, w, "No campaign found") { return } diff --git a/controllers/route.go b/controllers/route.go index d1c5cb60..629cb39b 100644 --- a/controllers/route.go +++ b/controllers/route.go @@ -173,8 +173,8 @@ func Login(w http.ResponseWriter, r *http.Request) { case r.Method == "POST": //Attempt to login succ, err := auth.Login(r) - if checkError(err, w, "Error logging in") { - return + if err != nil { + fmt.Println(err) } //If we've logged in, save the session and redirect to the dashboard if succ { diff --git a/db/db.go b/db/db.go index 8dc39e6d..66acbd93 100644 --- a/db/db.go +++ b/db/db.go @@ -118,6 +118,13 @@ func GetCampaigns(key interface{}) ([]models.Campaign, error) { return cs, err } -func GetCampaign(id int64) { - +func GetCampaign(id int64, key interface{}) (models.Campaign, error) { + c := models.Campaign{} + err := Conn.SelectOne(&c, "SELECT campaigns.id, name, created_date, completed_date, status, template FROM campaigns, users WHERE campaigns.uid=users.id AND campaigns.id =? AND users.api_key=?", id, key) + return c, err +} + +func PutCampaign(c *models.Campaign) error { + _, err := Conn.Update(c) + return err } diff --git a/static/css/main.css b/static/css/main.css index d10a3566..60fc9cbb 100644 --- a/static/css/main.css +++ b/static/css/main.css @@ -82,3 +82,7 @@ p { font-size:1.2em; } + + .form-label { + padding-top:7px; + } \ No newline at end of file diff --git a/templates/settings.html b/templates/settings.html index 23497bb8..e72f8124 100644 --- a/templates/settings.html +++ b/templates/settings.html @@ -23,22 +23,9 @@ {{%template "flashes" .Flashes%}}

User Settings

-
-

Username: -

-
+
- -
-
-
-
-
-

API Key: -

-
-
- +
@@ -46,6 +33,29 @@

+
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+
diff --git a/templates/users.html b/templates/users.html index f1c1a6c2..f9b1af11 100644 --- a/templates/users.html +++ b/templates/users.html @@ -36,7 +36,9 @@ {{group.name}} - {{group.targets}} + + {{target.email}}{{$last ? '' : ', '}} + {{group.modified_date | date:'medium'}}