From 15b30babce8c244e6d4ce5ff7de548a6e62823f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20=C5=A0ediv=C3=BD?= Date: Sun, 31 Jul 2022 23:26:00 +0200 Subject: [PATCH] admin path prefix & password. --- Dockerfile | 2 +- dev/start | 1 + dev/traefik/start | 1 - internal/config/server.go | 48 ++++++++++++++++++---------- internal/server/manager.go | 65 +++++++++++++++++++++++++++----------- 5 files changed, 80 insertions(+), 37 deletions(-) diff --git a/Dockerfile b/Dockerfile index f6ba64d..664d417 100644 --- a/Dockerfile +++ b/Dockerfile @@ -33,7 +33,7 @@ COPY --from=frontend /src/dist/ /var/www ENV DOCKER_API_VERSION=1.39 ENV NEKO_ROOMS_BIND=:8080 -ENV NEKO_ROOMS_STATIC=/var/www +ENV NEKO_ROOMS_ADMIN_STATIC=/var/www EXPOSE 8080 diff --git a/dev/start b/dev/start index fed2a65..5588ddb 100755 --- a/dev/start +++ b/dev/start @@ -53,6 +53,7 @@ docker run --rm -it \ -e "NEKO_ROOMS_STORAGE_EXTERNAL=`realpath ${DATA_PATH}`" \ -e "NEKO_ROOMS_MOUNTS_WHITELIST=`realpath ${EXTERNAL_PATH}`" \ -e "NEKO_ROOMS_PATH_PREFIX=/room/" \ + -e "NEKO_ROOMS_ADMIN_PATH_PREFIX=/" \ -e "NEKO_ROOMS_TRAEFIK_ENABLED=false" \ -e 'DOCKER_API_VERSION=1.39' \ -v "/var/run/docker.sock:/var/run/docker.sock" \ diff --git a/dev/traefik/start b/dev/traefik/start index 7371258..3106674 100755 --- a/dev/traefik/start +++ b/dev/traefik/start @@ -24,7 +24,6 @@ docker run --rm -it \ -e "NEKO_ROOMS_MUX=true" \ -e "NEKO_ROOMS_NAT1TO1=${NEKO_ROOMS_NAT1TO1}" \ -e "NEKO_ROOMS_PATH_PREFIX=/room/" \ - -e "NEKO_ROOMS_ADMIN_PATH_PREFIX=/" \ -e "NEKO_ROOMS_STORAGE_INTERNAL=/data" \ -e "NEKO_ROOMS_STORAGE_EXTERNAL=`realpath ${DATA_PATH}`" \ -e "NEKO_ROOMS_MOUNTS_WHITELIST=`realpath ${EXTERNAL_PATH}`" \ diff --git a/internal/config/server.go b/internal/config/server.go index 1f119f9..d829adc 100644 --- a/internal/config/server.go +++ b/internal/config/server.go @@ -5,15 +5,20 @@ import ( "github.com/spf13/viper" ) -type Server struct { - Cert string - Key string - Bind string - Static string - Proxy bool - PProf bool +type Admin struct { + Static string + Password string + PathPrefix string +} - AdminPathPrefix string +type Server struct { + Cert string + Key string + Bind string + Proxy bool + PProf bool + + Admin Admin } func (Server) Init(cmd *cobra.Command) error { @@ -32,11 +37,6 @@ func (Server) Init(cmd *cobra.Command) error { return err } - cmd.PersistentFlags().String("static", "./www", "path to neko_rooms client files to serve") - if err := viper.BindPFlag("static", cmd.PersistentFlags().Lookup("static")); err != nil { - return err - } - cmd.PersistentFlags().Bool("proxy", false, "trust reverse proxy headers") if err := viper.BindPFlag("proxy", cmd.PersistentFlags().Lookup("proxy")); err != nil { return err @@ -47,8 +47,21 @@ func (Server) Init(cmd *cobra.Command) error { return err } - cmd.PersistentFlags().String("admin_path_prefix", "/", "set custom path prefix for admin") - if err := viper.BindPFlag("admin_path_prefix", cmd.PersistentFlags().Lookup("admin_path_prefix")); err != nil { + // Admin + + cmd.PersistentFlags().String("admin.static", "", "path to neko_rooms admin client files to serve") + if err := viper.BindPFlag("admin.static", cmd.PersistentFlags().Lookup("admin.static")); err != nil { + return err + } + + cmd.PersistentFlags().String("admin.password", "", "admin password") + if err := viper.BindPFlag("admin.password", cmd.PersistentFlags().Lookup("admin.password")); err != nil { + return err + } + + // TODO: Default in v2 will be '/admin'. + cmd.PersistentFlags().String("admin.path_prefix", "", "set custom path prefix for admin") + if err := viper.BindPFlag("admin.path_prefix", cmd.PersistentFlags().Lookup("admin.path_prefix")); err != nil { return err } @@ -59,9 +72,10 @@ func (s *Server) Set() { s.Cert = viper.GetString("cert") s.Key = viper.GetString("key") s.Bind = viper.GetString("bind") - s.Static = viper.GetString("static") s.Proxy = viper.GetBool("proxy") s.PProf = viper.GetBool("pprof") - s.AdminPathPrefix = viper.GetString("admin_path_prefix") + s.Admin.Static = viper.GetString("admin.static") + s.Admin.Password = viper.GetString("admin.password") + s.Admin.PathPrefix = viper.GetString("admin.path_prefix") } diff --git a/internal/server/manager.go b/internal/server/manager.go index 50b74f2..e073e0b 100644 --- a/internal/server/manager.go +++ b/internal/server/manager.go @@ -3,7 +3,8 @@ package server import ( "context" "net/http" - "os" + "path" + "strings" "time" "github.com/go-chi/chi" @@ -54,24 +55,10 @@ func New(ApiManager types.ApiManager, roomConfig *config.Room, config *config.Se logger.Info().Msgf("with pprof endpoint at %s", pprofPath) } - // admin page - router.Route(config.AdminPathPrefix, func(r chi.Router) { - r.Route("/api", ApiManager.Mount) - - // serve static files - if config.Static != "" { - fs := http.FileServer(http.Dir(config.Static)) - r.Get("/*", func(w http.ResponseWriter, r *http.Request) { - if _, err := os.Stat(config.Static + r.URL.Path); !os.IsNotExist(err) { - fs.ServeHTTP(w, r) - } else { - http.NotFound(w, r) - } - }) - } - }) - + // // rooms page + // + router.Route(roomConfig.PathPrefix, func(r chi.Router) { if !roomConfig.Traefik.Enabled { r.Handle("/*", proxyHandler) @@ -82,6 +69,48 @@ func New(ApiManager types.ApiManager, roomConfig *config.Room, config *config.Se } }) + // + // admin page + // + + // in v1 default location was at / with traefik overriding + // the actual room address. in order to keep this setting + // we set new default path prefix only without traefik + if !roomConfig.Traefik.Enabled && config.Admin.PathPrefix == "" { + config.Admin.PathPrefix = "/admin" + } + + router.Group(func(r chi.Router) { + // handle authorization + if config.Admin.Password != "" { + r.Use(middleware.BasicAuth("neko-rooms admin", map[string]string{ + "admin": config.Admin.Password, + })) + } + + // bind API + apiPath := path.Join("/", config.Admin.PathPrefix, "/api") + router.Route(apiPath, ApiManager.Mount) + + // serve static files + if config.Admin.Static != "" { + prefix := config.Admin.PathPrefix + dir := http.Dir(config.Admin.Static) + + fs := http.FileServer(dir) + fs = http.StripPrefix(prefix, fs) + + router.Handle(prefix+"/", fs) + } + }) + + // redirect / to admin path prefix + if config.Admin.PathPrefix != "/" { + router.Get("/", func(w http.ResponseWriter, r *http.Request) { + http.Redirect(w, r, strings.TrimPrefix(config.Admin.PathPrefix, "/"), http.StatusTemporaryRedirect) + }) + } + // we could use custom 404 router.NotFound(http.NotFound)