1
0
mirror of https://github.com/osmarks/mycorrhiza.git synced 2025-05-11 10:34:06 +00:00

Refactor the locking mechanism

This commit is contained in:
handlerug 2021-07-16 01:14:05 +07:00
parent 6fdab4be34
commit 3ee21e312d
8 changed files with 37 additions and 122 deletions

View File

@ -32,9 +32,6 @@ func initAdmin(r *mux.Router) {
// handlerAdmin provides the admin panel. // handlerAdmin provides the admin panel.
func handlerAdmin(w http.ResponseWriter, rq *http.Request) { func handlerAdmin(w http.ResponseWriter, rq *http.Request) {
util.PrepareRq(rq) util.PrepareRq(rq)
if shown := user.FromRequest(rq).ShowLockMaybe(w, rq); shown {
return
}
if user.CanProceed(rq, "admin") { if user.CanProceed(rq, "admin") {
w.Header().Set("Content-Type", "text/html;charset=utf-8") w.Header().Set("Content-Type", "text/html;charset=utf-8")
w.WriteHeader(http.StatusOK) w.WriteHeader(http.StatusOK)
@ -48,9 +45,6 @@ func handlerAdmin(w http.ResponseWriter, rq *http.Request) {
// handlerAdminShutdown kills the wiki. // handlerAdminShutdown kills the wiki.
func handlerAdminShutdown(w http.ResponseWriter, rq *http.Request) { func handlerAdminShutdown(w http.ResponseWriter, rq *http.Request) {
util.PrepareRq(rq) util.PrepareRq(rq)
if shown := user.FromRequest(rq).ShowLockMaybe(w, rq); shown {
return
}
if user.CanProceed(rq, "admin/shutdown") && rq.Method == "POST" { if user.CanProceed(rq, "admin/shutdown") && rq.Method == "POST" {
log.Fatal("An admin commanded the wiki to shutdown") log.Fatal("An admin commanded the wiki to shutdown")
} }
@ -59,9 +53,6 @@ func handlerAdminShutdown(w http.ResponseWriter, rq *http.Request) {
// handlerAdminReindexUsers reinitialises the user system. // handlerAdminReindexUsers reinitialises the user system.
func handlerAdminReindexUsers(w http.ResponseWriter, rq *http.Request) { func handlerAdminReindexUsers(w http.ResponseWriter, rq *http.Request) {
util.PrepareRq(rq) util.PrepareRq(rq)
if shown := user.FromRequest(rq).ShowLockMaybe(w, rq); shown {
return
}
if user.CanProceed(rq, "admin") && rq.Method == "POST" { if user.CanProceed(rq, "admin") && rq.Method == "POST" {
user.ReadUsersFromFilesystem() user.ReadUsersFromFilesystem()
redirectTo := rq.Referer() redirectTo := rq.Referer()
@ -74,9 +65,6 @@ func handlerAdminReindexUsers(w http.ResponseWriter, rq *http.Request) {
func handlerAdminUsers(w http.ResponseWriter, rq *http.Request) { func handlerAdminUsers(w http.ResponseWriter, rq *http.Request) {
util.PrepareRq(rq) util.PrepareRq(rq)
if shown := user.FromRequest(rq).ShowLockMaybe(w, rq); shown {
return
}
if user.CanProceed(rq, "admin") { if user.CanProceed(rq, "admin") {
path := strings.TrimPrefix(rq.URL.Path, "/admin/users") path := strings.TrimPrefix(rq.URL.Path, "/admin/users")
parts := strings.Split(path, "/")[1:] parts := strings.Split(path, "/")[1:]
@ -178,9 +166,6 @@ func handlerAdminUsers(w http.ResponseWriter, rq *http.Request) {
func handlerAdminUserNew(w http.ResponseWriter, rq *http.Request) { func handlerAdminUserNew(w http.ResponseWriter, rq *http.Request) {
util.PrepareRq(rq) util.PrepareRq(rq)
if shown := user.FromRequest(rq).ShowLockMaybe(w, rq); shown {
return
}
if user.CanProceed(rq, "admin") { if user.CanProceed(rq, "admin") {
if rq.Method == http.MethodGet { if rq.Method == http.MethodGet {
// New user form // New user form

View File

@ -40,9 +40,6 @@ func handlerLock(w http.ResponseWriter, rq *http.Request) {
// handlerRegister both displays the register form (GET) and registers users (POST). // handlerRegister both displays the register form (GET) and registers users (POST).
func handlerRegister(w http.ResponseWriter, rq *http.Request) { func handlerRegister(w http.ResponseWriter, rq *http.Request) {
if shown := user.FromRequest(rq).ShowLockMaybe(w, rq); shown {
return
}
util.PrepareRq(rq) util.PrepareRq(rq)
if !cfg.AllowRegistration { if !cfg.AllowRegistration {
w.WriteHeader(http.StatusForbidden) w.WriteHeader(http.StatusForbidden)
@ -112,9 +109,6 @@ func handlerLogoutConfirm(w http.ResponseWriter, rq *http.Request) {
// handlerLogin shows the login form. // handlerLogin shows the login form.
func handlerLogin(w http.ResponseWriter, rq *http.Request) { func handlerLogin(w http.ResponseWriter, rq *http.Request) {
if shown := user.FromRequest(rq).ShowLockMaybe(w, rq); shown {
return
}
util.PrepareRq(rq) util.PrepareRq(rq)
w.Header().Set("Content-Type", "text/html;charset=utf-8") w.Header().Set("Content-Type", "text/html;charset=utf-8")
if cfg.UseAuth { if cfg.UseAuth {

View File

@ -27,9 +27,6 @@ func initHistory(r *mux.Router) {
// handlerHistory lists all revisions of a hypha. // handlerHistory lists all revisions of a hypha.
func handlerHistory(w http.ResponseWriter, rq *http.Request) { func handlerHistory(w http.ResponseWriter, rq *http.Request) {
util.PrepareRq(rq) util.PrepareRq(rq)
if shown := user.FromRequest(rq).ShowLockMaybe(w, rq); shown {
return
}
hyphaName := util.HyphaNameFromRq(rq, "history") hyphaName := util.HyphaNameFromRq(rq, "history")
var list string var list string
@ -47,9 +44,6 @@ func handlerHistory(w http.ResponseWriter, rq *http.Request) {
// handlerRecentChanges displays the /recent-changes/ page. // handlerRecentChanges displays the /recent-changes/ page.
func handlerRecentChanges(w http.ResponseWriter, rq *http.Request) { func handlerRecentChanges(w http.ResponseWriter, rq *http.Request) {
util.PrepareRq(rq) util.PrepareRq(rq)
if shown := user.FromRequest(rq).ShowLockMaybe(w, rq); shown {
return
}
var ( var (
noPrefix = strings.TrimPrefix(rq.URL.String(), "/recent-changes/") noPrefix = strings.TrimPrefix(rq.URL.String(), "/recent-changes/")
n, err = strconv.Atoi(noPrefix) n, err = strconv.Atoi(noPrefix)
@ -64,9 +58,6 @@ func handlerRecentChanges(w http.ResponseWriter, rq *http.Request) {
// genericHandlerOfFeeds is a helper function for the web feed handlers. // genericHandlerOfFeeds is a helper function for the web feed handlers.
func genericHandlerOfFeeds(w http.ResponseWriter, rq *http.Request, f func() (string, error), name string) { func genericHandlerOfFeeds(w http.ResponseWriter, rq *http.Request, f func() (string, error), name string) {
util.PrepareRq(rq) util.PrepareRq(rq)
if shown := user.FromRequest(rq).ShowLockMaybe(w, rq); shown {
return
}
if content, err := f(); err != nil { if content, err := f(); err != nil {
w.Header().Set("Content-Type", "text/plain;charset=utf-8") w.Header().Set("Content-Type", "text/plain;charset=utf-8")
w.WriteHeader(http.StatusInternalServerError) w.WriteHeader(http.StatusInternalServerError)

View File

@ -44,9 +44,6 @@ func factoryHandlerAsker(
h = hyphae.ByName(hyphaName) h = hyphae.ByName(hyphaName)
u = user.FromRequest(rq) u = user.FromRequest(rq)
) )
if shown := u.ShowLockMaybe(w, rq); shown {
return
}
if err, errtitle := asker(u, h); err != nil { if err, errtitle := asker(u, h); err != nil {
httpErr( httpErr(
w, w,
@ -97,9 +94,6 @@ func factoryHandlerConfirmer(
h = hyphae.ByName(hyphaName) h = hyphae.ByName(hyphaName)
u = user.FromRequest(rq) u = user.FromRequest(rq)
) )
if shown := u.ShowLockMaybe(w, rq); shown {
return
}
if hop, errtitle := confirmer(h, u, rq); hop.HasErrors() { if hop, errtitle := confirmer(h, u, rq); hop.HasErrors() {
httpErr(w, http.StatusInternalServerError, hyphaName, httpErr(w, http.StatusInternalServerError, hyphaName,
errtitle, errtitle,
@ -147,9 +141,6 @@ func handlerEdit(w http.ResponseWriter, rq *http.Request) {
err error err error
u = user.FromRequest(rq) u = user.FromRequest(rq)
) )
if shown := u.ShowLockMaybe(w, rq); shown {
return
}
if err, errtitle := shroom.CanEdit(u, h); err != nil { if err, errtitle := shroom.CanEdit(u, h); err != nil {
httpErr(w, http.StatusInternalServerError, hyphaName, httpErr(w, http.StatusInternalServerError, hyphaName,
errtitle, errtitle,
@ -189,9 +180,6 @@ func handlerUploadText(w http.ResponseWriter, rq *http.Request) {
hop *history.HistoryOp hop *history.HistoryOp
errtitle string errtitle string
) )
if shown := u.ShowLockMaybe(w, rq); shown {
return
}
if action != "Preview" { if action != "Preview" {
hop, errtitle = shroom.UploadText(h, []byte(textData), message, u) hop, errtitle = shroom.UploadText(h, []byte(textData), message, u)
@ -233,9 +221,6 @@ func handlerUploadBinary(w http.ResponseWriter, rq *http.Request) {
u = user.FromRequest(rq) u = user.FromRequest(rq)
file, handler, err = rq.FormFile("binary") file, handler, err = rq.FormFile("binary")
) )
if shown := u.ShowLockMaybe(w, rq); shown {
return
}
if err != nil { if err != nil {
httpErr(w, http.StatusInternalServerError, hyphaName, httpErr(w, http.StatusInternalServerError, hyphaName,
"Error", "Error",

View File

@ -39,9 +39,6 @@ func handlerAttachment(w http.ResponseWriter, rq *http.Request) {
h = hyphae.ByName(hyphaName) h = hyphae.ByName(hyphaName)
u = user.FromRequest(rq) u = user.FromRequest(rq)
) )
if shown := u.ShowLockMaybe(w, rq); shown {
return
}
util.HTTP200Page(w, util.HTTP200Page(w,
views.BaseHTML( views.BaseHTML(
fmt.Sprintf("Attachment of %s", util.BeautifulName(hyphaName)), fmt.Sprintf("Attachment of %s", util.BeautifulName(hyphaName)),
@ -59,9 +56,6 @@ func handlerPrimitiveDiff(w http.ResponseWriter, rq *http.Request) {
h = hyphae.ByName(hyphaName) h = hyphae.ByName(hyphaName)
u = user.FromRequest(rq) u = user.FromRequest(rq)
) )
if shown := u.ShowLockMaybe(w, rq); shown {
return
}
util.HTTP200Page(w, util.HTTP200Page(w,
views.BaseHTML( views.BaseHTML(
fmt.Sprintf("Diff of %s at %s", hyphaName, revHash), fmt.Sprintf("Diff of %s at %s", hyphaName, revHash),
@ -82,9 +76,6 @@ func handlerRevision(w http.ResponseWriter, rq *http.Request) {
textContents, err = history.FileAtRevision(h.TextPath, revHash) textContents, err = history.FileAtRevision(h.TextPath, revHash)
u = user.FromRequest(rq) u = user.FromRequest(rq)
) )
if shown := u.ShowLockMaybe(w, rq); shown {
return
}
if err == nil { if err == nil {
ctx, _ := mycocontext.ContextFromStringInput(hyphaName, textContents) ctx, _ := mycocontext.ContextFromStringInput(hyphaName, textContents)
contents = mycomarkup.BlocksToHTML(ctx, mycomarkup.BlockTree(ctx)) contents = mycomarkup.BlocksToHTML(ctx, mycomarkup.BlockTree(ctx))
@ -103,9 +94,6 @@ func handlerRevision(w http.ResponseWriter, rq *http.Request) {
// handlerText serves raw source text of the hypha. // handlerText serves raw source text of the hypha.
func handlerText(w http.ResponseWriter, rq *http.Request) { func handlerText(w http.ResponseWriter, rq *http.Request) {
util.PrepareRq(rq) util.PrepareRq(rq)
if shown := user.FromRequest(rq).ShowLockMaybe(w, rq); shown {
return
}
hyphaName := util.HyphaNameFromRq(rq, "text") hyphaName := util.HyphaNameFromRq(rq, "text")
if h := hyphae.ByName(hyphaName); h.Exists { if h := hyphae.ByName(hyphaName); h.Exists {
log.Println("Serving", h.TextPath) log.Println("Serving", h.TextPath)
@ -117,9 +105,6 @@ func handlerText(w http.ResponseWriter, rq *http.Request) {
// handlerBinary serves binary part of the hypha. // handlerBinary serves binary part of the hypha.
func handlerBinary(w http.ResponseWriter, rq *http.Request) { func handlerBinary(w http.ResponseWriter, rq *http.Request) {
util.PrepareRq(rq) util.PrepareRq(rq)
if shown := user.FromRequest(rq).ShowLockMaybe(w, rq); shown {
return
}
hyphaName := util.HyphaNameFromRq(rq, "binary") hyphaName := util.HyphaNameFromRq(rq, "binary")
if h := hyphae.ByName(hyphaName); h.Exists { if h := hyphae.ByName(hyphaName); h.Exists {
log.Println("Serving", h.BinaryPath) log.Println("Serving", h.BinaryPath)
@ -138,9 +123,6 @@ func handlerHypha(w http.ResponseWriter, rq *http.Request) {
openGraph string openGraph string
u = user.FromRequest(rq) u = user.FromRequest(rq)
) )
if shown := u.ShowLockMaybe(w, rq); shown {
return
}
if h.Exists { if h.Exists {
fileContentsT, errT := os.ReadFile(h.TextPath) fileContentsT, errT := os.ReadFile(h.TextPath)
_, errB := os.Stat(h.BinaryPath) _, errB := os.Stat(h.BinaryPath)

View File

@ -24,9 +24,6 @@ func handlerTitleSearch(w http.ResponseWriter, rq *http.Request) {
query = rq.FormValue("q") query = rq.FormValue("q")
u = user.FromRequest(rq) u = user.FromRequest(rq)
) )
if shown := u.ShowLockMaybe(w, rq); shown {
return
}
w.WriteHeader(http.StatusOK) w.WriteHeader(http.StatusOK)
_, _ = io.WriteString( _, _ = io.WriteString(
w, w,
@ -41,13 +38,7 @@ func handlerTitleSearch(w http.ResponseWriter, rq *http.Request) {
func handlerTitleSearchJSON(w http.ResponseWriter, rq *http.Request) { func handlerTitleSearchJSON(w http.ResponseWriter, rq *http.Request) {
util.PrepareRq(rq) util.PrepareRq(rq)
_ = rq.ParseForm() _ = rq.ParseForm()
var ( query := rq.FormValue("q")
query = rq.FormValue("q")
u = user.FromRequest(rq)
)
if shown := u.ShowLockMaybe(w, rq); shown {
return
}
w.WriteHeader(http.StatusOK) w.WriteHeader(http.StatusOK)
_, _ = io.WriteString( _, _ = io.WriteString(
w, w,

View File

@ -37,10 +37,6 @@ func initStuff(r *mux.Router) {
// handlerHelp gets the appropriate documentation or tells you where you (personally) have failed. // handlerHelp gets the appropriate documentation or tells you where you (personally) have failed.
func handlerHelp(w http.ResponseWriter, rq *http.Request) { func handlerHelp(w http.ResponseWriter, rq *http.Request) {
if shown := user.FromRequest(rq).ShowLockMaybe(w, rq); shown {
return
}
content, err := help.Get(rq.URL.Path[6:]) // Drop /help/ content, err := help.Get(rq.URL.Path[6:]) // Drop /help/
if err != nil && strings.HasPrefix(err.Error(), "open") { if err != nil && strings.HasPrefix(err.Error(), "open") {
w.WriteHeader(http.StatusNotFound) w.WriteHeader(http.StatusNotFound)
@ -80,9 +76,6 @@ func handlerHelp(w http.ResponseWriter, rq *http.Request) {
// handlerList shows a list of all hyphae in the wiki in random order. // handlerList shows a list of all hyphae in the wiki in random order.
func handlerList(w http.ResponseWriter, rq *http.Request) { func handlerList(w http.ResponseWriter, rq *http.Request) {
u := user.FromRequest(rq) u := user.FromRequest(rq)
if shown := u.ShowLockMaybe(w, rq); shown {
return
}
util.PrepareRq(rq) util.PrepareRq(rq)
util.HTTP200Page(w, views.BaseHTML("List of pages", views.HyphaListHTML(), u)) util.HTTP200Page(w, views.BaseHTML("List of pages", views.HyphaListHTML(), u))
} }
@ -90,9 +83,6 @@ func handlerList(w http.ResponseWriter, rq *http.Request) {
// handlerReindex reindexes all hyphae by checking the wiki storage directory anew. // handlerReindex reindexes all hyphae by checking the wiki storage directory anew.
func handlerReindex(w http.ResponseWriter, rq *http.Request) { func handlerReindex(w http.ResponseWriter, rq *http.Request) {
util.PrepareRq(rq) util.PrepareRq(rq)
if shown := user.FromRequest(rq).ShowLockMaybe(w, rq); shown {
return
}
if ok := user.CanProceed(rq, "reindex"); !ok { if ok := user.CanProceed(rq, "reindex"); !ok {
httpErr(w, http.StatusForbidden, cfg.HomeHypha, "Not enough rights", "You must be an admin to reindex hyphae.") httpErr(w, http.StatusForbidden, cfg.HomeHypha, "Not enough rights", "You must be an admin to reindex hyphae.")
log.Println("Rejected", rq.URL) log.Println("Rejected", rq.URL)
@ -110,9 +100,6 @@ func handlerReindex(w http.ResponseWriter, rq *http.Request) {
// See https://mycorrhiza.wiki/hypha/configuration/header // See https://mycorrhiza.wiki/hypha/configuration/header
func handlerUpdateHeaderLinks(w http.ResponseWriter, rq *http.Request) { func handlerUpdateHeaderLinks(w http.ResponseWriter, rq *http.Request) {
util.PrepareRq(rq) util.PrepareRq(rq)
if shown := user.FromRequest(rq).ShowLockMaybe(w, rq); shown {
return
}
if ok := user.CanProceed(rq, "update-header-links"); !ok { if ok := user.CanProceed(rq, "update-header-links"); !ok {
httpErr(w, http.StatusForbidden, cfg.HomeHypha, "Not enough rights", "You must be a moderator to update header links.") httpErr(w, http.StatusForbidden, cfg.HomeHypha, "Not enough rights", "You must be a moderator to update header links.")
log.Println("Rejected", rq.URL) log.Println("Rejected", rq.URL)
@ -125,9 +112,6 @@ func handlerUpdateHeaderLinks(w http.ResponseWriter, rq *http.Request) {
// handlerRandom redirects to a random hypha. // handlerRandom redirects to a random hypha.
func handlerRandom(w http.ResponseWriter, rq *http.Request) { func handlerRandom(w http.ResponseWriter, rq *http.Request) {
util.PrepareRq(rq) util.PrepareRq(rq)
if shown := user.FromRequest(rq).ShowLockMaybe(w, rq); shown {
return
}
var ( var (
randomHyphaName string randomHyphaName string
amountOfHyphae = hyphae.Count() amountOfHyphae = hyphae.Count()
@ -149,9 +133,6 @@ func handlerRandom(w http.ResponseWriter, rq *http.Request) {
// handlerAbout shows a summary of wiki's software. // handlerAbout shows a summary of wiki's software.
func handlerAbout(w http.ResponseWriter, rq *http.Request) { func handlerAbout(w http.ResponseWriter, rq *http.Request) {
if shown := user.FromRequest(rq).ShowLockMaybe(w, rq); shown {
return
}
w.Header().Set("Content-Type", "text/html;charset=utf-8") w.Header().Set("Content-Type", "text/html;charset=utf-8")
w.WriteHeader(http.StatusOK) w.WriteHeader(http.StatusOK)
_, err := io.WriteString(w, views.BaseHTML("About "+cfg.WikiName, views.AboutHTML(), user.FromRequest(rq))) _, err := io.WriteString(w, views.BaseHTML("About "+cfg.WikiName, views.AboutHTML(), user.FromRequest(rq)))

View File

@ -56,9 +56,6 @@ func handlerStyle(w http.ResponseWriter, rq *http.Request) {
} }
func handlerUserList(w http.ResponseWriter, rq *http.Request) { func handlerUserList(w http.ResponseWriter, rq *http.Request) {
if shown := user.FromRequest(rq).ShowLockMaybe(w, rq); shown {
return
}
w.Header().Set("Content-Type", mime.TypeByExtension(".html")) w.Header().Set("Content-Type", mime.TypeByExtension(".html"))
w.WriteHeader(http.StatusOK) w.WriteHeader(http.StatusOK)
w.Write([]byte(views.BaseHTML("User list", views.UserListHTML(), user.FromRequest(rq)))) w.Write([]byte(views.BaseHTML("User list", views.UserListHTML(), user.FromRequest(rq))))
@ -76,8 +73,8 @@ func handlerRobotsTxt(w http.ResponseWriter, rq *http.Request) {
} }
func Handler() http.Handler { func Handler() http.Handler {
r := mux.NewRouter() router := mux.NewRouter()
r.Use(func(next http.Handler) http.Handler { router.Use(func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Do stuff here // Do stuff here
log.Println(r.RequestURI) log.Println(r.RequestURI)
@ -86,32 +83,41 @@ func Handler() http.Handler {
}) })
}) })
// Available all the time // Public routes
initAuth(r) initAuth(router)
router.HandleFunc("/robots.txt", handlerRobotsTxt)
router.HandleFunc("/static/style.css", handlerStyle)
router.PathPrefix("/static/").
Handler(http.StripPrefix("/static/", http.FileServer(http.FS(static.FS))))
initReaders(r) // Wiki routes. They may be locked or restricted
initMutators(r) wikiRouter := router.PathPrefix("").Subrouter()
wikiRouter.Use(func(next http.Handler) http.Handler {
initAdmin(r) return http.HandlerFunc(func(w http.ResponseWriter, rq *http.Request) {
initHistory(r) user := user.FromRequest(rq)
initStuff(r) if !user.ShowLockMaybe(w, rq) {
initSearch(r) next.ServeHTTP(w, rq)
}
// Miscellaneous })
r.HandleFunc("/user-list", handlerUserList)
r.HandleFunc("/robots.txt", handlerRobotsTxt)
// Static assets
r.HandleFunc("/static/style.css", handlerStyle)
r.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(http.FS(static.FS))))
// Index page
r.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
// Let's pray it never fails
addr, _ := url.Parse("/hypha/" + cfg.HomeHypha)
r.URL = addr
handlerHypha(w, r)
}) })
return r initReaders(wikiRouter)
initMutators(wikiRouter)
initAdmin(wikiRouter)
initHistory(wikiRouter)
initStuff(wikiRouter)
initSearch(wikiRouter)
// Miscellaneous
wikiRouter.HandleFunc("/user-list", handlerUserList)
// Index page
wikiRouter.HandleFunc("/", func(w http.ResponseWriter, rq *http.Request) {
// Let's pray it never fails
addr, _ := url.Parse("/hypha/" + cfg.HomeHypha)
rq.URL = addr
handlerHypha(w, rq)
})
return router
} }