diff --git a/.travis.yml b/.travis.yml index c6b9cdfc..ae717ce6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,7 +18,7 @@ services: env: global: - - VERSION=0.29.7 + - VERSION=0.29.8 - DB_HOST=localhost - DB_USER=travis - DB_PASS= @@ -65,8 +65,9 @@ before_script: - go get script: - - if [[ "$TRAVIS_BRANCH" == "master" ]]; then /bin/bash -c .travis/compile.sh; fi - - go test -v -covermode=count -coverprofile=coverage.out && $GOPATH/bin/goveralls -coverprofile=coverage.out -service=travis -repotoken $COVERALLS + - /bin/bash -c .travis/compile.sh + - go test -v -covermode=count -coverprofile=coverage.out + - if [[ "$TRAVIS_BRANCH" == "master" ]]; then $GOPATH/bin/goveralls -coverprofile=coverage.out -service=travis -repotoken $COVERALLS; fi after_success: - if [[ "$TRAVIS_BRANCH" == "master" ]]; then travis_wait 30 docker pull karalabe/xgo-latest; fi diff --git a/Dockerfile b/Dockerfile index 17a5dc5e..316d0aca 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ FROM alpine:latest -ENV VERSION=v0.29.7 +ENV VERSION=v0.29.8 RUN apk --no-cache add libstdc++ ca-certificates RUN wget -q https://github.com/hunterlong/statup/releases/download/$VERSION/statup-linux-alpine.tar.gz && \ diff --git a/core/users.go b/core/users.go index 9ab74707..a341aa9b 100644 --- a/core/users.go +++ b/core/users.go @@ -32,6 +32,13 @@ func (u *User) Delete() error { return user.Delete() } +func (u *User) Update() error { + u.CreatedAt = time.Now() + col := DbSession.Collection("users") + user := col.Find("id", u.Id) + return user.Update(u) +} + func (u *User) Create() (int64, error) { u.CreatedAt = time.Now() u.Password = utils.HashPassword(u.Password) diff --git a/handlers/routes.go b/handlers/routes.go index 145e55ca..42476c54 100644 --- a/handlers/routes.go +++ b/handlers/routes.go @@ -29,9 +29,10 @@ func Router() *mux.Router { r.Handle("/service/{id}/delete_failures", http.HandlerFunc(ServicesDeleteFailuresHandler)).Methods("GET") r.Handle("/service/{id}/checkin", http.HandlerFunc(CheckinCreateUpdateHandler)).Methods("POST") r.Handle("/users", http.HandlerFunc(UsersHandler)).Methods("GET") - r.Handle("/user/{id}", http.HandlerFunc(UsersHandler)).Methods("GET") r.Handle("/users", http.HandlerFunc(CreateUserHandler)).Methods("POST") - r.Handle("/users/{id}/delete", http.HandlerFunc(UsersDeleteHandler)).Methods("GET") + r.Handle("/user/{id}", http.HandlerFunc(UsersEditHandler)).Methods("GET") + r.Handle("/user/{id}", http.HandlerFunc(UpdateUserHandler)).Methods("POST") + r.Handle("/user/{id}/delete", http.HandlerFunc(UsersDeleteHandler)).Methods("GET") r.Handle("/settings", http.HandlerFunc(PluginsHandler)).Methods("GET") r.Handle("/settings", http.HandlerFunc(SaveSettingsHandler)).Methods("POST") r.Handle("/settings/css", http.HandlerFunc(SaveSASSHandler)).Methods("POST") diff --git a/handlers/users.go b/handlers/users.go index 39d8d768..854d1bdf 100644 --- a/handlers/users.go +++ b/handlers/users.go @@ -1,6 +1,7 @@ package handlers import ( + "fmt" "github.com/gorilla/mux" "github.com/hunterlong/statup/core" "github.com/hunterlong/statup/types" @@ -18,13 +19,16 @@ func SessionUser(r *http.Request) *types.User { var user *types.User col := core.DbSession.Collection("users") res := col.Find("id", uuid) - res.One(&user) + err := res.One(&user) + if err != nil { + utils.Log(3, fmt.Sprintf("cannot fetch user %v", uuid)) + return nil + } return user } func UsersHandler(w http.ResponseWriter, r *http.Request) { - auth := IsAuthenticated(r) - if !auth { + if !IsAuthenticated(r) { http.Redirect(w, r, "/", http.StatusSeeOther) return } @@ -32,9 +36,41 @@ func UsersHandler(w http.ResponseWriter, r *http.Request) { ExecuteResponse(w, r, "users.html", users) } +func UsersEditHandler(w http.ResponseWriter, r *http.Request) { + if !IsAuthenticated(r) { + http.Redirect(w, r, "/", http.StatusSeeOther) + return + } + vars := mux.Vars(r) + id, _ := strconv.Atoi(vars["id"]) + user, _ := core.SelectUser(int64(id)) + ExecuteResponse(w, r, "user.html", user) +} + +func UpdateUserHandler(w http.ResponseWriter, r *http.Request) { + if !IsAuthenticated(r) { + http.Redirect(w, r, "/", http.StatusSeeOther) + return + } + r.ParseForm() + vars := mux.Vars(r) + id, _ := strconv.Atoi(vars["id"]) + user, _ := core.SelectUser(int64(id)) + + user.Username = r.PostForm.Get("username") + user.Email = r.PostForm.Get("email") + user.Admin = (r.PostForm.Get("admin") == "on") + password := r.PostForm.Get("password") + if password != "##########" { + user.Password = utils.HashPassword(password) + } + user.Update() + users, _ := core.SelectAllUsers() + ExecuteResponse(w, r, "users.html", users) +} + func CreateUserHandler(w http.ResponseWriter, r *http.Request) { - auth := IsAuthenticated(r) - if !auth { + if !IsAuthenticated(r) { http.Redirect(w, r, "/", http.StatusSeeOther) return } @@ -59,8 +95,7 @@ func CreateUserHandler(w http.ResponseWriter, r *http.Request) { } func UsersDeleteHandler(w http.ResponseWriter, r *http.Request) { - auth := IsAuthenticated(r) - if !auth { + if !IsAuthenticated(r) { http.Redirect(w, r, "/", http.StatusSeeOther) return } diff --git a/main_test.go b/main_test.go index cc0739b1..f93064e6 100644 --- a/main_test.go +++ b/main_test.go @@ -64,6 +64,9 @@ func TestRunAll(t *testing.T) { t.Run(dbt+" Create Users", func(t *testing.T) { RunUser_Create(t) }) + t.Run(dbt+" Update User", func(t *testing.T) { + RunUser_Update(t) + }) t.Run(dbt+" Create Non Unique Users", func(t *testing.T) { t.SkipNow() RunUser_NonUniqueCreate(t) @@ -134,6 +137,9 @@ func TestRunAll(t *testing.T) { t.Run(dbt+" HTTP /users", func(t *testing.T) { RunUsersHandler(t) }) + t.Run(dbt+" HTTP /user/1", func(t *testing.T) { + RunUserViewHandler(t) + }) t.Run(dbt+" HTTP /services", func(t *testing.T) { RunServicesHandler(t) }) @@ -264,6 +270,7 @@ func RunUser_Create(t *testing.T) { Username: "admin", Password: "admin", Email: "info@testuser.com", + Admin: true, } id, err := user.Create() assert.Nil(t, err) @@ -279,6 +286,17 @@ func RunUser_Create(t *testing.T) { assert.Equal(t, int64(2), id) } +func RunUser_Update(t *testing.T) { + user, err := core.SelectUser(1) + user.Email = "info@updatedemail.com" + assert.Nil(t, err) + err = user.Update() + assert.Nil(t, err) + updatedUser, err := core.SelectUser(1) + assert.Nil(t, err) + assert.Equal(t, "info@updatedemail.com", updatedUser.Email) +} + func RunUser_NonUniqueCreate(t *testing.T) { user := &core.User{ Username: "admin", @@ -481,6 +499,15 @@ func RunUsersHandler(t *testing.T) { assert.True(t, strings.Contains(rr.Body.String(), "footer")) } +func RunUserViewHandler(t *testing.T) { + req, err := http.NewRequest("GET", "/user/1", nil) + assert.Nil(t, err) + rr := httptest.NewRecorder() + route.ServeHTTP(rr, req) + assert.True(t, strings.Contains(rr.Body.String(), "
Username | -- |
---|---|
{{.Username}} | -
-
- Delete
-
- |
-