diff options
-rw-r--r-- | system/admin/admin.go | 116 | ||||
-rw-r--r-- | system/admin/handlers.go | 26 | ||||
-rw-r--r-- | system/admin/server.go | 2 | ||||
-rw-r--r-- | system/db/user.go | 50 |
4 files changed, 194 insertions, 0 deletions
diff --git a/system/admin/admin.go b/system/admin/admin.go index b375eb6..e56453f 100644 --- a/system/admin/admin.go +++ b/system/admin/admin.go @@ -4,9 +4,12 @@ package admin import ( "bytes" + "encoding/json" "html/template" + "net/http" "github.com/bosssauce/ponzu/content" + "github.com/bosssauce/ponzu/system/admin/user" "github.com/bosssauce/ponzu/system/db" ) @@ -241,6 +244,119 @@ func Login() ([]byte, error) { return buf.Bytes(), nil } +// UsersList ... +func UsersList(req *http.Request) ([]byte, error) { + html := ` + <div class="card"> + <form class="row" enctype="multipart/form-data" action="/admin/configure/users/edit" method="post"> + <div>Edit your account:</div> + <div class="input-feild col s12"> + <label class="active">Email Address</label> + <input type="email" name="email" value="{{ .User.Email }}"/> + </div> + + <div>To approve changes, enter your password:</div> + <div class="input-feild col s12"> + <label class="active">Current Password</label> + <input type="password" name="password"/> + </div> + + <div class="input-feild col s12"> + <label class="active">New Password: (leave blank if no password change needed)</label> + <input type="email" name="new_password" type="password"/> + </div> + + <button class="btn waves-effect waves-light green" type="submit">Save</button> + </form> + + <form class="row" enctype="multipart/form-data" action="/admin/configure/users" method="post"> + <div>Add a new user:</div> + <div class="input-feild col s12"> + <label class="active">Email Address</label> + <input type="email" name="email" value=""/> + </div> + + <div class="input-feild col s12"> + <label class="active">Password</label> + <input type="password" name="password"/> + </div> + + <button class="btn waves-effect waves-light green" type="submit">Add User</button> + </form> + + <ul class="users row"> + {{ range .Users }} + <li class="col s12"> + {{ .Email }} + <form enctype="multipart/form-data" class="delete-user __ponzu right" action="/admin/configure/users/delete" method="post"> + <span>Delete</span> + <input type="hidden" name="email" value="{{ .Email }}"/> + <input type="hidden" name="id" value="{{ .ID }}"/> + </form> + <li> + {{ end }} + </ul> + </div> + ` + script := ` + <script> + $(function() { + var del = $('.delete-user.__ponzu span'); + del.on('click', function(e) { + if (confirm("[Ponzu] Please confirm:\n\nAre you sure you want to delete this user?\nThis cannot be undone.")) { + $(e.target).parent().submit(); + } + }); + }); + </script> + ` + var usr user.User + var usrs []user.User + // get current user out to pass as data to execute template + j, err := db.CurrentUser(req) + if err != nil { + return nil, err + } + err = json.Unmarshal(j, &usr) + if err != nil { + return nil, err + } + + // get all users to list + jj, err := db.UserAll() + if err != nil { + return nil, err + } + for i := range jj { + var u user.User + err = json.Unmarshal(jj[i], &u) + if err != nil { + return nil, err + } + usrs = append(usrs, u) + } + + // make buffer to execute html into then pass buffer's bytes to Admin + buf := &bytes.Buffer{} + tmpl := template.Must(template.New("users").Parse(html + script)) + data := map[string]interface{}{ + "User": usr, + "Users": usrs, + } + + err = tmpl.Execute(buf, data) + if err != nil { + return nil, err + } + + view, err := Admin(buf.Bytes()) + if err != nil { + return nil, err + } + + return view, nil +} + var err400HTML = ` <div class="error-page e400 col s6"> <div class="card"> diff --git a/system/admin/handlers.go b/system/admin/handlers.go index 497dec6..045d7b3 100644 --- a/system/admin/handlers.go +++ b/system/admin/handlers.go @@ -182,6 +182,32 @@ func configUsersHandler(res http.ResponseWriter, req *http.Request) { } } +func configUsersEditHandler(res http.ResponseWriter, req *http.Request) { + switch req.Method { + case http.MethodGet: + // list all users and delete buttons + + case http.MethodPost: + // create new user + + default: + res.WriteHeader(http.StatusMethodNotAllowed) + } +} + +func configUsersDeleteHandler(res http.ResponseWriter, req *http.Request) { + switch req.Method { + case http.MethodGet: + // list all users and delete buttons + + case http.MethodPost: + // create new user + + default: + res.WriteHeader(http.StatusMethodNotAllowed) + } +} + func loginHandler(res http.ResponseWriter, req *http.Request) { if !db.SystemInitComplete() { redir := req.URL.Scheme + req.URL.Host + "/admin/init" diff --git a/system/admin/server.go b/system/admin/server.go index b3b128d..c22c278 100644 --- a/system/admin/server.go +++ b/system/admin/server.go @@ -20,6 +20,8 @@ func Run() { http.HandleFunc("/admin/configure", user.Auth(configHandler)) http.HandleFunc("/admin/configure/users", user.Auth(configUsersHandler)) + http.HandleFunc("/admin/configure/users/edit", user.Auth(configUsersEditHandler)) + http.HandleFunc("/admin/configure/users/delete", user.Auth(configUsersDeleteHandler)) http.HandleFunc("/admin/posts", user.Auth(postsHandler)) http.HandleFunc("/admin/posts/search", user.Auth(searchHandler)) diff --git a/system/db/user.go b/system/db/user.go index a3a0be3..3b09dbe 100644 --- a/system/db/user.go +++ b/system/db/user.go @@ -4,10 +4,13 @@ import ( "bytes" "encoding/json" "errors" + "fmt" + "net/http" "github.com/bosssauce/ponzu/system/admin/user" "github.com/boltdb/bolt" + "github.com/nilslice/jwt" ) // ErrUserExists is used for the db to report to admin user of existing user @@ -72,3 +75,50 @@ func User(email string) ([]byte, error) { return val.Bytes(), nil } + +// UserAll returns all users from the db +func UserAll() ([][]byte, error) { + var users [][]byte + err := store.View(func(tx *bolt.Tx) error { + b := tx.Bucket([]byte("_users")) + err := b.ForEach(func(k, v []byte) error { + users = append(users, v) + return nil + }) + if err != nil { + return err + } + + return nil + }) + if err != nil { + return nil, err + } + + return users, nil +} + +// CurrentUser extracts the user from the request data and returns the current user from the db +func CurrentUser(req *http.Request) ([]byte, error) { + if !user.IsValid(req) { + return nil, fmt.Errorf("Error. Invalid User.") + } + + token, err := req.Cookie("_token") + if err != nil { + return nil, err + } + + claims := jwt.GetClaims(token.Value) + email, ok := claims["user"] + if !ok { + return nil, fmt.Errorf("Error. No user data found in request token.") + } + + usr, err := User(email.(string)) + if err != nil { + return nil, err + } + + return usr, nil +} |