summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd/ponzu/main.go5
-rw-r--r--system/admin/admin.go126
-rw-r--r--system/admin/handlers.go297
-rw-r--r--system/admin/server.go2
-rw-r--r--system/admin/static/dashboard/css/admin.css12
-rw-r--r--system/db/content.go2
-rw-r--r--system/db/user.go114
-rw-r--r--system/tls/enable.go5
8 files changed, 524 insertions, 39 deletions
diff --git a/cmd/ponzu/main.go b/cmd/ponzu/main.go
index 434de67..48aef9e 100644
--- a/cmd/ponzu/main.go
+++ b/cmd/ponzu/main.go
@@ -186,10 +186,7 @@ func main() {
}
if https {
- // fmt.Println("TLS through Let's Encrypt is not implemented yet.")
- // fmt.Println("Please run 'ponzu serve' without the --https flag for now.")
- // os.Exit(1)
-
+ fmt.Println("Enabling HTTPS...")
tls.Enable()
}
diff --git a/system/admin/admin.go b/system/admin/admin.go
index b375eb6..824edc8 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,129 @@ func Login() ([]byte, error) {
return buf.Bytes(), nil
}
+// UsersList ...
+func UsersList(req *http.Request) ([]byte, error) {
+ html := `
+ <div class="card user-management">
+ <div class="card-title">Edit your account:</div>
+ <form class="row" enctype="multipart/form-data" action="/admin/configure/users/edit" method="post">
+ <div class="input-feild col s9">
+ <label class="active">Email Address</label>
+ <input type="email" name="email" value="{{ .User.Email }}"/>
+ </div>
+
+ <div class="input-feild col s9">
+ <div>To approve changes, enter your password:</div>
+
+ <label class="active">Current Password</label>
+ <input type="password" name="password"/>
+ </div>
+
+ <div class="input-feild col s9">
+ <label class="active">New Password: (leave blank if no password change needed)</label>
+ <input name="new_password" type="password"/>
+ </div>
+
+ <div class="input-feild col s9">
+ <button class="btn waves-effect waves-light green right" type="submit">Save</button>
+ </div>
+ </form>
+
+ <div class="card-title">Add a new user:</div>
+ <form class="row" enctype="multipart/form-data" action="/admin/configure/users" method="post">
+ <div class="input-feild col s9">
+ <label class="active">Email Address</label>
+ <input type="email" name="email" value=""/>
+ </div>
+
+ <div class="input-feild col s9">
+ <label class="active">Password</label>
+ <input type="password" name="password"/>
+ </div>
+
+ <div class="input-feild col s9">
+ <button class="btn waves-effect waves-light green right" type="submit">Add User</button>
+ </div>
+ </form>
+
+ <div class="card-title">Remove Admin Users</div>
+ <ul class="users row">
+ {{ range .Users }}
+ <li class="col s9">
+ {{ .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>
+ `
+ // get current user out to pass as data to execute template
+ j, err := db.CurrentUser(req)
+ if err != nil {
+ return nil, err
+ }
+
+ var usr user.User
+ 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
+ }
+
+ var usrs []user.User
+ for i := range jj {
+ var u user.User
+ err = json.Unmarshal(jj[i], &u)
+ if err != nil {
+ return nil, err
+ }
+ if u.Email != usr.Email {
+ 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..d508ef2 100644
--- a/system/admin/handlers.go
+++ b/system/admin/handlers.go
@@ -23,7 +23,7 @@ import (
func adminHandler(res http.ResponseWriter, req *http.Request) {
view, err := Admin(nil)
if err != nil {
- fmt.Println(err)
+ log.Println(err)
res.WriteHeader(http.StatusInternalServerError)
return
}
@@ -42,7 +42,7 @@ func initHandler(res http.ResponseWriter, req *http.Request) {
case http.MethodGet:
view, err := Init()
if err != nil {
- fmt.Println(err)
+ log.Println(err)
res.WriteHeader(http.StatusInternalServerError)
return
}
@@ -52,7 +52,7 @@ func initHandler(res http.ResponseWriter, req *http.Request) {
case http.MethodPost:
err := req.ParseForm()
if err != nil {
- fmt.Println(err)
+ log.Println(err)
res.WriteHeader(http.StatusInternalServerError)
return
}
@@ -72,7 +72,7 @@ func initHandler(res http.ResponseWriter, req *http.Request) {
_, err = db.SetUser(usr)
if err != nil {
- fmt.Println(err)
+ log.Println(err)
res.WriteHeader(http.StatusInternalServerError)
return
}
@@ -81,7 +81,7 @@ func initHandler(res http.ResponseWriter, req *http.Request) {
req.Form.Set("admin_email", email)
err = db.SetConfig(req.Form)
if err != nil {
- fmt.Println(err)
+ log.Println(err)
res.WriteHeader(http.StatusInternalServerError)
return
}
@@ -100,6 +100,7 @@ func initHandler(res http.ResponseWriter, req *http.Request) {
Name: "_token",
Value: token,
Expires: week,
+ Path: "/",
})
redir := strings.TrimSuffix(req.URL.String(), "/init")
@@ -115,7 +116,7 @@ func configHandler(res http.ResponseWriter, req *http.Request) {
case http.MethodGet:
data, err := db.ConfigAll()
if err != nil {
- fmt.Println(err)
+ log.Println(err)
res.WriteHeader(http.StatusInternalServerError)
return
}
@@ -124,21 +125,21 @@ func configHandler(res http.ResponseWriter, req *http.Request) {
err = json.Unmarshal(data, c)
if err != nil {
- fmt.Println(err)
+ log.Println(err)
res.WriteHeader(http.StatusInternalServerError)
return
}
cfg, err := c.MarshalEditor()
if err != nil {
- fmt.Println(err)
+ log.Println(err)
res.WriteHeader(http.StatusInternalServerError)
return
}
adminView, err := Admin(cfg)
if err != nil {
- fmt.Println(err)
+ log.Println(err)
res.WriteHeader(http.StatusInternalServerError)
return
}
@@ -149,14 +150,14 @@ func configHandler(res http.ResponseWriter, req *http.Request) {
case http.MethodPost:
err := req.ParseForm()
if err != nil {
- fmt.Println(err)
+ log.Println(err)
res.WriteHeader(http.StatusInternalServerError)
return
}
err = db.SetConfig(req.Form)
if err != nil {
- fmt.Println(err)
+ log.Println(err)
res.WriteHeader(http.StatusInternalServerError)
return
}
@@ -172,10 +173,246 @@ func configHandler(res http.ResponseWriter, req *http.Request) {
func configUsersHandler(res http.ResponseWriter, req *http.Request) {
switch req.Method {
case http.MethodGet:
- // list all users and delete buttons
+ view, err := UsersList(req)
+ if err != nil {
+ log.Println(err)
+ res.WriteHeader(http.StatusInternalServerError)
+ errView, err := Error500()
+ if err != nil {
+ return
+ }
+
+ res.Write(errView)
+ return
+ }
+
+ res.Write(view)
case http.MethodPost:
// create new user
+ err := req.ParseMultipartForm(1024 * 1024 * 4) // maxMemory 4MB
+ if err != nil {
+ log.Println(err)
+ res.WriteHeader(http.StatusInternalServerError)
+ errView, err := Error500()
+ if err != nil {
+ return
+ }
+
+ res.Write(errView)
+ return
+ }
+
+ email := strings.ToLower(req.FormValue("email"))
+ password := req.PostFormValue("password")
+
+ if email == "" || password == "" {
+ res.WriteHeader(http.StatusInternalServerError)
+ errView, err := Error500()
+ if err != nil {
+ return
+ }
+
+ res.Write(errView)
+ return
+ }
+
+ usr := user.NewUser(email, password)
+
+ _, err = db.SetUser(usr)
+ if err != nil {
+ log.Println(err)
+ res.WriteHeader(http.StatusInternalServerError)
+ errView, err := Error500()
+ if err != nil {
+ return
+ }
+
+ res.Write(errView)
+ return
+ }
+
+ http.Redirect(res, req, req.URL.String(), http.StatusFound)
+
+ default:
+ res.WriteHeader(http.StatusMethodNotAllowed)
+ }
+}
+
+func configUsersEditHandler(res http.ResponseWriter, req *http.Request) {
+ switch req.Method {
+ case http.MethodPost:
+ err := req.ParseMultipartForm(1024 * 1024 * 4) // maxMemory 4MB
+
+ // check if user to be edited is current user
+ j, err := db.CurrentUser(req)
+ if err != nil {
+ log.Println(err)
+ res.WriteHeader(http.StatusInternalServerError)
+ errView, err := Error500()
+ if err != nil {
+ return
+ }
+
+ res.Write(errView)
+ return
+ }
+
+ usr := &user.User{}
+ err = json.Unmarshal(j, usr)
+ if err != nil {
+ log.Println(err)
+ res.WriteHeader(http.StatusInternalServerError)
+ errView, err := Error500()
+ if err != nil {
+ return
+ }
+
+ res.Write(errView)
+ return
+ }
+
+ // check if password matches
+ password := req.PostFormValue("password")
+
+ if !user.IsUser(usr, password) {
+ log.Println("Unexpected user/password combination for", usr.Email)
+ res.WriteHeader(http.StatusBadRequest)
+ errView, err := Error405()
+ if err != nil {
+ return
+ }
+
+ res.Write(errView)
+ return
+ }
+
+ email := strings.ToLower(req.PostFormValue("email"))
+ newPassword := req.PostFormValue("new_password")
+ var updatedUser *user.User
+ if newPassword != "" {
+ updatedUser = user.NewUser(email, newPassword)
+ } else {
+ updatedUser = user.NewUser(email, password)
+ }
+
+ // set the ID to the same ID as current user
+ updatedUser.ID = usr.ID
+
+ // set user in db
+ err = db.UpdateUser(usr, updatedUser)
+ if err != nil {
+ log.Println(err)
+ res.WriteHeader(http.StatusInternalServerError)
+ errView, err := Error500()
+ if err != nil {
+ return
+ }
+
+ res.Write(errView)
+ return
+ }
+
+ // create new token
+ week := time.Now().Add(time.Hour * 24 * 7)
+ claims := map[string]interface{}{
+ "exp": week,
+ "user": updatedUser.Email,
+ }
+ token, err := jwt.New(claims)
+ if err != nil {
+ log.Println(err)
+ res.WriteHeader(http.StatusInternalServerError)
+ errView, err := Error500()
+ if err != nil {
+ return
+ }
+
+ res.Write(errView)
+ return
+ }
+
+ // add token to cookie +1 week expiration
+ cookie := &http.Cookie{
+ Name: "_token",
+ Value: token,
+ Expires: week,
+ Path: "/",
+ }
+ http.SetCookie(res, cookie)
+
+ // add new token cookie to the request
+ req.AddCookie(cookie)
+
+ http.Redirect(res, req, strings.TrimSuffix(req.URL.String(), "/edit"), http.StatusFound)
+
+ default:
+ res.WriteHeader(http.StatusMethodNotAllowed)
+ }
+}
+
+func configUsersDeleteHandler(res http.ResponseWriter, req *http.Request) {
+ switch req.Method {
+ case http.MethodPost:
+ err := req.ParseMultipartForm(1024 * 1024 * 4) // maxMemory 4MB
+
+ // do not allow current user to delete themselves
+ j, err := db.CurrentUser(req)
+ if err != nil {
+ log.Println(err)
+ res.WriteHeader(http.StatusInternalServerError)
+ errView, err := Error500()
+ if err != nil {
+ return
+ }
+
+ res.Write(errView)
+ return
+ }
+
+ usr := &user.User{}
+ err = json.Unmarshal(j, &usr)
+ if err != nil {
+ log.Println(err)
+ res.WriteHeader(http.StatusInternalServerError)
+ errView, err := Error500()
+ if err != nil {
+ return
+ }
+
+ res.Write(errView)
+ return
+ }
+
+ email := strings.ToLower(req.PostFormValue("email"))
+
+ if usr.Email == email {
+ log.Println(err)
+ res.WriteHeader(http.StatusBadRequest)
+ errView, err := Error405()
+ if err != nil {
+ return
+ }
+
+ res.Write(errView)
+ return
+ }
+
+ // delete existing user
+ err = db.DeleteUser(email)
+ if err != nil {
+ log.Println(err)
+ res.WriteHeader(http.StatusInternalServerError)
+ errView, err := Error500()
+ if err != nil {
+ return
+ }
+
+ res.Write(errView)
+ return
+ }
+
+ http.Redirect(res, req, strings.TrimSuffix(req.URL.String(), "/delete"), http.StatusFound)
default:
res.WriteHeader(http.StatusMethodNotAllowed)
@@ -198,7 +435,7 @@ func loginHandler(res http.ResponseWriter, req *http.Request) {
view, err := Login()
if err != nil {
- fmt.Println(err)
+ log.Println(err)
res.WriteHeader(http.StatusInternalServerError)
return
}
@@ -214,7 +451,7 @@ func loginHandler(res http.ResponseWriter, req *http.Request) {
err := req.ParseForm()
if err != nil {
- fmt.Println(err)
+ log.Println(err)
http.Redirect(res, req, req.URL.String(), http.StatusFound)
return
}
@@ -222,7 +459,7 @@ func loginHandler(res http.ResponseWriter, req *http.Request) {
// check email & password
j, err := db.User(strings.ToLower(req.FormValue("email")))
if err != nil {
- fmt.Println(err)
+ log.Println(err)
http.Redirect(res, req, req.URL.String(), http.StatusFound)
return
}
@@ -235,7 +472,7 @@ func loginHandler(res http.ResponseWriter, req *http.Request) {
usr := &user.User{}
err = json.Unmarshal(j, usr)
if err != nil {
- fmt.Println(err)
+ log.Println(err)
http.Redirect(res, req, req.URL.String(), http.StatusFound)
return
}
@@ -252,7 +489,7 @@ func loginHandler(res http.ResponseWriter, req *http.Request) {
}
token, err := jwt.New(claims)
if err != nil {
- fmt.Println(err)
+ log.Println(err)
http.Redirect(res, req, req.URL.String(), http.StatusFound)
return
}
@@ -262,6 +499,7 @@ func loginHandler(res http.ResponseWriter, req *http.Request) {
Name: "_token",
Value: token,
Expires: week,
+ Path: "/",
})
http.Redirect(res, req, strings.TrimSuffix(req.URL.String(), "/login"), http.StatusFound)
@@ -273,6 +511,7 @@ func logoutHandler(res http.ResponseWriter, req *http.Request) {
Name: "_token",
Expires: time.Unix(0, 0),
Value: "",
+ Path: "/",
})
http.Redirect(res, req, req.URL.Scheme+req.URL.Host+"/admin/login", http.StatusFound)
@@ -421,7 +660,7 @@ func postsHandler(res http.ResponseWriter, req *http.Request) {
adminView, err := Admin([]byte(html))
if err != nil {
- fmt.Println(err)
+ log.Println(err)
res.WriteHeader(http.StatusInternalServerError)
return
}
@@ -480,7 +719,7 @@ func editHandler(res http.ResponseWriter, req *http.Request) {
if i != "" {
data, err := db.Content(t + ":" + i)
if err != nil {
- fmt.Println(err)
+ log.Println(err)
res.WriteHeader(http.StatusInternalServerError)
errView, err := Error500()
if err != nil {
@@ -504,7 +743,7 @@ func editHandler(res http.ResponseWriter, req *http.Request) {
err = json.Unmarshal(data, post)
if err != nil {
- fmt.Println(err)
+ log.Println(err)
res.WriteHeader(http.StatusInternalServerError)
errView, err := Error500()
if err != nil {
@@ -520,7 +759,7 @@ func editHandler(res http.ResponseWriter, req *http.Request) {
m, err := manager.Manage(post.(editor.Editable), t)
if err != nil {
- fmt.Println(err)
+ log.Println(err)
res.WriteHeader(http.StatusInternalServerError)
errView, err := Error500()
if err != nil {
@@ -533,7 +772,7 @@ func editHandler(res http.ResponseWriter, req *http.Request) {
adminView, err := Admin(m)
if err != nil {
- fmt.Println(err)
+ log.Println(err)
res.WriteHeader(http.StatusInternalServerError)
return
}
@@ -544,7 +783,7 @@ func editHandler(res http.ResponseWriter, req *http.Request) {
case http.MethodPost:
err := req.ParseMultipartForm(1024 * 1024 * 4) // maxMemory 4MB
if err != nil {
- fmt.Println(err)
+ log.Println(err)
res.WriteHeader(http.StatusBadRequest)
errView, err := Error405()
if err != nil {
@@ -572,7 +811,7 @@ func editHandler(res http.ResponseWriter, req *http.Request) {
urlPaths, err := storeFileUploads(req)
if err != nil {
- fmt.Println(err)
+ log.Println(err)
res.WriteHeader(http.StatusInternalServerError)
errView, err := Error500()
if err != nil {
@@ -610,7 +849,7 @@ func editHandler(res http.ResponseWriter, req *http.Request) {
id, err := db.SetContent(t+":"+cid, req.PostForm)
if err != nil {
- fmt.Println(err)
+ log.Println(err)
res.WriteHeader(http.StatusInternalServerError)
errView, err := Error500()
if err != nil {
@@ -641,7 +880,7 @@ func deleteHandler(res http.ResponseWriter, req *http.Request) {
err := req.ParseMultipartForm(1024 * 1024 * 4) // maxMemory 4MB
if err != nil {
- fmt.Println("req.ParseMPF")
+ log.Println(err)
res.WriteHeader(http.StatusInternalServerError)
return
}
@@ -656,7 +895,7 @@ func deleteHandler(res http.ResponseWriter, req *http.Request) {
err = db.DeleteContent(t + ":" + id)
if err != nil {
- fmt.Println("db.DeleteContent")
+ log.Println(err)
res.WriteHeader(http.StatusInternalServerError)
return
}
@@ -674,7 +913,7 @@ func editUploadHandler(res http.ResponseWriter, req *http.Request) {
urlPaths, err := storeFileUploads(req)
if err != nil {
- fmt.Println("Couldn't store file uploads.", err)
+ log.Println("Couldn't store file uploads.", err)
res.WriteHeader(http.StatusInternalServerError)
return
}
@@ -739,7 +978,7 @@ func searchHandler(res http.ResponseWriter, req *http.Request) {
adminView, err := Admin([]byte(html))
if err != nil {
- fmt.Println(err)
+ log.Println(err)
res.WriteHeader(http.StatusInternalServerError)
return
}
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/admin/static/dashboard/css/admin.css b/system/admin/static/dashboard/css/admin.css
index e23658e..7acffab 100644
--- a/system/admin/static/dashboard/css/admin.css
+++ b/system/admin/static/dashboard/css/admin.css
@@ -44,7 +44,7 @@
padding: 0px !important;
}
-ul.posts li {
+ul.posts li, ul.users li {
display: block;
margin: 0 0 20px 0;
padding: 0 0 20px 0 !important;
@@ -164,15 +164,15 @@ span.post-detail {
font-style: italic;
}
-.quick-delete-post {
+.quick-delete-post, .delete-user {
display: none;
}
-li:hover .quick-delete-post {
+li:hover .quick-delete-post, li:hover .delete-user {
display: inline-block;
}
-.quick-delete-post span {
+.quick-delete-post span, .delete-user span {
cursor: pointer;
color: #F44336;
text-transform: uppercase;
@@ -181,6 +181,10 @@ li:hover .quick-delete-post {
margin-right: 20px;
}
+.user-management {
+ padding: 20px;
+}
+
/* OVERRIDE Bootstrap + Materialize conflicts */
.iso-texteditor.input-field label {
diff --git a/system/db/content.go b/system/db/content.go
index 2d6e8ea..9ab1f89 100644
--- a/system/db/content.go
+++ b/system/db/content.go
@@ -178,7 +178,7 @@ func Content(target string) ([]byte, error) {
b := tx.Bucket([]byte(ns))
_, err := val.Write(b.Get([]byte(id)))
if err != nil {
- fmt.Println(err)
+ log.Println(err)
return err
}
diff --git a/system/db/user.go b/system/db/user.go
index a3a0be3..d2dc3a9 100644
--- a/system/db/user.go
+++ b/system/db/user.go
@@ -4,15 +4,21 @@ 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
var ErrUserExists = errors.New("Error. User exists.")
+// ErrNoUserExists is used for the db to report to admin user of non-existing user
+var ErrNoUserExists = errors.New("Error. No user exists.")
+
// SetUser sets key:value pairs in the db for user settings
func SetUser(usr *user.User) (int, error) {
err := store.Update(func(tx *bolt.Tx) error {
@@ -38,7 +44,7 @@ func SetUser(usr *user.User) (int, error) {
return err
}
- err = users.Put([]byte(usr.Email), j)
+ err = users.Put(email, j)
if err != nil {
return err
}
@@ -52,6 +58,65 @@ func SetUser(usr *user.User) (int, error) {
return usr.ID, nil
}
+// UpdateUser sets key:value pairs in the db for existing user settings
+func UpdateUser(usr, updatedUsr *user.User) error {
+ err := store.Update(func(tx *bolt.Tx) error {
+ users := tx.Bucket([]byte("_users"))
+
+ // check if user is found by email, fail if nil
+ exists := users.Get([]byte(usr.Email))
+ if exists == nil {
+ return ErrNoUserExists
+ }
+
+ // marshal User to json and put into bucket
+ j, err := json.Marshal(updatedUsr)
+ if err != nil {
+ return err
+ }
+
+ err = users.Put([]byte(updatedUsr.Email), j)
+ if err != nil {
+ return err
+ }
+
+ // if email address was changed, delete the old record of former
+ // user with original email address
+ if usr.Email != updatedUsr.Email {
+ err = users.Delete([]byte(usr.Email))
+ if err != nil {
+ return err
+ }
+
+ }
+
+ return nil
+ })
+ if err != nil {
+ return err
+ }
+
+ return nil
+}
+
+// DeleteUser deletes a user from the db by email
+func DeleteUser(email string) error {
+ err := store.Update(func(tx *bolt.Tx) error {
+ b := tx.Bucket([]byte("_users"))
+ err := b.Delete([]byte(email))
+ if err != nil {
+ return err
+ }
+
+ return nil
+ })
+ if err != nil {
+ return err
+ }
+
+ return nil
+}
+
// User gets the user by email from the db
func User(email string) ([]byte, error) {
val := &bytes.Buffer{}
@@ -72,3 +137,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
+}
diff --git a/system/tls/enable.go b/system/tls/enable.go
index 4be0aa8..c53fac6 100644
--- a/system/tls/enable.go
+++ b/system/tls/enable.go
@@ -2,6 +2,7 @@ package tls
import (
"crypto/tls"
+ "fmt"
"log"
"net/http"
"os"
@@ -41,6 +42,8 @@ func setup() {
if host == nil {
log.Fatalln("No 'domain' field set in Configuration. Please add a domain before attempting to make certificates.")
}
+ fmt.Println("Using", host, "as host/domain for certificate...")
+ fmt.Println("NOTE: if the host/domain is not configured properly or is unreachable, HTTPS set-up will fail.")
email, err := db.Config("admin_email")
if err != nil {
@@ -50,6 +53,7 @@ func setup() {
if email == nil {
log.Fatalln("No 'admin_email' field set in Configuration. Please add an admin email before attempting to make certificates.")
}
+ fmt.Println("Using", email, "as contact email for certificate...")
m = autocert.Manager{
Prompt: autocert.AcceptTOS,
@@ -71,4 +75,5 @@ func Enable() {
}
go log.Fatalln(server.ListenAndServeTLS("", ""))
+ fmt.Println("Server listening for HTTPS requests...")
}