diff --git a/auth/web.go b/auth/web.go
deleted file mode 100644
index ee93bc9..0000000
--- a/auth/web.go
+++ /dev/null
@@ -1,225 +0,0 @@
-package auth
-
-import (
- "errors"
- "fmt"
- "io"
- "log"
- "mime"
- "net/http"
- "strings"
-
- "github.com/bouncepaw/mycorrhiza/viewutil"
-
- "github.com/gorilla/mux"
-
- "github.com/bouncepaw/mycorrhiza/cfg"
- "github.com/bouncepaw/mycorrhiza/l18n"
- "github.com/bouncepaw/mycorrhiza/user"
- "github.com/bouncepaw/mycorrhiza/util"
-)
-
-func InitAuth(r *mux.Router) {
- r.HandleFunc("/user-list", handlerUserList)
- r.HandleFunc("/lock", handlerLock)
- // The check below saves a lot of extra checks and lines of codes in other places in this file.
- if !cfg.UseAuth {
- return
- }
- if cfg.AllowRegistration {
- r.HandleFunc("/register", handlerRegister).Methods(http.MethodPost, http.MethodGet)
- }
- if cfg.TelegramEnabled {
- r.HandleFunc("/telegram-login", handlerTelegramLogin)
- }
- r.HandleFunc("/login", handlerLogin)
- r.HandleFunc("/logout", handlerLogout)
-}
-
-func handlerUserList(w http.ResponseWriter, rq *http.Request) {
- lc := l18n.FromRequest(rq)
- w.Header().Set("Content-Type", mime.TypeByExtension(".html"))
- w.WriteHeader(http.StatusOK)
- w.Write([]byte(viewutil.Base(viewutil.MetaFrom(w, rq), lc.Get("ui.users_title"), UserList(lc), map[string]string{})))
-}
-
-func handlerLock(w http.ResponseWriter, rq *http.Request) {
- _, _ = io.WriteString(w, Lock(l18n.FromRequest(rq)))
-}
-
-// handlerRegister displays the register form (GET) or registers the user (POST).
-func handlerRegister(w http.ResponseWriter, rq *http.Request) {
- lc := l18n.FromRequest(rq)
- util.PrepareRq(rq)
- if rq.Method == http.MethodGet {
- _, _ = io.WriteString(
- w,
- viewutil.Base(
- viewutil.MetaFrom(w, rq),
- lc.Get("auth.register_title"),
- Register(rq),
- map[string]string{},
- ),
- )
- return
- }
-
- var (
- username = rq.PostFormValue("username")
- password = rq.PostFormValue("password")
- err = user.Register(username, password, "editor", "local", false)
- )
- if err != nil {
- log.Printf("Failed to register ‘%s’: %s", username, err.Error())
- w.Header().Set("Content-Type", mime.TypeByExtension(".html"))
- w.WriteHeader(http.StatusBadRequest)
- _, _ = io.WriteString(
- w,
- viewutil.Base(
- viewutil.MetaFrom(w, rq),
- lc.Get("auth.register_title"),
- fmt.Sprintf(
- `%s
%s
`,
- err.Error(),
- lc.Get("auth.try_again"),
- ),
- map[string]string{},
- ),
- )
- return
- }
-
- log.Printf("Successfully registered ‘%s’", username)
- if err := user.LoginDataHTTP(w, username, password); err != nil {
- return
- }
- http.Redirect(w, rq, "/"+rq.URL.RawQuery, http.StatusSeeOther)
-}
-
-// handlerLogout shows the logout form (GET) or logs the user out (POST).
-func handlerLogout(w http.ResponseWriter, rq *http.Request) {
- if rq.Method == http.MethodGet {
- var (
- u = user.FromRequest(rq)
- can = u != nil
- lc = l18n.FromRequest(rq)
- )
- w.Header().Set("Content-Type", "text/html;charset=utf-8")
- if can {
- log.Println("User", u.Name, "tries to log out")
- w.WriteHeader(http.StatusOK)
- } else {
- log.Println("Unknown user tries to log out")
- w.WriteHeader(http.StatusForbidden)
- }
- _, _ = io.WriteString(
- w,
- viewutil.Base(viewutil.MetaFrom(w, rq), lc.Get("auth.logout_title"), Logout(can, lc), map[string]string{}),
- )
- } else if rq.Method == http.MethodPost {
- user.LogoutFromRequest(w, rq)
- http.Redirect(w, rq, "/", http.StatusSeeOther)
- }
-}
-
-// handlerLogin shows the login form (GET) or logs the user in (POST).
-func handlerLogin(w http.ResponseWriter, rq *http.Request) {
- lc := l18n.FromRequest(rq)
- if rq.Method == http.MethodGet {
- w.Header().Set("Content-Type", "text/html;charset=utf-8")
- w.WriteHeader(http.StatusOK)
- _, _ = io.WriteString(
- w,
- viewutil.Base(
- viewutil.MetaFrom(w, rq),
- lc.Get("auth.login_title"),
- Login(lc),
- map[string]string{},
- ),
- )
- } else if rq.Method == http.MethodPost {
- var (
- username = util.CanonicalName(rq.PostFormValue("username"))
- password = rq.PostFormValue("password")
- err = user.LoginDataHTTP(w, username, password)
- )
- if err != nil {
- w.Header().Set("Content-Type", "text/html;charset=utf-8")
- w.WriteHeader(http.StatusInternalServerError)
- _, _ = io.WriteString(w, viewutil.Base(viewutil.MetaFrom(w, rq), err.Error(), LoginError(err.Error(), lc), map[string]string{}))
- return
- }
- http.Redirect(w, rq, "/", http.StatusSeeOther)
- }
-}
-
-func handlerTelegramLogin(w http.ResponseWriter, rq *http.Request) {
- // Note there is no lock here.
- lc := l18n.FromRequest(rq)
- w.Header().Set("Content-Type", "text/html;charset=utf-8")
- rq.ParseForm()
- var (
- values = rq.URL.Query()
- username = strings.ToLower(values.Get("username"))
- seemsValid = user.TelegramAuthParamsAreValid(values)
- err = user.Register(
- username,
- "", // Password matters not
- "editor",
- "telegram",
- false,
- )
- )
- // If registering a user via Telegram failed, because a Telegram user with this name
- // has already registered, then everything is actually ok!
- if user.HasUsername(username) && user.ByName(username).Source == "telegram" {
- err = nil
- }
-
- if !seemsValid {
- err = errors.New("Wrong parameters")
- }
-
- if err != nil {
- log.Printf("Failed to register ‘%s’ using Telegram: %s", username, err.Error())
- w.WriteHeader(http.StatusBadRequest)
- _, _ = io.WriteString(
- w,
- viewutil.Base(
- viewutil.MetaFrom(w, rq),
- lc.Get("ui.error"),
- fmt.Sprintf(
- `%s
%s
%s
`,
- lc.Get("auth.error_telegram"),
- err.Error(),
- lc.Get("auth.go_login"),
- ),
- map[string]string{},
- ),
- )
- return
- }
-
- errmsg := user.LoginDataHTTP(w, username, "")
- if errmsg != nil {
- log.Printf("Failed to login ‘%s’ using Telegram: %s", username, err.Error())
- w.WriteHeader(http.StatusBadRequest)
- _, _ = io.WriteString(
- w,
- viewutil.Base(
- viewutil.MetaFrom(w, rq),
- "Error",
- fmt.Sprintf(
- `%s
%s
%s
`,
- lc.Get("auth.error_telegram"),
- err.Error(),
- lc.Get("auth.go_login"),
- ),
- map[string]string{},
- ),
- )
- return
- }
- log.Printf("Authorize ‘%s’ from Telegram", username)
- http.Redirect(w, rq, "/", http.StatusSeeOther)
-}
diff --git a/web/web.go b/web/web.go
index 3b2c0f6..b4d31e1 100644
--- a/web/web.go
+++ b/web/web.go
@@ -2,9 +2,16 @@
package web
import (
+ "errors"
+ "fmt"
+ "github.com/bouncepaw/mycorrhiza/l18n"
+ "github.com/bouncepaw/mycorrhiza/viewutil"
"io"
+ "log"
+ "mime"
"net/http"
"net/url"
+ "strings"
"github.com/bouncepaw/mycorrhiza/admin"
"github.com/bouncepaw/mycorrhiza/auth"
@@ -39,11 +46,25 @@ func Handler() http.Handler {
// Public routes. They're always accessible regardless of the user status.
misc.InitAssetHandlers(router)
- auth.InitAuth(router)
+
+ // Auth
+ router.HandleFunc("/user-list", handlerUserList)
+ router.HandleFunc("/lock", handlerLock)
+ // The check below saves a lot of extra checks and lines of codes in other places in this file.
+ if cfg.UseAuth {
+ if cfg.AllowRegistration {
+ router.HandleFunc("/register", handlerRegister).Methods(http.MethodPost, http.MethodGet)
+ }
+ if cfg.TelegramEnabled {
+ router.HandleFunc("/telegram-login", handlerTelegramLogin)
+ }
+ router.HandleFunc("/login", handlerLogin)
+ router.HandleFunc("/logout", handlerLogout)
+ }
// Wiki routes. They may be locked or restricted.
- wikiRouter := router.PathPrefix("").Subrouter()
- wikiRouter.Use(func(next http.Handler) http.Handler {
+ r := router.PathPrefix("").Subrouter()
+ r.Use(func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, rq *http.Request) {
user := user.FromRequest(rq)
if !user.ShowLockMaybe(w, rq) {
@@ -52,35 +73,37 @@ func Handler() http.Handler {
})
})
- initReaders(wikiRouter)
- initMutators(wikiRouter)
- help.InitHandlers(wikiRouter)
- categories.InitHandlers(wikiRouter)
- misc.InitHandlers(wikiRouter)
+ initReaders(r)
+ initMutators(r)
+ help.InitHandlers(r)
+ categories.InitHandlers(r)
+ misc.InitHandlers(r)
hypview.Init()
- histweb.InitHandlers(wikiRouter)
- interwiki.InitHandlers(wikiRouter)
+ histweb.InitHandlers(r)
+ interwiki.InitHandlers(r)
// Admin routes
if cfg.UseAuth {
- adminRouter := wikiRouter.PathPrefix("/admin").Subrouter()
+ adminRouter := r.PathPrefix("/admin").Subrouter()
adminRouter.Use(groupMiddleware("admin"))
admin.Init(adminRouter)
- settingsRouter := wikiRouter.PathPrefix("/settings").Subrouter()
+ settingsRouter := r.PathPrefix("/settings").Subrouter()
// TODO: check if necessary?
//settingsRouter.Use(groupMiddleware("settings"))
settings.Init(settingsRouter)
}
// Index page
- wikiRouter.HandleFunc("/", func(w http.ResponseWriter, rq *http.Request) {
+ r.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)
})
+ initPages()
+
return router
}
@@ -100,3 +123,192 @@ func groupMiddleware(group string) func(http.Handler) http.Handler {
})
}
}
+
+// Auth
+func handlerUserList(w http.ResponseWriter, rq *http.Request) {
+ lc := l18n.FromRequest(rq)
+ w.Header().Set("Content-Type", mime.TypeByExtension(".html"))
+ w.WriteHeader(http.StatusOK)
+ w.Write([]byte(viewutil.Base(viewutil.MetaFrom(w, rq), lc.Get("ui.users_title"), auth.UserList(lc), map[string]string{})))
+}
+
+func handlerLock(w http.ResponseWriter, rq *http.Request) {
+ _, _ = io.WriteString(w, auth.Lock(l18n.FromRequest(rq)))
+}
+
+// handlerRegister displays the register form (GET) or registers the user (POST).
+func handlerRegister(w http.ResponseWriter, rq *http.Request) {
+ lc := l18n.FromRequest(rq)
+ util.PrepareRq(rq)
+ if rq.Method == http.MethodGet {
+ _, _ = io.WriteString(
+ w,
+ viewutil.Base(
+ viewutil.MetaFrom(w, rq),
+ lc.Get("auth.register_title"),
+ auth.Register(rq),
+ map[string]string{},
+ ),
+ )
+ return
+ }
+
+ var (
+ username = rq.PostFormValue("username")
+ password = rq.PostFormValue("password")
+ err = user.Register(username, password, "editor", "local", false)
+ )
+ if err != nil {
+ log.Printf("Failed to register ‘%s’: %s", username, err.Error())
+ w.Header().Set("Content-Type", mime.TypeByExtension(".html"))
+ w.WriteHeader(http.StatusBadRequest)
+ _, _ = io.WriteString(
+ w,
+ viewutil.Base(
+ viewutil.MetaFrom(w, rq),
+ lc.Get("auth.register_title"),
+ fmt.Sprintf(
+ `%s
%s
`,
+ err.Error(),
+ lc.Get("auth.try_again"),
+ ),
+ map[string]string{},
+ ),
+ )
+ return
+ }
+
+ log.Printf("Successfully registered ‘%s’", username)
+ if err := user.LoginDataHTTP(w, username, password); err != nil {
+ return
+ }
+ http.Redirect(w, rq, "/"+rq.URL.RawQuery, http.StatusSeeOther)
+}
+
+// handlerLogout shows the logout form (GET) or logs the user out (POST).
+func handlerLogout(w http.ResponseWriter, rq *http.Request) {
+ if rq.Method == http.MethodGet {
+ var (
+ u = user.FromRequest(rq)
+ can = u != nil
+ lc = l18n.FromRequest(rq)
+ )
+ w.Header().Set("Content-Type", "text/html;charset=utf-8")
+ if can {
+ log.Println("User", u.Name, "tries to log out")
+ w.WriteHeader(http.StatusOK)
+ } else {
+ log.Println("Unknown user tries to log out")
+ w.WriteHeader(http.StatusForbidden)
+ }
+ _, _ = io.WriteString(
+ w,
+ viewutil.Base(viewutil.MetaFrom(w, rq), lc.Get("auth.logout_title"), auth.Logout(can, lc), map[string]string{}),
+ )
+ } else if rq.Method == http.MethodPost {
+ user.LogoutFromRequest(w, rq)
+ http.Redirect(w, rq, "/", http.StatusSeeOther)
+ }
+}
+
+// handlerLogin shows the login form (GET) or logs the user in (POST).
+func handlerLogin(w http.ResponseWriter, rq *http.Request) {
+ lc := l18n.FromRequest(rq)
+ if rq.Method == http.MethodGet {
+ w.Header().Set("Content-Type", "text/html;charset=utf-8")
+ w.WriteHeader(http.StatusOK)
+ _, _ = io.WriteString(
+ w,
+ viewutil.Base(
+ viewutil.MetaFrom(w, rq),
+ lc.Get("auth.login_title"),
+ auth.Login(lc),
+ map[string]string{},
+ ),
+ )
+ } else if rq.Method == http.MethodPost {
+ var (
+ username = util.CanonicalName(rq.PostFormValue("username"))
+ password = rq.PostFormValue("password")
+ err = user.LoginDataHTTP(w, username, password)
+ )
+ if err != nil {
+ w.Header().Set("Content-Type", "text/html;charset=utf-8")
+ w.WriteHeader(http.StatusInternalServerError)
+ _, _ = io.WriteString(w, viewutil.Base(viewutil.MetaFrom(w, rq), err.Error(), auth.LoginError(err.Error(), lc), map[string]string{}))
+ return
+ }
+ http.Redirect(w, rq, "/", http.StatusSeeOther)
+ }
+}
+
+func handlerTelegramLogin(w http.ResponseWriter, rq *http.Request) {
+ // Note there is no lock here.
+ lc := l18n.FromRequest(rq)
+ w.Header().Set("Content-Type", "text/html;charset=utf-8")
+ rq.ParseForm()
+ var (
+ values = rq.URL.Query()
+ username = strings.ToLower(values.Get("username"))
+ seemsValid = user.TelegramAuthParamsAreValid(values)
+ err = user.Register(
+ username,
+ "", // Password matters not
+ "editor",
+ "telegram",
+ false,
+ )
+ )
+ // If registering a user via Telegram failed, because a Telegram user with this name
+ // has already registered, then everything is actually ok!
+ if user.HasUsername(username) && user.ByName(username).Source == "telegram" {
+ err = nil
+ }
+
+ if !seemsValid {
+ err = errors.New("Wrong parameters")
+ }
+
+ if err != nil {
+ log.Printf("Failed to register ‘%s’ using Telegram: %s", username, err.Error())
+ w.WriteHeader(http.StatusBadRequest)
+ _, _ = io.WriteString(
+ w,
+ viewutil.Base(
+ viewutil.MetaFrom(w, rq),
+ lc.Get("ui.error"),
+ fmt.Sprintf(
+ `%s
%s
%s
`,
+ lc.Get("auth.error_telegram"),
+ err.Error(),
+ lc.Get("auth.go_login"),
+ ),
+ map[string]string{},
+ ),
+ )
+ return
+ }
+
+ errmsg := user.LoginDataHTTP(w, username, "")
+ if errmsg != nil {
+ log.Printf("Failed to login ‘%s’ using Telegram: %s", username, err.Error())
+ w.WriteHeader(http.StatusBadRequest)
+ _, _ = io.WriteString(
+ w,
+ viewutil.Base(
+ viewutil.MetaFrom(w, rq),
+ "Error",
+ fmt.Sprintf(
+ `%s
%s
%s
`,
+ lc.Get("auth.error_telegram"),
+ err.Error(),
+ lc.Get("auth.go_login"),
+ ),
+ map[string]string{},
+ ),
+ )
+ return
+ }
+ log.Printf("Authorize ‘%s’ from Telegram", username)
+ http.Redirect(w, rq, "/", http.StatusSeeOther)
+}