aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--login.go1
-rw-r--r--main.go106
-rw-r--r--readme.md13
3 files changed, 98 insertions, 22 deletions
diff --git a/login.go b/login.go
deleted file mode 100644
index 06ab7d0..0000000
--- a/login.go
+++ /dev/null
@@ -1 +0,0 @@
-package main
diff --git a/main.go b/main.go
index c0deb6c..df0711a 100644
--- a/main.go
+++ b/main.go
@@ -128,9 +128,44 @@ func hashPasswd(pass string) (string, error) {
return string(b), err
}
+func writeSampleConf(fn string) (*os.File, error) {
+ c := &Conf{
+ Users: map[string]*User{
+ "admin": &User{
+ Password: "admin",
+ },
+ },
+ }
+
+ fh, err := os.OpenFile(fn, os.O_CREATE|os.O_RDWR, 0600)
+ if err != nil {
+ return nil, err
+ }
+
+ enc := yaml.NewEncoder(fh)
+ enc.SetIndent(2)
+
+ err = enc.Encode(c)
+ if err != nil {
+ return nil, err
+ }
+
+ err = fh.Close()
+ if err != nil {
+ return nil, err
+ }
+
+ return os.Open(fn)
+}
+
func readConf(fn string) (*Conf, error) {
fh, err := os.Open(fn)
- if err != nil {
+ if errors.Is(err, os.ErrNotExist) {
+ fh, err = writeSampleConf(fn)
+ if err != nil {
+ return nil, err
+ }
+ } else if err != nil {
return nil, err
}
@@ -279,12 +314,13 @@ func main() {
r := mux.NewRouter()
- r.Handle("/new", requireJWT(pubKey, c.Users, newPasteJson()))
- r.HandleFunc("/view/{id}", loadPaste)
- r.HandleFunc("/view/json/{id}", loadPasteJson)
+ r.Handle("/new", handlerRequireJWT(pubKey, c.Users, handlerNewPasteJSON()))
+ r.HandleFunc("/view/{id}", handlerFuncLoadPaste)
+ r.HandleFunc("/view/json/{id}", handlerFuncLoadPasteJson)
+ r.Handle("/list", handlerRequireJWT(pubKey, c.Users, handlerList()))
r.PathPrefix("/static").Handler(http.FileServer(http.FS(staticFS)))
- r.Handle("/login", handleLogin(key, c.Users))
- r.HandleFunc("/", index)
+ r.Handle("/login", handlerLogin(key, c.Users))
+ r.Handle("/", handlerIndex())
logger.Println("listening on: ", *listen)
@@ -323,7 +359,7 @@ func jsonErr(logMsg string, msg string,
}
}
-func handleLogin(key ed25519.PrivateKey, users map[string]*User) http.Handler {
+func handlerLogin(key ed25519.PrivateKey, users map[string]*User) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
reqU := &User{}
dec := json.NewDecoder(r.Body)
@@ -372,13 +408,13 @@ func handleLogin(key ed25519.PrivateKey, users map[string]*User) http.Handler {
w.Header().Add("Content-type", "application/json")
w.Header().Add("Authorization", "Bearer "+s)
enc := json.NewEncoder(w)
- enc.Encode(map[string]string{
+ _ = enc.Encode(map[string]string{
"token": s,
})
})
}
-func requireJWT(key ed25519.PublicKey, users map[string]*User,
+func handlerRequireJWT(key ed25519.PublicKey, users map[string]*User,
next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
@@ -428,7 +464,7 @@ func requireJWT(key ed25519.PublicKey, users map[string]*User,
})
}
-func newPasteJson() http.Handler {
+func handlerNewPasteJSON() http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
dec := json.NewDecoder(r.Body)
dec.DisallowUnknownFields()
@@ -465,7 +501,7 @@ func newPasteJson() http.Handler {
})
}
-func newPaste(w http.ResponseWriter, r *http.Request) {
+func handlerFuncNewPaste(w http.ResponseWriter, r *http.Request) {
err := r.ParseForm()
if err != nil {
logger.Println(err)
@@ -498,7 +534,7 @@ func newPaste(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, "/view/"+p.Id, http.StatusFound)
}
-func loadPasteJson(w http.ResponseWriter, r *http.Request) {
+func handlerFuncLoadPasteJson(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
id, ok := vars["id"]
@@ -517,12 +553,10 @@ func loadPasteJson(w http.ResponseWriter, r *http.Request) {
jsonErr(
fmt.Sprintf("Snip with id: %s not found", id),
"ID not found", w, http.StatusNotFound)
- return
} else {
jsonErr(
fmt.Sprintf("Snip with id faild loading: %s", err),
"Failed to load snippet", w, http.StatusInternalServerError)
- return
}
return
}
@@ -530,7 +564,7 @@ func loadPasteJson(w http.ResponseWriter, r *http.Request) {
jsonResp(w, http.StatusOK, p)
}
-func loadPaste(w http.ResponseWriter, r *http.Request) {
+func handlerFuncLoadPaste(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
id, ok := vars["id"]
@@ -576,10 +610,40 @@ func loadPaste(w http.ResponseWriter, r *http.Request) {
}
}
-func index(w http.ResponseWriter, r *http.Request) {
- err := tpls["index"].Execute(w, nil)
- if err != nil {
- logger.Println(err)
- http.Error(w, "Internal server error", http.StatusInternalServerError)
- }
+func handlerList() http.Handler {
+ return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ lst, err := os.ReadDir("p")
+ if err != nil {
+ jsonErr(
+ fmt.Sprintf("Failed reading directory: %s", err),
+ "Internal server error",
+ w, http.StatusInternalServerError)
+ return
+ }
+
+ out := struct {
+ Pastes []string
+ }{
+ Pastes: []string{},
+ }
+
+ for _, e := range lst {
+ if e.IsDir() {
+ continue
+ }
+ out.Pastes = append(out.Pastes, e.Name())
+ }
+
+ jsonResp(w, http.StatusOK, out)
+ })
+}
+
+func handlerIndex() http.Handler {
+ return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ err := tpls["index"].Execute(w, nil)
+ if err != nil {
+ logger.Println(err)
+ http.Error(w, "Internal server error", http.StatusInternalServerError)
+ }
+ })
}
diff --git a/readme.md b/readme.md
index 610ff6d..230e004 100644
--- a/readme.md
+++ b/readme.md
@@ -9,3 +9,16 @@ when you fire it up.
The client require a configuration file in your home folder and outputs
the URL to the paste if successful.
+
+## Ideas for future versions
+
+ * Index for all the pastes
+ * Including tags on each of the pastes
+ * Automatic syntax highlighting
+ * React UI
+ * Swagger Documentation -- embedded into the application as well ( swaggo? )
+ * Deleting pastes
+ * Updating pastes
+ * read templates from disk or embed
+ * write out sample/default configuration if a new directory is being used
+ * option to be backed by S3