145 lines
3.8 KiB
Go
145 lines
3.8 KiB
Go
package handlers
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"net/http"
|
|
|
|
"github.com/gorilla/mux"
|
|
"github.com/gorilla/securecookie"
|
|
"github.com/gorilla/sessions"
|
|
"go.mindeco.de/http/auth"
|
|
"go.mindeco.de/http/render"
|
|
|
|
"github.com/ssb-ngi-pointer/gossb-rooms/admindb"
|
|
"github.com/ssb-ngi-pointer/gossb-rooms/internal/repo"
|
|
"github.com/ssb-ngi-pointer/gossb-rooms/web"
|
|
"github.com/ssb-ngi-pointer/gossb-rooms/web/handlers/admin"
|
|
roomsAuth "github.com/ssb-ngi-pointer/gossb-rooms/web/handlers/auth"
|
|
"github.com/ssb-ngi-pointer/gossb-rooms/web/handlers/news"
|
|
"github.com/ssb-ngi-pointer/gossb-rooms/web/i18n"
|
|
"github.com/ssb-ngi-pointer/gossb-rooms/web/router"
|
|
)
|
|
|
|
// New initializes the whole web stack for rooms, with all the sub-modules and routing.
|
|
func New(
|
|
m *mux.Router,
|
|
repo repo.Interface,
|
|
as admindb.AuthService,
|
|
fs admindb.FallbackAuth,
|
|
) (http.Handler, error) {
|
|
if m == nil {
|
|
m = router.CompleteApp()
|
|
}
|
|
|
|
locHelper, err := i18n.New(repo)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
r, err := render.New(web.Templates,
|
|
render.BaseTemplates("/base.tmpl"),
|
|
render.AddTemplates(concatTemplates(
|
|
[]string{
|
|
"/landing/index.tmpl",
|
|
"/landing/about.tmpl",
|
|
"/error.tmpl",
|
|
},
|
|
news.HTMLTemplates,
|
|
admin.HTMLTemplates,
|
|
)...),
|
|
render.FuncMap(web.TemplateFuncs(m)),
|
|
// TODO: add plural and template data variants
|
|
// TODO: move these to the i18n helper pkg
|
|
render.InjectTemplateFunc("i18n", func(r *http.Request) interface{} {
|
|
lang := r.FormValue("lang")
|
|
accept := r.Header.Get("Accept-Language")
|
|
loc := locHelper.NewLocalizer(lang, accept)
|
|
return loc.LocalizeSimple
|
|
}),
|
|
)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("web Handler: failed to create renderer: %w", err)
|
|
}
|
|
|
|
// TODO: generate & persist me
|
|
// repo.GetPath("web-cookie")
|
|
store := &sessions.CookieStore{
|
|
Codecs: securecookie.CodecsFromPairs(
|
|
bytes.Repeat([]byte("acab"), 8),
|
|
bytes.Repeat([]byte("beef"), 8),
|
|
// securecookie.GenerateRandomKey(32), // new key every time we startup
|
|
// securecookie.GenerateRandomKey(32),
|
|
),
|
|
Options: &sessions.Options{
|
|
Path: "/",
|
|
MaxAge: 30,
|
|
},
|
|
}
|
|
|
|
notAuthorizedH := r.HTML("/error.tmpl", func(rw http.ResponseWriter, req *http.Request) (interface{}, error) {
|
|
statusCode := http.StatusUnauthorized
|
|
rw.WriteHeader(statusCode)
|
|
return errorTemplateData{
|
|
statusCode,
|
|
"Unauthorized",
|
|
"you are not authorized to access the requested site",
|
|
}, nil
|
|
})
|
|
|
|
a, err := auth.NewHandler(fs,
|
|
auth.SetStore(store),
|
|
auth.SetNotAuthorizedHandler(notAuthorizedH),
|
|
)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("web Handler: failed to init fallback auth system: %w", err)
|
|
}
|
|
|
|
// hookup handlers to the router
|
|
roomsAuth.Handler(m, r, a)
|
|
|
|
adminRouter := m.PathPrefix("/admin").Subrouter()
|
|
adminRouter.Use(a.Authenticate)
|
|
|
|
// we dont strip path here because it somehow fucks with the middleware setup
|
|
adminRouter.PathPrefix("/").Handler(admin.Handler(adminRouter, r))
|
|
|
|
m.PathPrefix("/news").Handler(http.StripPrefix("/news", news.Handler(m, r)))
|
|
|
|
m.Get(router.CompleteIndex).Handler(r.StaticHTML("/landing/index.tmpl"))
|
|
m.Get(router.CompleteAbout).Handler(r.StaticHTML("/landing/about.tmpl"))
|
|
|
|
m.PathPrefix("/assets/").Handler(http.StripPrefix("/assets/", http.FileServer(web.Assets)))
|
|
|
|
m.NotFoundHandler = r.HTML("/error.tmpl", func(rw http.ResponseWriter, req *http.Request) (interface{}, error) {
|
|
rw.WriteHeader(http.StatusNotFound)
|
|
return errorTemplateData{http.StatusNotFound, "Not Found", "the requested page wasnt found.."}, nil
|
|
})
|
|
|
|
if web.Production {
|
|
return m, nil
|
|
}
|
|
|
|
return r.GetReloader()(m), nil
|
|
}
|
|
|
|
// utils
|
|
|
|
type errorTemplateData struct {
|
|
StatusCode int
|
|
Status string
|
|
Err string
|
|
}
|
|
|
|
func concatTemplates(lst ...[]string) []string {
|
|
var catted []string
|
|
|
|
for _, tpls := range lst {
|
|
for _, t := range tpls {
|
|
catted = append(catted, t)
|
|
}
|
|
|
|
}
|
|
return catted
|
|
}
|