mirror of
https://github.com/bitechdev/ResolveSpec.git
synced 2025-12-31 17:28:58 +00:00
Updated the security package
This commit is contained in:
@@ -10,38 +10,72 @@ type contextKey string
|
||||
|
||||
const (
|
||||
// Context keys for user information
|
||||
UserIDKey contextKey = "user_id"
|
||||
UserRolesKey contextKey = "user_roles"
|
||||
UserTokenKey contextKey = "user_token"
|
||||
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"
|
||||
)
|
||||
|
||||
// AuthMiddleware extracts user authentication from request and adds to context
|
||||
// This should be applied before the ResolveSpec handler
|
||||
// Uses GlobalSecurity.AuthenticateCallback if set, otherwise returns error
|
||||
func AuthMiddleware(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
// Check if callback is set
|
||||
if GlobalSecurity.AuthenticateCallback == nil {
|
||||
http.Error(w, "AuthenticateCallback not set - you must provide an authentication callback", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
// 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 user-provided authentication callback
|
||||
userID, roles, err := GlobalSecurity.AuthenticateCallback(r)
|
||||
if err != nil {
|
||||
http.Error(w, "Authentication failed: "+err.Error(), http.StatusUnauthorized)
|
||||
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 := context.WithValue(r.Context(), UserIDKey, userID)
|
||||
if roles != "" {
|
||||
ctx = context.WithValue(ctx, UserRolesKey, roles)
|
||||
}
|
||||
// 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)
|
||||
|
||||
// Continue with authenticated context
|
||||
next.ServeHTTP(w, r.WithContext(ctx))
|
||||
})
|
||||
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
|
||||
@@ -50,8 +84,38 @@ func GetUserID(ctx context.Context) (int, bool) {
|
||||
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)
|
||||
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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user