package handler import ( "encoding/json" "net/http" "freeleaps.com/gitea-webhook-ambassador/internal/auth" "freeleaps.com/gitea-webhook-ambassador/internal/config" "freeleaps.com/gitea-webhook-ambassador/internal/database" "freeleaps.com/gitea-webhook-ambassador/internal/logger" ) // AdminHandler handles administrative API endpoints type AdminHandler struct { db *database.DB config *config.Configuration auth *auth.Middleware } // NewAdminHandler creates a new admin handler func NewAdminHandler(db *database.DB, config *config.Configuration) *AdminHandler { return &AdminHandler{ db: db, config: config, auth: auth.NewMiddleware(config.Server.SecretKey), } } // CreateAPIKeyRequest represents a request to create a new API key type CreateAPIKeyRequest struct { Key string `json:"key"` Description string `json:"description"` } // APIKeyResponse represents an API key response type APIKeyResponse struct { ID int64 `json:"id"` Key string `json:"key"` Description string `json:"description"` CreatedAt string `json:"created_at"` UpdatedAt string `json:"updated_at"` } // verifyAuth verifies the JWT token in the request func (h *AdminHandler) verifyAuth(r *http.Request) error { return h.auth.VerifyToken(r) } // HandleCreateAPIKey handles the creation of new API keys func (h *AdminHandler) HandleCreateAPIKey(w http.ResponseWriter, r *http.Request) { // Verify JWT token if err := h.verifyAuth(r); err != nil { http.Error(w, "Unauthorized", http.StatusUnauthorized) return } // Parse request var req CreateAPIKeyRequest if err := json.NewDecoder(r.Body).Decode(&req); err != nil { http.Error(w, "Invalid request body", http.StatusBadRequest) return } // Validate request if req.Key == "" { http.Error(w, "API key is required", http.StatusBadRequest) return } // Create API key apiKey := &database.APIKey{ Key: req.Key, Description: req.Description, } if err := h.db.CreateAPIKey(apiKey); err != nil { logger.Error("Failed to create API key: %v", err) http.Error(w, "Internal server error", http.StatusInternalServerError) return } // Return response response := APIKeyResponse{ ID: apiKey.ID, Key: apiKey.Key, Description: apiKey.Description, CreatedAt: apiKey.CreatedAt.Format("2006-01-02T15:04:05Z07:00"), UpdatedAt: apiKey.UpdatedAt.Format("2006-01-02T15:04:05Z07:00"), } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(response) } // HandleDeleteAPIKey handles the deletion of API keys func (h *AdminHandler) HandleDeleteAPIKey(w http.ResponseWriter, r *http.Request) { // Verify JWT token if err := h.verifyAuth(r); err != nil { http.Error(w, "Unauthorized", http.StatusUnauthorized) return } // Get key from URL key := r.URL.Query().Get("key") if key == "" { http.Error(w, "API key is required", http.StatusBadRequest) return } // Delete API key if err := h.db.DeleteAPIKey(key); err != nil { logger.Error("Failed to delete API key: %v", err) http.Error(w, "Internal server error", http.StatusInternalServerError) return } w.WriteHeader(http.StatusNoContent) } // HandleListAPIKeys handles listing all API keys func (h *AdminHandler) HandleListAPIKeys(w http.ResponseWriter, r *http.Request) { // Verify JWT token if err := h.verifyAuth(r); err != nil { http.Error(w, "Unauthorized", http.StatusUnauthorized) return } // Get API keys apiKeys, err := h.db.GetAPIKeys() if err != nil { logger.Error("Failed to get API keys: %v", err) http.Error(w, "Internal server error", http.StatusInternalServerError) return } // Convert to response format response := make([]APIKeyResponse, len(apiKeys)) for i, key := range apiKeys { response[i] = APIKeyResponse{ ID: key.ID, Key: key.Key, Description: key.Description, CreatedAt: key.CreatedAt.Format("2006-01-02T15:04:05Z07:00"), UpdatedAt: key.UpdatedAt.Format("2006-01-02T15:04:05Z07:00"), } } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(response) }