From d3934eac7a3dcfb7e61ed82c9bfd19288a2f1bb4 Mon Sep 17 00:00:00 2001 From: Knut Ahlers Date: Thu, 13 Jun 2024 16:38:59 +0200 Subject: [PATCH] Add renew-route, shorten token lifetime Signed-off-by: Knut Ahlers --- configEditor_global.go | 51 +++++++++++++++++++-- internal/service/editortoken/editortoken.go | 2 +- 2 files changed, 49 insertions(+), 4 deletions(-) diff --git a/configEditor_global.go b/configEditor_global.go index b1f7dd6..6f61b69 100644 --- a/configEditor_global.go +++ b/configEditor_global.go @@ -4,6 +4,7 @@ import ( "encoding/json" "net/http" "regexp" + "strings" "time" log "github.com/sirupsen/logrus" @@ -14,6 +15,14 @@ import ( const frontendNotifyTypeReload = "configReload" +type ( + configEditorLoginResponse struct { + ExpiresAt time.Time `json:"expiresAt"` + Token string `json:"token"` + User string `json:"user"` + } +) + var frontendNotifyHooks = newHooker() //nolint:funlen // Just contains a collection of objects @@ -73,6 +82,16 @@ func registerEditorGlobalMethods() { Path: "/notify-config", ResponseType: plugins.HTTPRouteResponseTypeTextPlain, }, + { + Description: "Takes the authorization token present in the request and returns a new one for the same user", + HandlerFunc: configEditorGlobalRefreshToken, + Method: http.MethodGet, + Module: moduleConfigEditor, + Name: "Refresh Auth-Token", + Path: "/refreshToken", + RequiresEditorsAuth: true, + ResponseType: plugins.HTTPRouteResponseTypeJSON, + }, { Description: "Validate a cron expression and return the next executions", HandlerFunc: configEditorGlobalValidateCron, @@ -187,9 +206,35 @@ func configEditorGlobalLogin(w http.ResponseWriter, r *http.Request) { return } - if err := json.NewEncoder(w).Encode(map[string]any{ - "expiresAt": expiresAt, - "token": tok, + if err := json.NewEncoder(w).Encode(configEditorLoginResponse{ + ExpiresAt: expiresAt, + Token: tok, + User: user, + }); err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + } +} + +func configEditorGlobalRefreshToken(w http.ResponseWriter, r *http.Request) { + tokenType, token, found := strings.Cut(r.Header.Get("Authorization"), " ") + if !found || !strings.EqualFold(tokenType, "bearer") { + http.Error(w, "invalid renew request", http.StatusBadRequest) + } + + id, user, _, err := editorTokenService.ValidateLoginToken(token) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + } + + tok, expiresAt, err := editorTokenService.CreateLoginToken(id, user) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + } + + if err := json.NewEncoder(w).Encode(configEditorLoginResponse{ + ExpiresAt: expiresAt, + Token: tok, + User: user, }); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } diff --git a/internal/service/editortoken/editortoken.go b/internal/service/editortoken/editortoken.go index 6ae6ad1..1038ae0 100644 --- a/internal/service/editortoken/editortoken.go +++ b/internal/service/editortoken/editortoken.go @@ -15,7 +15,7 @@ import ( const ( coreMetaSigningKey = "editortoken:signing-key" - tokenValidity = 24 * time.Hour + tokenValidity = time.Hour ) type (