feat: add api security, update services list and add gitignore

This commit is contained in:
Jose Luis Montañes Ojados
2026-01-28 15:35:22 +01:00
parent a857c1a051
commit f0b4a0142d
4 changed files with 254 additions and 11 deletions

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
*.exe

View File

@@ -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)
}
}

View File

@@ -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
}

View File

@@ -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"
}