Files
query-orchestration/internal/cognitoauth/utils.go
T
2025-04-08 16:27:06 -07:00

98 lines
2.5 KiB
Go

package cognitoauth
import (
"log/slog"
"regexp"
"strings"
)
// matchRoute checks if a request path matches a route pattern
// Converts Echo route patterns to regex for matching
// Supports parameter patterns like '/users/:id' and wildcard patterns
func matchRoute(requestPath, routePattern string) bool {
// Convert Echo route pattern to regex pattern
// e.g., "/users/:id" to "/users/([^/]+)"
regexPattern := "^"
patternParts := strings.Split(routePattern, "/")
for i, part := range patternParts {
if i > 0 {
regexPattern += "/"
}
if strings.HasPrefix(part, ":") {
// Parameter part (e.g., :id)
regexPattern += "([^/]+)"
} else if part == "*" {
// Wildcard - match anything
regexPattern += ".*"
} else {
// Literal part - escape any regex metacharacters
regexPattern += regexp.QuoteMeta(part)
}
}
regexPattern += "$"
// Compile and match
regex, err := regexp.Compile(regexPattern)
if err != nil {
return false
}
return regex.MatchString(requestPath)
}
// checkPermissions checks if the user has the required permissions
// Used by both the main token validation middleware and the OAuth callback handler
// Returns true if authorized, false if not, along with the required groups
func checkPermissions(path string, userGroups []string, routePermissions map[string][]string, logger *slog.Logger) (bool, []string) {
// Find matching route pattern
var requiredGroups []string
var matched bool
for pattern, groups := range routePermissions {
if matchRoute(path, pattern) {
requiredGroups = groups
matched = true
logger.Debug("Found matching route pattern", "pattern", pattern, "requiredGroups", requiredGroups)
break
}
}
if !matched {
// No matching pattern found - could either allow or deny by default
logger.Info("No matching route pattern found for path", "path", path)
return true, nil // Allowing by default
}
// If no groups are required, allow access
if len(requiredGroups) == 0 {
return true, requiredGroups
}
// Check if user has any of the required groups
for _, requiredGroup := range requiredGroups {
for _, userGroup := range userGroups {
if userGroup == requiredGroup {
logger.Debug("User has required group", "group", requiredGroup)
return true, requiredGroups
}
}
}
return false, requiredGroups
}
// Helper function to mask sensitive values
// Used for logging sensitive information like client IDs
func maskString(s string) string {
if s == "" {
return "<not set>"
}
if len(s) <= 8 {
return "****"
}
return s[:4] + "..." + s[len(s)-4:]
}