mirror of
https://github.com/bitechdev/ResolveSpec.git
synced 2025-12-06 14:26:22 +00:00
122 lines
3.8 KiB
Go
122 lines
3.8 KiB
Go
package security
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
)
|
|
|
|
// contextKey is a custom type for context keys to avoid collisions
|
|
type contextKey string
|
|
|
|
const (
|
|
// Context keys for user information
|
|
UserIDKey contextKey = "user_id"
|
|
UserNameKey contextKey = "user_name"
|
|
UserLevelKey contextKey = "user_level"
|
|
SessionIDKey contextKey = "session_id"
|
|
RemoteIDKey contextKey = "remote_id"
|
|
UserRolesKey contextKey = "user_roles"
|
|
UserEmailKey contextKey = "user_email"
|
|
UserContextKey contextKey = "user_context"
|
|
)
|
|
|
|
// NewAuthMiddleware creates an authentication middleware with the given security list
|
|
// This middleware extracts user authentication from the request and adds it to context
|
|
func NewAuthMiddleware(securityList *SecurityList) func(http.Handler) http.Handler {
|
|
return func(next http.Handler) http.Handler {
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
// Get the security provider
|
|
provider := securityList.Provider()
|
|
if provider == nil {
|
|
http.Error(w, "Security provider not configured", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
// Call the provider's Authenticate method
|
|
userCtx, err := provider.Authenticate(r)
|
|
if err != nil {
|
|
http.Error(w, "Authentication failed: "+err.Error(), http.StatusUnauthorized)
|
|
return
|
|
}
|
|
|
|
// Add user information to context
|
|
ctx := r.Context()
|
|
ctx = context.WithValue(ctx, UserContextKey, userCtx)
|
|
ctx = context.WithValue(ctx, UserIDKey, userCtx.UserID)
|
|
ctx = context.WithValue(ctx, UserNameKey, userCtx.UserName)
|
|
ctx = context.WithValue(ctx, UserLevelKey, userCtx.UserLevel)
|
|
ctx = context.WithValue(ctx, SessionIDKey, userCtx.SessionID)
|
|
ctx = context.WithValue(ctx, RemoteIDKey, userCtx.RemoteID)
|
|
|
|
if len(userCtx.Roles) > 0 {
|
|
ctx = context.WithValue(ctx, UserRolesKey, userCtx.Roles)
|
|
}
|
|
if userCtx.Email != "" {
|
|
ctx = context.WithValue(ctx, UserEmailKey, userCtx.Email)
|
|
}
|
|
|
|
// Continue with authenticated context
|
|
next.ServeHTTP(w, r.WithContext(ctx))
|
|
})
|
|
}
|
|
}
|
|
|
|
// SetSecurityMiddleware adds security context to requests
|
|
// This middleware should be applied after AuthMiddleware
|
|
func SetSecurityMiddleware(securityList *SecurityList) func(http.Handler) http.Handler {
|
|
return func(next http.Handler) http.Handler {
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
ctx := context.WithValue(r.Context(), SECURITY_CONTEXT_KEY, securityList)
|
|
next.ServeHTTP(w, r.WithContext(ctx))
|
|
})
|
|
}
|
|
}
|
|
|
|
// GetUserContext extracts the full user context from request context
|
|
func GetUserContext(ctx context.Context) (*UserContext, bool) {
|
|
userCtx, ok := ctx.Value(UserContextKey).(*UserContext)
|
|
return userCtx, ok
|
|
}
|
|
|
|
// GetUserID extracts the user ID from context
|
|
func GetUserID(ctx context.Context) (int, bool) {
|
|
userID, ok := ctx.Value(UserIDKey).(int)
|
|
return userID, ok
|
|
}
|
|
|
|
// GetUserName extracts the user name from context
|
|
func GetUserName(ctx context.Context) (string, bool) {
|
|
userName, ok := ctx.Value(UserNameKey).(string)
|
|
return userName, ok
|
|
}
|
|
|
|
// GetUserLevel extracts the user level from context
|
|
func GetUserLevel(ctx context.Context) (int, bool) {
|
|
userLevel, ok := ctx.Value(UserLevelKey).(int)
|
|
return userLevel, ok
|
|
}
|
|
|
|
// GetSessionID extracts the session ID from context
|
|
func GetSessionID(ctx context.Context) (string, bool) {
|
|
sessionID, ok := ctx.Value(SessionIDKey).(string)
|
|
return sessionID, ok
|
|
}
|
|
|
|
// GetRemoteID extracts the remote ID from context
|
|
func GetRemoteID(ctx context.Context) (string, bool) {
|
|
remoteID, ok := ctx.Value(RemoteIDKey).(string)
|
|
return remoteID, ok
|
|
}
|
|
|
|
// GetUserRoles extracts user roles from context
|
|
func GetUserRoles(ctx context.Context) ([]string, bool) {
|
|
roles, ok := ctx.Value(UserRolesKey).([]string)
|
|
return roles, ok
|
|
}
|
|
|
|
// GetUserEmail extracts user email from context
|
|
func GetUserEmail(ctx context.Context) (string, bool) {
|
|
email, ok := ctx.Value(UserEmailKey).(string)
|
|
return email, ok
|
|
}
|