From ddb11f061928392ebafbc93e7532264b7adea71b Mon Sep 17 00:00:00 2001 From: ston1th Date: Sat, 27 Oct 2018 21:28:19 +0200 Subject: [PATCH] general improvements --- pkg/cmd/cmd.go | 63 +++++++++++---------- pkg/core/types.go | 1 + pkg/db/db.go | 9 +-- pkg/db/user.go | 4 ++ pkg/log/log.go | 9 +-- pkg/otp/otp.go | 10 +++- pkg/server/context.go | 16 ++++-- pkg/server/handler.go | 118 +++++++++++++++++++++++++-------------- pkg/server/helper.go | 47 ++++++++++++++++ pkg/server/routes.go | 14 ++--- pkg/server/server.go | 18 ++---- pkg/server/templates.go | 68 ++++++++++++++++------ templates.sh | 1 + templates/forbidden.html | 17 ++++++ templates/login.html | 2 +- templates/notFound.html | 4 +- templates/page.html | 2 +- templates/pageEdit.html | 3 +- templates/pageMD.html | 2 +- templates/pageNew.html | 2 +- templates/pageShare.html | 18 ++++-- templates/user.html | 10 +++- templates/userEdit.html | 3 +- templates/userNew.html | 2 +- templates/userTotp.html | 2 +- 25 files changed, 305 insertions(+), 140 deletions(-) create mode 100644 pkg/server/helper.go create mode 100644 templates/forbidden.html diff --git a/pkg/cmd/cmd.go b/pkg/cmd/cmd.go index b49885c..234b59c 100644 --- a/pkg/cmd/cmd.go +++ b/pkg/cmd/cmd.go @@ -28,27 +28,27 @@ const ( ) var ( - conf core.Config - dumpFile string - config string + config core.Config + dumpFile string + configFile string ) -func initServer(conf core.Config) (err error) { +func initServer(cfg core.Config) (err error) { if err = godrop.PledgePromises("stdio rpath wpath cpath inet fattr flock proc exec id unveil"); err != nil { return } dropCfg := godrop.Config{ - User: conf.User, - Group: conf.Group, - Foreground: conf.Foreground, + User: cfg.User, + Group: cfg.Group, + Foreground: cfg.Foreground, } err = godrop.Drop(dropCfg, func() (net.Listener, error) { - return net.Listen("tcp", conf.ListenAddr) + return net.Listen("tcp", cfg.ListenAddr) }) if err != nil { return } - if err = os.Chdir(conf.DataDir); err != nil { + if err = os.Chdir(cfg.DataDir); err != nil { return } @@ -61,14 +61,14 @@ func initServer(conf core.Config) (err error) { return } - log.InitLogger(conf.DataDir, conf.LogFile, conf.Debug) + log.InitLogger(cfg) - srv := server.NewHTTPServer(l, conf) + srv := server.NewHTTPServer(cfg, l) err = srv.Start() if err != nil { return } - log.Println("gowiki " + conf.Version + " started") + log.Println("gowiki " + cfg.Version + " started") sigs := make(chan os.Signal) signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM) sig := <-sigs @@ -86,14 +86,14 @@ func initServer(conf core.Config) (err error) { } func loadConfig() error { - if config == "" { + if configFile == "" { return nil } - file, err := os.Open(config) + file, err := os.Open(configFile) if err != nil { return err } - err = json.NewDecoder(file).Decode(&conf) + err = json.NewDecoder(file).Decode(&config) if err != nil { return err } @@ -114,8 +114,8 @@ func Run(version string) { if err := loadConfig(); err != nil { stdlog.Fatal("server: ", err) } - conf.Version = app.Version - if err := initServer(conf); err != nil { + config.Version = app.Version + if err := initServer(config); err != nil { stdlog.Fatal("server: ", err) } return nil @@ -139,7 +139,7 @@ func Run(version string) { stdlog.Fatal("dump: ", err) } } - DB, err := db.New(conf.DataDir) + DB, err := db.New(config) if err != nil { stdlog.Fatal("dump: ", err) } @@ -172,7 +172,7 @@ func Run(version string) { stdlog.Fatal("restore: ", err) } } - DB, err := db.New(conf.DataDir) + DB, err := db.New(config) if err != nil { stdlog.Fatal("restore: ", err) } @@ -197,45 +197,50 @@ func serverFlags() []cli.Flag { Name: "user, u", Value: defRunUser, Usage: "drop privileges to user", - Destination: &conf.User, + Destination: &config.User, }, cli.StringFlag{ Name: "group, g", Value: defRunGroup, Usage: "drop privileges to group", - Destination: &conf.Group, + Destination: &config.Group, }, cli.StringFlag{ Name: "listen, l", Value: defListen, Usage: "listening
:", - Destination: &conf.ListenAddr, + Destination: &config.ListenAddr, }, cli.StringFlag{ Name: "log", Value: defLogFile, Usage: "log file (use - for stdout, this only works in combination with -f)", - Destination: &conf.LogFile, + Destination: &config.LogFile, }, cli.StringFlag{ Name: "secret", Usage: "static hmac secret (at least 64 chars, used for JWT signing)", - Destination: &conf.Secret, + Destination: &config.Secret, + }, + cli.BoolTFlag{ + Name: "admin, a", + Usage: "use -a=false to disable the admin user", + Destination: &config.Admin, }, cli.BoolFlag{ Name: "foreground, f", Usage: "do not fork into the background", - Destination: &conf.Foreground, + Destination: &config.Foreground, }, cli.BoolFlag{ Name: "secure, s", Usage: "enable secure cookie", - Destination: &conf.SecureCookie, + Destination: &config.SecureCookie, }, cli.BoolFlag{ Name: "debug", Usage: "enable debugging", - Destination: &conf.Debug, + Destination: &config.Debug, }, } } @@ -256,13 +261,13 @@ func defaultFlags(f []cli.Flag) []cli.Flag { cli.StringFlag{ Name: "config, c", Usage: "config file", - Destination: &config, + Destination: &configFile, }, cli.StringFlag{ Name: "data, d", Value: defDataDir, Usage: "data directory", - Destination: &conf.DataDir, + Destination: &config.DataDir, }, }, f...) } diff --git a/pkg/core/types.go b/pkg/core/types.go index 1e811e1..a73b224 100644 --- a/pkg/core/types.go +++ b/pkg/core/types.go @@ -51,6 +51,7 @@ type Config struct { LogFile string `json:"log_file,omitempty"` Version string `json:"-"` Secret string `json:"secret,omitempty"` + Admin bool `json:"admin,omitempty"` Foreground bool `json:"foreground,omitempty"` SecureCookie bool `json:"secure_cookie,omitempty"` Debug bool `json:"debug,omitempty"` diff --git a/pkg/db/db.go b/pkg/db/db.go index 18606cb..1406d8c 100644 --- a/pkg/db/db.go +++ b/pkg/db/db.go @@ -26,14 +26,15 @@ You can customize it how you like.` const blevePath = "bleve" type DB struct { + admin bool store store.Store cache *cache.Cache Index *index.Index } -func New(dir string) (db *DB, err error) { - db = &DB{cache: cache.NewCache()} - dbFile := filepath.Join(dir, storeFile) +func New(cfg core.Config) (db *DB, err error) { + db = &DB{admin: cfg.Admin, cache: cache.NewCache()} + dbFile := filepath.Join(cfg.DataDir, storeFile) err = godrop.Unveil(dbFile, "rwc") if err != nil { return @@ -42,7 +43,7 @@ func New(dir string) (db *DB, err error) { if err != nil { return } - db.Index, err = index.NewIndex(filepath.Join(dir, blevePath)) + db.Index, err = index.NewIndex(filepath.Join(cfg.DataDir, blevePath)) if err != nil { return } diff --git a/pkg/db/user.go b/pkg/db/user.go index e76a135..7558aa4 100644 --- a/pkg/db/user.go +++ b/pkg/db/user.go @@ -83,6 +83,10 @@ func (db *DB) CreateUser(username, password string, admin bool) error { } func (db *DB) Login(username, password string) (u core.User, err error) { + if username == defUser && !db.admin { + err = errors.New("db: user disabled") + return + } u, err = db.GetUser(username) if err != nil { return diff --git a/pkg/log/log.go b/pkg/log/log.go index 5e2427f..e724397 100644 --- a/pkg/log/log.go +++ b/pkg/log/log.go @@ -4,6 +4,7 @@ package log import ( "git.giftfish.de/ston1th/godrop/v2" + "git.giftfish.de/ston1th/gowiki/pkg/core" stdlog "log" "os" "path/filepath" @@ -14,12 +15,12 @@ var ( debug = false ) -func InitLogger(dir, file string, d bool) { - debug = d - if file == "-" { +func InitLogger(cfg core.Config) { + debug = cfg.Debug + if cfg.LogFile == "-" { return } - logfile := filepath.Join(dir, file) + logfile := filepath.Join(cfg.DataDir, cfg.LogFile) err := godrop.Unveil(logfile, "rwc") if err != nil { stdlog.Fatal(err) diff --git a/pkg/otp/otp.go b/pkg/otp/otp.go index 3408eb0..75e52ba 100644 --- a/pkg/otp/otp.go +++ b/pkg/otp/otp.go @@ -5,25 +5,28 @@ package otp import ( "bytes" "encoding/base64" + "errors" "github.com/pquerna/otp" "github.com/pquerna/otp/totp" "html/template" "image/png" ) -const dataUrl = "data:image/png;base64," +const size = 200 func base64Image(key *otp.Key) (data template.URL, err error) { var buf bytes.Buffer - img, err := key.Image(200, 200) + img, err := key.Image(size, size) if err != nil { + err = errors.New("otp: " + err.Error()) return } err = png.Encode(&buf, img) if err != nil { + err = errors.New("otp: " + err.Error()) return } - data = template.URL(dataUrl + base64.StdEncoding.EncodeToString(buf.Bytes())) + data = template.URL("data:image/png;base64," + base64.StdEncoding.EncodeToString(buf.Bytes())) return } @@ -64,6 +67,7 @@ func Validate(pin, secret string) bool { func ImageSecretFromURL(url string) (data template.URL, secret string, err error) { key, err := otp.NewKeyFromURL(url) if err != nil { + err = errors.New("otp: " + err.Error()) return } secret = key.Secret() diff --git a/pkg/server/context.go b/pkg/server/context.go index 55412cf..33411f4 100644 --- a/pkg/server/context.go +++ b/pkg/server/context.go @@ -55,7 +55,7 @@ func newContext(w http.ResponseWriter, r *http.Request, s *HTTPServer) (ctx *Con ctx.Token = *t return } - ctx.Redirect(core.TotpURI, 302) + ctx.Redirect(core.TotpURI, http.StatusFound) return nil } @@ -114,7 +114,7 @@ func (c *Context) Exec() { } c.Data.Token = newXsrf(c.Token.RawSig()[:keySize]) - c.Data.Version = c.Srv.Version + c.Data.Version = c.Srv.Config.Version if c.Data.BodyTitle == "" { c.Data.BodyTitle = c.Data.Title } @@ -162,6 +162,14 @@ func (c *Context) NotFound() { c.Exec() } +func (c *Context) Forbidden() { + c.Template("forbiddenHandler") + c.Data = webData{Title: "403"} + c.Status = http.StatusForbidden + c.Response.WriteHeader(http.StatusForbidden) + c.Exec() +} + func (c *Context) Template(name string) { c.T = c.Srv.templ[name] } @@ -221,7 +229,7 @@ func (c *Context) LoggedOn() (ok bool) { } func (c *Context) LogSetCookie(msg string, err error) { - log.Println(msg, err) + log.Printf("ctx: %s %s\n", msg, err) c.SetCookie(nil) } @@ -240,7 +248,7 @@ func (c *Context) SetCookieToken(t *jwt.Token) { Value: c.Token.String(), Path: "/", MaxAge: int(jwt.DefaultExpiry.Seconds()), - Secure: c.Srv.Secure, + Secure: c.Srv.Config.SecureCookie, HttpOnly: true, SameSite: http.SameSiteStrictMode, } diff --git a/pkg/server/handler.go b/pkg/server/handler.go index c242d1b..f575692 100644 --- a/pkg/server/handler.go +++ b/pkg/server/handler.go @@ -26,7 +26,7 @@ func totpAuthHandler(h ctxHandler) ctxHandler { h(ctx) return } - ctx.Redirect(core.IndexURI, 302) + ctx.Redirect(core.IndexURI, http.StatusFound) } } @@ -36,7 +36,7 @@ func adminAuthHandler(h ctxHandler) ctxHandler { h(ctx) return } - ctx.NotFound() + ctx.Forbidden() } } @@ -50,7 +50,7 @@ func userAuthHandler(h ctxHandler) ctxHandler { h(ctx) return } - ctx.NotFound() + ctx.Forbidden() } } @@ -60,7 +60,7 @@ func authHandler(h ctxHandler) ctxHandler { h(ctx) return } - ctx.NotFound() + ctx.Forbidden() } } @@ -80,12 +80,12 @@ func staticHandler(ctx *Context) { } func indexHandler(ctx *Context) { - ctx.Redirect(core.IndexURI, 302) + ctx.Redirect(core.IndexURI, http.StatusFound) } func loginHandler(ctx *Context) { if ctx.LoggedOn() { - ctx.Redirect(core.IndexURI, 302) + ctx.Redirect(core.IndexURI, http.StatusFound) return } ctx.Template("loginHandler") @@ -93,17 +93,20 @@ func loginHandler(ctx *Context) { Title: "Login", BodyTitle: "Login", } + var user string switch ctx.Method() { case "GET": + ctx.Data.Data = user ctx.Exec() case "POST": if !ctx.CheckXsrf() { return } - user := ctx.Form("user") + user = ctx.Form("user") + ctx.Data.Data = user password := ctx.Form("password") if user == "" || password == "" { - ctx.Error("wrong inputs") + ctx.Error("empty user or password") return } u, err := ctx.Srv.DB.Login(user, password) @@ -112,21 +115,22 @@ func loginHandler(ctx *Context) { return } if u.Secret == "" { + log.Println("login:", u.Username) ctx.SetCookie(jwt.Claims{userClaim: u.Username, createdClaim: u.Created, adminClaim: u.Admin}) - ctx.Redirect(core.IndexURI, 302) + ctx.Redirect(core.IndexURI, http.StatusFound) return } ctx.SetCookieToken(jwt.NewToken(map[string]interface{}{ totpClaim: u.Username, jwt.ExpClaim: jwt.NewExp(time.Minute), }, nil)) - ctx.Redirect(core.TotpURI, 302) + ctx.Redirect(core.TotpURI, http.StatusFound) } } func loginTotpHandler(ctx *Context) { if ctx.LoggedOn() { - ctx.Redirect(core.IndexURI, 302) + ctx.Redirect(core.IndexURI, http.StatusFound) return } ctx.Template("loginTotpHandler") @@ -143,7 +147,7 @@ func loginTotpHandler(ctx *Context) { } pin := ctx.Form("pin") if pin == "" { - ctx.Error("wrong inputs") + ctx.Error("empty pin") return } u, err := ctx.Srv.DB.Totp(ctx.Totp(), pin) @@ -151,8 +155,9 @@ func loginTotpHandler(ctx *Context) { ctx.Error(err) return } + log.Println("login:", u.Username) ctx.SetCookie(jwt.Claims{userClaim: u.Username, createdClaim: u.Created, adminClaim: u.Admin}) - ctx.Redirect(core.IndexURI, 302) + ctx.Redirect(core.IndexURI, http.StatusFound) } } @@ -214,6 +219,14 @@ func pageNewHandler(ctx *Context) { Perm: perm, } ctx.Data.Data = p + if title == "" { + ctx.Error("empty title") + return + } + if perm == core.Invalid { + ctx.Error("invalid permission") + return + } if section != core.WikiSection { section = ctx.User() @@ -223,7 +236,7 @@ func pageNewHandler(ctx *Context) { ctx.Error(err) return } - ctx.Redirect(page.StoreTitle, 302) + ctx.Redirect(page.StoreTitle, http.StatusFound) } } @@ -237,19 +250,19 @@ func pageHandler(ctx *Context) { if key := ctx.Var("key"); key != "" { t, err := jwt.DecodeToken(key) if err != nil { - log.Println("DecodeToken:", err) + log.Println("share: DecodeToken:", err) ctx.NotFound() return } if err = ctx.Srv.JWT.Verify(t); err != nil { - log.Println("VerifyToken:", err) + log.Println("share: VerifyToken:", err) ctx.NotFound() return } user = t.Claims.GetString(sharedClaim) if ctx.Srv.DB.LockedOut(user, t.Claims.GetString(createdClaim)) { if err = ctx.Srv.JWT.Invalidate(t); err != nil { - log.Println("Invalidate:", err) + log.Println("share: Invalidate:", err) } ctx.NotFound() return @@ -310,7 +323,7 @@ func pageShareHandler(ctx *Context) { return } - d, err := time.ParseDuration(ctx.Form("duration")) + d, err := duration(ctx.Form("duration"), ctx.Form("mode")) if err != nil { ctx.Error(err) return @@ -324,7 +337,7 @@ func pageShareHandler(ctx *Context) { }, nil) if err = ctx.Srv.JWT.Sign(t); err != nil { - log.Println("SignToken:", err) + log.Println("share: SignToken:", err) ctx.NotFound() return } @@ -404,7 +417,7 @@ func pageEditHandler(ctx *Context) { ctx.Error(err) return } - ctx.Redirect(page.StoreTitle, 302) + ctx.Redirect(page.StoreTitle, http.StatusFound) } } @@ -426,7 +439,7 @@ func pageDelHandler(ctx *Context) { ctx.Error(err) return } - ctx.Redirect(core.IndexURI, 302) + ctx.Redirect(core.IndexURI, http.StatusFound) } } @@ -471,15 +484,20 @@ func userNewHandler(ctx *Context) { adm = true } - if user == "" || password == "" || password != repeat { - ctx.Error("wrong inputs") + if user == "" || password == "" { + ctx.Error("empty user or password") + return + } + if password != repeat { + ctx.Error("passwords do not match") return } if err := ctx.Srv.DB.CreateUser(user, password, adm); err != nil { ctx.Error(err) return } - ctx.Redirect("/user", 302) + log.Printf("create: %s created by %s\n", user, ctx.User()) + ctx.Redirect("/user", http.StatusFound) } } @@ -511,8 +529,8 @@ func userEditHandler(ctx *Context) { adm = true } - if user == "" || password != repeat { - ctx.Error("wrong inputs") + if password != repeat { + ctx.Error("passwords do not match") return } if ctx.Admin() { @@ -520,17 +538,16 @@ func userEditHandler(ctx *Context) { ctx.Error(err) return } - } else { - if user == ctx.User() { - if err := ctx.Srv.DB.UpdateUserPassword(user, password); err != nil { - ctx.Error(err) - return - } - ctx.Redirect(core.IndexURI, 302) - return - } + log.Printf("update: %s updated by %s\n", user, ctx.User()) + ctx.Redirect("/user", http.StatusFound) + return } - ctx.Redirect("/user", 302) + if err := ctx.Srv.DB.UpdateUserPassword(user, password); err != nil { + ctx.Error(err) + return + } + log.Printf("update: %s updated by %s\n", user, ctx.User()) + ctx.Redirect(core.IndexURI, http.StatusFound) } } @@ -558,7 +575,7 @@ func userTotpHandler(ctx *Context) { req.URL = ctx.Form("url") req.Image, req.Secret, err = otp.ImageSecretFromURL(req.URL) if err != nil { - ctx.Error("wrong inputs") + ctx.Error(err) return } } @@ -582,7 +599,8 @@ func userTotpHandler(ctx *Context) { secret = u.Secret } valid := otp.Validate(pin, secret) - if ctx.User() != req.Username && ctx.Admin() { + user := ctx.User() + if user != req.Username && ctx.Admin() { valid = true } @@ -594,7 +612,12 @@ func userTotpHandler(ctx *Context) { ctx.Error(err) return } - ctx.Redirect("/user/edit/"+req.Username, 302) + if req.Secret == "" { + log.Printf("totp: disabled by %s for %s\n", user, req.Username) + } else { + log.Printf("totp: enabled by %s for %s\n", user, req.Username) + } + ctx.Redirect("/user/edit/"+req.Username, http.StatusFound) } } @@ -603,7 +626,8 @@ func userUnlockHandler(ctx *Context) { if err := ctx.Srv.DB.UnlockUser(user); err != nil { log.Println("unlock:", err) } - ctx.Redirect("/user", 302) + log.Printf("unlock: %s unlocked by %s\n", user, ctx.User()) + ctx.Redirect("/user", http.StatusFound) } func userDelHandler(ctx *Context) { @@ -625,15 +649,23 @@ func userDelHandler(ctx *Context) { if !ctx.CheckXsrf() { return } - if err := ctx.Srv.DB.DeleteUser(ctx.Var("user")); err != nil { + self := ctx.User() + user := ctx.Var("user") + if err := ctx.Srv.DB.DeleteUser(user); err != nil { log.Println("delete:", err) } - ctx.Redirect("/user", 302) + log.Printf("delete: %s deleted by %s\n", user, self) + if user == self { + ctx.Redirect("/logout", http.StatusFound) + return + } + ctx.Redirect("/user", http.StatusFound) } } func logoutHandler(ctx *Context) { + log.Println("logout:", ctx.User()) ctx.Srv.JWT.Invalidate(&ctx.Token) ctx.SetCookie(nil) - ctx.Redirect(core.IndexURI, 302) + ctx.Redirect(core.IndexURI, http.StatusFound) } diff --git a/pkg/server/helper.go b/pkg/server/helper.go new file mode 100644 index 0000000..4b6c475 --- /dev/null +++ b/pkg/server/helper.go @@ -0,0 +1,47 @@ +// Copyright (C) 2018 Marius Schellenberger + +package server + +import ( + "errors" + "strconv" + "time" +) + +const ( + day = time.Hour * 24 + min = time.Second * 30 + max = day * 90 +) + +func duration(duration, mode string) (d time.Duration, err error) { + var m int + m, _ = strconv.Atoi(mode) + switch m { + case 0: + err = errors.New("invalid mode") + return + case 1: + d, err = time.ParseDuration(duration) + if err != nil { + err = errors.New("could not parse duration") + return + } + case 2: + var t int + t, err = strconv.Atoi(duration) + if err != nil { + err = errors.New("could not parse duration") + return + } + d = time.Duration(int(day) * t) + } + + if d < min { + err = errors.New("minimum duration is 30 seconds") + } + if d > max { + err = errors.New("maximum duration is 90 days") + } + return +} diff --git a/pkg/server/routes.go b/pkg/server/routes.go index 9ed0603..8bf4259 100644 --- a/pkg/server/routes.go +++ b/pkg/server/routes.go @@ -71,16 +71,10 @@ var routes = []route{ }, { "/user/del/{user:[a-zA-Z0-9]+$}", - adminAuthHandler( + userAuthHandler( userDelHandler), []string{"GET", "POST"}, }, - { - "/user/unlock/{user:[a-zA-Z0-9]+$}", - adminAuthHandler( - userUnlockHandler), - []string{"POST"}, - }, { "/user/edit/{user:[a-zA-Z0-9]+$}", userAuthHandler( @@ -93,6 +87,12 @@ var routes = []route{ userTotpHandler), []string{"GET", "POST"}, }, + { + "/user/unlock/{user:[a-zA-Z0-9]+$}", + adminAuthHandler( + userUnlockHandler), + []string{"POST"}, + }, { "/logout", logoutHandler, diff --git a/pkg/server/server.go b/pkg/server/server.go index 9ff07ac..7c5f4cf 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -23,10 +23,7 @@ const ( ) type HTTPServer struct { - Version string - Secure bool - Secret string - DataDir string + Config core.Config listener net.Listener srv *http.Server @@ -38,12 +35,9 @@ type HTTPServer struct { res map[string][]byte } -func NewHTTPServer(l net.Listener, conf core.Config) (srv *HTTPServer) { +func NewHTTPServer(cfg core.Config, l net.Listener) (srv *HTTPServer) { srv = &HTTPServer{ - Version: conf.Version, - Secure: conf.SecureCookie, - Secret: conf.Secret, - DataDir: conf.DataDir, + Config: cfg, listener: l, } srv.loadTemplates() @@ -54,7 +48,7 @@ func NewHTTPServer(l net.Listener, conf core.Config) (srv *HTTPServer) { } func (s *HTTPServer) Start() (err error) { - s.DB, err = db.New(s.DataDir) + s.DB, err = db.New(s.Config) if err != nil { return errors.New("db: " + err.Error()) } @@ -62,8 +56,8 @@ func (s *HTTPServer) Start() (err error) { if err != nil { return } - if s.Secret != "" { - s.JWT, err = jwt.New(jwt.DefaultExpiry, s.DB, bytes.NewBufferString(s.Secret)) + if s.Config.Secret != "" { + s.JWT, err = jwt.New(jwt.DefaultExpiry, s.DB, bytes.NewBufferString(s.Config.Secret)) } else { s.JWT, err = jwt.New(jwt.DefaultExpiry, s.DB, nil) } diff --git a/pkg/server/templates.go b/pkg/server/templates.go index f2a6471..d2a9129 100644 --- a/pkg/server/templates.go +++ b/pkg/server/templates.go @@ -42,6 +42,23 @@ const ( {{end}} +{{end}}` + forbidden = `{{define "body"}} + {{end}}` index = ` @@ -99,7 +116,7 @@ const (
- +
@@ -168,10 +185,10 @@ const (
- 404 + 404 - Page Not Found
-

Page not found

+
The requested page could not be found
Back
@@ -252,7 +269,8 @@ const (
- + + Back {{end}}` page = `{{define "body"}} @@ -293,7 +311,7 @@ const ( Share {{end}} {{if ne .Data.StoreTitle "wiki/Index"}} - Delete + Delete {{end}} {{end}} @@ -304,7 +322,7 @@ const ( pageMD = `{{define "body"}}
@@ -348,11 +366,10 @@ const (
- + {{end}}` pageShare = `{{define "body"}} -{{if not .Msg}} -{{end}} {{end}}` pageView = `{{define "body"}} {{end}} - + {{if .Admin}} Back {{else}} Back {{end}} + Delete {{if .Admin}} {{if eq .Data.Locked 3}} @@ -555,7 +584,7 @@ const ( Username - Admin + Flags Options @@ -564,8 +593,12 @@ const ( {{$admin := .Admin}} {{range $item := .Data}} - {{$item.Username}} {{if $item.Secret}}TOTP{{end}} - {{if $item.Admin}}yes{{else}}no{{end}} + {{$item.Username}} + + {{if $item.Secret}}TOTP{{end}} + {{if eq $item.Locked 3}}Locked{{end}} + {{if $item.Admin}}Admin{{end}} +
{{if $admin}} @@ -612,7 +645,7 @@ const (
- + Back @@ -637,7 +670,7 @@ const (
-

{{.Data.Secret}}

+
{{.Data.Secret}}
{{end}}
@@ -836,6 +869,7 @@ func (s *HTTPServer) loadTemplates() { // pages s.templ["notFoundHandler"] = parse(index, menu, notFound) + s.templ["forbiddenHandler"] = parse(index, menu, forbidden) s.templ["loginHandler"] = parse(index, menu, login) s.templ["loginTotpHandler"] = parse(index, menu, loginTotp) s.templ["searchHandler"] = parse(index, menu, search) diff --git a/templates.sh b/templates.sh index 5842f58..4e1ff80 100755 --- a/templates.sh +++ b/templates.sh @@ -70,6 +70,7 @@ func (s *HTTPServer) loadTemplates() { // pages s.templ["notFoundHandler"] = parse(index, menu, notFound) + s.templ["forbiddenHandler"] = parse(index, menu, forbidden) s.templ["loginHandler"] = parse(index, menu, login) s.templ["loginTotpHandler"] = parse(index, menu, loginTotp) s.templ["searchHandler"] = parse(index, menu, search) diff --git a/templates/forbidden.html b/templates/forbidden.html new file mode 100644 index 0000000..dcf22f7 --- /dev/null +++ b/templates/forbidden.html @@ -0,0 +1,17 @@ +{{define "body"}} + +{{end}} diff --git a/templates/login.html b/templates/login.html index ca31e22..2fd684c 100644 --- a/templates/login.html +++ b/templates/login.html @@ -11,7 +11,7 @@
- +
diff --git a/templates/notFound.html b/templates/notFound.html index bc2061f..baa6f51 100644 --- a/templates/notFound.html +++ b/templates/notFound.html @@ -4,10 +4,10 @@
- 404 + 404 - Page Not Found
-

Page not found

+
The requested page could not be found
Back
diff --git a/templates/page.html b/templates/page.html index 179ad16..e2127b2 100644 --- a/templates/page.html +++ b/templates/page.html @@ -36,7 +36,7 @@ Share {{end}} {{if ne .Data.StoreTitle "wiki/Index"}} - Delete + Delete {{end}} {{end}}
diff --git a/templates/pageEdit.html b/templates/pageEdit.html index 706d64a..3cba21b 100644 --- a/templates/pageEdit.html +++ b/templates/pageEdit.html @@ -28,6 +28,7 @@
- + + Back {{end}} diff --git a/templates/pageMD.html b/templates/pageMD.html index 22ca0c7..4f116ed 100644 --- a/templates/pageMD.html +++ b/templates/pageMD.html @@ -1,7 +1,7 @@ {{define "body"}}
diff --git a/templates/pageNew.html b/templates/pageNew.html index 45de737..f8d0496 100644 --- a/templates/pageNew.html +++ b/templates/pageNew.html @@ -35,6 +35,6 @@
- + {{end}} diff --git a/templates/pageShare.html b/templates/pageShare.html index a1d01ce..03e568f 100644 --- a/templates/pageShare.html +++ b/templates/pageShare.html @@ -1,5 +1,4 @@ {{define "body"}} -{{if not .Msg}} {{end}} -{{end}} diff --git a/templates/user.html b/templates/user.html index f078273..d68a4d2 100644 --- a/templates/user.html +++ b/templates/user.html @@ -18,7 +18,7 @@ Username - Admin + Flags Options @@ -27,8 +27,12 @@ {{$admin := .Admin}} {{range $item := .Data}} - {{$item.Username}} {{if $item.Secret}}TOTP{{end}} - {{if $item.Admin}}yes{{else}}no{{end}} + {{$item.Username}} + + {{if $item.Secret}}TOTP{{end}} + {{if eq $item.Locked 3}}Locked{{end}} + {{if $item.Admin}}Admin{{end}} +
{{if $admin}} diff --git a/templates/userEdit.html b/templates/userEdit.html index d8648bc..077b4c3 100644 --- a/templates/userEdit.html +++ b/templates/userEdit.html @@ -36,12 +36,13 @@ {{end}}
{{end}} - + {{if .Admin}} Back {{else}} Back {{end}} + Delete {{if .Admin}} {{if eq .Data.Locked 3}} diff --git a/templates/userNew.html b/templates/userNew.html index 576656f..0715c00 100644 --- a/templates/userNew.html +++ b/templates/userNew.html @@ -24,7 +24,7 @@ - + Back diff --git a/templates/userTotp.html b/templates/userTotp.html index a19801c..dc5b834 100644 --- a/templates/userTotp.html +++ b/templates/userTotp.html @@ -16,7 +16,7 @@
-

{{.Data.Secret}}

+
{{.Data.Secret}}
{{end}}