|
|
|
@ -18,12 +18,11 @@ limitations under the License.
|
|
|
|
|
package main
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"fmt"
|
|
|
|
|
"io/fs"
|
|
|
|
|
"net/http"
|
|
|
|
|
|
|
|
|
|
"github.com/julienschmidt/httprouter"
|
|
|
|
|
"github.com/justinas/alice"
|
|
|
|
|
"github.com/go-chi/chi/v5"
|
|
|
|
|
"github.com/go-chi/chi/v5/middleware"
|
|
|
|
|
"github.com/vearutop/statigz"
|
|
|
|
|
"github.com/vearutop/statigz/brotli"
|
|
|
|
|
|
|
|
|
@ -40,65 +39,75 @@ func (app *application) routes() http.Handler {
|
|
|
|
|
|
|
|
|
|
fileServer := statigz.FileServer(staticData, brotli.AddEncoding, statigz.EncodeOnInit)
|
|
|
|
|
|
|
|
|
|
router := httprouter.New()
|
|
|
|
|
router := chi.NewRouter()
|
|
|
|
|
|
|
|
|
|
router.NotFound = http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { app.notFound(w) })
|
|
|
|
|
router.PanicHandler = func(w http.ResponseWriter, _ *http.Request, err interface{}) {
|
|
|
|
|
w.Header().Set("Connection", "close")
|
|
|
|
|
app.serverError(w, fmt.Errorf("%s", err))
|
|
|
|
|
}
|
|
|
|
|
router.Use(middleware.RealIP)
|
|
|
|
|
router.Use(middleware.RequestLogger(&middleware.DefaultLogFormatter{Logger: app.infoLog}))
|
|
|
|
|
router.Use(middleware.Recoverer)
|
|
|
|
|
router.Use(secureHeaders)
|
|
|
|
|
|
|
|
|
|
router.NotFound(func(w http.ResponseWriter, _ *http.Request) { app.notFound(w) })
|
|
|
|
|
|
|
|
|
|
router.Handler(
|
|
|
|
|
http.MethodGet,
|
|
|
|
|
router.Get(
|
|
|
|
|
"/",
|
|
|
|
|
http.RedirectHandler("/motions/", http.StatusMovedPermanently),
|
|
|
|
|
http.RedirectHandler("/motions/", http.StatusMovedPermanently).ServeHTTP,
|
|
|
|
|
)
|
|
|
|
|
router.Handler(
|
|
|
|
|
http.MethodGet,
|
|
|
|
|
router.Get(
|
|
|
|
|
"/favicon.ico",
|
|
|
|
|
http.RedirectHandler("/static/images/favicon.ico", http.StatusMovedPermanently),
|
|
|
|
|
http.RedirectHandler("/static/images/favicon.ico", http.StatusMovedPermanently).ServeHTTP,
|
|
|
|
|
)
|
|
|
|
|
router.Handler(http.MethodGet, "/static/*filepath", http.StripPrefix("/static", fileServer))
|
|
|
|
|
|
|
|
|
|
dynamic := alice.New(
|
|
|
|
|
app.sessionManager.LoadAndSave,
|
|
|
|
|
app.tryAuthenticate,
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
canVote := dynamic.Append(app.userCanVote, noSurf)
|
|
|
|
|
canEditVote := dynamic.Append(app.userCanEditVote, noSurf)
|
|
|
|
|
canManageUsers := dynamic.Append(app.userCanChangeVoters, noSurf)
|
|
|
|
|
|
|
|
|
|
router.Handler(http.MethodGet, "/motions/", dynamic.ThenFunc(app.motionList))
|
|
|
|
|
router.Handler(http.MethodGet, "/motions/:tag", dynamic.ThenFunc(app.motionDetails))
|
|
|
|
|
router.Handler(http.MethodGet, "/motions/:tag/edit", canEditVote.ThenFunc(app.editMotionForm))
|
|
|
|
|
router.Handler(http.MethodPost, "/motions/:tag/edit", canEditVote.ThenFunc(app.editMotionSubmit))
|
|
|
|
|
router.Handler(http.MethodGet, "/motions/:tag/withdraw", canEditVote.ThenFunc(app.withdrawMotionForm))
|
|
|
|
|
router.Handler(http.MethodPost, "/motions/:tag/withdraw", canEditVote.ThenFunc(app.withdrawMotionSubmit))
|
|
|
|
|
router.Handler(http.MethodGet, "/vote/:tag/:choice", canVote.ThenFunc(app.voteForm))
|
|
|
|
|
router.Handler(http.MethodPost, "/vote/:tag/:choice", canVote.ThenFunc(app.voteSubmit))
|
|
|
|
|
router.Handler(http.MethodGet, "/proxy/:tag", canVote.ThenFunc(app.proxyVoteForm))
|
|
|
|
|
router.Handler(http.MethodPost, "/proxy/:tag", canVote.ThenFunc(app.proxyVoteSubmit))
|
|
|
|
|
router.Handler(http.MethodGet, "/newmotion/", canEditVote.ThenFunc(app.newMotionForm))
|
|
|
|
|
router.Handler(http.MethodPost, "/newmotion/", canEditVote.ThenFunc(app.newMotionSubmit))
|
|
|
|
|
|
|
|
|
|
router.Handler(http.MethodGet, "/users/", canManageUsers.ThenFunc(app.userList))
|
|
|
|
|
router.Handler(http.MethodGet, "/new-user/", canManageUsers.ThenFunc(app.newUserForm))
|
|
|
|
|
router.Handler(http.MethodPost, "/new-user/", canManageUsers.ThenFunc(app.newUserSubmit))
|
|
|
|
|
router.Handler(http.MethodGet, "/users/:id/", canManageUsers.ThenFunc(app.editUserForm))
|
|
|
|
|
router.Handler(http.MethodPost, "/users/:id/", canManageUsers.ThenFunc(app.editUserSubmit))
|
|
|
|
|
router.Handler(http.MethodGet, "/users/:id/add-mail", canManageUsers.ThenFunc(app.userAddEmailForm))
|
|
|
|
|
router.Handler(http.MethodPost, "/users/:id/add-mail", canManageUsers.ThenFunc(app.userAddEmailSubmit))
|
|
|
|
|
router.Handler(http.MethodGet, "/users/:id/mail/:address/delete",
|
|
|
|
|
canManageUsers.ThenFunc(app.userDeleteEmailForm))
|
|
|
|
|
router.Handler(http.MethodPost, "/users/:id/mail/:address/delete",
|
|
|
|
|
canManageUsers.ThenFunc(app.userDeleteEmailSubmit))
|
|
|
|
|
router.Handler(http.MethodGet, "/users/:id/delete", canManageUsers.ThenFunc(app.deleteUserForm))
|
|
|
|
|
router.Handler(http.MethodPost, "/users/:id/delete", canManageUsers.ThenFunc(app.deleteUserSubmit))
|
|
|
|
|
|
|
|
|
|
router.HandlerFunc(http.MethodGet, "/health", app.healthCheck)
|
|
|
|
|
|
|
|
|
|
standard := alice.New(app.logRequest, secureHeaders)
|
|
|
|
|
|
|
|
|
|
return standard.Then(router)
|
|
|
|
|
router.Get("/static/*", http.StripPrefix("/static", fileServer).ServeHTTP)
|
|
|
|
|
|
|
|
|
|
router.Group(func(r chi.Router) {
|
|
|
|
|
r.Use(app.sessionManager.LoadAndSave, app.tryAuthenticate)
|
|
|
|
|
|
|
|
|
|
r.Get("/motions/", app.motionList)
|
|
|
|
|
r.Get("/motions/{tag}", app.motionDetails)
|
|
|
|
|
|
|
|
|
|
r.Group(func(r chi.Router) {
|
|
|
|
|
r.Use(app.userCanEditVote, noSurf)
|
|
|
|
|
|
|
|
|
|
r.Get("/newmotion/", app.newMotionForm)
|
|
|
|
|
r.Post("/newmotion/", app.newMotionSubmit)
|
|
|
|
|
|
|
|
|
|
r.Route("/motions/{tag}", func(r chi.Router) {
|
|
|
|
|
r.Get("/edit", app.editMotionForm)
|
|
|
|
|
r.Post("/edit", app.editMotionSubmit)
|
|
|
|
|
r.Get("/withdraw", app.withdrawMotionForm)
|
|
|
|
|
r.Post("/withdraw", app.withdrawMotionSubmit)
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
r.Group(func(r chi.Router) {
|
|
|
|
|
r.Use(app.userCanVote, noSurf)
|
|
|
|
|
|
|
|
|
|
r.Get("/vote/{tag}/{choice}", app.voteForm)
|
|
|
|
|
r.Post("/vote/{tag}/{choice}", app.voteSubmit)
|
|
|
|
|
r.Get("/proxy/{tag}", app.proxyVoteForm)
|
|
|
|
|
r.Post("/proxy/{tag}", app.proxyVoteSubmit)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
r.Group(func(r chi.Router) {
|
|
|
|
|
r.Use(app.canManageUsers, noSurf)
|
|
|
|
|
|
|
|
|
|
r.Get("/users/", app.userList)
|
|
|
|
|
r.Get("/new-user/", app.newUserForm)
|
|
|
|
|
r.Post("/new-user/", app.newUserSubmit)
|
|
|
|
|
|
|
|
|
|
r.Route("/users/{id}", func(r chi.Router) {
|
|
|
|
|
r.Get("/", app.editUserForm)
|
|
|
|
|
r.Post("/", app.editUserSubmit)
|
|
|
|
|
r.Get("/add-mail", app.userAddEmailForm)
|
|
|
|
|
r.Post("/add-mail", app.userAddEmailSubmit)
|
|
|
|
|
r.Get("/mail/{address}/delete", app.userDeleteEmailForm)
|
|
|
|
|
r.Post("/mail/{address}/delete", app.userDeleteEmailSubmit)
|
|
|
|
|
r.Get("/delete", app.deleteUserForm)
|
|
|
|
|
r.Post("/delete", app.deleteUserSubmit)
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
router.Get("/health", app.healthCheck)
|
|
|
|
|
|
|
|
|
|
return router
|
|
|
|
|
}
|
|
|
|
|