bump copyright, added stats page and updated dependencies

This commit is contained in:
ston1th 2020-01-11 11:32:27 +01:00
commit 0265d820fe
111 changed files with 9556 additions and 3835 deletions

2
pkg/cache/cache.go vendored
View file

@ -1,4 +1,4 @@
// Copyright (C) 2019 Marius Schellenberger
// Copyright (C) 2020 Marius Schellenberger
package cache

View file

@ -1,4 +1,4 @@
// Copyright (C) 2019 Marius Schellenberger
// Copyright (C) 2020 Marius Schellenberger
package cache

View file

@ -1,4 +1,4 @@
// Copyright (C) 2019 Marius Schellenberger
// Copyright (C) 2020 Marius Schellenberger
package cmd
@ -137,7 +137,7 @@ func Run(version string) {
}
log.Stderr()
if dumpFile != "-" {
file, err = os.OpenFile(dumpFile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0640)
file, err = os.OpenFile(dumpFile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
if err != nil {
stdlog.Fatal("dump: ", err)
}
@ -241,7 +241,7 @@ func serverFlags() []cli.Flag {
cli.StringFlag{
Name: "log",
Value: defLogFile,
Usage: "log file (use - for stdout, this only works in combination with -f)",
Usage: "log file (use -log=- for stdout, this only works in combination with -f)",
Destination: &config.LogFile,
},
cli.StringFlag{

View file

@ -1,4 +1,4 @@
// Copyright (C) 2019 Marius Schellenberger
// Copyright (C) 2020 Marius Schellenberger
package core
@ -8,10 +8,20 @@ const (
IndexURI = WikiSection + "/" + IndexPage
LoginURI = "/login"
LogoutURI = "/logout"
TotpURI = "/totp"
SectionsURI = "/sections"
RootURI = "/"
WikiURI = "/wiki"
LoginURI = "/login"
LogoutURI = "/logout"
TotpURI = "/totp"
SectionsURI = "/sections"
SectionURI = "/section"
SearchURI = "/search"
StatsURI = "/stats"
NewURI = "/new"
BlacklistURI = "/blacklist"
UsersURI = "/users"
UserURI = "/user"
ViewURI = "/view"
BootstrapCSS = "/bootstrap.css"
CustomCSS = "/custom.css"

View file

@ -1,4 +1,4 @@
// Copyright (C) 2019 Marius Schellenberger
// Copyright (C) 2020 Marius Schellenberger
package core

View file

@ -1,4 +1,4 @@
// Copyright (C) 2019 Marius Schellenberger
// Copyright (C) 2020 Marius Schellenberger
package core

View file

@ -1,4 +1,4 @@
// Copyright (C) 2019 Marius Schellenberger
// Copyright (C) 2020 Marius Schellenberger
package core
@ -72,6 +72,14 @@ type Result struct {
HTML template.HTML
}
type Stats struct {
Goroutines int
Alloc string
Sys string
Docs uint64
GoVersion string
}
type Config struct {
DataDir string `json:"data_dir,omitempty"`
User string `json:"user,omitempty"`

View file

@ -1,4 +1,4 @@
// Copyright (C) 2019 Marius Schellenberger
// Copyright (C) 2020 Marius Schellenberger
package db

View file

@ -1,25 +1,37 @@
// Copyright (C) 2019 Marius Schellenberger
// Copyright (C) 2020 Marius Schellenberger
package db
import (
"crypto/sha256"
"git.giftfish.de/ston1th/gowiki/pkg/core"
"time"
)
var reservedNames = []string{
"blacklist",
"login",
"logout",
"new",
"search",
"section",
"sections",
"user",
"users",
"view",
func init() {
reservedNames = make([]string, len(reservedURIs))
for i, v := range reservedURIs {
reservedNames[i] = v[1:]
}
}
var reservedURIs = []string{
core.LoginURI,
core.LogoutURI,
core.TotpURI,
core.SectionsURI,
core.SectionURI,
core.SearchURI,
core.StatsURI,
core.NewURI,
core.BlacklistURI,
core.UsersURI,
core.UserURI,
core.ViewURI,
}
var reservedNames []string
func validatePassword(pw string) (b []byte) {
b = []byte(pw)
if len(pw) <= 56 {

View file

@ -1,4 +1,4 @@
// Copyright (C) 2019 Marius Schellenberger
// Copyright (C) 2020 Marius Schellenberger
package db

View file

@ -1,4 +1,4 @@
// Copyright (C) 2019 Marius Schellenberger
// Copyright (C) 2020 Marius Schellenberger
package db

View file

@ -1,9 +1,10 @@
// Copyright (C) 2019 Marius Schellenberger
// Copyright (C) 2020 Marius Schellenberger
package db
import (
"errors"
"fmt"
"git.giftfish.de/ston1th/gowiki/pkg/core"
"git.giftfish.de/ston1th/gowiki/pkg/log"
"sort"
@ -62,7 +63,7 @@ func (db *DB) CreateSection(section string, members []string, user bool) error {
func (db *DB) UpdateSection(section string, members []string, user bool) error {
section = userRe.ReplaceAllString(section, "")
if _, ok := core.Contains(section, reservedNames); ok {
return errNameReserved
return fmt.Errorf("%s: %s", errNameReserved, section)
}
var m []string
if user {

View file

@ -1,9 +1,10 @@
// Copyright (C) 2019 Marius Schellenberger
// Copyright (C) 2020 Marius Schellenberger
package db
import (
"errors"
"fmt"
"git.giftfish.de/ston1th/gowiki/pkg/core"
"git.giftfish.de/ston1th/gowiki/pkg/otp"
"git.giftfish.de/ston1th/jwt/v3"
@ -64,7 +65,8 @@ func (db *DB) UserExists(username string) error {
func (db *DB) CreateUser(username, password string, admin bool) error {
username = userRe.ReplaceAllString(username, "")
if _, ok := core.Contains(username, reservedNames); ok {
return errNameReserved
return fmt.Errorf("%s: %s", errNameReserved, username)
}
if err := db.UserExists(username); err == nil {
return errUserExists

View file

@ -1,4 +1,4 @@
// Copyright (C) 2019 Marius Schellenberger
// Copyright (C) 2020 Marius Schellenberger
package index
@ -73,6 +73,11 @@ func New(path string) (i *Index, err error) {
return
}
func (i *Index) DocCount() (c uint64) {
c, _ = i.i.DocCount()
return
}
func (i *Index) Close() error {
return i.i.Close()
}

View file

@ -1,4 +1,4 @@
// Copyright (C) 2019 Marius Schellenberger
// Copyright (C) 2020 Marius Schellenberger
package index

View file

@ -1,4 +1,4 @@
// Copyright (C) 2019 Marius Schellenberger
// Copyright (C) 2020 Marius Schellenberger
package log
@ -30,7 +30,7 @@ func InitLogger(cfg core.Config) {
stdlog.Fatal(err)
return
}
f, err := os.OpenFile(logfile, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0640)
f, err := os.OpenFile(logfile, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0600)
if err != nil {
stdlog.Fatal(err)
}

View file

@ -1,4 +1,4 @@
// Copyright (C) 2019 Marius Schellenberger
// Copyright (C) 2020 Marius Schellenberger
package otp

View file

@ -1,4 +1,4 @@
// Copyright (C) 2019 Marius Schellenberger
// Copyright (C) 2020 Marius Schellenberger
package otp

View file

@ -1,4 +1,4 @@
// Copyright (C) 2019 Marius Schellenberger
// Copyright (C) 2020 Marius Schellenberger
package render

View file

@ -1,4 +1,4 @@
// Copyright (C) 2019 Marius Schellenberger
// Copyright (C) 2020 Marius Schellenberger
package render

View file

@ -1,4 +1,4 @@
// Copyright (C) 2019 Marius Schellenberger
// Copyright (C) 2020 Marius Schellenberger
package server

View file

@ -1,4 +1,4 @@
// Copyright (C) 2019 Marius Schellenberger
// Copyright (C) 2020 Marius Schellenberger
package server
@ -712,7 +712,7 @@ func userNewHandler(ctx *Context) {
return
}
log.Printf("create: user %s created by %s\n", user, ctx.User())
ctx.Redirect("/users", http.StatusFound)
ctx.Redirect(core.UsersURI, http.StatusFound)
}
}
@ -754,7 +754,7 @@ func userEditHandler(ctx *Context) {
return
}
log.Printf("update: user %s updated by %s\n", user, ctx.User())
ctx.Redirect("/users", http.StatusFound)
ctx.Redirect(core.UsersURI, http.StatusFound)
return
}
if err := ctx.Srv.DB.UpdateUserPassword(user, password); err != nil {
@ -832,7 +832,7 @@ func userTotpHandler(ctx *Context) {
} else {
log.Printf("totp: enabled by %s for %s\n", user, req.Username)
}
ctx.Redirect("/user/edit/"+req.Username, http.StatusFound)
ctx.Redirect(core.UserURI+"/edit/"+req.Username, http.StatusFound)
}
}
@ -842,7 +842,7 @@ func userUnlockHandler(ctx *Context) {
log.Println("unlock:", err)
}
log.Printf("unlock: %s unlocked by %s\n", user, ctx.User())
ctx.Redirect("/users", http.StatusFound)
ctx.Redirect(core.UsersURI, http.StatusFound)
}
func userDelHandler(ctx *Context) {
@ -871,10 +871,23 @@ func userDelHandler(ctx *Context) {
}
log.Printf("delete: user %s deleted by %s\n", user, self)
if user == self {
ctx.Redirect("/logout", http.StatusFound)
ctx.Redirect(core.LogoutURI, http.StatusFound)
return
}
ctx.Redirect("/users", http.StatusFound)
ctx.Redirect(core.UsersURI, http.StatusFound)
}
}
func statsHandler(ctx *Context) {
ctx.Template("statsHandler")
ctx.Data = webData{
Title: "Stats",
BodyTitle: "Stats",
}
switch ctx.Method() {
case "GET":
ctx.Data.Data = getStats(ctx.Srv.DB.Index)
ctx.Exec()
}
}

View file

@ -1,9 +1,12 @@
// Copyright (C) 2019 Marius Schellenberger
// Copyright (C) 2020 Marius Schellenberger
package server
import (
"errors"
"git.giftfish.de/ston1th/gowiki/pkg/core"
bleve "git.giftfish.de/ston1th/gowiki/pkg/index"
"runtime"
"strconv"
"time"
)
@ -12,6 +15,8 @@ const (
day = time.Hour * 24
min = time.Second * 30
max = day * 90
div = 1048576
)
func duration(duration, mode string) (d time.Duration, err error) {
@ -43,3 +48,19 @@ func duration(duration, mode string) (d time.Duration, err error) {
}
return
}
func fmtMem(i uint64) string {
return strconv.FormatFloat(float64(i)/div, 'f', 2, 64)
}
func getStats(i *bleve.Index) *core.Stats {
mem := new(runtime.MemStats)
runtime.ReadMemStats(mem)
return &core.Stats{
Goroutines: runtime.NumGoroutine(),
Alloc: fmtMem(mem.Alloc),
Sys: fmtMem(mem.Sys),
Docs: i.DocCount(),
GoVersion: runtime.Version(),
}
}

View file

@ -1,4 +1,4 @@
// Copyright (C) 2019 Marius Schellenberger
// Copyright (C) 2020 Marius Schellenberger
package server
@ -30,127 +30,134 @@ var static = []route{
var routes = []route{
{
"/",
core.RootURI,
jwtHandler(
indexHandler),
[]string{"GET"},
},
{
"/sections",
core.SectionsURI,
jwtHandler(
sectionsHandler),
[]string{"GET"},
},
{
"/section/new",
core.SectionURI + "/new",
jwtHandler(
adminAuthHandler(
sectionNewHandler)),
[]string{"GET", "POST"},
},
{
"/section/edit/{section:[a-zA-Z0-9]+$}",
core.SectionURI + "/edit/{section:[a-zA-Z0-9]+$}",
jwtHandler(
adminAuthHandler(
sectionEditHandler)),
[]string{"GET", "POST"},
},
{
"/section/del/{section:[a-zA-Z0-9]+$}",
core.SectionURI + "/del/{section:[a-zA-Z0-9]+$}",
jwtHandler(
adminAuthHandler(
sectionDelHandler)),
[]string{"GET", "POST"},
},
{
"/search",
core.SearchURI,
jwtHandler(
searchHandler),
[]string{"GET", "POST"},
},
{
"/new",
core.NewURI,
jwtHandler(
authHandler(
pageNewHandler)),
[]string{"GET", "POST"},
},
{
"/login",
core.LoginURI,
jwtHandler(
loginHandler),
[]string{"GET", "POST"},
},
{
"/totp",
core.TotpURI,
jwtHandler(
totpAuthHandler(
loginTotpHandler)),
[]string{"GET", "POST"},
},
{
"/blacklist",
core.BlacklistURI,
jwtHandler(
authHandler(
pageBlacklistHandler)),
[]string{"GET", "POST"},
},
{
"/users",
core.UsersURI,
jwtHandler(
adminAuthHandler(
usersHandler)),
[]string{"GET"},
},
{
"/user/new",
core.UserURI + "/new",
jwtHandler(
adminAuthHandler(
userNewHandler)),
[]string{"GET", "POST"},
},
{
"/user/edit/{user:[a-zA-Z0-9]+$}",
core.UserURI + "/edit/{user:[a-zA-Z0-9]+$}",
jwtHandler(
userAuthHandler(
userEditHandler)),
[]string{"GET", "POST"},
},
{
"/user/del/{user:[a-zA-Z0-9]+$}",
core.UserURI + "/del/{user:[a-zA-Z0-9]+$}",
jwtHandler(
userAuthHandler(
userDelHandler)),
[]string{"GET", "POST"},
},
{
"/user/totp/{user:[a-zA-Z0-9]+$}",
core.UserURI + "/totp/{user:[a-zA-Z0-9]+$}",
jwtHandler(
userAuthHandler(
userTotpHandler)),
[]string{"GET", "POST"},
},
{
"/user/unlock/{user:[a-zA-Z0-9]+$}",
core.UserURI + "/unlock/{user:[a-zA-Z0-9]+$}",
jwtHandler(
adminAuthHandler(
userUnlockHandler)),
[]string{"POST"},
},
{
"/logout",
core.StatsURI,
jwtHandler(
adminAuthHandler(
statsHandler)),
[]string{"GET"},
},
{
core.LogoutURI,
jwtHandler(
logoutHandler),
[]string{"GET", "POST"},
},
{
"/view/{key}",
core.ViewURI + "/{key}",
jwtHandler(
pageHandler),
[]string{"GET"},
},
{
"/view/{key}/md",
core.ViewURI + "/{key}/md",
jwtHandler(
pageMDHandler(
pageHandler)),

View file

@ -1,4 +1,4 @@
// Copyright (C) 2019 Marius Schellenberger
// Copyright (C) 2020 Marius Schellenberger
package server

View file

@ -1,4 +1,4 @@
// Copyright (C) 2019 Marius Schellenberger
// Copyright (C) 2020 Marius Schellenberger
// This file is auto-generated by templates.sh
// using the contents of the templates directory
@ -151,6 +151,7 @@ const (
{{if .Login}}
{{if .Admin}}
<li class="nav-item"><a class="nav-link" href="/users">Users</a></li>
<li class="nav-item"><a class="nav-link" href="/stats">Stats</a></li>
{{else}}
<li class="nav-item"><a class="nav-link" href="/user/edit/{{.User}}">Profile</a></li>
{{end}}
@ -625,6 +626,39 @@ const (
{{end}}
</div>
{{end}}
{{end}}`
stats = `{{define "body"}}
<div class="page-header">
<div class="row">
<h2>{{.BodyTitle}}</h2>
</div>
</div>
<div class="row">
<table class="table table-stripped table-hover">
<tbody>
<tr>
<td><b>Goroutines</b></td>
<td>{{.Data.Goroutines}}</td>
</tr>
<tr>
<td><b>Memory usage</b></td>
<td>{{.Data.Alloc}} MiB</td>
</tr>
<tr>
<td><b>Memory allocated</b></td>
<td>{{.Data.Sys}} MiB</td>
</tr>
<tr>
<td><b>Documents</b></td>
<td>{{.Data.Docs}}</td>
</tr>
<tr>
<td><b>Go Version</b></td>
<td>{{.Data.GoVersion}}</td>
</tr>
</tbody>
</table>
</div>
{{end}}`
userDel = `{{define "body"}}
{{if .Data}}
@ -1068,6 +1102,8 @@ func (s *HTTPServer) loadTemplates() {
s.templ["userDelHandler"] = parse(index, menu, userDel)
// totp
s.templ["userTotpHandler"] = parse(index, menu, userTotp)
// stats
s.templ["statsHandler"] = parse(index, menu, stats)
if fatal {
log.Fatal("parse: ", errors.New("parsing templates failed"))

View file

@ -1,4 +1,4 @@
// Copyright (C) 2019 Marius Schellenberger
// Copyright (C) 2020 Marius Schellenberger
package server

View file

@ -1,4 +1,4 @@
// Copyright (C) 2019 Marius Schellenberger
// Copyright (C) 2020 Marius Schellenberger
package server

View file

@ -1,4 +1,4 @@
// Copyright (C) 2019 Marius Schellenberger
// Copyright (C) 2020 Marius Schellenberger
package store
@ -10,7 +10,7 @@ import (
const (
defaultBoltBucket = "default"
fileMode = 0640
fileMode = 0600
)
type BoltStore struct {

View file

@ -1,4 +1,4 @@
// Copyright (C) 2019 Marius Schellenberger
// Copyright (C) 2020 Marius Schellenberger
package store

View file

@ -1,4 +1,4 @@
// Copyright (C) 2019 Marius Schellenberger
// Copyright (C) 2020 Marius Schellenberger
package store

View file

@ -1,4 +1,4 @@
// Copyright (C) 2019 Marius Schellenberger
// Copyright (C) 2020 Marius Schellenberger
package store

View file

@ -1,4 +1,4 @@
// Copyright (C) 2019 Marius Schellenberger
// Copyright (C) 2020 Marius Schellenberger
package store

View file

@ -1,4 +1,4 @@
// Copyright (C) 2019 Marius Schellenberger
// Copyright (C) 2020 Marius Schellenberger
package store

View file

@ -1,4 +1,4 @@
// Copyright (C) 2019 Marius Schellenberger
// Copyright (C) 2020 Marius Schellenberger
package store

View file

@ -1,4 +1,4 @@
// Copyright (C) 2019 Marius Schellenberger
// Copyright (C) 2020 Marius Schellenberger
package store

View file

@ -1,4 +1,4 @@
// Copyright (C) 2019 Marius Schellenberger
// Copyright (C) 2020 Marius Schellenberger
package store