From 42534cdd79c02ff7d73ff023c3b681ac810c5730 Mon Sep 17 00:00:00 2001 From: kolaente Date: Tue, 15 Jul 2025 23:26:28 +0200 Subject: [PATCH] fix: don't panic when using api token when not correctly put into context (#1119) --- pkg/routes/api_tokens.go | 7 +++++++ pkg/user/error.go | 27 +++++++++++++++++++++++++++ pkg/user/user.go | 16 +++++++++++++++- 3 files changed, 49 insertions(+), 1 deletion(-) diff --git a/pkg/routes/api_tokens.go b/pkg/routes/api_tokens.go index e29762aeb..73de7c1fc 100644 --- a/pkg/routes/api_tokens.go +++ b/pkg/routes/api_tokens.go @@ -25,6 +25,7 @@ import ( "code.vikunja.io/api/pkg/db" "code.vikunja.io/api/pkg/log" "code.vikunja.io/api/pkg/models" + "code.vikunja.io/api/pkg/user" echojwt "github.com/labstack/echo-jwt/v4" "github.com/labstack/echo/v4" @@ -87,7 +88,13 @@ func checkAPITokenAndPutItInContext(tokenHeaderValue string, c echo.Context) err return echo.NewHTTPError(http.StatusUnauthorized) } + u, err := user.GetUserByID(s, token.OwnerID) + if err != nil { + return echo.NewHTTPError(http.StatusInternalServerError).SetInternal(err) + } + c.Set("api_token", token) + c.Set("api_user", u) return nil } diff --git a/pkg/user/error.go b/pkg/user/error.go index 707c51fe9..398802c61 100644 --- a/pkg/user/error.go +++ b/pkg/user/error.go @@ -632,3 +632,30 @@ const ErrorCodeUsernameReserved = 1026 func (err ErrUsernameReserved) HTTPError() web.HTTPError { return web.HTTPError{HTTPCode: http.StatusBadRequest, Code: ErrorCodeUsernameReserved, Message: "This username is reserved and cannot be used."} } + +// ErrInvalidUserContext represents an error where the user context is invalid or missing +type ErrInvalidUserContext struct { + Reason string +} + +// IsErrInvalidUserContext checks if an error is a ErrInvalidUserContext. +func IsErrInvalidUserContext(err error) bool { + _, ok := err.(ErrInvalidUserContext) + return ok +} + +func (err ErrInvalidUserContext) Error() string { + return fmt.Sprintf("Invalid user context: %s", err.Reason) +} + +// ErrorCodeInvalidUserContext holds the unique world-error code of this error +const ErrorCodeInvalidUserContext = 1027 + +// HTTPError holds the http error description +func (err ErrInvalidUserContext) HTTPError() web.HTTPError { + return web.HTTPError{ + HTTPCode: http.StatusUnauthorized, + Code: ErrorCodeInvalidUserContext, + Message: "Invalid user context. Please make sure the passed token is valid and try again.", + } +} diff --git a/pkg/user/user.go b/pkg/user/user.go index 9f0f2fb1a..1479a8d3e 100644 --- a/pkg/user/user.go +++ b/pkg/user/user.go @@ -429,7 +429,21 @@ func GetCurrentUserFromDB(s *xorm.Session, c echo.Context) (user *User, err erro // GetCurrentUser returns the current user based on its jwt token func GetCurrentUser(c echo.Context) (user *User, err error) { - jwtinf := c.Get("user").(*jwt.Token) + if apiUser, ok := c.Get("api_user").(*User); ok { + return apiUser, nil + } + + jwtinf, is := c.Get("user").(*jwt.Token) + if jwtinf == nil { + log.Error("No user found in context") + return nil, ErrInvalidUserContext{Reason: "no user found in context"} + } + + if !is { + log.Errorf("User in context is not a JWT token, got type: %T", jwtinf) + return nil, ErrInvalidUserContext{Reason: "user in context is not a JWT token"} + } + claims := jwtinf.Claims.(jwt.MapClaims) return GetUserFromClaims(claims) }