From 53a3fbc46479e3c316245997c5e7bb7bd2113dcf Mon Sep 17 00:00:00 2001 From: Jakob Schrettenbrunner Date: Thu, 17 May 2018 21:18:02 +0200 Subject: [PATCH] remove trailing slashes from api use correct handler to provide server logs remove Baerer from Authorization header to compare it with known tokens fix wings-api.paw routes --- api/api.go | 10 +++++----- api/auth.go | 7 +++++-- api/handlers_server.go | 4 ---- config/config_test.go | 2 +- wings-api.paw | Bin 20278 -> 21104 bytes 5 files changed, 11 insertions(+), 12 deletions(-) diff --git a/api/api.go b/api/api.go index 42f62c5..7fde00a 100644 --- a/api/api.go +++ b/api/api.go @@ -51,7 +51,7 @@ func (api *InternalAPI) Listen() { func (api *InternalAPI) register() { v1 := api.router.Group("/api/v1") { - v1.GET("/", AuthHandler(""), GetIndex) + v1.GET("", AuthHandler(""), GetIndex) //v1.PATCH("/config", AuthHandler("c:config"), PatchConfiguration) v1.GET("/servers", AuthHandler("c:list"), handleGetServers) @@ -59,15 +59,15 @@ func (api *InternalAPI) register() { v1ServerRoutes := v1.Group("/servers/:server") { - v1ServerRoutes.GET("/", AuthHandler("s:get"), handleGetServer) - v1ServerRoutes.PATCH("/", AuthHandler("s:config"), handlePatchServer) - v1ServerRoutes.DELETE("/", AuthHandler("g:server:delete"), handleDeleteServer) + v1ServerRoutes.GET("", AuthHandler("s:get"), handleGetServer) + v1ServerRoutes.PATCH("", AuthHandler("s:config"), handlePatchServer) + v1ServerRoutes.DELETE("", AuthHandler("g:server:delete"), handleDeleteServer) v1ServerRoutes.POST("/reinstall", AuthHandler("s:install-server"), handlePostServerReinstall) v1ServerRoutes.POST("/rebuild", AuthHandler("g:server:rebuild"), handlePostServerRebuild) v1ServerRoutes.POST("/password", AuthHandler(""), handlePostServerPassword) v1ServerRoutes.POST("/power", AuthHandler("s:power"), handlePostServerPower) v1ServerRoutes.POST("/command", AuthHandler("s:command"), handlePostServerCommand) - v1ServerRoutes.GET("/log", AuthHandler("s:console"), handleGetServerLog) + v1ServerRoutes.GET("/log", AuthHandler("s:console"), handleGetConsole) v1ServerRoutes.POST("/suspend", AuthHandler(""), handlePostServerSuspend) v1ServerRoutes.POST("/unsuspend", AuthHandler(""), handlePostServerUnsuspend) } diff --git a/api/auth.go b/api/auth.go index b9bb645..f19efee 100644 --- a/api/auth.go +++ b/api/auth.go @@ -2,8 +2,9 @@ package api import ( "net/http" + "strings" - "strconv" + "strconv" "github.com/gin-gonic/gin" "github.com/google/jsonapi" @@ -71,7 +72,9 @@ func (a *authorizationManager) HasPermission(permission string) bool { func AuthHandler(permission string) gin.HandlerFunc { return func(c *gin.Context) { requestToken := c.Request.Header.Get(accessTokenHeader) - if requestToken == "" { + if requestToken != "" && strings.HasPrefix(requestToken, "Baerer ") { + requestToken = requestToken[7:] + } else { requestToken = c.Query("token") } requestServer := c.Param("server") diff --git a/api/handlers_server.go b/api/handlers_server.go index a339b3c..3107f12 100644 --- a/api/handlers_server.go +++ b/api/handlers_server.go @@ -181,10 +181,6 @@ func handleGetConsole(c *gin.Context) { server.Websockets().Upgrade(c.Writer, c.Request) } -func handleGetServerLog(c *gin.Context) { - -} - func handlePostServerSuspend(c *gin.Context) { } diff --git a/config/config_test.go b/config/config_test.go index 1773208..7450c44 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -8,7 +8,7 @@ import ( "github.com/stretchr/testify/assert" ) -const configFile = "../config.yml.example" +const configFile = "../config.example.yml" func TestLoadConfiguraiton(t *testing.T) { err := LoadConfiguration(configFile) diff --git a/wings-api.paw b/wings-api.paw index a13dc590345a1890092ccd3384a997a5aab126c4..af01f9c6e041240ed4be513d378e9f571771e70e 100644 GIT binary patch delta 10396 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 delta 9670 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