95c821deb2
Add detailed [DEBUG] logging to every controller module when logging.level is set to "debug". Each module with stateful debug uses SetDebug(bool) wired from main.go. Covers stacks, backup, cloudflare, integrations, system, monitor, settings, scheduler, web handlers, storage, metrics, API, selfupdate, and assets. Also includes the app export/import (.fab bundles) feature from v0.32.0 and its debug page integration. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
182 lines
5.5 KiB
Go
182 lines
5.5 KiB
Go
package api
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"net/http"
|
|
|
|
cf "gitea.dooplex.hu/admin/felhom-controller/internal/cloudflare"
|
|
"gitea.dooplex.hu/admin/felhom-controller/internal/settings"
|
|
)
|
|
|
|
func (r *Router) geoStatus(w http.ResponseWriter, _ *http.Request) {
|
|
geo := r.sett.GetGeoRestriction()
|
|
|
|
data := map[string]interface{}{
|
|
"cf_configured": r.cfg.Infrastructure.CFAPIToken != "",
|
|
"geo_available": r.geoSync != nil,
|
|
}
|
|
|
|
if geo != nil {
|
|
data["enabled"] = geo.Enabled
|
|
data["allowed_countries"] = geo.AllowedCountries
|
|
data["app_overrides"] = geo.AppOverrides
|
|
data["last_sync"] = geo.LastSync
|
|
data["last_sync_error"] = geo.LastSyncError
|
|
data["syncing"] = r.geoSync != nil && r.geoSync.IsRunning()
|
|
} else {
|
|
data["enabled"] = false
|
|
data["allowed_countries"] = []string{"HU"}
|
|
}
|
|
|
|
writeJSON(w, http.StatusOK, apiResponse{OK: true, Data: data})
|
|
}
|
|
|
|
func (r *Router) geoUpdateSettings(w http.ResponseWriter, req *http.Request) {
|
|
limitBody(w, req)
|
|
r.dbg("geoUpdateSettings: contentLength=%d", req.ContentLength)
|
|
|
|
var body struct {
|
|
Enabled bool `json:"enabled"`
|
|
AllowedCountries []string `json:"allowed_countries"`
|
|
}
|
|
if err := json.NewDecoder(req.Body).Decode(&body); err != nil {
|
|
writeJSON(w, http.StatusBadRequest, apiResponse{OK: false, Error: "invalid request body"})
|
|
return
|
|
}
|
|
|
|
// Validate country codes
|
|
for _, code := range body.AllowedCountries {
|
|
if !cf.ValidCountryCode(code) {
|
|
writeJSON(w, http.StatusBadRequest, apiResponse{OK: false, Error: "invalid country code: " + code})
|
|
return
|
|
}
|
|
}
|
|
|
|
// Get existing settings to preserve app overrides and sync state
|
|
existing := r.sett.GetGeoRestriction()
|
|
geo := &settings.GeoRestriction{
|
|
Enabled: body.Enabled,
|
|
AllowedCountries: body.AllowedCountries,
|
|
}
|
|
if existing != nil {
|
|
geo.AppOverrides = existing.AppOverrides
|
|
geo.ZoneID = existing.ZoneID
|
|
geo.RulesetID = existing.RulesetID
|
|
}
|
|
|
|
if err := r.sett.SetGeoRestriction(geo); err != nil {
|
|
r.logger.Printf("[API] Failed to save geo settings: %v", err)
|
|
writeJSON(w, http.StatusInternalServerError, apiResponse{OK: false, Error: err.Error()})
|
|
return
|
|
}
|
|
|
|
r.logger.Printf("[API] Geo settings updated: enabled=%v, countries=%v", body.Enabled, body.AllowedCountries)
|
|
|
|
// Trigger async CF sync
|
|
if r.geoSync != nil {
|
|
go func() {
|
|
if err := r.geoSync.Sync(context.Background()); err != nil {
|
|
r.logger.Printf("[API] Geo sync after settings update failed: %v", err)
|
|
}
|
|
}()
|
|
}
|
|
|
|
writeJSON(w, http.StatusOK, apiResponse{OK: true, Message: "Geo-korlátozás beállítva"})
|
|
}
|
|
|
|
func (r *Router) geoTriggerSync(w http.ResponseWriter, _ *http.Request) {
|
|
if r.geoSync == nil {
|
|
writeJSON(w, http.StatusBadRequest, apiResponse{OK: false, Error: "Cloudflare API nincs konfigurálva"})
|
|
return
|
|
}
|
|
|
|
go func() {
|
|
if err := r.geoSync.Sync(context.Background()); err != nil {
|
|
r.logger.Printf("[API] Manual geo sync failed: %v", err)
|
|
}
|
|
}()
|
|
|
|
writeJSON(w, http.StatusOK, apiResponse{OK: true, Message: "Szinkronizálás elindítva"})
|
|
}
|
|
|
|
func (r *Router) geoCountries(w http.ResponseWriter, _ *http.Request) {
|
|
writeJSON(w, http.StatusOK, apiResponse{OK: true, Data: cf.AllCountries()})
|
|
}
|
|
|
|
func (r *Router) geoSetAppOverride(w http.ResponseWriter, req *http.Request, appName string) {
|
|
if appName == "" {
|
|
writeJSON(w, http.StatusBadRequest, apiResponse{OK: false, Error: "invalid app name"})
|
|
return
|
|
}
|
|
limitBody(w, req)
|
|
|
|
var body struct {
|
|
AllowedCountries []string `json:"allowed_countries"`
|
|
}
|
|
if err := json.NewDecoder(req.Body).Decode(&body); err != nil {
|
|
writeJSON(w, http.StatusBadRequest, apiResponse{OK: false, Error: "invalid request body"})
|
|
return
|
|
}
|
|
|
|
// Validate country codes
|
|
for _, code := range body.AllowedCountries {
|
|
if !cf.ValidCountryCode(code) {
|
|
writeJSON(w, http.StatusBadRequest, apiResponse{OK: false, Error: "invalid country code: " + code})
|
|
return
|
|
}
|
|
}
|
|
|
|
// Verify app exists
|
|
if _, ok := r.stackMgr.GetStack(appName); !ok {
|
|
writeJSON(w, http.StatusNotFound, apiResponse{OK: false, Error: "app not found: " + appName})
|
|
return
|
|
}
|
|
|
|
override := &settings.AppGeoOverride{AllowedCountries: body.AllowedCountries}
|
|
if err := r.sett.SetGeoAppOverride(appName, override); err != nil {
|
|
r.logger.Printf("[API] Failed to save geo override for %s: %v", appName, err)
|
|
writeJSON(w, http.StatusInternalServerError, apiResponse{OK: false, Error: err.Error()})
|
|
return
|
|
}
|
|
|
|
r.logger.Printf("[API] Geo override set for %s: countries=%v", appName, body.AllowedCountries)
|
|
|
|
// Trigger async CF sync
|
|
if r.geoSync != nil {
|
|
go func() {
|
|
if err := r.geoSync.Sync(context.Background()); err != nil {
|
|
r.logger.Printf("[API] Geo sync after app override failed: %v", err)
|
|
}
|
|
}()
|
|
}
|
|
|
|
writeJSON(w, http.StatusOK, apiResponse{OK: true, Message: "Alkalmazás geo-korlátozás beállítva"})
|
|
}
|
|
|
|
func (r *Router) geoRemoveAppOverride(w http.ResponseWriter, _ *http.Request, appName string) {
|
|
if appName == "" {
|
|
writeJSON(w, http.StatusBadRequest, apiResponse{OK: false, Error: "invalid app name"})
|
|
return
|
|
}
|
|
|
|
if err := r.sett.RemoveGeoAppOverride(appName); err != nil {
|
|
r.logger.Printf("[API] Failed to remove geo override for %s: %v", appName, err)
|
|
writeJSON(w, http.StatusInternalServerError, apiResponse{OK: false, Error: err.Error()})
|
|
return
|
|
}
|
|
|
|
r.logger.Printf("[API] Geo override removed for %s", appName)
|
|
|
|
// Trigger async CF sync
|
|
if r.geoSync != nil {
|
|
go func() {
|
|
if err := r.geoSync.Sync(context.Background()); err != nil {
|
|
r.logger.Printf("[API] Geo sync after override removal failed: %v", err)
|
|
}
|
|
}()
|
|
}
|
|
|
|
writeJSON(w, http.StatusOK, apiResponse{OK: true, Message: "Alkalmazás geo-korlátozás eltávolítva"})
|
|
}
|