fix: migrate to go-jwt-middleware v3 API
schemas / check-release (pull_request) Successful in 1m57s
schemas / vulnerabilities (pull_request) Successful in 2m48s
schemas / check (pull_request) Successful in 8m17s
pre-commit / pre-commit (pull_request) Successful in 11m38s
schemas / build (pull_request) Successful in 5m31s
schemas / deploy-prod (pull_request) Has been skipped

- Use validator and jwks packages for JWT validation
- Replace manual JWKS caching with jwks.NewCachingProvider
- Add CustomClaims struct for https://unbound.se/roles claim
- Rename TokenFromContext to ClaimsFromContext
- Update middleware/auth.go to use new claims structure
- Update tests to use core.SetClaims and validator.ValidatedClaims

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-19 20:31:45 +01:00
parent e2c1803683
commit 817927cb7d
5 changed files with 133 additions and 242 deletions
+9 -26
View File
@@ -6,7 +6,6 @@ import (
"net/http"
"github.com/99designs/gqlgen/graphql"
"github.com/golang-jwt/jwt/v5"
"gitea.unbound.se/unboundsoftware/schemas/domain"
)
@@ -33,14 +32,9 @@ type AuthMiddleware struct {
func (m *AuthMiddleware) Handler(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
token, err := TokenFromContext(r.Context())
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
_, _ = w.Write([]byte("Invalid JWT token format"))
return
}
if token != nil {
ctx = context.WithValue(ctx, UserKey, token.Claims.(jwt.MapClaims)["sub"])
claims := ClaimsFromContext(r.Context())
if claims != nil {
ctx = context.WithValue(ctx, UserKey, claims.RegisteredClaims.Subject)
}
apiKey, err := ApiKeyFromContext(r.Context())
if err != nil {
@@ -68,29 +62,18 @@ func UserFromContext(ctx context.Context) string {
}
func UserHasRole(ctx context.Context, role string) bool {
token, err := TokenFromContext(ctx)
if err != nil || token == nil {
claims := ClaimsFromContext(ctx)
if claims == nil {
return false
}
claims, ok := token.Claims.(jwt.MapClaims)
if !ok {
customClaims, ok := claims.CustomClaims.(*CustomClaims)
if !ok || customClaims == nil {
return false
}
// Check the custom roles claim
rolesInterface, ok := claims["https://unbound.se/roles"]
if !ok {
return false
}
roles, ok := rolesInterface.([]interface{})
if !ok {
return false
}
for _, r := range roles {
if roleStr, ok := r.(string); ok && roleStr == role {
for _, r := range customClaims.Roles {
if r == role {
return true
}
}