- Changed the build process to include a web UI build stage using Node.js. - Updated Go build stage to copy web UI files to the correct location. - Removed the main.go file as it is no longer needed. - Added SQLite database configuration to example config. - Updated dependencies in go.mod and go.sum, including new packages for JWT and SQLite. - Modified .gitignore to include new database and configuration files. Signed-off-by: zhenyus <zhenyus@mathmast.com>
151 lines
4.0 KiB
Go
151 lines
4.0 KiB
Go
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)
|
|
}
|