func (h *HandlersAdmin) NodeActionsPOSTHandler(w http.ResponseWriter, r *http.Request) {
	h.Inc(metricAdminReq)
	utils.DebugHTTPDump(r, h.Settings.DebugHTTP(settings.ServiceAdmin), true)
	var m NodeMultiActionRequest
	ctx := r.Context().Value(sessions.ContextKey("session")).(sessions.ContextValue)
	if !h.Users.CheckPermissions(ctx[sessions.CtxUser], users.AdminLevel, users.NoEnvironment) {
		adminErrorResponse(w, fmt.Sprintf("%s has insuficient permissions", ctx[sessions.CtxUser]), http.StatusForbidden, nil)
		h.Inc(metricAdminErr)
		return
	}
	if h.Settings.DebugService(settings.ServiceAdmin) {
		log.Println("DebugService: Decoding POST body")
	}
	if err := json.NewDecoder(r.Body).Decode(&m); err != nil {
		adminErrorResponse(w, "error parsing POST body", http.StatusInternalServerError, err)
		h.Inc(metricAdminErr)
		return
	}
	if !sessions.CheckCSRFToken(ctx[sessions.CtxCSRF], m.CSRFToken) {
		adminErrorResponse(w, "invalid CSRF token", http.StatusInternalServerError, nil)
		h.Inc(metricAdminErr)
		return
	}
	switch m.Action {
	case "delete":
		okCount := 0
		errCount := 0
		for _, u := range m.UUIDs {
			if err := h.Nodes.ArchiveDeleteByUUID(u); err != nil {
				errCount++
				if h.Settings.DebugService(settings.ServiceAdmin) {
					log.Printf("DebugService: error deleting node %s %v", u, err)
				}
			} else {
				okCount++
			}
		}
		if errCount == 0 {
			adminOKResponse(w, fmt.Sprintf("%d Node(s) have been deleted successfully", okCount))
		} else {
			adminErrorResponse(w, fmt.Sprintf("Error deleting %d node(s)", errCount), http.StatusInternalServerError, nil)
			h.Inc(metricAdminErr)
			return
		}
	case "archive":
		if h.Settings.DebugService(settings.ServiceAdmin) {
			log.Printf("DebugService: archiving node")
		}
		adminOKResponse(w, "node archived successfully")
	case "tag":
		okCount := 0
		errCount := 0
		for _, u := range m.UUIDs {
			if err := h.Nodes.ArchiveDeleteByUUID(u); err != nil {
				errCount++
				if h.Settings.DebugService(settings.ServiceAdmin) {
					log.Printf("DebugService: error tagging node %s %v", u, err)
				}
			} else {
				okCount++
			}
		}
		if errCount == 0 {
			adminOKResponse(w, fmt.Sprintf("%d Node(s) have been deleted successfully", okCount))
		} else {
			adminErrorResponse(w, fmt.Sprintf("Error deleting %d node(s)", errCount), http.StatusInternalServerError, nil)
			h.Inc(metricAdminErr)
			return
		}
	}
	if h.Settings.DebugService(settings.ServiceAdmin) {
		log.Println("DebugService: Multi-node action response sent")
	}
	h.Inc(metricAdminOK)
}
NodeActionsPOSTHandler for POST requests for multi node action
package handlers
import (
	"encoding/base64"
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"github.com/gorilla/mux"
	"github.com/jmpsec/osctrl/admin/sessions"
	"github.com/jmpsec/osctrl/environments"
	"github.com/jmpsec/osctrl/nodes"
	"github.com/jmpsec/osctrl/queries"
	"github.com/jmpsec/osctrl/settings"
	"github.com/jmpsec/osctrl/users"
	"github.com/jmpsec/osctrl/utils"
)
func (h *HandlersAdmin) LoginPOSTHandler(w http.ResponseWriter, r *http.Request) {
	h.Inc(metricAdminReq)
	utils.DebugHTTPDump(r, h.Settings.DebugHTTP(settings.ServiceAdmin), false)
	var l LoginRequest
	if h.Settings.DebugService(settings.ServiceAdmin) {
		log.Println("DebugService: Decoding POST body")
	}
	if err := json.NewDecoder(r.Body).Decode(&l); err != nil {
		adminErrorResponse(w, "error parsing POST body", http.StatusInternalServerError, err)
		h.Inc(metricAdminErr)
		return
	}
	access, user := h.Users.CheckLoginCredentials(l.Username, l.Password)
	if !access {
		adminErrorResponse(w, "invalid credentials", http.StatusForbidden, nil)
		h.Inc(metricAdminErr)
		return
	}
	permissions, err := h.Users.ConvertPermissions(user.Permissions.RawMessage)
	if err != nil {
		adminErrorResponse(w, "error processing login", http.StatusInternalServerError, err)
		h.Inc(metricAdminErr)
		return
	}
	_, err = h.Sessions.Save(r, w, user, permissions)
	if err != nil {
		adminErrorResponse(w, "session error", http.StatusForbidden, err)
		h.Inc(metricAdminErr)
		return
	}
	if h.Settings.DebugService(settings.ServiceAdmin) {
		log.Println("DebugService: Login response sent")
	}
	adminOKResponse(w, "/environment/"+user.DefaultEnv+"/active")
	h.Inc(metricAdminOK)
}
func (h *HandlersAdmin) LogoutPOSTHandler(w http.ResponseWriter, r *http.Request) {
	h.Inc(metricAdminReq)
	utils.DebugHTTPDump(r, h.Settings.DebugHTTP(settings.ServiceAdmin), false)
	var l LogoutRequest
	ctx := r.Context().Value(sessions.ContextKey("session")).(sessions.ContextValue)
	if h.Settings.DebugService(settings.ServiceAdmin) {
		log.Println("DebugService: Decoding POST body")
	}
	if err := json.NewDecoder(r.Body).Decode(&l); err != nil {
		adminErrorResponse(w, "error parsing POST body", http.StatusInternalServerError, err)
		h.Inc(metricAdminErr)
		return
	}
	if !sessions.CheckCSRFToken(ctx[sessions.CtxCSRF], l.CSRFToken) {
		adminErrorResponse(w, "invalid CSRF token", http.StatusInternalServerError, nil)
		h.Inc(metricAdminErr)
		return
	}
	if err := h.Sessions.Destroy(r); err != nil {
		adminErrorResponse(w, "error destroying session", http.StatusInternalServerError, err)
		h.Inc(metricAdminErr)
		return
	}
	if h.Settings.DebugService(settings.ServiceAdmin) {
		log.Println("DebugService: Logout response sent")
	}
	adminOKResponse(w, "OK")
	h.Inc(metricAdminOK)
}
func (h *HandlersAdmin) QueryRunPOSTHandler(w http.ResponseWriter, r *http.Request) {
	h.Inc(metricAdminReq)
	utils.DebugHTTPDump(r, h.Settings.DebugHTTP(settings.ServiceAdmin), true)
	var q DistributedQueryRequest
	ctx := r.Context().Value(sessions.ContextKey("session")).(sessions.ContextValue)
	if !h.Users.CheckPermissions(ctx[sessions.CtxUser], users.QueryLevel, users.NoEnvironment) {
		adminErrorResponse(w, fmt.Sprintf("%s has insuficient permissions", ctx[sessions.CtxUser]), http.StatusForbidden, nil)
		h.Inc(metricAdminErr)
		return
	}
	if h.Settings.DebugService(settings.ServiceAdmin) {
		log.Println("DebugService: Decoding POST body")
	}
	if err := json.NewDecoder(r.Body).Decode(&q); err != nil {
		adminErrorResponse(w, "error parsing POST body", http.StatusInternalServerError, err)
		h.Inc(metricAdminErr)
		return
	}
	if !sessions.CheckCSRFToken(ctx[sessions.CtxCSRF], q.CSRFToken) {
		adminErrorResponse(w, "invalid CSRF token", http.StatusInternalServerError, nil)
		h.Inc(metricAdminErr)
		return
	}
	if q.Query == "" {
		adminErrorResponse(w, "query can not be empty", http.StatusInternalServerError, nil)
		h.Inc(metricAdminErr)
		return
	}
	newQuery := newQueryReady(ctx[sessions.CtxUser], q.Query)
	if err := h.Queries.Create(newQuery); err != nil {
		adminErrorResponse(w, "error creating query", http.StatusInternalServerError, err)
		h.Inc(metricAdminErr)
		return
	}
	var expected []string
	if len(q.Environments) > 0 {
		for _, e := range q.Environments {
			if (e != "") && h.Envs.Exists(e) {
				if err := h.Queries.CreateTarget(newQuery.Name, queries.QueryTargetEnvironment, e); err != nil {
					adminErrorResponse(w, "error creating query environment target", http.StatusInternalServerError, err)
					h.Inc(metricAdminErr)
					return
				}
				nodes, err := h.Nodes.GetByEnv(e, "active", h.Settings.InactiveHours())
				if err != nil {
					adminErrorResponse(w, "error getting nodes by environment", http.StatusInternalServerError, err)
					h.Inc(metricAdminErr)
					return
				}
				for _, n := range nodes {
					expected = append(expected, n.UUID)
				}
			}
		}
	}
	if len(q.Platforms) > 0 {
		platforms, _ := h.Nodes.GetAllPlatforms()
		for _, p := range q.Platforms {
			if (p != "") && checkValidPlatform(platforms, p) {
				if err := h.Queries.CreateTarget(newQuery.Name, queries.QueryTargetPlatform, p); err != nil {
					adminErrorResponse(w, "error creating query platform target", http.StatusInternalServerError, err)
					h.Inc(metricAdminErr)
					return
				}
				nodes, err := h.Nodes.GetByPlatform(p, "active", h.Settings.InactiveHours())
				if err != nil {
					adminErrorResponse(w, "error getting nodes by platform", http.StatusInternalServerError, err)
					h.Inc(metricAdminErr)
					return
				}
				for _, n := range nodes {
					expected = append(expected, n.UUID)
				}
			}
		}
	}
	if len(q.UUIDs) > 0 {
		for _, u := range q.UUIDs {
			if (u != "") && h.Nodes.CheckByUUID(u) {
				if err := h.Queries.CreateTarget(newQuery.Name, queries.QueryTargetUUID, u); err != nil {
					adminErrorResponse(w, "error creating query UUID target", http.StatusInternalServerError, err)
					h.Inc(metricAdminErr)
					return
				}
				expected = append(expected, u)
			}
		}
	}
	if len(q.Hosts) > 0 {
		for _, _h := range q.Hosts {
			if (_h != "") && h.Nodes.CheckByHost(_h) {
				if err := h.Queries.CreateTarget(newQuery.Name, queries.QueryTargetLocalname, _h); err != nil {
					adminErrorResponse(w, "error creating query hostname target", http.StatusInternalServerError, err)
					h.Inc(metricAdminErr)
					return
				}
				expected = append(expected, _h)
			}
		}
	}
	expectedClear := removeStringDuplicates(expected)
	if err := h.Queries.SetExpected(newQuery.Name, len(expectedClear)); err != nil {
		adminErrorResponse(w, "error setting expected", http.StatusInternalServerError, err)
		h.Inc(metricAdminErr)
		return
	}
	if q.Save && q.Name != "" {
		if err := h.Queries.CreateSaved(q.Name, q.Query, ctx[sessions.CtxUser]); err != nil {
			adminErrorResponse(w, "error saving query", http.StatusInternalServerError, err)
			h.Inc(metricAdminErr)
			return
		}
	}
	if h.Settings.DebugService(settings.ServiceAdmin) {
		log.Println("DebugService: Query run response sent")
	}
	adminOKResponse(w, "OK")
	h.Inc(metricAdminOK)
}
func (h *HandlersAdmin) CarvesRunPOSTHandler(w http.ResponseWriter, r *http.Request) {
	h.Inc(metricAdminReq)
	utils.DebugHTTPDump(r, h.Settings.DebugHTTP(settings.ServiceAdmin), true)
	var c DistributedCarveRequest
	ctx := r.Context().Value(sessions.ContextKey("session")).(sessions.ContextValue)
	if !h.Users.CheckPermissions(ctx[sessions.CtxUser], users.CarveLevel, users.NoEnvironment) {
		adminErrorResponse(w, fmt.Sprintf("%s has insuficient permissions", ctx[sessions.CtxUser]), http.StatusForbidden, nil)
		h.Inc(metricAdminErr)
		return
	}
	if h.Settings.DebugService(settings.ServiceAdmin) {
		log.Println("DebugService: Decoding POST body")
	}
	if err := json.NewDecoder(r.Body).Decode(&c); err != nil {
		adminErrorResponse(w, "error parsing POST body", http.StatusInternalServerError, err)
		h.Inc(metricAdminErr)
		return
	}
	if !sessions.CheckCSRFToken(ctx[sessions.CtxCSRF], c.CSRFToken) {
		adminErrorResponse(w, "invalid CSRF token", http.StatusInternalServerError, nil)
		h.Inc(metricAdminErr)
		return
	}
	if c.Path == "" {
		adminErrorResponse(w, "path can not be empty", http.StatusInternalServerError, nil)
		h.Inc(metricAdminErr)
		return
	}
	query := generateCarveQuery(c.Path, false)
	carveName := generateCarveName()
	newQuery := queries.DistributedQuery{
		Query:      query,
		Name:       carveName,
		Creator:    ctx[sessions.CtxUser],
		Expected:   0,
		Executions: 0,
		Active:     true,
		Completed:  false,
		Deleted:    false,
		Type:       queries.CarveQueryType,
		Path:       c.Path,
	}
	if err := h.Queries.Create(newQuery); err != nil {
		adminErrorResponse(w, "error creating carve", http.StatusInternalServerError, err)
		h.Inc(metricAdminErr)
		return
	}
	var expected []string
	if len(c.Environments) > 0 {
		for _, e := range c.Environments {
			if (e != "") && h.Envs.Exists(e) {
				if err := h.Queries.CreateTarget(carveName, queries.QueryTargetEnvironment, e); err != nil {
					adminErrorResponse(w, "error creating carve environment target", http.StatusInternalServerError, err)
					h.Inc(metricAdminErr)
					return
				}
				nodes, err := h.Nodes.GetByEnv(e, "active", h.Settings.InactiveHours())
				if err != nil {
					adminErrorResponse(w, "error getting nodes by environment", http.StatusInternalServerError, err)
					h.Inc(metricAdminErr)
					return
				}
				for _, n := range nodes {
					expected = append(expected, n.UUID)
				}
			}
		}
	}
	if len(c.Platforms) > 0 {
		platforms, _ := h.Nodes.GetAllPlatforms()
		for _, p := range c.Platforms {
			if (p != "") && checkValidPlatform(platforms, p) {
				if err := h.Queries.CreateTarget(carveName, queries.QueryTargetPlatform, p); err != nil {
					adminErrorResponse(w, "error creating carve platform target", http.StatusInternalServerError, err)
					h.Inc(metricAdminErr)
					return
				}
				nodes, err := h.Nodes.GetByPlatform(p, "active", h.Settings.InactiveHours())
				if err != nil {
					adminErrorResponse(w, "error getting nodes by platform", http.StatusInternalServerError, err)
					h.Inc(metricAdminErr)
					return
				}
				for _, n := range nodes {
					expected = append(expected, n.UUID)
				}
			}
		}
	}
	if len(c.UUIDs) > 0 {
		for _, u := range c.UUIDs {
			if (u != "") && h.Nodes.CheckByUUID(u) {
				if err := h.Queries.CreateTarget(carveName, queries.QueryTargetUUID, u); err != nil {
					adminErrorResponse(w, "error creating carve UUID target", http.StatusInternalServerError, err)
					h.Inc(metricAdminErr)
					return
				}
				expected = append(expected, u)
			}
		}
	}
	if len(c.Hosts) > 0 {
		for _, _h := range c.Hosts {
			if (_h != "") && h.Nodes.CheckByHost(_h) {
				if err := h.Queries.CreateTarget(carveName, queries.QueryTargetLocalname, _h); err != nil {
					adminErrorResponse(w, "error creating carve hostname target", http.StatusInternalServerError, err)
					h.Inc(metricAdminErr)
					return
				}
			}
		}
	}
	expectedClear := removeStringDuplicates(expected)
	if err := h.Queries.SetExpected(carveName, len(expectedClear)); err != nil {
		adminErrorResponse(w, "error setting expected", http.StatusInternalServerError, err)
		h.Inc(metricAdminErr)
		return
	}
	if h.Settings.DebugService(settings.ServiceAdmin) {
		log.Println("DebugService: Carve run response sent")
	}
	adminOKResponse(w, "OK")
	h.Inc(metricAdminOK)
}
func (h *HandlersAdmin) QueryActionsPOSTHandler(w http.ResponseWriter, r *http.Request) {
	h.Inc(metricAdminReq)
	utils.DebugHTTPDump(r, h.Settings.DebugHTTP(settings.ServiceAdmin), true)
	var q DistributedQueryActionRequest
	ctx := r.Context().Value(sessions.ContextKey("session")).(sessions.ContextValue)
	if !h.Users.CheckPermissions(ctx[sessions.CtxUser], users.QueryLevel, users.NoEnvironment) {
		adminErrorResponse(w, fmt.Sprintf("%s has insuficient permissions", ctx[sessions.CtxUser]), http.StatusForbidden, nil)
		h.Inc(metricAdminErr)
		return
	}
	if h.Settings.DebugService(settings.ServiceAdmin) {
		log.Println("DebugService: Decoding POST body")
	}
	if err := json.NewDecoder(r.Body).Decode(&q); err != nil {
		adminErrorResponse(w, "error parsing POST body", http.StatusInternalServerError, err)
		h.Inc(metricAdminErr)
		return
	}
	if !sessions.CheckCSRFToken(ctx[sessions.CtxCSRF], q.CSRFToken) {
		adminErrorResponse(w, "invalid CSRF token", http.StatusInternalServerError, nil)
		h.Inc(metricAdminErr)
		return
	}
	switch q.Action {
	case "delete":
		for _, n := range q.Names {
			if err := h.Queries.Delete(n); err != nil {
				adminErrorResponse(w, "error deleting query", http.StatusInternalServerError, err)
				h.Inc(metricAdminErr)
				return
			}
		}
		adminOKResponse(w, "queries delete successfully")
	case "complete":
		for _, n := range q.Names {
			if err := h.Queries.Complete(n); err != nil {
				adminErrorResponse(w, "error completing query", http.StatusInternalServerError, err)
				h.Inc(metricAdminErr)
				return
			}
		}
		adminOKResponse(w, "queries completed successfully")
	case "activate":
		for _, n := range q.Names {
			if err := h.Queries.Activate(n); err != nil {
				adminErrorResponse(w, "error activating query", http.StatusInternalServerError, err)
				h.Inc(metricAdminErr)
				return
			}
		}
		adminOKResponse(w, "queries activated successfully")
	case "saved_delete":
		for _, n := range q.Names {
			if err := h.Queries.DeleteSaved(n, ctx[sessions.CtxUser]); err != nil {
				adminErrorResponse(w, "error deleting query", http.StatusInternalServerError, err)
				h.Inc(metricAdminErr)
				return
			}
		}
		adminOKResponse(w, "queries delete successfully")
	}
	if h.Settings.DebugService(settings.ServiceAdmin) {
		log.Println("DebugService: Query run response sent")
	}
	h.Inc(metricAdminOK)
}
func (h *HandlersAdmin) CarvesActionsPOSTHandler(w http.ResponseWriter, r *http.Request) {
	h.Inc(metricAdminReq)
	utils.DebugHTTPDump(r, h.Settings.DebugHTTP(settings.ServiceAdmin), true)
	var q DistributedCarvesActionRequest
	ctx := r.Context().Value(sessions.ContextKey("session")).(sessions.ContextValue)
	if !h.Users.CheckPermissions(ctx[sessions.CtxUser], users.CarveLevel, users.NoEnvironment) {
		adminErrorResponse(w, fmt.Sprintf("%s has insuficient permissions", ctx[sessions.CtxUser]), http.StatusForbidden, nil)
		h.Inc(metricAdminErr)
		return
	}
	if h.Settings.DebugService(settings.ServiceAdmin) {
		log.Println("DebugService: Decoding POST body")
	}
	if err := json.NewDecoder(r.Body).Decode(&q); err != nil {
		adminErrorResponse(w, "error parsing POST body", http.StatusInternalServerError, err)
		h.Inc(metricAdminErr)
		return
	}
	if !sessions.CheckCSRFToken(ctx[sessions.CtxCSRF], q.CSRFToken) {
		adminErrorResponse(w, "invalid CSRF token", http.StatusInternalServerError, nil)
		h.Inc(metricAdminErr)
		return
	}
	switch q.Action {
	case "delete":
		for _, n := range q.IDs {
			if err := h.Carves.Delete(n); err != nil {
				adminErrorResponse(w, "error deleting carve", http.StatusInternalServerError, err)
				h.Inc(metricAdminErr)
				return
			}
		}
		adminOKResponse(w, "carves delete successfully")
	case "test":
		if h.Settings.DebugService(settings.ServiceAdmin) {
			log.Printf("DebugService: testing action")
		}
		adminOKResponse(w, "test successful")
	}
	if h.Settings.DebugService(settings.ServiceAdmin) {
		log.Println("DebugService: Carves action response sent")
	}
	h.Inc(metricAdminOK)
}
func (h *HandlersAdmin) ConfPOSTHandler(w http.ResponseWriter, r *http.Request) {
	h.Inc(metricAdminReq)
	utils.DebugHTTPDump(r, h.Settings.DebugHTTP(settings.ServiceAdmin), true)
	vars := mux.Vars(r)
	environmentVar, ok := vars["environment"]
	if !ok || !h.Envs.Exists(environmentVar) {
		adminErrorResponse(w, "error getting environment", http.StatusInternalServerError, nil)
		h.Inc(metricAdminErr)
		return
	}
	var c ConfigurationRequest
	ctx := r.Context().Value(sessions.ContextKey("session")).(sessions.ContextValue)
	if !h.Users.CheckPermissions(ctx[sessions.CtxUser], users.EnvLevel, environmentVar) {
		adminErrorResponse(w, fmt.Sprintf("%s has insuficient permissions", ctx[sessions.CtxUser]), http.StatusForbidden, nil)
		h.Inc(metricAdminErr)
		return
	}
	if h.Settings.DebugService(settings.ServiceAdmin) {
		log.Println("DebugService: Decoding POST body")
	}
	if err := json.NewDecoder(r.Body).Decode(&c); err != nil {
		adminErrorResponse(w, "error parsing POST body", http.StatusInternalServerError, err)
		h.Inc(metricAdminErr)
		return
	}
	if !sessions.CheckCSRFToken(ctx[sessions.CtxCSRF], c.CSRFToken) {
		adminErrorResponse(w, "invalid CSRF token", http.StatusInternalServerError, nil)
		h.Inc(metricAdminErr)
		return
	}
	if c.ConfigurationB64 != "" {
		configuration, err := base64.StdEncoding.DecodeString(c.ConfigurationB64)
		if err != nil {
			adminErrorResponse(w, "error decoding configuration", http.StatusInternalServerError, err)
			h.Inc(metricAdminErr)
			return
		}
		cnf, err := h.Envs.GenStructConf(configuration)
		if err != nil {
			adminErrorResponse(w, "error parsing configuration", http.StatusInternalServerError, err)
			h.Inc(metricAdminErr)
			return
		}
		if err := h.Envs.UpdateConfiguration(environmentVar, cnf); err != nil {
			adminErrorResponse(w, "error saving configuration", http.StatusInternalServerError, err)
			h.Inc(metricAdminErr)
			return
		}
		if err := h.Envs.UpdateConfigurationParts(environmentVar, cnf); err != nil {
			adminErrorResponse(w, "error saving configuration parts", http.StatusInternalServerError, err)
			h.Inc(metricAdminErr)
			return
		}
		if h.Settings.DebugService(settings.ServiceAdmin) {
			log.Println("DebugService: Configuration response sent")
		}
		adminOKResponse(w, "configuration saved successfully")
		h.Inc(metricAdminOK)
		return
	}
	if c.OptionsB64 != "" {
		options, err := base64.StdEncoding.DecodeString(c.OptionsB64)
		if err != nil {
			adminErrorResponse(w, "error decoding options", http.StatusInternalServerError, err)
			h.Inc(metricAdminErr)
			return
		}
		if err := h.Envs.UpdateOptions(environmentVar, string(options)); err != nil {
			adminErrorResponse(w, "error saving options", http.StatusInternalServerError, err)
			h.Inc(metricAdminErr)
			return
		}
		if err := h.Envs.RefreshConfiguration(environmentVar); err != nil {
			adminErrorResponse(w, "error updating configuration", http.StatusInternalServerError, err)
			h.Inc(metricAdminErr)
			return
		}
		if h.Settings.DebugService(settings.ServiceAdmin) {
			log.Println("DebugService: Options response sent")
		}
		adminOKResponse(w, "options saved successfully")
		h.Inc(metricAdminOK)
		return
	}
	if c.ScheduleB64 != "" {
		schedule, err := base64.StdEncoding.DecodeString(c.ScheduleB64)
		if err != nil {
			adminErrorResponse(w, "error decoding schedule", http.StatusInternalServerError, err)
			h.Inc(metricAdminErr)
			return
		}
		if err := h.Envs.UpdateSchedule(environmentVar, string(schedule)); err != nil {
			adminErrorResponse(w, "error saving schedule", http.StatusInternalServerError, err)
			h.Inc(metricAdminErr)
			return
		}
		if err := h.Envs.RefreshConfiguration(environmentVar); err != nil {
			adminErrorResponse(w, "error updating configuration", http.StatusInternalServerError, err)
			h.Inc(metricAdminErr)
			return
		}
		if h.Settings.DebugService(settings.ServiceAdmin) {
			log.Println("DebugService: Schedule response sent")
		}
		adminOKResponse(w, "schedule saved successfully")
		h.Inc(metricAdminOK)
		return
	}
	if c.PacksB64 != "" {
		packs, err := base64.StdEncoding.DecodeString(c.PacksB64)
		if err != nil {
			adminErrorResponse(w, "error decoding packs", http.StatusInternalServerError, err)
			h.Inc(metricAdminErr)
			return
		}
		if err := h.Envs.UpdatePacks(environmentVar, string(packs)); err != nil {
			adminErrorResponse(w, "error saving packs", http.StatusInternalServerError, err)
			h.Inc(metricAdminErr)
			return
		}
		if err := h.Envs.RefreshConfiguration(environmentVar); err != nil {
			adminErrorResponse(w, "error updating configuration", http.StatusInternalServerError, err)
			h.Inc(metricAdminErr)
			return
		}
		if h.Settings.DebugService(settings.ServiceAdmin) {
			log.Println("DebugService: Packs response sent")
		}
		adminOKResponse(w, "packs saved successfully")
		h.Inc(metricAdminOK)
		return
	}
	if c.DecoratorsB64 != "" {
		decorators, err := base64.StdEncoding.DecodeString(c.DecoratorsB64)
		if err != nil {
			adminErrorResponse(w, "error decoding decorators", http.StatusInternalServerError, err)
			h.Inc(metricAdminErr)
			return
		}
		if err := h.Envs.UpdateDecorators(environmentVar, string(decorators)); err != nil {
			adminErrorResponse(w, "error saving decorators", http.StatusInternalServerError, err)
			h.Inc(metricAdminErr)
			return
		}
		if err := h.Envs.RefreshConfiguration(environmentVar); err != nil {
			adminErrorResponse(w, "error updating configuration", http.StatusInternalServerError, err)
			h.Inc(metricAdminErr)
			return
		}
		if h.Settings.DebugService(settings.ServiceAdmin) {
			log.Println("DebugService: Decorators response sent")
		}
		adminOKResponse(w, "decorators saved successfully")
		h.Inc(metricAdminOK)
		return
	}
	if c.ATCB64 != "" {
		schedule, err := base64.StdEncoding.DecodeString(c.ATCB64)
		if err != nil {
			adminErrorResponse(w, "error decoding ATC", http.StatusInternalServerError, err)
			h.Inc(metricAdminErr)
			return
		}
		if err := h.Envs.UpdateATC(environmentVar, string(schedule)); err != nil {
			adminErrorResponse(w, "error saving ATC", http.StatusInternalServerError, err)
			h.Inc(metricAdminErr)
			return
		}
		if err := h.Envs.RefreshConfiguration(environmentVar); err != nil {
			adminErrorResponse(w, "error updating configuration", http.StatusInternalServerError, err)
			h.Inc(metricAdminErr)
			return
		}
		if h.Settings.DebugService(settings.ServiceAdmin) {
			log.Println("DebugService: ATC response sent")
		}
		adminOKResponse(w, "ATC saved successfully")
		h.Inc(metricAdminOK)
		return
	}
	responseMessage := "empty configuration"
	utils.HTTPResponse(w, utils.JSONApplicationUTF8, http.StatusInternalServerError, AdminResponse{Message: responseMessage})
	if h.Settings.DebugService(settings.ServiceAdmin) {
		log.Printf("DebugService: %s", responseMessage)
	}
	h.Inc(metricAdminErr)
}
func (h *HandlersAdmin) IntervalsPOSTHandler(w http.ResponseWriter, r *http.Request) {
	h.Inc(metricAdminReq)
	utils.DebugHTTPDump(r, h.Settings.DebugHTTP(settings.ServiceAdmin), true)
	vars := mux.Vars(r)
	envVar, ok := vars["environment"]
	if !ok || !h.Envs.Exists(envVar) {
		adminErrorResponse(w, "error getting environment", http.StatusInternalServerError, nil)
		h.Inc(metricAdminErr)
		return
	}
	env, err := h.Envs.Get(envVar)
	if err != nil {
		adminErrorResponse(w, "error getting environment", http.StatusInternalServerError, nil)
		h.Inc(metricAdminErr)
		return
	}
	var c IntervalsRequest
	ctx := r.Context().Value(sessions.ContextKey("session")).(sessions.ContextValue)
	if !h.Users.CheckPermissions(ctx[sessions.CtxUser], users.EnvLevel, env.Name) {
		adminErrorResponse(w, fmt.Sprintf("%s has insuficient permissions", ctx[sessions.CtxUser]), http.StatusForbidden, nil)
		h.Inc(metricAdminErr)
		return
	}
	if h.Settings.DebugService(settings.ServiceAdmin) {
		log.Println("DebugService: Decoding POST body")
	}
	if err := json.NewDecoder(r.Body).Decode(&c); err != nil {
		adminErrorResponse(w, "error parsing POST body", http.StatusInternalServerError, err)
		h.Inc(metricAdminErr)
		return
	}
	if !sessions.CheckCSRFToken(ctx[sessions.CtxCSRF], c.CSRFToken) {
		adminErrorResponse(w, "invalid CSRF token", http.StatusInternalServerError, nil)
		h.Inc(metricAdminErr)
		return
	}
	if err := h.Envs.UpdateIntervals(env.Name, c.ConfigInterval, c.LogInterval, c.QueryInterval); err != nil {
		adminErrorResponse(w, "error updating intervals", http.StatusInternalServerError, err)
		h.Inc(metricAdminErr)
		return
	}
	flags, err := h.Envs.GenerateFlagsEnv(envVar, "", "")
	if err != nil {
		adminErrorResponse(w, "error re-generating flags", http.StatusInternalServerError, err)
		h.Inc(metricAdminErr)
		return
	}
	if err := h.Envs.UpdateFlags(envVar, flags); err != nil {
		adminErrorResponse(w, "error updating flags", http.StatusInternalServerError, err)
		h.Inc(metricAdminErr)
		return
	}
	if h.Settings.DebugService(settings.ServiceAdmin) {
		log.Println("DebugService: Intervals response sent")
	}
	adminOKResponse(w, "intervals saved successfully")
	h.Inc(metricAdminOK)
}
func (h *HandlersAdmin) ExpirationPOSTHandler(w http.ResponseWriter, r *http.Request) {
	h.Inc(metricAdminReq)
	utils.DebugHTTPDump(r, h.Settings.DebugHTTP(settings.ServiceAdmin), true)
	vars := mux.Vars(r)
	environmentVar, ok := vars["environment"]
	if !ok || !h.Envs.Exists(environmentVar) {
		adminErrorResponse(w, "error getting environment", http.StatusInternalServerError, nil)
		h.Inc(metricAdminErr)
		return
	}
	var e ExpirationRequest
	ctx := r.Context().Value(sessions.ContextKey("session")).(sessions.ContextValue)
	if !h.Users.CheckPermissions(ctx[sessions.CtxUser], users.EnvLevel, environmentVar) {
		adminErrorResponse(w, fmt.Sprintf("%s has insuficient permissions", ctx[sessions.CtxUser]), http.StatusForbidden, nil)
		h.Inc(metricAdminErr)
		return
	}
	if h.Settings.DebugService(settings.ServiceAdmin) {
		log.Println("DebugService: Decoding POST body")
	}
	if err := json.NewDecoder(r.Body).Decode(&e); err != nil {
		adminErrorResponse(w, "error parsing POST body", http.StatusInternalServerError, err)
		h.Inc(metricAdminErr)
		return
	}
	if !sessions.CheckCSRFToken(ctx[sessions.CtxCSRF], e.CSRFToken) {
		adminErrorResponse(w, "invalid CSRF token", http.StatusInternalServerError, nil)
		h.Inc(metricAdminErr)
		return
	}
	switch e.Type {
	case "enroll":
		switch e.Action {
		case "expire":
			if err := h.Envs.ExpireEnroll(environmentVar); err != nil {
				adminErrorResponse(w, "error expiring enroll", http.StatusInternalServerError, err)
				h.Inc(metricAdminErr)
				return
			}
			adminOKResponse(w, "link expired successfully")
		case "extend":
			if err := h.Envs.RotateEnrollPath(environmentVar); err != nil {
				adminErrorResponse(w, "error extending enroll", http.StatusInternalServerError, err)
				h.Inc(metricAdminErr)
				return
			}
			adminOKResponse(w, "link extended successfully")
		}
	case "remove":
		switch e.Action {
		case "expire":
			if err := h.Envs.ExpireRemove(environmentVar); err != nil {
				adminErrorResponse(w, "error expiring remove", http.StatusInternalServerError, err)
				h.Inc(metricAdminErr)
				return
			}
			adminOKResponse(w, "link expired successfully")
		case "extend":
			if err := h.Envs.RotateRemove(environmentVar); err != nil {
				adminErrorResponse(w, "error extending remove", http.StatusInternalServerError, err)
				h.Inc(metricAdminErr)
				return
			}
			adminOKResponse(w, "link extended successfully")
		}
	}
	if h.Settings.DebugService(settings.ServiceAdmin) {
		log.Println("DebugService: Expiration response sent")
	}
	h.Inc(metricAdminOK)
}