package main import ( "context" "encoding/json" "fmt" "net/http" "time" ) type PolicyList struct { Status string `json:"status"` Policies map[string]Policy `json:"policies"` Count int `json:"count"` Timestamp string `json:"timestamp"` } func ListPolicy(w http.ResponseWriter, r *http.Request) { // Only allow POST method if r.Method != http.MethodPost { http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) return } // XXX Temporary Account Handler accountid := r.Header.Get("Account") if accountid == "" { http.Error(w, "Account header is required", http.StatusUnauthorized) return } // Optional: enforce content type if r.Header.Get("Content-Type") != "application/json" { http.Error(w, "Content-Type must be application/json", http.StatusUnsupportedMediaType) return } // Read body with size limit (protect against huge requests) const maxBodyBytes = 1 << 20 // 1 MB r.Body = http.MaxBytesReader(w, r.Body, maxBodyBytes) // Check if policy with the same name already exists for the account rows, err := pool.Query(context.Background(), "SELECT policyname, document FROM policies WHERE accountid = $1", accountid) if err != nil { http.Error(w, "Internal Server Error", http.StatusInternalServerError) return } defer rows.Close() var policylist PolicyList policylist.Policies = make(map[string]Policy) for rows.Next() { var policyname string var document Policy err = rows.Scan(&policyname, &document) if err != nil { http.Error(w, "Internal Server Error", http.StatusInternalServerError) return } policylist.Count = policylist.Count + 1 policylist.Policies["pri:iam::"+accountid+":policy/"+policyname] = document } policylist.Status = "success" policylist.Timestamp = fmt.Sprintf("%d", time.Now().Unix()) json.NewEncoder(w).Encode(policylist) }