diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..adb36c8 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.exe \ No newline at end of file diff --git a/cmd/server/main.go b/cmd/server/main.go index 0ae3a07..8e19959 100644 --- a/cmd/server/main.go +++ b/cmd/server/main.go @@ -16,6 +16,7 @@ var ( services = []models.Service{} mu sync.Mutex dataFile = "services.json" + apiToken = "ENVGUARD_SECRET_TOKEN" ) func main() { @@ -32,9 +33,9 @@ func main() { fmt.Printf("✅ %d servicios cargados desde disco\n", len(services)) } - http.HandleFunc("/services", handleServices) - http.HandleFunc("/lock", handleLock) - http.HandleFunc("/unlock", handleUnlock) + http.HandleFunc("/services", authMiddleware(handleServices)) + http.HandleFunc("/lock", authMiddleware(handleLock)) + http.HandleFunc("/unlock", authMiddleware(handleUnlock)) fmt.Println("🚦 Lock Server corriendo en :8080") if err := http.ListenAndServe(":8080", nil); err != nil { @@ -148,3 +149,14 @@ func handleUnlock(w http.ResponseWriter, r *http.Request) { http.Error(w, "Service not found", http.StatusNotFound) } + +func authMiddleware(next http.HandlerFunc) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + token := r.Header.Get("X-API-Key") + if token != apiToken { + http.Error(w, "Unauthorized", http.StatusUnauthorized) + return + } + next(w, r) + } +} diff --git a/internal/api/client.go b/internal/api/client.go index 3bf2b4f..d4b4121 100644 --- a/internal/api/client.go +++ b/internal/api/client.go @@ -12,6 +12,8 @@ import ( var baseURL = "http://localhost:8080" +const apiToken = "ENVGUARD_SECRET_TOKEN" + func SetBaseURL(url string) { baseURL = url } @@ -19,7 +21,13 @@ func SetBaseURL(url string) { var client = &http.Client{Timeout: 5 * time.Second} func GetServices() ([]models.Service, error) { - resp, err := client.Get(baseURL + "/services") + req, err := http.NewRequest("GET", baseURL+"/services", nil) + if err != nil { + return nil, err + } + req.Header.Set("X-API-Key", apiToken) + + resp, err := client.Do(req) if err != nil { return nil, err } @@ -39,7 +47,14 @@ func LockService(serviceName, user string) error { } data, _ := json.Marshal(reqBody) - resp, err := client.Post(baseURL+"/lock", "application/json", bytes.NewBuffer(data)) + req, err := http.NewRequest("POST", baseURL+"/lock", bytes.NewBuffer(data)) + if err != nil { + return err + } + req.Header.Set("Content-Type", "application/json") + req.Header.Set("X-API-Key", apiToken) + + resp, err := client.Do(req) if err != nil { return err } @@ -58,7 +73,14 @@ func UnlockService(serviceName, user string) error { } data, _ := json.Marshal(reqBody) - resp, err := client.Post(baseURL+"/unlock", "application/json", bytes.NewBuffer(data)) + req, err := http.NewRequest("POST", baseURL+"/unlock", bytes.NewBuffer(data)) + if err != nil { + return err + } + req.Header.Set("Content-Type", "application/json") + req.Header.Set("X-API-Key", apiToken) + + resp, err := client.Do(req) if err != nil { return err } diff --git a/services.json b/services.json index decb08d..2bf95b7 100644 --- a/services.json +++ b/services.json @@ -1,26 +1,234 @@ [ { - "name": "auth-service", + "name": "analytics-api", + "is_locked": true, + "locked_by": "josle", + "locked_at": "2026-01-28T15:24:49.4825113+01:00" + }, + { + "name": "analytics-etl", "is_locked": false, "locked_at": "0001-01-01T00:00:00Z" }, { - "name": "payments-api", + "name": "d3a-ai", + "is_locked": true, + "locked_by": "josle", + "locked_at": "2026-01-28T15:24:50.2494892+01:00" + }, + { + "name": "d3a-ai-assistant", "is_locked": false, "locked_at": "0001-01-01T00:00:00Z" }, { - "name": "user-db", + "name": "d3a-ai-audit", "is_locked": false, "locked_at": "0001-01-01T00:00:00Z" }, { - "name": "notifications", + "name": "d3a-ai-coder", "is_locked": false, "locked_at": "0001-01-01T00:00:00Z" }, { - "name": "front-web", + "name": "d3a-ai-mentor", + "is_locked": false, + "locked_at": "0001-01-01T00:00:00Z" + }, + { + "name": "d3a-ai-stream", + "is_locked": false, + "locked_at": "0001-01-01T00:00:00Z" + }, + { + "name": "d3a-ai-summarize", + "is_locked": true, + "locked_by": "josle", + "locked_at": "2026-01-28T15:24:56.6279814+01:00" + }, + { + "name": "d3a-ai-translation", + "is_locked": false, + "locked_at": "0001-01-01T00:00:00Z" + }, + { + "name": "d3a-ai-tts", + "is_locked": false, + "locked_at": "0001-01-01T00:00:00Z" + }, + { + "name": "d3a-api", + "is_locked": false, + "locked_at": "0001-01-01T00:00:00Z" + }, + { + "name": "d3a-billing", + "is_locked": false, + "locked_at": "0001-01-01T00:00:00Z" + }, + { + "name": "d3a-delio-proxy", + "is_locked": false, + "locked_at": "0001-01-01T00:00:00Z" + }, + { + "name": "d3a-helper", + "is_locked": false, + "locked_at": "0001-01-01T00:00:00Z" + }, + { + "name": "d3a-mobile", + "is_locked": false, + "locked_at": "0001-01-01T00:00:00Z" + }, + { + "name": "d3a-monitor", + "is_locked": false, + "locked_at": "0001-01-01T00:00:00Z" + }, + { + "name": "d3a-notifier", + "is_locked": false, + "locked_at": "0001-01-01T00:00:00Z" + }, + { + "name": "d3a-notifier-consumer", + "is_locked": false, + "locked_at": "0001-01-01T00:00:00Z" + }, + { + "name": "d3a-public", + "is_locked": false, + "locked_at": "0001-01-01T00:00:00Z" + }, + { + "name": "d3a-rag", + "is_locked": false, + "locked_at": "0001-01-01T00:00:00Z" + }, + { + "name": "d3a-redis", + "is_locked": false, + "locked_at": "0001-01-01T00:00:00Z" + }, + { + "name": "d3a-task-manager", + "is_locked": false, + "locked_at": "0001-01-01T00:00:00Z" + }, + { + "name": "d3a-webui", + "is_locked": false, + "locked_at": "0001-01-01T00:00:00Z" + }, + { + "name": "memcached", + "is_locked": false, + "locked_at": "0001-01-01T00:00:00Z" + }, + { + "name": "rabbitmq", + "is_locked": false, + "locked_at": "0001-01-01T00:00:00Z" + }, + { + "name": "sio", + "is_locked": false, + "locked_at": "0001-01-01T00:00:00Z" + }, + { + "name": "sio-api", + "is_locked": false, + "locked_at": "0001-01-01T00:00:00Z" + }, + { + "name": "sio-webchat", + "is_locked": false, + "locked_at": "0001-01-01T00:00:00Z" + }, + { + "name": "sio-webchat-api", + "is_locked": false, + "locked_at": "0001-01-01T00:00:00Z" + }, + { + "name": "sio-whatsapp", + "is_locked": false, + "locked_at": "0001-01-01T00:00:00Z" + }, + { + "name": "sonar-api", + "is_locked": false, + "locked_at": "0001-01-01T00:00:00Z" + }, + { + "name": "sonar-cloud-audio-socket", + "is_locked": false, + "locked_at": "0001-01-01T00:00:00Z" + }, + { + "name": "sonar-cloud-call-recording", + "is_locked": false, + "locked_at": "0001-01-01T00:00:00Z" + }, + { + "name": "sonar-cloud-manager", + "is_locked": false, + "locked_at": "0001-01-01T00:00:00Z" + }, + { + "name": "sonar-cloud-pbx", + "is_locked": false, + "locked_at": "0001-01-01T00:00:00Z" + }, + { + "name": "sonar-cloud-pbx-dialplan", + "is_locked": false, + "locked_at": "0001-01-01T00:00:00Z" + }, + { + "name": "sonar-cloud-proxy", + "is_locked": false, + "locked_at": "0001-01-01T00:00:00Z" + }, + { + "name": "sonar-cloud-redis", + "is_locked": false, + "locked_at": "0001-01-01T00:00:00Z" + }, + { + "name": "sonar-cloud-rtpengine-01", + "is_locked": false, + "locked_at": "0001-01-01T00:00:00Z" + }, + { + "name": "sonar-cloud-rtpengine-02", + "is_locked": false, + "locked_at": "0001-01-01T00:00:00Z" + }, + { + "name": "sonar-cloud-rtpengine-03", + "is_locked": false, + "locked_at": "0001-01-01T00:00:00Z" + }, + { + "name": "sonar-cloud-speaker", + "is_locked": false, + "locked_at": "0001-01-01T00:00:00Z" + }, + { + "name": "sonar-cloud-transcriber", + "is_locked": false, + "locked_at": "0001-01-01T00:00:00Z" + }, + { + "name": "users-api", + "is_locked": false, + "locked_at": "0001-01-01T00:00:00Z" + }, + { + "name": "walmeric-conf", "is_locked": false, "locked_at": "0001-01-01T00:00:00Z" }