mirror of
https://github.com/tobychui/zoraxy.git
synced 2025-08-06 13:18:30 +02:00
feat(plugins): Implement plugin API key management and authentication middleware
The purpose of this is to allow plugins to access certain internal APIs via - Added PluginAPIKey and APIKeyManager for managing API keys associated with plugins. - Introduced PluginAuthMiddleware to handle API key validation for plugin requests. - Updated RouterDef to support plugin accessible endpoints with authentication. - Modified various API registration functions to include plugin accessibility checks. - Enhanced plugin lifecycle management to generate and revoke API keys as needed. - Updated plugin specifications to include permitted API endpoints for access control.
This commit is contained in:
77
src/mod/auth/plugin_middleware.go
Normal file
77
src/mod/auth/plugin_middleware.go
Normal file
@@ -0,0 +1,77 @@
|
||||
// Handles the API-Key based authentication for plugins
|
||||
|
||||
package auth
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// PluginAuthMiddleware provides authentication middleware for plugin API requests
|
||||
type PluginAuthMiddleware struct {
|
||||
apiKeyManager *APIKeyManager
|
||||
}
|
||||
|
||||
// NewPluginAuthMiddleware creates a new plugin authentication middleware
|
||||
func NewPluginAuthMiddleware(apiKeyManager *APIKeyManager) *PluginAuthMiddleware {
|
||||
return &PluginAuthMiddleware{
|
||||
apiKeyManager: apiKeyManager,
|
||||
}
|
||||
}
|
||||
|
||||
// ValidatePluginAPIRequest validates an API request with plugin API key for a specific endpoint
|
||||
func (m *PluginAuthMiddleware) ValidatePluginAPIRequest(endpoint string, method string, apiKey string) (*PluginAPIKey, error) {
|
||||
return m.apiKeyManager.ValidateAPIKeyForEndpoint(endpoint, method, apiKey)
|
||||
}
|
||||
|
||||
// WrapHandler wraps an HTTP handler with plugin authentication middleware
|
||||
func (m *PluginAuthMiddleware) WrapHandler(endpoint string, handler http.HandlerFunc) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
// First, remove any existing plugin authentication headers
|
||||
r.Header.Del("X-Zoraxy-Plugin-ID")
|
||||
r.Header.Del("X-Zoraxy-Plugin-Auth")
|
||||
|
||||
// Check for API key in the Authorization header
|
||||
authHeader := r.Header.Get("Authorization")
|
||||
if authHeader == "" {
|
||||
// No authorization header, proceed with normal authentication
|
||||
handler(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
// Check if it's a plugin API key (Bearer token)
|
||||
if !strings.HasPrefix(authHeader, "Bearer ") {
|
||||
// Not a Bearer token, proceed with normal authentication
|
||||
handler(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
// Extract the API key
|
||||
apiKey := strings.TrimPrefix(authHeader, "Bearer ")
|
||||
|
||||
// Validate the API key for this endpoint
|
||||
pluginAPIKey, err := m.ValidatePluginAPIRequest(endpoint, r.Method, apiKey)
|
||||
if err != nil {
|
||||
// Invalid API key or endpoint not permitted
|
||||
http.Error(w, "Unauthorized: Invalid API key or endpoint not permitted", http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
// Add plugin information to the request context
|
||||
r.Header.Set("X-Zoraxy-Plugin-ID", pluginAPIKey.PluginID)
|
||||
r.Header.Set("X-Zoraxy-Plugin-Auth", "true")
|
||||
|
||||
// Call the original handler
|
||||
handler(w, r)
|
||||
}
|
||||
}
|
||||
|
||||
// GetPluginIDFromRequest extracts the plugin ID from the request if authenticated via plugin API key
|
||||
func GetPluginIDFromRequest(r *http.Request) string {
|
||||
return r.Header.Get("X-Plugin-ID")
|
||||
}
|
||||
|
||||
// IsPluginAuthenticated checks if the request is authenticated via plugin API key
|
||||
func IsPluginAuthenticated(r *http.Request) bool {
|
||||
return r.Header.Get("X-Plugin-Auth") == "true"
|
||||
}
|
Reference in New Issue
Block a user