bugfixes and updated go.mod

This commit is contained in:
ston1th 2019-05-15 22:52:27 +02:00
commit 6e317eb08b
300 changed files with 53136 additions and 9719 deletions

View file

@ -27,53 +27,19 @@ const (
refererClaim = "referer"
)
func newContext(w http.ResponseWriter, r *http.Request, s *HTTPServer) (ctx *Context) {
func newContext(w http.ResponseWriter, r *http.Request, s *HTTPServer) *Context {
h := w.Header()
h.Set("X-Frame-Options", "DENY")
h.Set("X-Content-Type-Options", "nosniff")
h.Set("X-XSS-Protection", "1; mode=block")
h.Set("Content-Security-Policy", "default-src 'none';style-src 'self';img-src 'self' https: data:;connect-src 'self';frame-ancestors 'none'")
h.Set("Referrer-Policy", "same-origin")
ctx = &Context{
return &Context{
Request: r,
Response: w,
Srv: s,
Time: time.Now(),
}
path := ctx.Path()
if path == "/bootstrap.css" || path == "/custom.css" {
return
}
if c, err := r.Cookie(cookieName); err == nil {
t, err := jwt.DecodeToken(c.Value)
if err != nil {
ctx.LogSetCookie("DecodeToken:", err)
return
}
if err = s.JWT.Verify(t); err != nil {
ctx.LogSetCookie("VerifyToken:", err)
return
}
if t.Claims.GetString(totpClaim) != "" {
if path == core.TotpURI || path == core.LoginURI || path == core.LogoutURI {
ctx.Token = *t
return
}
ctx.Redirect(core.TotpURI, http.StatusFound)
return nil
}
if !s.DB.LockedOut(t.Claims.GetString(userClaim), t.Claims.GetString(userCreatedClaim)) {
ctx.Token = *t
return
}
if err = s.JWT.Invalidate(t); err != nil {
log.Println("Invalidate:", err)
}
}
ctx.SetCookie(nil, 0)
return
}
type Context struct {
@ -132,7 +98,10 @@ func (c *Context) Exec() {
c.Err = errors.New("template is nil")
return
}
c.Data.Token = newXsrf(c.Token.RawSig()[:keySize])
sig := c.Token.RawSig()
if len(sig) >= keySize {
c.Data.Token = newXsrf(sig[:keySize])
}
c.Data.Version = c.Srv.Config.Version
if c.Data.BodyTitle == "" {

View file

@ -20,6 +20,43 @@ func (nf *notFoundHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
newContext(w, r, nf.s).NotFound()
}
func jwtHandler(h ctxHandler) ctxHandler {
return func(ctx *Context) {
if c, err := ctx.Request.Cookie(cookieName); err == nil {
t, err := jwt.DecodeToken(c.Value)
if err != nil {
ctx.LogSetCookie("DecodeToken:", err)
return
}
if err = ctx.Srv.JWT.Verify(t); err != nil {
ctx.LogSetCookie("VerifyToken:", err)
return
}
if t.Claims.GetString(totpClaim) != "" {
path := ctx.Path()
if path == core.TotpURI || path == core.LoginURI || path == core.LogoutURI {
ctx.Token = *t
h(ctx)
return
}
ctx.Redirect(core.TotpURI, http.StatusFound)
return
}
if !ctx.Srv.DB.LockedOut(t.Claims.GetString(userClaim), t.Claims.GetString(userCreatedClaim)) {
ctx.Token = *t
h(ctx)
return
}
if err = ctx.Srv.JWT.Invalidate(t); err != nil {
log.Println("Invalidate:", err)
}
}
ctx.SetCookie(nil, 0)
h(ctx)
}
}
func totpAuthHandler(h ctxHandler) ctxHandler {
return func(ctx *Context) {
if ctx.Totp() != "" {
@ -69,11 +106,11 @@ func staticHandler(ctx *Context) {
ctx.SetHeader("Content-Type", "text/css; charset=utf-8")
ctx.SetHeader("Expires", time.Now().UTC().Add(max).Format(http.TimeFormat))
switch ctx.Path() {
case "/bootstrap.css":
case core.BootstrapCSS:
err = ctx.Write(ctx.Srv.res["bootstrap.css"])
case "/custom.css":
case core.CustomCSS:
err = ctx.Write(ctx.Srv.res["custom.css"])
case "/favicon.ico":
case core.Favicon:
ctx.SetHeader("Content-Type", "image/x-icon")
err = ctx.Write(ctx.Srv.res["favicon.ico"])
}
@ -458,8 +495,8 @@ func pageHandler(ctx *Context) {
return
}
ctx.Data.Data = page
ctx.Data.Title = page.Title
ctx.Data.BodyTitle = page.Title
ctx.Data.Title = section + " | " + page.Title
ctx.Data.BodyTitle = section
ctx.Exec()
}

View file

@ -2,167 +2,197 @@
package server
import "git.giftfish.de/ston1th/gowiki/pkg/core"
type route struct {
Path string
Handler ctxHandler
Methods []string
}
var static = []route{
{
core.Favicon,
staticHandler,
[]string{"GET"},
},
{
core.BootstrapCSS,
staticHandler,
[]string{"GET"},
},
{
core.CustomCSS,
staticHandler,
[]string{"GET"},
},
}
var routes = []route{
{
"/",
indexHandler,
[]string{"GET"},
},
{
"/favicon.ico",
staticHandler,
[]string{"GET"},
},
{
"/bootstrap.css",
staticHandler,
[]string{"GET"},
},
{
"/custom.css",
staticHandler,
jwtHandler(
indexHandler),
[]string{"GET"},
},
{
"/sections",
sectionsHandler,
jwtHandler(
sectionsHandler),
[]string{"GET"},
},
{
"/section/new",
adminAuthHandler(
sectionNewHandler),
jwtHandler(
adminAuthHandler(
sectionNewHandler)),
[]string{"GET", "POST"},
},
{
"/section/edit/{section:[a-zA-Z0-9]+$}",
adminAuthHandler(
sectionEditHandler),
jwtHandler(
adminAuthHandler(
sectionEditHandler)),
[]string{"GET", "POST"},
},
{
"/section/del/{section:[a-zA-Z0-9]+$}",
adminAuthHandler(
sectionDelHandler),
jwtHandler(
adminAuthHandler(
sectionDelHandler)),
[]string{"GET", "POST"},
},
{
"/search",
searchHandler,
jwtHandler(
searchHandler),
[]string{"GET", "POST"},
},
{
"/new",
authHandler(
pageNewHandler),
jwtHandler(
authHandler(
pageNewHandler)),
[]string{"GET", "POST"},
},
{
"/login",
loginHandler,
jwtHandler(
loginHandler),
[]string{"GET", "POST"},
},
{
"/totp",
totpAuthHandler(
loginTotpHandler),
jwtHandler(
totpAuthHandler(
loginTotpHandler)),
[]string{"GET", "POST"},
},
{
"/blacklist",
authHandler(
pageBlacklistHandler),
jwtHandler(
authHandler(
pageBlacklistHandler)),
[]string{"GET", "POST"},
},
{
"/users",
adminAuthHandler(
usersHandler),
jwtHandler(
adminAuthHandler(
usersHandler)),
[]string{"GET"},
},
{
"/user/new",
adminAuthHandler(
userNewHandler),
jwtHandler(
adminAuthHandler(
userNewHandler)),
[]string{"GET", "POST"},
},
{
"/user/edit/{user:[a-zA-Z0-9]+$}",
userAuthHandler(
userEditHandler),
jwtHandler(
userAuthHandler(
userEditHandler)),
[]string{"GET", "POST"},
},
{
"/user/del/{user:[a-zA-Z0-9]+$}",
userAuthHandler(
userDelHandler),
jwtHandler(
userAuthHandler(
userDelHandler)),
[]string{"GET", "POST"},
},
{
"/user/totp/{user:[a-zA-Z0-9]+$}",
userAuthHandler(
userTotpHandler),
jwtHandler(
userAuthHandler(
userTotpHandler)),
[]string{"GET", "POST"},
},
{
"/user/unlock/{user:[a-zA-Z0-9]+$}",
adminAuthHandler(
userUnlockHandler),
jwtHandler(
adminAuthHandler(
userUnlockHandler)),
[]string{"POST"},
},
{
"/logout",
logoutHandler,
jwtHandler(
logoutHandler),
[]string{"GET", "POST"},
},
{
"/view/{key}",
pageHandler,
jwtHandler(
pageHandler),
[]string{"GET"},
},
{
"/view/{key}/md",
pageMDHandler(
pageHandler),
jwtHandler(
pageMDHandler(
pageHandler)),
[]string{"GET"},
},
{
"/{section:[a-zA-Z0-9]+}",
sectionHandler,
jwtHandler(
sectionHandler),
[]string{"GET"},
},
{
"/{section:[a-zA-Z0-9]+}/{title:[a-zA-Z0-9+-]+}",
pageHandler,
[]string{"GET"},
},
{
"/{section:[a-zA-Z0-9]+}/{title:[a-zA-Z0-9+-]+}/md",
pageMDHandler(
jwtHandler(
pageHandler),
[]string{"GET"},
},
{
"/{section:[a-zA-Z0-9]+}/{title:[a-zA-Z0-9+-]+}/md",
jwtHandler(
pageMDHandler(
pageHandler)),
[]string{"GET"},
},
{
"/{section:[a-zA-Z0-9]+}/{title:[a-zA-Z0-9+-]+}/share",
pageShareHandler,
jwtHandler(
pageShareHandler),
[]string{"GET", "POST"},
},
{
"/{section:[a-zA-Z0-9]+}/{title:[a-zA-Z0-9+-]+}/edit",
authHandler(
pageEditHandler),
jwtHandler(
authHandler(
pageEditHandler)),
[]string{"GET", "POST"},
},
{
"/{section:[a-zA-Z0-9]+}/{title:[a-zA-Z0-9+-]+}/del",
authHandler(
pageDelHandler),
jwtHandler(
authHandler(
pageDelHandler)),
[]string{"GET", "POST"},
},
}

View file

@ -19,7 +19,7 @@ import (
)
const (
cookieName = "gosession"
cookieName = "gowiki_session"
)
type HTTPServer struct {
@ -81,6 +81,9 @@ func (s *HTTPServer) Stop() error {
func (s *HTTPServer) buildRoutes() http.Handler {
m := mux.NewRouter()
m.NotFoundHandler = &notFoundHandler{s}
for _, v := range static {
m.HandleFunc(v.Path, s.contextWrapper(v.Handler)).Methods(v.Methods...)
}
for _, v := range routes {
m.HandleFunc(v.Path, s.contextWrapper(v.Handler)).Methods(v.Methods...)
}
@ -88,10 +91,6 @@ func (s *HTTPServer) buildRoutes() http.Handler {
}
func (s *HTTPServer) contextWrapper(h ctxHandler) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
ctx := newContext(w, r, s)
if ctx == nil {
return
}
h(ctx)
h(newContext(w, r, s))
}
}

File diff suppressed because one or more lines are too long