diff --git a/handlers.go b/handlers.go index 86bd4f9..9bcf6e6 100644 --- a/handlers.go +++ b/handlers.go @@ -31,6 +31,7 @@ type Response struct { Error string User string + IsAdmin bool Section string // Paging @@ -54,16 +55,28 @@ type Response struct { Youtubes []youtube.Video } +func stringInSlice(a string, list []string) bool { + for _, b := range list { + if b == a { + return true + } + } + return false +} + func NewResponse(r *http.Request, ps httprouter.Params) *Response { diskInfo, err := NewDiskInfo(datadir) if err != nil { panic(err) } + user, _, _ := r.BasicAuth() + isAdmin := stringInSlice(user, httpAdminUsers) return &Response{ Config: config.Get(), Request: r, Params: &ps, User: ps.ByName("user"), + IsAdmin: isAdmin, HTTPHost: httpHost, Version: version, Backlink: backlink, diff --git a/main.go b/main.go index ce0ed27..d7b2e28 100644 --- a/main.go +++ b/main.go @@ -32,6 +32,9 @@ var ( debug bool httpAddr string httpAdmins arrayFlags + httpAdminUsers []string + httpReadOnlys arrayFlags + httpReadOnlyUsers []string httpHost string httpPrefix string letsencrypt bool @@ -61,7 +64,8 @@ func init() { cli.StringVar(&datadir, "data-dir", "/data", "data directory") cli.BoolVar(&debug, "debug", false, "debug mode") cli.StringVar(&httpAddr, "http-addr", ":80", "listen address") - cli.Var(&httpAdmins, "http-admin", "HTTP basic auth user/password for admin.") + cli.Var(&httpAdmins, "http-admin", "HTTP basic auth user/password for admins.") + cli.Var(&httpReadOnlys, "http-read-only", "HTTP basic auth user/password for read only users.") cli.StringVar(&httpHost, "http-host", "", "HTTP host") cli.StringVar(&httpPrefix, "http-prefix", "/streamlist", "HTTP URL prefix (not actually supported yet!)") cli.BoolVar(&letsencrypt, "letsencrypt", false, "enable TLS using Let's Encrypt") @@ -74,6 +78,17 @@ func main() { cli.Parse(os.Args[1:]) + for _, httpUser := range httpAdmins { + split := strings.Split(httpUser, ":") + httpUsername := split[0] + httpAdminUsers = append(httpAdminUsers, httpUsername) + } + for _, httpUser := range httpReadOnlys { + split := strings.Split(httpUser, ":") + httpUsername := split[0] + httpReadOnlyUsers = append(httpReadOnlyUsers, httpUsername) + } + // logtailer logtail, err = logtailer.NewLogtailer(200 * 1024) if err != nil { @@ -159,55 +174,55 @@ func main() { r.HandleMethodNotAllowed = false // Handlers - r.GET("/", Log(Auth(index, false))) - r.GET(Prefix("/logs"), Log(Auth(logs, false))) - r.GET(Prefix("/"), Log(Auth(home, false))) + r.GET("/", Log(auth(index, "readonly"))) + r.GET(Prefix("/logs"), Log(auth(logs, "admin"))) + r.GET(Prefix("/"), Log(auth(home, "readonly"))) // Library - r.GET(Prefix("/library"), Log(Auth(library, false))) + r.GET(Prefix("/library"), Log(auth(library, "readonly"))) // Media - r.GET(Prefix("/media/thumbnail/:media"), Log(Auth(thumbnailMedia, false))) - r.GET(Prefix("/media/view/:media"), Log(Auth(viewMedia, false))) - r.GET(Prefix("/media/delete/:media"), Log(Auth(deleteMedia, false))) - r.GET(Prefix("/media/access/:filename"), Auth(streamMedia, false)) - r.GET(Prefix("/media/download/:filename"), Auth(downloadMedia, false)) + r.GET(Prefix("/media/thumbnail/:media"), Log(auth(thumbnailMedia, "readonly"))) + r.GET(Prefix("/media/view/:media"), Log(auth(viewMedia, "readonly"))) + r.GET(Prefix("/media/delete/:media"), Log(auth(deleteMedia, "admin"))) + r.GET(Prefix("/media/access/:filename"), auth(streamMedia, "readonly")) + r.GET(Prefix("/media/download/:filename"), auth(downloadMedia, "readonly")) // Publicly accessible streaming (using playlist id as "auth") - r.GET(Prefix("/stream/:list/:filename"), Auth(streamMedia, true)) + r.GET(Prefix("/stream/:list/:filename"), auth(streamMedia, "none")) // Import - r.GET(Prefix("/import"), Log(Auth(importHandler, false))) + r.GET(Prefix("/import"), Log(auth(importHandler, "admin"))) // Archiver - r.GET(Prefix("/archiver/jobs"), Auth(archiverJobs, false)) - r.POST(Prefix("/archiver/save/:id"), Log(Auth(archiverSave, false))) - r.GET(Prefix("/archiver/cancel/:id"), Log(Auth(archiverCancel, false))) + r.GET(Prefix("/archiver/jobs"), auth(archiverJobs, "admin")) + r.POST(Prefix("/archiver/save/:id"), Log(auth(archiverSave, "admin"))) + r.GET(Prefix("/archiver/cancel/:id"), Log(auth(archiverCancel, "admin"))) // List - r.GET(Prefix("/create"), Log(Auth(createList, false))) - r.POST(Prefix("/create"), Log(Auth(createList, false))) - r.POST(Prefix("/add/:list/:media"), Log(Auth(addMediaList, false))) - r.POST(Prefix("/remove/:list/:media"), Log(Auth(removeMediaList, false))) - r.GET(Prefix("/remove/:list/:media"), Log(Auth(removeMediaList, false))) + r.GET(Prefix("/create"), Log(auth(createList, "admin"))) + r.POST(Prefix("/create"), Log(auth(createList, "admin"))) + r.POST(Prefix("/add/:list/:media"), Log(auth(addMediaList, "admin"))) + r.POST(Prefix("/remove/:list/:media"), Log(auth(removeMediaList, "admin"))) + r.GET(Prefix("/remove/:list/:media"), Log(auth(removeMediaList, "admin"))) - r.GET(Prefix("/edit/:id"), Log(Auth(editList, false))) - r.POST(Prefix("/edit/:id"), Log(Auth(editList, false))) - r.GET(Prefix("/shuffle/:id"), Log(Auth(shuffleList, false))) - r.GET(Prefix("/play/:id"), Log(Auth(playList, true))) - r.GET(Prefix("/m3u/:id"), Log(Auth(m3uList, true))) - r.GET(Prefix("/podcast/:id"), Log(Auth(podcastList, true))) + r.GET(Prefix("/edit/:id"), Log(auth(editList, "admin"))) + r.POST(Prefix("/edit/:id"), Log(auth(editList, "admin"))) + r.GET(Prefix("/shuffle/:id"), Log(auth(shuffleList, "admin"))) + r.GET(Prefix("/play/:id"), Log(auth(playList, "none"))) + r.GET(Prefix("/m3u/:id"), Log(auth(m3uList, "none"))) + r.GET(Prefix("/podcast/:id"), Log(auth(podcastList, "none"))) - r.POST(Prefix("/config"), Log(Auth(configHandler, false))) + r.POST(Prefix("/config"), Log(auth(configHandler, "admin"))) - r.GET(Prefix("/delete/:id"), Log(Auth(deleteList, false))) + r.GET(Prefix("/delete/:id"), Log(auth(deleteList, "admin"))) // API - r.GET(Prefix("/v1/status"), Log(Auth(v1status, true))) + r.GET(Prefix("/v1/status"), Log(auth(v1status, "none"))) // Assets - r.GET(Prefix("/static/*path"), Auth(staticAsset, true)) // TODO: Auth() but by checking Origin/Referer for a valid playlist ID? - r.GET(Prefix("/logo.png"), Log(Auth(logo, true))) + r.GET(Prefix("/static/*path"), auth(staticAsset, "none")) + r.GET(Prefix("/logo.png"), Log(auth(logo, "none"))) // // Server diff --git a/templates/header.html b/templates/header.html index 38dd8b4..cb57c67 100644 --- a/templates/header.html +++ b/templates/header.html @@ -18,7 +18,6 @@
- {{if $.User}} {{end}} diff --git a/templates/home.html b/templates/home.html index a10f5b2..65703eb 100644 --- a/templates/home.html +++ b/templates/home.html @@ -1,7 +1,9 @@ {{template "header.html" .}}