This commit is contained in:
@@ -11,21 +11,17 @@ import (
|
||||
)
|
||||
|
||||
type Router struct {
|
||||
static fs.FS
|
||||
lib Library
|
||||
rcol RecordCollection
|
||||
static fs.FS
|
||||
lib Library
|
||||
rcol RecordCollection
|
||||
ts *tailscale.LocalClient
|
||||
isAdmin bool
|
||||
}
|
||||
|
||||
type AdminRouter struct {
|
||||
static fs.FS
|
||||
lib Library
|
||||
ts *tailscale.LocalClient
|
||||
}
|
||||
type path map[string]func()
|
||||
|
||||
type handler map[string]func()
|
||||
|
||||
func (h handler) Handle(w http.ResponseWriter, req *http.Request) {
|
||||
if f, ok := h[req.Method]; ok {
|
||||
func (h path) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
if f, ok := h[r.Method]; ok {
|
||||
f()
|
||||
return
|
||||
}
|
||||
@@ -50,31 +46,33 @@ func writeJSON(w http.ResponseWriter, b any, status int) {
|
||||
|
||||
func (router *Router) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
switch r.URL.Path {
|
||||
case "/api/records":
|
||||
handler{
|
||||
http.MethodGet: func() { getRecords(router.rcol, w, r) },
|
||||
}.Handle(w, r)
|
||||
case "/api/books":
|
||||
handler{
|
||||
http.MethodGet: func() { getBooks(router.lib, w, r) },
|
||||
}.Handle(w, r)
|
||||
default:
|
||||
static(router.static).ServeHTTP(w, r)
|
||||
}
|
||||
}
|
||||
|
||||
func (router *AdminRouter) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
switch r.URL.Path {
|
||||
case "/api/mode":
|
||||
path{
|
||||
http.MethodGet: func() {
|
||||
writeJSON(w, struct{ Admin bool }{Admin: router.isAdmin}, http.StatusOK)
|
||||
},
|
||||
}.ServeHTTP(w, r)
|
||||
case "/api/whoami":
|
||||
handler{
|
||||
if !router.isAdmin {
|
||||
http.NotFoundHandler().ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
path{
|
||||
http.MethodGet: func() { getWhoAmI(router.ts, w, r) },
|
||||
}.Handle(w, r)
|
||||
}.ServeHTTP(w, r)
|
||||
case "/api/records":
|
||||
path{
|
||||
http.MethodGet: func() { getRecords(router.rcol, w, r) },
|
||||
}.ServeHTTP(w, r)
|
||||
case "/api/books":
|
||||
handler{
|
||||
http.MethodGet: func() { getBooks(router.lib, w, r) },
|
||||
http.MethodPost: func() { addBook(router.lib, w, r) },
|
||||
http.MethodDelete: func() { deleteBook(router.lib, w, r) },
|
||||
}.Handle(w, r)
|
||||
p := path{
|
||||
http.MethodGet: func() { getBooks(router.lib, w, r) },
|
||||
}
|
||||
if router.isAdmin {
|
||||
p[http.MethodPost] = func() { addBook(router.lib, w, r) }
|
||||
p[http.MethodDelete] = func() { deleteBook(router.lib, w, r) }
|
||||
}
|
||||
p.ServeHTTP(w, r)
|
||||
default:
|
||||
static(router.static).ServeHTTP(w, r)
|
||||
}
|
||||
|
@@ -55,24 +55,26 @@ func main() {
|
||||
c.DiscogsToken, time.Hour*24, c.DiscogsUser, c.DiscogsPersist, c.DiscogsCacheFile,
|
||||
))
|
||||
|
||||
frontendRoot := must.Get(frontend.Root())
|
||||
adminRoot := must.Get(frontend.AdminRoot())
|
||||
staticRoot := must.Get(frontend.Root())
|
||||
|
||||
servers := make(chan (*http.Server), 3)
|
||||
errGroup := errgroup.Group{}
|
||||
errGroup.Go(func() error {
|
||||
return start(servers)(
|
||||
publicServer(8080, &Router{
|
||||
static: frontendRoot,
|
||||
lib: lib,
|
||||
rcol: discogsCache,
|
||||
static: staticRoot,
|
||||
lib: lib,
|
||||
rcol: discogsCache,
|
||||
isAdmin: false,
|
||||
}))
|
||||
})
|
||||
errGroup.Go(func() error {
|
||||
return start(servers)(
|
||||
tailscaleListener("library-admin", &AdminRouter{
|
||||
static: adminRoot,
|
||||
lib: lib,
|
||||
tailscaleListener("library-admin", &Router{
|
||||
static: staticRoot,
|
||||
lib: lib,
|
||||
rcol: discogsCache,
|
||||
isAdmin: true,
|
||||
}))
|
||||
})
|
||||
errGroup.Go(func() error {
|
||||
@@ -143,10 +145,15 @@ func publicServer(port int, handler http.Handler) (*http.Server, net.Listener, e
|
||||
return server, ln, nil
|
||||
}
|
||||
|
||||
func tailscaleListener(hostname string, handler *AdminRouter) (*http.Server, net.Listener, error) {
|
||||
func tailscaleListener(hostname string, handler *Router) (*http.Server, net.Listener, error) {
|
||||
s := &tsnet.Server{
|
||||
Dir: ".config/" + hostname,
|
||||
Hostname: hostname,
|
||||
Logf: func(s string, a ...any) { // silence most tsnet logs
|
||||
if strings.HasPrefix(s, "To start this tsnet server") {
|
||||
log.Printf(s, a...)
|
||||
}
|
||||
},
|
||||
}
|
||||
ln, err := s.Listen("tcp", ":80")
|
||||
if err != nil {
|
||||
|
Reference in New Issue
Block a user