diff --git a/cmd/server.go b/cmd/server.go index 71f5a54..724af2a 100644 --- a/cmd/server.go +++ b/cmd/server.go @@ -81,6 +81,18 @@ func init() { // server.api.key - --server-api-key serverCmd.Flags().String("server-api-key", "", "Key to use for authenticating to /v1 routes") viper.BindPFlag("server.api.key", serverCmd.Flags().Lookup("server-api-key")) + + // server.admin.auth - --server-admin-auth + serverCmd.Flags().Bool("server-admin-auth", false, "Enable to allow basic authentication for /admin routes (config: server.admin.auth)") + viper.BindPFlag("server.admin.auth", serverCmd.Flags().Lookup("server-admin-auth")) + + // server.admin.username - --server-frontend-username + serverCmd.Flags().String("server-admin-username", "", "Username for basic authentication for /admin routes (config: server.admin.username)") + viper.BindPFlag("server.admin.username", serverCmd.Flags().Lookup("server-admin-username")) + + // server.admin.password - --server-frontend-password + serverCmd.Flags().String("server-admin-password", "", "Password for basic authentication for /admin routes (config: server.admin.password)") + viper.BindPFlag("server.admin.password", serverCmd.Flags().Lookup("server-admin-password")) } func RunServer() { @@ -106,6 +118,35 @@ func RunServer() { groupV1.Use(middleware.KeyAuth(func(key string, c echo.Context) (bool, error) { return subtle.ConstantTimeCompare([]byte(key), []byte(viper.GetString("server.api.key"))) == 1, nil })) + + log.Println("Key auth for /v1 activated") + } + + groupAdmin := e.Group("/admin") + + groupAdmin.Use(middleware.AddTrailingSlash()) + + if viper.GetBool("server.admin.auth") { + username := viper.GetString("server.admin.username") + password := viper.GetString("server.admin.password") + if len(username) < 5 { + log.Fatal("server.admin.auth is enabled, but server.admin.username is too small (needs at least 5 characters)") + } + + if len(password) < 10 { + log.Fatal("server.admin.auth is enabled, but server.admin.password is too small (needs at least 10 characters)") + } + + groupAdmin.Use(middleware.BasicAuth(func(username_entered, password_entered string, c echo.Context) (bool, error) { + // Be careful to use constant time comparison to prevent timing attacks + if subtle.ConstantTimeCompare([]byte(username_entered), []byte(username)) == 1 && + subtle.ConstantTimeCompare([]byte(password_entered), []byte(password)) == 1 { + return true, nil + } + return false, nil + })) + + log.Println("Basic auth for /admin activated") } // API Routes @@ -154,6 +195,10 @@ func RunServer() { e.GET("/public/documentation/:bucket/:document", handlePublicDocumentation) + // Admin Routes + + groupAdmin.GET("", handleAdmin) + e.Logger.Fatal(e.Start( fmt.Sprintf(":%d", viper.GetInt("server.port")))) } @@ -671,6 +716,10 @@ func handlePublicDocumentation(c echo.Context) error { return c.Blob(http.StatusOK, "application/octet-stream", result) } +func handleAdmin(c echo.Context) error { + return c.JSON(http.StatusNotImplemented, map[string]string{"message": "Not Implemented"}) +} + // CSS Handlers func handleStaticCSSIndex(c echo.Context) error {