bugfixes and updated go.mod
This commit is contained in:
parent
9424084a36
commit
6e317eb08b
300 changed files with 53136 additions and 9719 deletions
|
|
@ -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 == "" {
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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"},
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 = ¬FoundHandler{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
Loading…
Add table
Add a link
Reference in a new issue