diff --git a/admin/auth.go b/admin/auth.go index d5ac337c..cf3affed 100644 --- a/admin/auth.go +++ b/admin/auth.go @@ -25,8 +25,54 @@ const ( ) // Helper to verify if user is an admin -func checkAdminLevel(level string) bool { - return (level == adminLevel) +func checkAdminLevel(user users.AdminUser) bool { + return user.Admin +} + +// Helper to check if query access is granted +func checkQueryLevel(permissions users.UserPermissions) bool { + return permissions.Query +} + +// Helper to check if carve access is granted +func checkCarveLevel(permissions users.UserPermissions) bool { + return permissions.Carve +} + +// Helper to check if environment access is granted +func checkEnvironmentLevel(permissions users.UserPermissions, environment string) bool { + return permissions.Environments[environment] +} + +// Helper to check permissions for a user +func checkPermissions(username string, query, carve, env bool, environment string) bool { + exist, user := adminUsers.ExistsGet(username) + if !exist { + return false + } + // Admin always have access + if user.Admin { + return true + } + perms, err := adminUsers.ConvertPermissions(user.Permissions.RawMessage) + if err != nil { + log.Printf("error converting permissions %v", err) + return false + } + // Check for query access + if query { + return checkQueryLevel(perms) + } + // Check for carve access + if carve { + return checkCarveLevel(perms) + } + // Check for environment access + if env { + return checkEnvironmentLevel(perms, environment) + } + // At this point, no access granted + return false } // Handler to check access to a resource based on the authentication enabled diff --git a/admin/handlers-get.go b/admin/handlers-get.go index 8ea4537e..eef8e966 100644 --- a/admin/handlers-get.go +++ b/admin/handlers-get.go @@ -101,6 +101,14 @@ func environmentHandler(w http.ResponseWriter, r *http.Request) { log.Printf("error unknown environment (%s)", env) return } + // Get context data + ctx := r.Context().Value(contextKey("session")).(contextValue) + // Check permissions + if !checkPermissions(ctx[ctxUser], false, false, true, env) { + log.Printf("%s has insuficient permissions", ctx[ctxUser]) + incMetric(metricTokenErr) + return + } // Extract target // FIXME verify target target, ok := vars["target"] @@ -132,8 +140,6 @@ func environmentHandler(w http.ResponseWriter, r *http.Request) { log.Printf("error getting platforms: %v", err) return } - // Get context data - ctx := r.Context().Value(contextKey("session")).(contextValue) // Prepare template data templateData := TableTemplateData{ Title: "Nodes in " + env, @@ -176,6 +182,14 @@ func platformHandler(w http.ResponseWriter, r *http.Request) { log.Println("error getting target") return } + // Get context data + ctx := r.Context().Value(contextKey("session")).(contextValue) + // Check permissions + if !checkPermissions(ctx[ctxUser], false, false, false, "") { + log.Printf("%s has insuficient permissions", ctx[ctxUser]) + incMetric(metricTokenErr) + return + } // Prepare template t, err := template.ParseFiles( templatesFilesFolder+"/table.html", @@ -204,8 +218,6 @@ func platformHandler(w http.ResponseWriter, r *http.Request) { log.Printf("error getting platforms: %v", err) return } - // Get context data - ctx := r.Context().Value(contextKey("session")).(contextValue) // Prepare template data templateData := TableTemplateData{ Title: "Nodes in " + platform, @@ -234,7 +246,7 @@ func queryRunGETHandler(w http.ResponseWriter, r *http.Request) { // Get context data ctx := r.Context().Value(contextKey("session")).(contextValue) // Check permissions - if !checkAdminLevel(ctx[ctxLevel]) { + if !checkPermissions(ctx[ctxUser], true, false, false, "") { log.Printf("%s has insuficient permissions", ctx[ctxUser]) incMetric(metricAdminErr) return @@ -310,7 +322,7 @@ func queryListGETHandler(w http.ResponseWriter, r *http.Request) { // Get context data ctx := r.Context().Value(contextKey("session")).(contextValue) // Check permissions - if !checkAdminLevel(ctx[ctxLevel]) { + if !checkPermissions(ctx[ctxUser], true, false, false, "") { log.Printf("%s has insuficient permissions", ctx[ctxUser]) incMetric(metricAdminErr) return @@ -363,7 +375,7 @@ func carvesRunGETHandler(w http.ResponseWriter, r *http.Request) { // Get context data ctx := r.Context().Value(contextKey("session")).(contextValue) // Check permissions - if !checkAdminLevel(ctx[ctxLevel]) { + if !checkPermissions(ctx[ctxUser], false, true, false, "") { log.Printf("%s has insuficient permissions", ctx[ctxUser]) incMetric(metricAdminErr) return @@ -433,7 +445,7 @@ func carvesListGETHandler(w http.ResponseWriter, r *http.Request) { // Get context data ctx := r.Context().Value(contextKey("session")).(contextValue) // Check permissions - if !checkAdminLevel(ctx[ctxLevel]) { + if !checkPermissions(ctx[ctxUser], false, true, false, "") { log.Printf("%s has insuficient permissions", ctx[ctxUser]) incMetric(metricAdminErr) return @@ -486,7 +498,7 @@ func queryLogsHandler(w http.ResponseWriter, r *http.Request) { // Get context data ctx := r.Context().Value(contextKey("session")).(contextValue) // Check permissions - if !checkAdminLevel(ctx[ctxLevel]) { + if !checkPermissions(ctx[ctxUser], true, false, false, "") { log.Printf("%s has insuficient permissions", ctx[ctxUser]) incMetric(metricAdminErr) return @@ -568,7 +580,7 @@ func carvesDetailsHandler(w http.ResponseWriter, r *http.Request) { // Get context data ctx := r.Context().Value(contextKey("session")).(contextValue) // Check permissions - if !checkAdminLevel(ctx[ctxLevel]) { + if !checkPermissions(ctx[ctxUser], false, true, false, "") { log.Printf("%s has insuficient permissions", ctx[ctxUser]) incMetric(metricAdminErr) return @@ -676,6 +688,14 @@ func confGETHandler(w http.ResponseWriter, r *http.Request) { log.Printf("error unknown environment (%s)", envVar) return } + // Get context data + ctx := r.Context().Value(contextKey("session")).(contextValue) + // Check permissions + if !checkPermissions(ctx[ctxUser], false, false, true, envVar) { + log.Printf("%s has insuficient permissions", ctx[ctxUser]) + incMetric(metricAdminErr) + return + } // Prepare template tempateFiles := NewTemplateFiles(templatesFilesFolder, "conf.html").filepaths t, err := template.ParseFiles(tempateFiles...) @@ -705,8 +725,6 @@ func confGETHandler(w http.ResponseWriter, r *http.Request) { log.Printf("error getting environment %v", err) return } - // Get context data - ctx := r.Context().Value(contextKey("session")).(contextValue) // Prepare template data templateData := ConfTemplateData{ Title: envVar + " Configuration", @@ -744,6 +762,14 @@ func enrollGETHandler(w http.ResponseWriter, r *http.Request) { log.Printf("error unknown environment (%s)", envVar) return } + // Get context data + ctx := r.Context().Value(contextKey("session")).(contextValue) + // Check permissions + if !checkPermissions(ctx[ctxUser], false, false, true, envVar) { + log.Printf("%s has insuficient permissions", ctx[ctxUser]) + incMetric(metricAdminErr) + return + } // Prepare template tempateFiles := NewTemplateFiles(templatesFilesFolder, "enroll.html").filepaths t, err := template.ParseFiles(tempateFiles...) @@ -773,8 +799,6 @@ func enrollGETHandler(w http.ResponseWriter, r *http.Request) { log.Printf("error getting environment %v", err) return } - // Get context data - ctx := r.Context().Value(contextKey("session")).(contextValue) // Prepare template data shellQuickAdd, _ := environments.QuickAddOneLinerShell(env) powershellQuickAdd, _ := environments.QuickAddOneLinerPowershell(env) @@ -886,7 +910,7 @@ func envsGETHandler(w http.ResponseWriter, r *http.Request) { // Get context data ctx := r.Context().Value(contextKey("session")).(contextValue) // Check permissions - if !checkAdminLevel(ctx[ctxLevel]) { + if !checkPermissions(ctx[ctxUser], false, false, false, "") { log.Printf("%s has insuficient permissions", ctx[ctxUser]) incMetric(metricAdminErr) return @@ -939,7 +963,7 @@ func settingsGETHandler(w http.ResponseWriter, r *http.Request) { // Get context data ctx := r.Context().Value(contextKey("session")).(contextValue) // Check permissions - if !checkAdminLevel(ctx[ctxLevel]) { + if !checkPermissions(ctx[ctxUser], false, false, false, "") { log.Printf("%s has insuficient permissions", ctx[ctxUser]) incMetric(metricAdminErr) return @@ -1019,7 +1043,7 @@ func usersGETHandler(w http.ResponseWriter, r *http.Request) { // Get context data ctx := r.Context().Value(contextKey("session")).(contextValue) // Check permissions - if !checkAdminLevel(ctx[ctxLevel]) { + if !checkPermissions(ctx[ctxUser], false, false, false, "") { log.Printf("%s has insuficient permissions", ctx[ctxUser]) incMetric(metricAdminErr) return @@ -1077,6 +1101,38 @@ func usersGETHandler(w http.ResponseWriter, r *http.Request) { incMetric(metricAdminOK) } +// Handler for platform/environment stats in JSON +func permissionsGETHandler(w http.ResponseWriter, r *http.Request) { + incMetric(metricAdminReq) + utils.DebugHTTPDump(r, settingsmgr.DebugHTTP(settings.ServiceAdmin), false) + vars := mux.Vars(r) + // Extract username and verify + usernameVar, ok := vars["username"] + if !ok || !adminUsers.Exists(usernameVar) { + if settingsmgr.DebugService(settings.ServiceAdmin) { + log.Printf("DebugService: error getting username") + } + return + } + // Get context data + ctx := r.Context().Value(contextKey("session")).(contextValue) + // Check permissions + if !checkPermissions(ctx[ctxUser], false, false, false, "") { + log.Printf("%s has insuficient permissions", ctx[ctxUser]) + incMetric(metricAdminErr) + return + } + // Get permissions + permissions, err := adminUsers.GetPermissions(usernameVar) + if err != nil { + incMetric(metricAdminErr) + log.Printf("error getting permissions %v", err) + } + // Serve JSON + utils.HTTPResponse(w, utils.JSONApplicationUTF8, http.StatusOK, permissions) + incMetric(metricJSONOK) +} + // Handler for GET requests to download carves func carvesDownloadHandler(w http.ResponseWriter, r *http.Request) { incMetric(metricAdminReq) @@ -1085,7 +1141,7 @@ func carvesDownloadHandler(w http.ResponseWriter, r *http.Request) { // Get context data ctx := r.Context().Value(contextKey("session")).(contextValue) // Check permissions - if !checkAdminLevel(ctx[ctxLevel]) { + if !checkPermissions(ctx[ctxUser], false, true, false, "") { log.Printf("%s has insuficient permissions", ctx[ctxUser]) incMetric(metricAdminErr) return diff --git a/admin/handlers-post.go b/admin/handlers-post.go index ded00415..9ffd355b 100644 --- a/admin/handlers-post.go +++ b/admin/handlers-post.go @@ -10,6 +10,7 @@ import ( "github.com/jmpsec/osctrl/environments" "github.com/jmpsec/osctrl/queries" "github.com/jmpsec/osctrl/settings" + "github.com/jmpsec/osctrl/users" "github.com/jmpsec/osctrl/utils" "github.com/gorilla/mux" @@ -25,1303 +26,1166 @@ const ( func loginPOSTHandler(w http.ResponseWriter, r *http.Request) { incMetric(metricAdminReq) utils.DebugHTTPDump(r, settingsmgr.DebugHTTP(settings.ServiceAdmin), false) - responseMessage := "OK" - responseCode := http.StatusOK var l LoginRequest // Parse request JSON body - err := json.NewDecoder(r.Body).Decode(&l) + if settingsmgr.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) + incMetric(metricAdminErr) + return + } + // Check credentials + access, user := adminUsers.CheckLoginCredentials(l.Username, l.Password) + if !access { + adminErrorResponse(w, "invalid credentials", http.StatusForbidden, nil) + incMetric(metricAdminErr) + return + } + _, err := sessionsmgr.Save(r, w, user) if err != nil { - responseMessage = "error parsing POST body" - responseCode = http.StatusInternalServerError - if settingsmgr.DebugService(settings.ServiceAdmin) { - log.Printf("DebugService: %s %v", responseMessage, err) - } - } else { - // Check credentials - if access, user := adminUsers.CheckLoginCredentials(l.Username, l.Password); access { - _, err = sessionsmgr.Save(r, w, user) - if err != nil { - responseMessage = "session error" - responseCode = http.StatusForbidden - if settingsmgr.DebugService(settings.ServiceAdmin) { - log.Printf("DebugService: %s %v)", responseMessage, err) - } - } - } else { - responseMessage = "invalid credentials" - responseCode = http.StatusForbidden - if settingsmgr.DebugService(settings.ServiceAdmin) { - log.Printf("DebugService: %s %v", responseMessage, err) - } - } + adminErrorResponse(w, "session error", http.StatusForbidden, err) + incMetric(metricAdminErr) + return } // Serialize and send response if settingsmgr.DebugService(settings.ServiceAdmin) { log.Println("DebugService: Login response sent") } - utils.HTTPResponse(w, utils.JSONApplicationUTF8, responseCode, AdminResponse{Message: responseMessage}) + adminOKResponse(w, "OK") incMetric(metricAdminOK) } // Handle POST requests to logout -func logoutHandler(w http.ResponseWriter, r *http.Request) { +func logoutPOSTHandler(w http.ResponseWriter, r *http.Request) { incMetric(metricAdminReq) - responseMessage := "OK" - responseCode := http.StatusOK utils.DebugHTTPDump(r, settingsmgr.DebugHTTP(settings.ServiceAdmin), false) var l LogoutRequest // Get context data ctx := r.Context().Value(contextKey("session")).(contextValue) // Parse request JSON body - err := json.NewDecoder(r.Body).Decode(&l) - if err != nil { + if settingsmgr.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) incMetric(metricAdminErr) - responseMessage = "error parsing POST body" - responseCode = http.StatusInternalServerError - if settingsmgr.DebugService(settings.ServiceAdmin) { - log.Printf("DebugService: %s %v", responseMessage, err) - } - } else { - // Check CSRF Token - if checkCSRFToken(ctx[ctxCSRF], l.CSRFToken) { - // Destroy existing session - err := sessionsmgr.Destroy(r) - if err != nil { - log.Printf("error destroying session [ %v ]", err) - http.Error(w, "Session Error", http.StatusInternalServerError) - return - } - } else { - responseMessage = "invalid CSRF token" - responseCode = http.StatusInternalServerError - if settingsmgr.DebugService(settings.ServiceAdmin) { - log.Printf("DebugService: %s %v", responseMessage, err) - } - } + return + } + // Check CSRF Token + if !checkCSRFToken(ctx[ctxCSRF], l.CSRFToken) { + adminErrorResponse(w, "invalid CSRF token", http.StatusInternalServerError, nil) + incMetric(metricAdminErr) + return + } + // Destroy existing session + if err := sessionsmgr.Destroy(r); err != nil { + adminErrorResponse(w, "error destroying session", http.StatusInternalServerError, err) + incMetric(metricAdminErr) + return } // Serialize and send response if settingsmgr.DebugService(settings.ServiceAdmin) { log.Println("DebugService: Logout response sent") } - utils.HTTPResponse(w, utils.JSONApplicationUTF8, responseCode, AdminResponse{Message: responseMessage}) + adminOKResponse(w, "OK") incMetric(metricAdminOK) } // Handler for POST requests to run queries func queryRunPOSTHandler(w http.ResponseWriter, r *http.Request) { incMetric(metricAdminReq) - responseMessage := "The query was created successfully" - responseCode := http.StatusOK utils.DebugHTTPDump(r, settingsmgr.DebugHTTP(settings.ServiceAdmin), true) var q DistributedQueryRequest // Get context data ctx := r.Context().Value(contextKey("session")).(contextValue) - // Check permissions - if !checkAdminLevel(ctx[ctxLevel]) { - responseMessage = "insuficient permissions" - responseCode = http.StatusForbidden - log.Printf("%s has %s", ctx[ctxUser], responseMessage) - goto send_response + // Check permissions for query + if !checkPermissions(ctx[ctxUser], true, false, false, "") { + adminErrorResponse(w, fmt.Sprintf("%s has insuficient permissions", ctx[ctxUser]), http.StatusForbidden, nil) + incMetric(metricAdminErr) + return } // Parse request JSON body + if settingsmgr.DebugService(settings.ServiceAdmin) { + log.Println("DebugService: Decoding POST body") + } if err := json.NewDecoder(r.Body).Decode(&q); err != nil { - responseMessage = "error parsing POST body" - responseCode = http.StatusInternalServerError - log.Printf("%s %v", responseMessage, err) - goto send_response + adminErrorResponse(w, "error parsing POST body", http.StatusInternalServerError, err) + incMetric(metricAdminErr) + return } // Check CSRF Token - if checkCSRFToken(ctx[ctxCSRF], q.CSRFToken) { - // FIXME check validity of query - // Query can not be empty - if q.Query == "" { - responseMessage = "query can not be empty" - responseCode = http.StatusInternalServerError - log.Printf("%s", responseMessage) - goto send_response - } - // Prepare and create new query - newQuery := newQueryReady(ctx[ctxUser], q.Query) - if err := queriesmgr.Create(newQuery); err != nil { - responseMessage = "error creating query" - responseCode = http.StatusInternalServerError - log.Printf("%s %v", responseMessage, err) - goto send_response - } - // Temporary list of UUIDs to calculate Expected - var expected []string - // Create environment target - if len(q.Environments) > 0 { - for _, e := range q.Environments { - if (e != "") && envs.Exists(e) { - if err := queriesmgr.CreateTarget(newQuery.Name, queries.QueryTargetEnvironment, e); err != nil { - responseMessage = "error creating query environment target" - responseCode = http.StatusInternalServerError - log.Printf("%s %v", responseMessage, err) - goto send_response - } - nodes, err := nodesmgr.GetByEnv(e, "active", settingsmgr.InactiveHours()) - if err != nil { - responseMessage = "error getting nodes by environment" - responseCode = http.StatusInternalServerError - log.Printf("%s %v", responseMessage, err) - goto send_response - } - for _, n := range nodes { - expected = append(expected, n.UUID) - } + if !checkCSRFToken(ctx[ctxCSRF], q.CSRFToken) { + adminErrorResponse(w, "invalid CSRF token", http.StatusInternalServerError, nil) + incMetric(metricAdminErr) + return + } + // FIXME check validity of query + // Query can not be empty + if q.Query == "" { + adminErrorResponse(w, "query can not be empty", http.StatusInternalServerError, nil) + incMetric(metricAdminErr) + return + } + // FIXME check if query is carve and user has permissions to carve + // Prepare and create new query + newQuery := newQueryReady(ctx[ctxUser], q.Query) + if err := queriesmgr.Create(newQuery); err != nil { + adminErrorResponse(w, "error creating query", http.StatusInternalServerError, err) + incMetric(metricAdminErr) + return + } + // Temporary list of UUIDs to calculate Expected + var expected []string + // Create environment target + if len(q.Environments) > 0 { + for _, e := range q.Environments { + if (e != "") && envs.Exists(e) { + if err := queriesmgr.CreateTarget(newQuery.Name, queries.QueryTargetEnvironment, e); err != nil { + adminErrorResponse(w, "error creating query environment target", http.StatusInternalServerError, err) + incMetric(metricAdminErr) + return + } + nodes, err := nodesmgr.GetByEnv(e, "active", settingsmgr.InactiveHours()) + if err != nil { + adminErrorResponse(w, "error getting nodes by environment", http.StatusInternalServerError, err) + incMetric(metricAdminErr) + return + } + for _, n := range nodes { + expected = append(expected, n.UUID) } } } - // Create platform target - if len(q.Platforms) > 0 { - for _, p := range q.Platforms { - if (p != "") && checkValidPlatform(p) { - if err := queriesmgr.CreateTarget(newQuery.Name, queries.QueryTargetPlatform, p); err != nil { - responseMessage = "error creating query platform target" - responseCode = http.StatusInternalServerError - log.Printf("%s %v", responseMessage, err) - goto send_response - } - nodes, err := nodesmgr.GetByPlatform(p, "active", settingsmgr.InactiveHours()) - if err != nil { - responseMessage = "error getting nodes by platform" - responseCode = http.StatusInternalServerError - log.Printf("%s %v", responseMessage, err) - goto send_response - } - for _, n := range nodes { - expected = append(expected, n.UUID) - } + } + // Create platform target + if len(q.Platforms) > 0 { + for _, p := range q.Platforms { + if (p != "") && checkValidPlatform(p) { + if err := queriesmgr.CreateTarget(newQuery.Name, queries.QueryTargetPlatform, p); err != nil { + adminErrorResponse(w, "error creating query platform target", http.StatusInternalServerError, err) + incMetric(metricAdminErr) + return + } + nodes, err := nodesmgr.GetByPlatform(p, "active", settingsmgr.InactiveHours()) + if err != nil { + adminErrorResponse(w, "error getting nodes by platform", http.StatusInternalServerError, err) + incMetric(metricAdminErr) + return + } + for _, n := range nodes { + expected = append(expected, n.UUID) } } } - // Create UUIDs target - if len(q.UUIDs) > 0 { - for _, u := range q.UUIDs { - if (u != "") && nodesmgr.CheckByUUID(u) { - if err := queriesmgr.CreateTarget(newQuery.Name, queries.QueryTargetUUID, u); err != nil { - responseMessage = "error creating query UUID target" - responseCode = http.StatusInternalServerError - log.Printf("%s %v", responseMessage, err) - goto send_response - } - expected = append(expected, u) + } + // Create UUIDs target + if len(q.UUIDs) > 0 { + for _, u := range q.UUIDs { + if (u != "") && nodesmgr.CheckByUUID(u) { + if err := queriesmgr.CreateTarget(newQuery.Name, queries.QueryTargetUUID, u); err != nil { + adminErrorResponse(w, "error creating query UUID target", http.StatusInternalServerError, err) + incMetric(metricAdminErr) + return } + expected = append(expected, u) } } - // Create hostnames target - if len(q.Hosts) > 0 { - for _, h := range q.Hosts { - if (h != "") && nodesmgr.CheckByHost(h) { - if err := queriesmgr.CreateTarget(newQuery.Name, queries.QueryTargetLocalname, h); err != nil { - responseMessage = "error creating query hostname target" - responseCode = http.StatusInternalServerError - log.Printf("%s %v", responseMessage, err) - goto send_response - } - expected = append(expected, h) + } + // Create hostnames target + if len(q.Hosts) > 0 { + for _, h := range q.Hosts { + if (h != "") && nodesmgr.CheckByHost(h) { + if err := queriesmgr.CreateTarget(newQuery.Name, queries.QueryTargetLocalname, h); err != nil { + adminErrorResponse(w, "error creating query hostname target", http.StatusInternalServerError, err) + incMetric(metricAdminErr) + return } + expected = append(expected, h) } } - // Remove duplicates from expected - expectedClear := removeStringDuplicates(expected) - // Update value for expected - if err := queriesmgr.SetExpected(newQuery.Name, len(expectedClear)); err != nil { - responseMessage = "error setting expected" - responseCode = http.StatusInternalServerError - log.Printf("%s %v", responseMessage, err) - goto send_response - } - } else { - responseMessage = "invalid CSRF token" - responseCode = http.StatusInternalServerError - log.Printf("%s", responseMessage) } -send_response: + // Remove duplicates from expected + expectedClear := removeStringDuplicates(expected) + // Update value for expected + if err := queriesmgr.SetExpected(newQuery.Name, len(expectedClear)); err != nil { + adminErrorResponse(w, "error setting expected", http.StatusInternalServerError, err) + incMetric(metricAdminErr) + return + } // Serialize and send response if settingsmgr.DebugService(settings.ServiceAdmin) { log.Println("DebugService: Query run response sent") } - utils.HTTPResponse(w, utils.JSONApplicationUTF8, responseCode, AdminResponse{Message: responseMessage}) + adminOKResponse(w, "OK") incMetric(metricAdminOK) } // Handler for POST requests to run file carves func carvesRunPOSTHandler(w http.ResponseWriter, r *http.Request) { incMetric(metricAdminReq) - responseMessage := "The carve was created successfully" - responseCode := http.StatusOK utils.DebugHTTPDump(r, settingsmgr.DebugHTTP(settings.ServiceAdmin), true) var c DistributedCarveRequest // Get context data ctx := r.Context().Value(contextKey("session")).(contextValue) // Check permissions - if !checkAdminLevel(ctx[ctxLevel]) { - responseMessage = "insuficient permissions" - responseCode = http.StatusForbidden - log.Printf("%s has %s", ctx[ctxUser], responseMessage) - goto send_response + if !checkPermissions(ctx[ctxUser], false, true, false, "") { + adminErrorResponse(w, fmt.Sprintf("%s has insuficient permissions", ctx[ctxUser]), http.StatusForbidden, nil) + incMetric(metricAdminErr) + return } // Parse request JSON body + if settingsmgr.DebugService(settings.ServiceAdmin) { + log.Println("DebugService: Decoding POST body") + } if err := json.NewDecoder(r.Body).Decode(&c); err != nil { - responseMessage = "error parsing POST body" - responseCode = http.StatusInternalServerError - log.Printf("%s %v", responseMessage, err) - goto send_response + adminErrorResponse(w, "error parsing POST body", http.StatusInternalServerError, err) + incMetric(metricAdminErr) + return } // Check CSRF Token - if checkCSRFToken(ctx[ctxCSRF], c.CSRFToken) { - // FIXME check validity of query - // Path can not be empty - if c.Path == "" { - responseMessage = "path can not be empty" - responseCode = http.StatusInternalServerError - log.Printf("%s", responseMessage) - goto send_response - } - query := generateCarveQuery(c.Path, false) - // Prepare and create new carve - carveName := generateCarveName() - newQuery := queries.DistributedQuery{ - Query: query, - Name: carveName, - Creator: ctx[ctxUser], - Expected: 0, - Executions: 0, - Active: true, - Completed: false, - Deleted: false, - Type: queries.CarveQueryType, - Path: c.Path, - } - if err := queriesmgr.Create(newQuery); err != nil { - responseMessage = "error creating carve" - responseCode = http.StatusInternalServerError - log.Printf("%s %v", responseMessage, err) - goto send_response - } - // Temporary list of UUIDs to calculate Expected - var expected []string - // Create environment target - if len(c.Environments) > 0 { - for _, e := range c.Environments { - if (e != "") && envs.Exists(e) { - if err := queriesmgr.CreateTarget(carveName, queries.QueryTargetEnvironment, e); err != nil { - responseMessage = "error creating carve environment target" - responseCode = http.StatusInternalServerError - log.Printf("%s %v", responseMessage, err) - goto send_response - } - nodes, err := nodesmgr.GetByEnv(e, "active", settingsmgr.InactiveHours()) - if err != nil { - responseMessage = "error getting nodes by environment" - responseCode = http.StatusInternalServerError - log.Printf("%s %v", responseMessage, err) - goto send_response - } - for _, n := range nodes { - expected = append(expected, n.UUID) - } + if !checkCSRFToken(ctx[ctxCSRF], c.CSRFToken) { + adminErrorResponse(w, "invalid CSRF token", http.StatusInternalServerError, nil) + incMetric(metricAdminErr) + return + } + // FIXME check validity of query + // Path can not be empty + if c.Path == "" { + adminErrorResponse(w, "path can not be empty", http.StatusInternalServerError, nil) + incMetric(metricAdminErr) + return + } + query := generateCarveQuery(c.Path, false) + // Prepare and create new carve + carveName := generateCarveName() + newQuery := queries.DistributedQuery{ + Query: query, + Name: carveName, + Creator: ctx[ctxUser], + Expected: 0, + Executions: 0, + Active: true, + Completed: false, + Deleted: false, + Type: queries.CarveQueryType, + Path: c.Path, + } + if err := queriesmgr.Create(newQuery); err != nil { + adminErrorResponse(w, "error creating carve", http.StatusInternalServerError, err) + incMetric(metricAdminErr) + return + } + // Temporary list of UUIDs to calculate Expected + var expected []string + // Create environment target + if len(c.Environments) > 0 { + for _, e := range c.Environments { + if (e != "") && envs.Exists(e) { + if err := queriesmgr.CreateTarget(carveName, queries.QueryTargetEnvironment, e); err != nil { + adminErrorResponse(w, "error creating carve environment target", http.StatusInternalServerError, err) + incMetric(metricAdminErr) + return + } + nodes, err := nodesmgr.GetByEnv(e, "active", settingsmgr.InactiveHours()) + if err != nil { + adminErrorResponse(w, "error getting nodes by environment", http.StatusInternalServerError, err) + incMetric(metricAdminErr) + return + } + for _, n := range nodes { + expected = append(expected, n.UUID) } } } - // Create platform target - if len(c.Platforms) > 0 { - for _, p := range c.Platforms { - if (p != "") && checkValidPlatform(p) { - if err := queriesmgr.CreateTarget(carveName, queries.QueryTargetPlatform, p); err != nil { - responseMessage = "error creating carve platform target" - responseCode = http.StatusInternalServerError - log.Printf("%s %v", responseMessage, err) - goto send_response - } - nodes, err := nodesmgr.GetByPlatform(p, "active", settingsmgr.InactiveHours()) - if err != nil { - responseMessage = "error getting nodes by platform" - responseCode = http.StatusInternalServerError - log.Printf("%s %v", responseMessage, err) - goto send_response - } - for _, n := range nodes { - expected = append(expected, n.UUID) - } + } + // Create platform target + if len(c.Platforms) > 0 { + for _, p := range c.Platforms { + if (p != "") && checkValidPlatform(p) { + if err := queriesmgr.CreateTarget(carveName, queries.QueryTargetPlatform, p); err != nil { + adminErrorResponse(w, "error creating carve platform target", http.StatusInternalServerError, err) + incMetric(metricAdminErr) + return + } + nodes, err := nodesmgr.GetByPlatform(p, "active", settingsmgr.InactiveHours()) + if err != nil { + adminErrorResponse(w, "error getting nodes by platform", http.StatusInternalServerError, err) + incMetric(metricAdminErr) + return + } + for _, n := range nodes { + expected = append(expected, n.UUID) } } } - // Create UUIDs target - if len(c.UUIDs) > 0 { - for _, u := range c.UUIDs { - if (u != "") && nodesmgr.CheckByUUID(u) { - if err := queriesmgr.CreateTarget(carveName, queries.QueryTargetUUID, u); err != nil { - responseMessage = "error creating carve UUID target" - responseCode = http.StatusInternalServerError - log.Printf("%s %v", responseMessage, err) - goto send_response - } - expected = append(expected, u) + } + // Create UUIDs target + if len(c.UUIDs) > 0 { + for _, u := range c.UUIDs { + if (u != "") && nodesmgr.CheckByUUID(u) { + if err := queriesmgr.CreateTarget(carveName, queries.QueryTargetUUID, u); err != nil { + adminErrorResponse(w, "error creating carve UUID target", http.StatusInternalServerError, err) + incMetric(metricAdminErr) + return } + expected = append(expected, u) } } - // Create hostnames target - if len(c.Hosts) > 0 { - for _, h := range c.Hosts { - if (h != "") && nodesmgr.CheckByHost(h) { - if err := queriesmgr.CreateTarget(carveName, queries.QueryTargetLocalname, h); err != nil { - responseMessage = "error creating carve hostname target" - responseCode = http.StatusInternalServerError - log.Printf("%s %v", responseMessage, err) - goto send_response - } + } + // Create hostnames target + if len(c.Hosts) > 0 { + for _, h := range c.Hosts { + if (h != "") && nodesmgr.CheckByHost(h) { + if err := queriesmgr.CreateTarget(carveName, queries.QueryTargetLocalname, h); err != nil { + adminErrorResponse(w, "error creating carve hostname target", http.StatusInternalServerError, err) + incMetric(metricAdminErr) + return } } } - // Remove duplicates from expected - expectedClear := removeStringDuplicates(expected) - // Update value for expected - if err := queriesmgr.SetExpected(carveName, len(expectedClear)); err != nil { - responseMessage = "error setting expected" - responseCode = http.StatusInternalServerError - log.Printf("%s %v", responseMessage, err) - goto send_response - } - } else { - responseMessage = "invalid CSRF token" - responseCode = http.StatusInternalServerError - log.Printf("%s", responseMessage) } -send_response: + // Remove duplicates from expected + expectedClear := removeStringDuplicates(expected) + // Update value for expected + if err := queriesmgr.SetExpected(carveName, len(expectedClear)); err != nil { + adminErrorResponse(w, "error setting expected", http.StatusInternalServerError, err) + incMetric(metricAdminErr) + return + } // Serialize and send response if settingsmgr.DebugService(settings.ServiceAdmin) { log.Println("DebugService: Carve run response sent") } - utils.HTTPResponse(w, utils.JSONApplicationUTF8, responseCode, AdminResponse{Message: responseMessage}) + adminOKResponse(w, "OK") incMetric(metricAdminOK) } // Handler for POST requests to queries func queryActionsPOSTHandler(w http.ResponseWriter, r *http.Request) { incMetric(metricAdminReq) - responseMessage := "OK" - responseCode := http.StatusOK utils.DebugHTTPDump(r, settingsmgr.DebugHTTP(settings.ServiceAdmin), true) var q DistributedQueryActionRequest // Get context data ctx := r.Context().Value(contextKey("session")).(contextValue) - // Check permissions - if !checkAdminLevel(ctx[ctxLevel]) { - responseMessage = "insuficient permissions" - responseCode = http.StatusForbidden - log.Printf("%s has %s", ctx[ctxUser], responseMessage) - goto send_response + // Check permissions for query + if !checkPermissions(ctx[ctxUser], true, false, false, "") { + adminErrorResponse(w, fmt.Sprintf("%s has insuficient permissions", ctx[ctxUser]), http.StatusForbidden, nil) + incMetric(metricAdminErr) + return } // Parse request JSON body + if settingsmgr.DebugService(settings.ServiceAdmin) { + log.Println("DebugService: Decoding POST body") + } if err := json.NewDecoder(r.Body).Decode(&q); err != nil { - responseMessage = "error parsing POST body" - responseCode = http.StatusInternalServerError - if settingsmgr.DebugService(settings.ServiceAdmin) { - log.Printf("DebugService: %s %v", responseMessage, err) + adminErrorResponse(w, "error parsing POST body", http.StatusInternalServerError, err) + incMetric(metricAdminErr) + return + } + // Check CSRF Token + if !checkCSRFToken(ctx[ctxCSRF], q.CSRFToken) { + adminErrorResponse(w, "invalid CSRF token", http.StatusInternalServerError, nil) + incMetric(metricAdminErr) + return + } + switch q.Action { + case "delete": + for _, n := range q.Names { + if err := queriesmgr.Delete(n); err != nil { + adminErrorResponse(w, "error deleting query", http.StatusInternalServerError, err) + incMetric(metricAdminErr) + return + } } - } else { - // Check CSRF Token - if checkCSRFToken(ctx[ctxCSRF], q.CSRFToken) { - switch q.Action { - case "delete": - for _, n := range q.Names { - err := queriesmgr.Delete(n) - if err != nil { - responseMessage = "error deleting query" - responseCode = http.StatusInternalServerError - if settingsmgr.DebugService(settings.ServiceAdmin) { - log.Printf("DebugService: %s %v", responseMessage, err) - } - } - } - case "complete": - for _, n := range q.Names { - err := queriesmgr.Complete(n) - if err != nil { - responseMessage = "error completing query" - responseCode = http.StatusInternalServerError - log.Printf("%s %v", responseMessage, err) - } - } - case "activate": - for _, n := range q.Names { - err := queriesmgr.Activate(n) - if err != nil { - responseMessage = "error activating query" - responseCode = http.StatusInternalServerError - if settingsmgr.DebugService(settings.ServiceAdmin) { - log.Printf("DebugService: %s %v", responseMessage, err) - } - } - } + adminOKResponse(w, "queries delete successfully") + case "complete": + for _, n := range q.Names { + if err := queriesmgr.Complete(n); err != nil { + adminErrorResponse(w, "error completing query", http.StatusInternalServerError, err) + incMetric(metricAdminErr) + return } - } else { - responseMessage = "invalid CSRF token" - responseCode = http.StatusInternalServerError - if settingsmgr.DebugService(settings.ServiceAdmin) { - log.Printf("DebugService: %s %v", responseMessage, err) + } + adminOKResponse(w, "queries completed successfully") + case "activate": + for _, n := range q.Names { + if err := queriesmgr.Activate(n); err != nil { + adminErrorResponse(w, "error activating query", http.StatusInternalServerError, err) + incMetric(metricAdminErr) + return } } + adminOKResponse(w, "queries activated successfully") } -send_response: // Serialize and send response if settingsmgr.DebugService(settings.ServiceAdmin) { log.Println("DebugService: Query run response sent") } - utils.HTTPResponse(w, utils.JSONApplicationUTF8, responseCode, AdminResponse{Message: responseMessage}) incMetric(metricAdminOK) } // Handler for POST requests to carves func carvesActionsPOSTHandler(w http.ResponseWriter, r *http.Request) { incMetric(metricAdminReq) - responseMessage := "OK" - responseCode := http.StatusOK utils.DebugHTTPDump(r, settingsmgr.DebugHTTP(settings.ServiceAdmin), true) var q DistributedCarvesActionRequest // Get context data ctx := r.Context().Value(contextKey("session")).(contextValue) // Check permissions - if !checkAdminLevel(ctx[ctxLevel]) { - responseMessage = "insuficient permissions" - responseCode = http.StatusForbidden - log.Printf("%s has %s", ctx[ctxUser], responseMessage) - goto send_response + if !checkPermissions(ctx[ctxUser], false, true, false, "") { + adminErrorResponse(w, fmt.Sprintf("%s has insuficient permissions", ctx[ctxUser]), http.StatusForbidden, nil) + incMetric(metricAdminErr) + return } // Parse request JSON body + if settingsmgr.DebugService(settings.ServiceAdmin) { + log.Println("DebugService: Decoding POST body") + } if err := json.NewDecoder(r.Body).Decode(&q); err != nil { - responseMessage = "error parsing POST body" - responseCode = http.StatusInternalServerError - if settingsmgr.DebugService(settings.ServiceAdmin) { - log.Printf("DebugService: %s %v", responseMessage, err) - } - } else { - // Check CSRF Token - if checkCSRFToken(ctx[ctxCSRF], q.CSRFToken) { - switch q.Action { - case "delete": - for _, n := range q.IDs { - err := carvesmgr.Delete(n) - if err != nil { - responseMessage = "error deleting carve" - responseCode = http.StatusInternalServerError - if settingsmgr.DebugService(settings.ServiceAdmin) { - log.Printf("DebugService: %s %v", responseMessage, err) - } - } - } - case "test": - log.Println("Testing action") - } - } else { - responseMessage = "invalid CSRF token" - responseCode = http.StatusInternalServerError - if settingsmgr.DebugService(settings.ServiceAdmin) { - log.Printf("DebugService: %s %v", responseMessage, err) + adminErrorResponse(w, "error parsing POST body", http.StatusInternalServerError, err) + incMetric(metricAdminErr) + return + } + // Check CSRF Token + if !checkCSRFToken(ctx[ctxCSRF], q.CSRFToken) { + adminErrorResponse(w, "invalid CSRF token", http.StatusInternalServerError, nil) + incMetric(metricAdminErr) + return + } + switch q.Action { + case "delete": + for _, n := range q.IDs { + if err := carvesmgr.Delete(n); err != nil { + adminErrorResponse(w, "error deleting carve", http.StatusInternalServerError, err) + incMetric(metricAdminErr) + return } } + adminOKResponse(w, "carves delete successfully") + case "test": + if settingsmgr.DebugService(settings.ServiceAdmin) { + log.Printf("DebugService: testing action") + } + adminOKResponse(w, "test successful") } -send_response: // Serialize and send response if settingsmgr.DebugService(settings.ServiceAdmin) { log.Println("DebugService: Carves action response sent") } - utils.HTTPResponse(w, utils.JSONApplicationUTF8, responseCode, AdminResponse{Message: responseMessage}) incMetric(metricAdminOK) } // Handler POST requests for saving configuration func confPOSTHandler(w http.ResponseWriter, r *http.Request) { incMetric(metricAdminReq) - responseMessage := "Configuration saved successfully" - responseCode := http.StatusOK utils.DebugHTTPDump(r, settingsmgr.DebugHTTP(settings.ServiceAdmin), true) vars := mux.Vars(r) // Extract environment and verify environmentVar, ok := vars["environment"] if !ok || !envs.Exists(environmentVar) { - if settingsmgr.DebugService(settings.ServiceAdmin) { - log.Printf("DebugService: error getting environment") - } - return - } - // Verify environment - if !envs.Exists(environmentVar) { - if settingsmgr.DebugService(settings.ServiceAdmin) { - log.Printf("DebugService: error unknown environment (%s)", environmentVar) - } + adminErrorResponse(w, "error getting environment", http.StatusInternalServerError, nil) + incMetric(metricAdminErr) return } var c ConfigurationRequest // Get context data ctx := r.Context().Value(contextKey("session")).(contextValue) // Check permissions - if !checkAdminLevel(ctx[ctxLevel]) { - responseMessage = "insuficient permissions" - responseCode = http.StatusForbidden - log.Printf("%s has %s", ctx[ctxUser], responseMessage) - goto send_response + if !checkPermissions(ctx[ctxUser], false, false, true, environmentVar) { + adminErrorResponse(w, fmt.Sprintf("%s has insuficient permissions", ctx[ctxUser]), http.StatusForbidden, nil) + incMetric(metricAdminErr) + return } // Parse request JSON body + if settingsmgr.DebugService(settings.ServiceAdmin) { + log.Println("DebugService: Decoding POST body") + } if err := json.NewDecoder(r.Body).Decode(&c); err != nil { - responseMessage = "error parsing POST body" - responseCode = http.StatusInternalServerError + adminErrorResponse(w, "error parsing POST body", http.StatusInternalServerError, err) + incMetric(metricAdminErr) + return + } + // Check CSRF Token + if !checkCSRFToken(ctx[ctxCSRF], c.CSRFToken) { + adminErrorResponse(w, "invalid CSRF token", http.StatusInternalServerError, nil) + incMetric(metricAdminErr) + return + } + if c.ConfigurationB64 == "" { + responseMessage := "empty configuration" + utils.HTTPResponse(w, utils.JSONApplicationUTF8, http.StatusInternalServerError, AdminResponse{Message: responseMessage}) if settingsmgr.DebugService(settings.ServiceAdmin) { - log.Printf("DebugService: %s %v", responseMessage, err) - } - } else { - // Check CSRF Token - if checkCSRFToken(ctx[ctxCSRF], c.CSRFToken) { - if c.ConfigurationB64 != "" { - configuration, err := base64.StdEncoding.DecodeString(c.ConfigurationB64) - if err != nil { - responseMessage = "error decoding configuration" - responseCode = http.StatusInternalServerError - if settingsmgr.DebugService(settings.ServiceAdmin) { - log.Printf("DebugService: %s %v", responseMessage, err) - } - } else { - err = envs.UpdateConfiguration(environmentVar, string(configuration)) - if err != nil { - responseMessage = "error saving configuration" - responseCode = http.StatusInternalServerError - if settingsmgr.DebugService(settings.ServiceAdmin) { - log.Printf("DebugService: %s %v", responseMessage, err) - } - } - } - } else { - responseMessage = "empty configuration" - responseCode = http.StatusInternalServerError - if settingsmgr.DebugService(settings.ServiceAdmin) { - log.Printf("DebugService: %s %v", responseMessage, err) - } - } - } else { - responseMessage = "invalid CSRF token" - responseCode = http.StatusInternalServerError - if settingsmgr.DebugService(settings.ServiceAdmin) { - log.Printf("DebugService: %s %v", responseMessage, err) - } + log.Printf("DebugService: %s", responseMessage) } + incMetric(metricAdminErr) + return + } + // Decode received configuration + configuration, err := base64.StdEncoding.DecodeString(c.ConfigurationB64) + if err != nil { + adminErrorResponse(w, "error decoding configuration", http.StatusInternalServerError, err) + incMetric(metricAdminErr) + return + } + // Update configuration + if err := envs.UpdateConfiguration(environmentVar, string(configuration)); err != nil { + adminErrorResponse(w, "error saving configuration", http.StatusInternalServerError, err) + incMetric(metricAdminErr) + return } -send_response: // Serialize and send response if settingsmgr.DebugService(settings.ServiceAdmin) { log.Println("DebugService: Configuration response sent") } - utils.HTTPResponse(w, utils.JSONApplicationUTF8, responseCode, AdminResponse{Message: responseMessage}) + adminOKResponse(w, "configuration saved successfully") incMetric(metricAdminOK) } // Handler POST requests for saving intervals func intervalsPOSTHandler(w http.ResponseWriter, r *http.Request) { incMetric(metricAdminReq) - responseMessage := "Intervals updated successfully" - responseCode := http.StatusOK utils.DebugHTTPDump(r, settingsmgr.DebugHTTP(settings.ServiceAdmin), true) vars := mux.Vars(r) - // Extract environment + // Extract environment and verify environmentVar, ok := vars["environment"] - if !ok { - if settingsmgr.DebugService(settings.ServiceAdmin) { - log.Printf("DebugService: error getting environment") - } - return - } - // Verify environment - if !envs.Exists(environmentVar) { - if settingsmgr.DebugService(settings.ServiceAdmin) { - log.Printf("DebugService: error unknown environment (%s)", environmentVar) - } + if !ok || !envs.Exists(environmentVar) { + adminErrorResponse(w, "error getting environment", http.StatusInternalServerError, nil) + incMetric(metricAdminErr) return } var c IntervalsRequest // Get context data ctx := r.Context().Value(contextKey("session")).(contextValue) + // Check permissions + if !checkPermissions(ctx[ctxUser], false, false, true, environmentVar) { + adminErrorResponse(w, fmt.Sprintf("%s has insuficient permissions", ctx[ctxUser]), http.StatusForbidden, nil) + incMetric(metricAdminErr) + return + } // Parse request JSON body - err := json.NewDecoder(r.Body).Decode(&c) + if settingsmgr.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) + incMetric(metricAdminErr) + return + } + // Check CSRF Token + if !checkCSRFToken(ctx[ctxCSRF], c.CSRFToken) { + adminErrorResponse(w, "invalid CSRF token", http.StatusInternalServerError, nil) + incMetric(metricAdminErr) + return + } + if err := envs.UpdateIntervals(environmentVar, c.ConfigInterval, c.LogInterval, c.QueryInterval); err != nil { + adminErrorResponse(w, "error updating intervals", http.StatusInternalServerError, err) + incMetric(metricAdminErr) + return + } + // After updating interval, you need to re-generate flags + flags, err := envs.GenerateFlagsEnv(environmentVar, "", "") if err != nil { - responseMessage = "error parsing POST body" - responseCode = http.StatusInternalServerError - if settingsmgr.DebugService(settings.ServiceAdmin) { - log.Printf("DebugService: %s %v", responseMessage, err) - } - } else { - // Check CSRF Token - if checkCSRFToken(ctx[ctxCSRF], c.CSRFToken) { - err = envs.UpdateIntervals(environmentVar, c.ConfigInterval, c.LogInterval, c.QueryInterval) - if err != nil { - responseMessage = "error updating intervals" - responseCode = http.StatusInternalServerError - if settingsmgr.DebugService(settings.ServiceAdmin) { - log.Printf("DebugService: %s %v", responseMessage, err) - } - } - // After updating interval, you need to re-generate flags - flags, err := envs.GenerateFlagsEnv(environmentVar, "", "") - if err == nil { - // Update flags in the newly created environment - if err := envs.UpdateFlags(environmentVar, flags); err != nil { - responseMessage = "error updating flags" - responseCode = http.StatusInternalServerError - if settingsmgr.DebugService(settings.ServiceAdmin) { - log.Printf("DebugService: %s %v", responseMessage, err) - } - } - } else { - responseMessage = "error re-generating flags" - responseCode = http.StatusInternalServerError - if settingsmgr.DebugService(settings.ServiceAdmin) { - log.Printf("DebugService: %s %v", responseMessage, err) - } - } - } else { - responseMessage = "invalid CSRF token" - responseCode = http.StatusInternalServerError - if settingsmgr.DebugService(settings.ServiceAdmin) { - log.Printf("DebugService: %s %v", responseMessage, err) - } - } + adminErrorResponse(w, "error re-generating flags", http.StatusInternalServerError, err) + incMetric(metricAdminErr) + return + } + // Update flags in the newly created environment + if err := envs.UpdateFlags(environmentVar, flags); err != nil { + adminErrorResponse(w, "error updating flags", http.StatusInternalServerError, err) + incMetric(metricAdminErr) + return } // Serialize and send response if settingsmgr.DebugService(settings.ServiceAdmin) { log.Println("DebugService: Intervals response sent") } - utils.HTTPResponse(w, utils.JSONApplicationUTF8, responseCode, AdminResponse{Message: responseMessage}) + adminOKResponse(w, "intervals saved successfully") incMetric(metricAdminOK) } // Handler POST requests for expiring enroll links func expirationPOSTHandler(w http.ResponseWriter, r *http.Request) { incMetric(metricAdminReq) - responseMessage := "OK" - responseCode := http.StatusOK utils.DebugHTTPDump(r, settingsmgr.DebugHTTP(settings.ServiceAdmin), true) vars := mux.Vars(r) - // Extract environment + // Extract environment and verify environmentVar, ok := vars["environment"] - if !ok { - if settingsmgr.DebugService(settings.ServiceAdmin) { - log.Printf("DebugService: error getting environment") - } - return - } - // Verify environment - if !envs.Exists(environmentVar) { - if settingsmgr.DebugService(settings.ServiceAdmin) { - log.Printf("DebugService: error unknown environment (%s)", environmentVar) - } + if !ok || !envs.Exists(environmentVar) { + adminErrorResponse(w, "error getting environment", http.StatusInternalServerError, nil) + incMetric(metricAdminErr) return } var e ExpirationRequest // Get context data ctx := r.Context().Value(contextKey("session")).(contextValue) + // Check permissions + if !checkPermissions(ctx[ctxUser], false, false, true, environmentVar) { + adminErrorResponse(w, fmt.Sprintf("%s has insuficient permissions", ctx[ctxUser]), http.StatusForbidden, nil) + incMetric(metricAdminErr) + return + } // Parse request JSON body - err := json.NewDecoder(r.Body).Decode(&e) - if err != nil { - responseMessage = "error parsing POST body" - responseCode = http.StatusInternalServerError - if settingsmgr.DebugService(settings.ServiceAdmin) { - log.Printf("DebugService: %s %v", responseMessage, err) + if settingsmgr.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) + incMetric(metricAdminErr) + return + } + // Check CSRF Token + if !checkCSRFToken(ctx[ctxCSRF], e.CSRFToken) { + adminErrorResponse(w, "invalid CSRF token", http.StatusInternalServerError, nil) + incMetric(metricAdminErr) + return + } + switch e.Type { + case "enroll": + switch e.Action { + case "expire": + if err := envs.ExpireEnroll(environmentVar); err != nil { + adminErrorResponse(w, "error expiring enroll", http.StatusInternalServerError, err) + incMetric(metricAdminErr) + return + } + adminOKResponse(w, "link expired successfully") + case "extend": + if err := envs.RotateEnrollPath(environmentVar); err != nil { + adminErrorResponse(w, "error extending enroll", http.StatusInternalServerError, err) + incMetric(metricAdminErr) + return + } + adminOKResponse(w, "link extended successfully") } - } else { - // Check CSRF Token - if checkCSRFToken(ctx[ctxCSRF], e.CSRFToken) { - switch e.Type { - case "enroll": - switch e.Action { - case "expire": - err = envs.ExpireEnroll(environmentVar) - if err != nil { - responseMessage = "error expiring enroll" - responseCode = http.StatusInternalServerError - if settingsmgr.DebugService(settings.ServiceAdmin) { - log.Printf("DebugService: %s %v", responseMessage, err) - } - } - case "extend": - err = envs.RotateEnrollPath(environmentVar) - if err != nil { - responseMessage = "error extending enroll" - responseCode = http.StatusInternalServerError - if settingsmgr.DebugService(settings.ServiceAdmin) { - log.Printf("DebugService: %s %v", responseMessage, err) - } - } - } - case "remove": - switch e.Action { - case "expire": - err = envs.ExpireRemove(environmentVar) - if err != nil { - responseMessage = "error expiring enroll" - responseCode = http.StatusInternalServerError - if settingsmgr.DebugService(settings.ServiceAdmin) { - log.Printf("DebugService: %s %v", responseMessage, err) - } - } - case "extend": - err = envs.RotateRemove(environmentVar) - if err != nil { - responseMessage = "error extending enroll" - responseCode = http.StatusInternalServerError - if settingsmgr.DebugService(settings.ServiceAdmin) { - log.Printf("DebugService: %s %v", responseMessage, err) - } - } - } + case "remove": + switch e.Action { + case "expire": + if err := envs.ExpireRemove(environmentVar); err != nil { + adminErrorResponse(w, "error expiring remove", http.StatusInternalServerError, err) + incMetric(metricAdminErr) + return } - } else { - responseMessage = "invalid CSRF token" - responseCode = http.StatusInternalServerError - if settingsmgr.DebugService(settings.ServiceAdmin) { - log.Printf("DebugService: %s %v", responseMessage, err) + adminOKResponse(w, "link expired successfully") + case "extend": + if err := envs.RotateRemove(environmentVar); err != nil { + adminErrorResponse(w, "error extending remove", http.StatusInternalServerError, err) + incMetric(metricAdminErr) + return } + adminOKResponse(w, "link extended successfully") } } // Serialize and send response if settingsmgr.DebugService(settings.ServiceAdmin) { log.Println("DebugService: Expiration response sent") } - utils.HTTPResponse(w, utils.JSONApplicationUTF8, responseCode, AdminResponse{Message: responseMessage}) incMetric(metricAdminOK) } // Handler POST requests for multi node action func nodeActionsPOSTHandler(w http.ResponseWriter, r *http.Request) { incMetric(metricAdminReq) - responseMessage := "OK" - responseCode := http.StatusOK utils.DebugHTTPDump(r, settingsmgr.DebugHTTP(settings.ServiceAdmin), true) var m NodeMultiActionRequest // Get context data ctx := r.Context().Value(contextKey("session")).(contextValue) // Parse request JSON body - err := json.NewDecoder(r.Body).Decode(&m) - if err != nil { - responseMessage = "error parsing POST body" - responseCode = http.StatusInternalServerError - if settingsmgr.DebugService(settings.ServiceAdmin) { - log.Printf("DebugService: %s %v", responseMessage, err) - } - } else { - // Check CSRF Token - if checkCSRFToken(ctx[ctxCSRF], m.CSRFToken) { - switch m.Action { - case "delete": - okCount := 0 - errCount := 0 - for _, u := range m.UUIDs { - err := nodesmgr.ArchiveDeleteByUUID(u) - if err != nil { - errCount++ - if settingsmgr.DebugService(settings.ServiceAdmin) { - log.Printf("DebugService: error deleting node %s %v", u, err) - } - } else { - okCount++ - } - } - if errCount == 0 { - responseMessage = fmt.Sprintf("%d Node(s) have been deleted successfully", okCount) - } else { - responseMessage = fmt.Sprintf("Error deleting %d node(s)", errCount) - responseCode = http.StatusInternalServerError + if settingsmgr.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) + incMetric(metricAdminErr) + return + } + // Check CSRF Token + if !checkCSRFToken(ctx[ctxCSRF], m.CSRFToken) { + adminErrorResponse(w, "invalid CSRF token", http.StatusInternalServerError, nil) + incMetric(metricAdminErr) + return + } + switch m.Action { + case "delete": + okCount := 0 + errCount := 0 + for _, u := range m.UUIDs { + if err := nodesmgr.ArchiveDeleteByUUID(u); err != nil { + errCount++ + if settingsmgr.DebugService(settings.ServiceAdmin) { + log.Printf("DebugService: error deleting node %s %v", u, err) } - case "archive": - log.Printf("DebugService: archiving node") + } else { + okCount++ } + } + if errCount == 0 { + adminOKResponse(w, fmt.Sprintf("%d Node(s) have been deleted successfully", okCount)) } else { - responseMessage = "invalid CSRF token" - responseCode = http.StatusInternalServerError - if settingsmgr.DebugService(settings.ServiceAdmin) { - log.Printf("DebugService: %s %v", responseMessage, err) - } + adminErrorResponse(w, fmt.Sprintf("Error deleting %d node(s)", errCount), http.StatusInternalServerError, nil) + incMetric(metricAdminErr) + return + } + case "archive": + if settingsmgr.DebugService(settings.ServiceAdmin) { + log.Printf("DebugService: archiving node") } + adminOKResponse(w, "node archived successfully") } // Serialize and send response if settingsmgr.DebugService(settings.ServiceAdmin) { log.Println("DebugService: Multi-node action response sent") } - utils.HTTPResponse(w, utils.JSONApplicationUTF8, responseCode, AdminResponse{Message: responseMessage}) incMetric(metricAdminOK) } // Handler for POST request for /environments func envsPOSTHandler(w http.ResponseWriter, r *http.Request) { incMetric(metricAdminReq) - responseMessage := "OK" - responseCode := http.StatusOK utils.DebugHTTPDump(r, settingsmgr.DebugHTTP(settings.ServiceAdmin), true) var c EnvironmentsRequest // Get context data ctx := r.Context().Value(contextKey("session")).(contextValue) // Parse request JSON body - err := json.NewDecoder(r.Body).Decode(&c) - if err != nil { - responseMessage = "error parsing POST body" - responseCode = http.StatusInternalServerError - if settingsmgr.DebugService(settings.ServiceAdmin) { - log.Printf("DebugService: %s %v", responseMessage, err) - } - goto send_response - } else { - // Check CSRF Token - if checkCSRFToken(ctx[ctxCSRF], c.CSRFToken) { - switch c.Action { - case "create": - // FIXME verify fields - if !envs.Exists(c.Name) { - env := envs.Empty(c.Name, c.Hostname) - env.Icon = c.Icon - env.Type = c.Type - if env.Configuration == "" { - env.Configuration = environments.ReadExternalFile(emptyConfiguration) - } - if env.Flags == "" { - // Generate flags - flags, err := environments.GenerateFlags(env, "", "") - if err != nil { - responseMessage = "error creating environment" - responseCode = http.StatusInternalServerError - if settingsmgr.DebugService(settings.ServiceAdmin) { - log.Printf("DebugService: %s %v", responseMessage, err) - } - goto send_response - } - env.Flags = flags - } - err := envs.Create(env) - if err != nil { - responseMessage = "error creating environment" - responseCode = http.StatusInternalServerError - if settingsmgr.DebugService(settings.ServiceAdmin) { - log.Printf("DebugService: %s %v", responseMessage, err) - } - goto send_response - } else { - responseMessage = "Environment created successfully" - } - } - case "delete": - if c.Name == settingsmgr.DefaultEnv(settings.ServiceAdmin) { - responseMessage = "Not a good idea" - responseCode = http.StatusInternalServerError - } else if envs.Exists(c.Name) { - err := envs.Delete(c.Name) - if err != nil { - responseMessage = "error deleting environment" - responseCode = http.StatusInternalServerError - if settingsmgr.DebugService(settings.ServiceAdmin) { - log.Printf("DebugService: %s %v", responseMessage, err) - } - goto send_response - } else { - responseMessage = "Environment deleted successfully" - } - } - case "debug": - // FIXME verify fields - if envs.Exists(c.Name) { - err := envs.ChangeDebugHTTP(c.Name, c.DebugHTTP) - if err != nil { - responseMessage = "error changing DebugHTTP" - responseCode = http.StatusInternalServerError - if settingsmgr.DebugService(settings.ServiceAdmin) { - log.Printf("DebugService: %s %v", responseMessage, err) - } - goto send_response - } else { - responseMessage = "DebugHTTP changed successfully" - } + if settingsmgr.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) + incMetric(metricAdminErr) + return + } + // Check CSRF Token + if !checkCSRFToken(ctx[ctxCSRF], c.CSRFToken) { + adminErrorResponse(w, "invalid CSRF token", http.StatusInternalServerError, nil) + incMetric(metricAdminErr) + return + } + switch c.Action { + case "create": + // FIXME verify fields + if !envs.Exists(c.Name) { + env := envs.Empty(c.Name, c.Hostname) + env.Icon = c.Icon + env.Type = c.Type + if env.Configuration == "" { + env.Configuration = environments.ReadExternalFile(emptyConfiguration) + } + if env.Flags == "" { + // Generate flags + flags, err := environments.GenerateFlags(env, "", "") + if err != nil { + adminErrorResponse(w, "error generating flags", http.StatusInternalServerError, err) + incMetric(metricAdminErr) + return } + env.Flags = flags } - } else { - responseMessage = "invalid CSRF token" - responseCode = http.StatusInternalServerError - if settingsmgr.DebugService(settings.ServiceAdmin) { - log.Printf("DebugService: %s %v", responseMessage, err) + if err := envs.Create(env); err != nil { + adminErrorResponse(w, "error creating environment", http.StatusInternalServerError, err) + incMetric(metricAdminErr) + return + } + } + adminOKResponse(w, "environment created successfully") + case "delete": + if c.Name == settingsmgr.DefaultEnv(settings.ServiceAdmin) { + adminErrorResponse(w, "not a good idea", http.StatusInternalServerError, fmt.Errorf("attempt to remove enviornment %s", c.Name)) + incMetric(metricAdminErr) + return + } + if envs.Exists(c.Name) { + if err := envs.Delete(c.Name); err != nil { + adminErrorResponse(w, "error deleting environment", http.StatusInternalServerError, err) + incMetric(metricAdminErr) + return + } + } + adminOKResponse(w, "environment deleted successfully") + case "debug": + // FIXME verify fields + if envs.Exists(c.Name) { + if err := envs.ChangeDebugHTTP(c.Name, c.DebugHTTP); err != nil { + adminErrorResponse(w, "error changing DebugHTTP", http.StatusInternalServerError, err) + incMetric(metricAdminErr) + return } - goto send_response } + adminOKResponse(w, "debug changed successfully") } -send_response: // Serialize and send response if settingsmgr.DebugService(settings.ServiceAdmin) { log.Println("DebugService: Environments response sent") } - utils.HTTPResponse(w, utils.JSONApplicationUTF8, responseCode, AdminResponse{Message: responseMessage}) incMetric(metricAdminOK) } // Handler for POST request for /settings func settingsPOSTHandler(w http.ResponseWriter, r *http.Request) { incMetric(metricAdminReq) - responseMessage := "OK" - responseCode := http.StatusOK utils.DebugHTTPDump(r, settingsmgr.DebugHTTP(settings.ServiceAdmin), true) vars := mux.Vars(r) // Extract service serviceVar, ok := vars["service"] if !ok { - if settingsmgr.DebugService(settings.ServiceAdmin) { - log.Printf("DebugService: error getting service") - } + adminErrorResponse(w, "error getting service", http.StatusInternalServerError, nil) + incMetric(metricAdminErr) return } // Verify service if !checkTargetService(serviceVar) { - if settingsmgr.DebugService(settings.ServiceAdmin) { - log.Printf("DebugService: error unknown service (%s)", serviceVar) - } + adminErrorResponse(w, fmt.Sprintf("unknown service (%s)", serviceVar), http.StatusForbidden, nil) + incMetric(metricAdminErr) return } var s SettingsRequest // Get context data ctx := r.Context().Value(contextKey("session")).(contextValue) // Check permissions - if !checkAdminLevel(ctx[ctxLevel]) { - responseMessage = "insuficient permissions" - responseCode = http.StatusForbidden - log.Printf("%s has %s", ctx[ctxUser], responseMessage) - goto send_response + if !checkPermissions(ctx[ctxUser], false, false, false, "") { + adminErrorResponse(w, fmt.Sprintf("%s has insuficient permissions", ctx[ctxUser]), http.StatusForbidden, nil) + incMetric(metricAdminErr) + return } // Parse request JSON body + if settingsmgr.DebugService(settings.ServiceAdmin) { + log.Println("DebugService: Decoding POST body") + } if err := json.NewDecoder(r.Body).Decode(&s); err != nil { - responseMessage = "error parsing POST body" - responseCode = http.StatusInternalServerError - if settingsmgr.DebugService(settings.ServiceAdmin) { - log.Printf("DebugService: %s %v", responseMessage, err) + adminErrorResponse(w, "error parsing POST body", http.StatusInternalServerError, err) + incMetric(metricAdminErr) + return + } + // Check CSRF Token + if !checkCSRFToken(ctx[ctxCSRF], s.CSRFToken) { + adminErrorResponse(w, "invalid CSRF token", http.StatusInternalServerError, nil) + incMetric(metricAdminErr) + return + } + switch s.Action { + case "add": + if !settingsmgr.VerifyType(s.Type) { + adminErrorResponse(w, "invalid type", http.StatusInternalServerError, nil) + incMetric(metricAdminErr) + return } - } else { - // Check CSRF Token - if checkCSRFToken(ctx[ctxCSRF], s.CSRFToken) { - switch s.Action { - case "add": - // FIXME verify type - var err error - switch s.Type { - case settings.TypeBoolean: - err = settingsmgr.NewBooleanValue(serviceVar, s.Name, stringToBoolean(s.Value)) - case settings.TypeInteger: - err = settingsmgr.NewIntegerValue(serviceVar, s.Name, stringToInteger(s.Value)) - case settings.TypeString: - err = settingsmgr.NewStringValue(serviceVar, s.Name, s.Value) - } - if err != nil { - responseMessage = "error adding setting" - responseCode = http.StatusInternalServerError - if settingsmgr.DebugService(settings.ServiceAdmin) { - log.Printf("DebugService: %s %v", responseMessage, err) - } - } else { - responseMessage = "Setting added successfully" - } - case "change": - // FIXME verify type - var err error - switch s.Type { - case settings.TypeBoolean: - err = settingsmgr.SetBoolean(s.Boolean, serviceVar, s.Name) - case settings.TypeInteger: - err = settingsmgr.SetInteger(stringToInteger(s.Value), serviceVar, s.Name) - case settings.TypeString: - err = settingsmgr.SetString(s.Value, serviceVar, s.Name, false) - } - if err != nil { - responseMessage = "error changing setting" - responseCode = http.StatusInternalServerError - if settingsmgr.DebugService(settings.ServiceAdmin) { - log.Printf("DebugService: %s %v", responseMessage, err) - } - } else { - responseMessage = "Setting changed successfully" - } - case "delete": - var err error - err = settingsmgr.DeleteValue(serviceVar, s.Name) - if err != nil { - responseMessage = "error deleting setting" - responseCode = http.StatusInternalServerError - if settingsmgr.DebugService(settings.ServiceAdmin) { - log.Printf("DebugService: %s %v", responseMessage, err) - } - } else { - responseMessage = "Setting deleted successfully" - } - } - } else { - responseMessage = "invalid CSRF token" - responseCode = http.StatusInternalServerError - if settingsmgr.DebugService(settings.ServiceAdmin) { - log.Printf("DebugService: %s %v", responseMessage, err) - } + var err error + switch s.Type { + case settings.TypeBoolean: + err = settingsmgr.NewBooleanValue(serviceVar, s.Name, stringToBoolean(s.Value)) + case settings.TypeInteger: + err = settingsmgr.NewIntegerValue(serviceVar, s.Name, stringToInteger(s.Value)) + case settings.TypeString: + err = settingsmgr.NewStringValue(serviceVar, s.Name, s.Value) + } + if err != nil { + adminErrorResponse(w, "error adding setting", http.StatusInternalServerError, err) + incMetric(metricAdminErr) + return + } + adminOKResponse(w, "setting added successfully") + case "change": + if !settingsmgr.VerifyType(s.Type) { + adminErrorResponse(w, "invalid type", http.StatusInternalServerError, nil) + incMetric(metricAdminErr) + return + } + var err error + switch s.Type { + case settings.TypeBoolean: + err = settingsmgr.SetBoolean(s.Boolean, serviceVar, s.Name) + case settings.TypeInteger: + err = settingsmgr.SetInteger(stringToInteger(s.Value), serviceVar, s.Name) + case settings.TypeString: + err = settingsmgr.SetString(s.Value, serviceVar, s.Name, false) + } + if err != nil { + adminErrorResponse(w, "error changing setting", http.StatusInternalServerError, err) + incMetric(metricAdminErr) + return } + adminOKResponse(w, "setting changed successfully") + case "delete": + if err := settingsmgr.DeleteValue(serviceVar, s.Name); err != nil { + adminErrorResponse(w, "error deleting setting", http.StatusInternalServerError, err) + incMetric(metricAdminErr) + return + } + adminOKResponse(w, "setting deleted successfully") } -send_response: // Serialize and send response if settingsmgr.DebugService(settings.ServiceAdmin) { log.Println("DebugService: Settings response sent") } - utils.HTTPResponse(w, utils.JSONApplicationUTF8, responseCode, AdminResponse{Message: responseMessage}) incMetric(metricAdminOK) } // Handler for POST request for /users func usersPOSTHandler(w http.ResponseWriter, r *http.Request) { incMetric(metricAdminReq) - responseMessage := "OK" - responseCode := http.StatusOK utils.DebugHTTPDump(r, settingsmgr.DebugHTTP(settings.ServiceAdmin), true) var u UsersRequest // Get context data ctx := r.Context().Value(contextKey("session")).(contextValue) // Check permissions - if !checkAdminLevel(ctx[ctxLevel]) { - responseMessage = "insuficient permissions" - responseCode = http.StatusForbidden - log.Printf("%s has %s", ctx[ctxUser], responseMessage) - goto send_response + if !checkPermissions(ctx[ctxUser], false, false, false, "") { + adminErrorResponse(w, fmt.Sprintf("%s has insuficient permissions", ctx[ctxUser]), http.StatusForbidden, nil) + incMetric(metricAdminErr) + return } // Parse request JSON body if settingsmgr.DebugService(settings.ServiceAdmin) { log.Println("DebugService: Decoding POST body") } if err := json.NewDecoder(r.Body).Decode(&u); err != nil { - responseMessage = "error parsing POST body" - responseCode = http.StatusInternalServerError - if settingsmgr.DebugService(settings.ServiceAdmin) { - log.Printf("DebugService: %s %v", responseMessage, err) + adminErrorResponse(w, "error parsing POST body", http.StatusInternalServerError, err) + incMetric(metricAdminErr) + return + } + // Check CSRF Token + if !checkCSRFToken(ctx[ctxCSRF], u.CSRFToken) { + adminErrorResponse(w, "invalid CSRF token", http.StatusInternalServerError, nil) + incMetric(metricAdminErr) + return + } + switch u.Action { + case "add": + // FIXME password complexity? + if adminUsers.Exists(u.Username) { + adminErrorResponse(w, "error adding user", http.StatusInternalServerError, fmt.Errorf("user %s already exists", u.Username)) + incMetric(metricAdminErr) + return } - } else { - // Check CSRF Token - if checkCSRFToken(ctx[ctxCSRF], u.CSRFToken) { - switch u.Action { - case "add": - // FIXME password complexity? - if adminUsers.Exists(u.Username) { - responseMessage = "user already exists" - responseCode = http.StatusInternalServerError - if settingsmgr.DebugService(settings.ServiceAdmin) { - log.Printf("DebugService: %s %v", responseMessage, err) - } - } else { - newUser, err := adminUsers.New(u.Username, u.Password, u.Email, u.Fullname, u.Admin) - if err != nil { - responseMessage = "error with new user" - responseCode = http.StatusInternalServerError - if settingsmgr.DebugService(settings.ServiceAdmin) { - log.Printf("DebugService: %s %v", responseMessage, err) - } - } else { - if err = adminUsers.Create(newUser); err != nil { - responseMessage = "error creating user" - responseCode = http.StatusInternalServerError - if settingsmgr.DebugService(settings.ServiceAdmin) { - log.Printf("DebugService: %s %v", responseMessage, err) - } - } - if newUser.Admin { - token, exp, err := adminUsers.CreateToken(newUser.Username, jwtConfig.HoursToExpire, jwtConfig.JWTSecret) - if err != nil { - responseMessage = "error creating token" - responseCode = http.StatusInternalServerError - if settingsmgr.DebugService(settings.ServiceAdmin) { - log.Printf("DebugService: %s %v", responseMessage, err) - } - goto send_response - } - if err = adminUsers.UpdateToken(newUser.Username, token, exp); err != nil { - responseMessage = "error saving token" - responseCode = http.StatusInternalServerError - if settingsmgr.DebugService(settings.ServiceAdmin) { - log.Printf("DebugService: %s %v", responseMessage, err) - } - goto send_response - } - } - responseMessage = "User added successfully" - } - } - case "edit": - if u.Fullname != "" { - if err := adminUsers.ChangeFullname(u.Username, u.Fullname); err != nil { - responseMessage = "error changing fullname" - responseCode = http.StatusInternalServerError - if settingsmgr.DebugService(settings.ServiceAdmin) { - log.Printf("DebugService: %s %v", responseMessage, err) - } - } else { - responseMessage = "User updated successfully" - } + // Prepare user to create + newUser, err := adminUsers.New(u.Username, u.Password, u.Email, u.Fullname, u.Admin) + if err != nil { + adminErrorResponse(w, "error with new user", http.StatusInternalServerError, err) + incMetric(metricAdminErr) + return + } + // Create new user + if err = adminUsers.Create(newUser); err != nil { + adminErrorResponse(w, "error creating user", http.StatusInternalServerError, err) + incMetric(metricAdminErr) + return + } + if u.Admin { + namesEnvs, err := envs.Names() + if err != nil { + adminErrorResponse(w, "error getting environments user", http.StatusInternalServerError, err) + incMetric(metricAdminErr) + return + } + perms := adminUsers.GenPermissions(namesEnvs, u.Admin) + if err := adminUsers.ChangePermissions(u.Username, perms); err != nil { + adminErrorResponse(w, "error changing permissions", http.StatusInternalServerError, err) + incMetric(metricAdminErr) + return + } + } + if u.Token { + token, exp, err := adminUsers.CreateToken(newUser.Username, jwtConfig.HoursToExpire, jwtConfig.JWTSecret) + if err != nil { + adminErrorResponse(w, "error creating token", http.StatusInternalServerError, err) + incMetric(metricAdminErr) + return + } + if err = adminUsers.UpdateToken(newUser.Username, token, exp); err != nil { + adminErrorResponse(w, "error saving token", http.StatusInternalServerError, err) + incMetric(metricAdminErr) + return + } + } + adminOKResponse(w, "user added successfully") + case "edit": + if u.Fullname != "" { + if err := adminUsers.ChangeFullname(u.Username, u.Fullname); err != nil { + adminErrorResponse(w, "error changing fullname", http.StatusInternalServerError, err) + incMetric(metricAdminErr) + return + } + } + if u.Email != "" { + if err := adminUsers.ChangeEmail(u.Username, u.Email); err != nil { + adminErrorResponse(w, "error changing email", http.StatusInternalServerError, err) + incMetric(metricAdminErr) + return + } + } + adminOKResponse(w, "user updated successfully") + case "remove": + if u.Username == ctx[ctxUser] { + adminErrorResponse(w, "not a good idea", http.StatusInternalServerError, fmt.Errorf("attempt to remove current user %s", u.Username)) + incMetric(metricAdminErr) + return + } + if adminUsers.Exists(u.Username) { + if err := adminUsers.Delete(u.Username); err != nil { + adminErrorResponse(w, "error removing user", http.StatusInternalServerError, err) + incMetric(metricAdminErr) + return + } + } + adminOKResponse(w, "user removed successfully") + case "admin": + if u.Username == ctx[ctxUser] { + adminErrorResponse(w, "not a good idea", http.StatusInternalServerError, fmt.Errorf("attempt to de-admin current user %s", u.Username)) + incMetric(metricAdminErr) + return + } + if adminUsers.Exists(u.Username) { + if err := adminUsers.ChangeAdmin(u.Username, u.Admin); err != nil { + adminErrorResponse(w, "error changing admin", http.StatusInternalServerError, err) + incMetric(metricAdminErr) + return + } + if u.Admin { + namesEnvs, err := envs.Names() + if err != nil { + adminErrorResponse(w, "error getting environments", http.StatusInternalServerError, err) + incMetric(metricAdminErr) + return } - if u.Email != "" { - if err := adminUsers.ChangeEmail(u.Username, u.Email); err != nil { - responseMessage = "error changing email" - responseCode = http.StatusInternalServerError - if settingsmgr.DebugService(settings.ServiceAdmin) { - log.Printf("DebugService: %s %v", responseMessage, err) - } - } else { - responseMessage = "User updated successfully" - } + perms := adminUsers.GenPermissions(namesEnvs, u.Admin) + if err := adminUsers.ChangePermissions(u.Username, perms); err != nil { + adminErrorResponse(w, "error changing permissions", http.StatusInternalServerError, err) + incMetric(metricAdminErr) + return } - case "remove": - if u.Username == ctx[ctxUser] { - responseMessage = "Not a good idea" - responseCode = http.StatusInternalServerError - log.Printf("Attempt to self remove by %s", ctx[ctxUser]) - goto send_response - } else if adminUsers.Exists(u.Username) { - err = adminUsers.Delete(u.Username) - if err != nil { - responseMessage = "error removing user" - responseCode = http.StatusInternalServerError - if settingsmgr.DebugService(settings.ServiceAdmin) { - log.Printf("DebugService: %s %v", responseMessage, err) - } - } else { - responseMessage = "User removed" - } + token, exp, err := adminUsers.CreateToken(u.Username, jwtConfig.HoursToExpire, jwtConfig.JWTSecret) + if err != nil { + adminErrorResponse(w, "error creating token", http.StatusInternalServerError, err) + incMetric(metricAdminErr) + return } - case "admin": - if u.Username == ctx[ctxUser] { - responseMessage = "Not a good idea" - responseCode = http.StatusInternalServerError - log.Printf("Attempt to change admin by %s", ctx[ctxUser]) - goto send_response - } else if adminUsers.Exists(u.Username) { - err = adminUsers.ChangeAdmin(u.Username, u.Admin) - if err != nil { - responseMessage = "error changing admin" - responseCode = http.StatusInternalServerError - if settingsmgr.DebugService(settings.ServiceAdmin) { - log.Printf("DebugService: %s %v", responseMessage, err) - } - } - if u.Admin { - token, exp, err := adminUsers.CreateToken(u.Username, jwtConfig.HoursToExpire, jwtConfig.JWTSecret) - if err != nil { - responseMessage = "error creating token" - responseCode = http.StatusInternalServerError - if settingsmgr.DebugService(settings.ServiceAdmin) { - log.Printf("DebugService: %s %v", responseMessage, err) - } - goto send_response - } - if err = adminUsers.UpdateToken(u.Username, token, exp); err != nil { - responseMessage = "error saving token" - responseCode = http.StatusInternalServerError - if settingsmgr.DebugService(settings.ServiceAdmin) { - log.Printf("DebugService: %s %v", responseMessage, err) - } - goto send_response - } - } - responseMessage = "Admin changed" + if err := adminUsers.UpdateToken(u.Username, token, exp); err != nil { + adminErrorResponse(w, "error saving token", http.StatusInternalServerError, err) + incMetric(metricAdminErr) + return } } - } else { - responseMessage = "invalid CSRF token" - responseCode = http.StatusInternalServerError - if settingsmgr.DebugService(settings.ServiceAdmin) { - log.Printf("DebugService: %s %v", responseMessage, err) - } + adminOKResponse(w, "admin changed successfully") } } -send_response: // Serialize and send response if settingsmgr.DebugService(settings.ServiceAdmin) { log.Println("DebugService: Users response sent") } - utils.HTTPResponse(w, utils.JSONApplicationUTF8, responseCode, AdminResponse{Message: responseMessage}) + incMetric(metricAdminOK) +} + +// Handler for POST request for /users/permissions +func permissionsPOSTHandler(w http.ResponseWriter, r *http.Request) { + incMetric(metricAdminReq) + utils.DebugHTTPDump(r, settingsmgr.DebugHTTP(settings.ServiceAdmin), true) + vars := mux.Vars(r) + // Extract username and verify + usernameVar, ok := vars["username"] + if !ok || !adminUsers.Exists(usernameVar) { + adminErrorResponse(w, "error getting username", http.StatusInternalServerError, nil) + incMetric(metricAdminErr) + return + } + var p PermissionsRequest + // Get context data + ctx := r.Context().Value(contextKey("session")).(contextValue) + // Check permissions + if !checkPermissions(ctx[ctxUser], false, false, false, "") { + adminErrorResponse(w, fmt.Sprintf("%s has insuficient permissions", ctx[ctxUser]), http.StatusForbidden, nil) + incMetric(metricAdminErr) + return + } + // Parse request JSON body + if settingsmgr.DebugService(settings.ServiceAdmin) { + log.Println("DebugService: Decoding POST body") + } + if err := json.NewDecoder(r.Body).Decode(&p); err != nil { + adminErrorResponse(w, "error parsing POST body", http.StatusInternalServerError, err) + incMetric(metricAdminErr) + return + } + // Check CSRF Token + if !checkCSRFToken(ctx[ctxCSRF], p.CSRFToken) { + adminErrorResponse(w, "invalid CSRF token", http.StatusInternalServerError, nil) + incMetric(metricAdminErr) + return + } + // TODO verify environments + perms := users.UserPermissions{ + Environments: p.Environments, + Query: p.Query, + Carve: p.Carve, + } + if err := adminUsers.ChangePermissions(usernameVar, perms); err != nil { + adminErrorResponse(w, "error changing permissions", http.StatusInternalServerError, err) + incMetric(metricAdminErr) + return + } + // Serialize and send response + if settingsmgr.DebugService(settings.ServiceAdmin) { + log.Println("DebugService: Users response sent") + } + adminOKResponse(w, "OK") incMetric(metricAdminOK) } // Handler POST requests enroll data func enrollPOSTHandler(w http.ResponseWriter, r *http.Request) { incMetric(metricAdminReq) - responseMessage := "Enroll data saved successfully" - responseCode := http.StatusOK utils.DebugHTTPDump(r, settingsmgr.DebugHTTP(settings.ServiceAdmin), true) vars := mux.Vars(r) // Extract environment and verify environmentVar, ok := vars["environment"] if !ok || !envs.Exists(environmentVar) { - if settingsmgr.DebugService(settings.ServiceAdmin) { - log.Printf("DebugService: error getting environment") - } - return - } - // Verify environment - if !envs.Exists(environmentVar) { - if settingsmgr.DebugService(settings.ServiceAdmin) { - log.Printf("DebugService: error unknown environment (%s)", environmentVar) - } + adminErrorResponse(w, "error getting environment", http.StatusInternalServerError, nil) + incMetric(metricAdminErr) return } var e EnrollRequest // Get context data ctx := r.Context().Value(contextKey("session")).(contextValue) // Check permissions - if !checkAdminLevel(ctx[ctxLevel]) { - responseMessage = "insuficient permissions" - responseCode = http.StatusForbidden - log.Printf("%s has %s", ctx[ctxUser], responseMessage) - goto send_response + if !checkPermissions(ctx[ctxUser], false, false, true, environmentVar) { + adminErrorResponse(w, fmt.Sprintf("%s has insuficient permissions", ctx[ctxUser]), http.StatusForbidden, nil) + incMetric(metricAdminErr) + return } // Parse request JSON body + if settingsmgr.DebugService(settings.ServiceAdmin) { + log.Println("DebugService: Decoding POST body") + } if err := json.NewDecoder(r.Body).Decode(&e); err != nil { - responseMessage = "error parsing POST body" - responseCode = http.StatusInternalServerError - if settingsmgr.DebugService(settings.ServiceAdmin) { - log.Printf("DebugService: %s %v", responseMessage, err) - } - } else { - // Check CSRF Token - if checkCSRFToken(ctx[ctxCSRF], e.CSRFToken) { - if e.CertificateB64 != "" { - certificate, err := base64.StdEncoding.DecodeString(e.CertificateB64) - if err != nil { - responseMessage = "error decoding certificate" - responseCode = http.StatusInternalServerError - if settingsmgr.DebugService(settings.ServiceAdmin) { - log.Printf("DebugService: %s %v", responseMessage, err) - } - } else { - err = envs.UpdateCertificate(environmentVar, string(certificate)) - if err != nil { - responseMessage = "error saving certificate" - responseCode = http.StatusInternalServerError - if settingsmgr.DebugService(settings.ServiceAdmin) { - log.Printf("DebugService: %s %v", responseMessage, err) - } - } - } - } else { - responseMessage = "empty certificate" - responseCode = http.StatusInternalServerError - if settingsmgr.DebugService(settings.ServiceAdmin) { - log.Printf("DebugService: %s %v", responseMessage, err) - } - } - } else { - responseMessage = "invalid CSRF token" - responseCode = http.StatusInternalServerError - if settingsmgr.DebugService(settings.ServiceAdmin) { - log.Printf("DebugService: %s %v", responseMessage, err) - } - } + adminErrorResponse(w, "error parsing POST body", http.StatusInternalServerError, err) + incMetric(metricAdminErr) + return + } + // Check CSRF Token + if !checkCSRFToken(ctx[ctxCSRF], e.CSRFToken) { + adminErrorResponse(w, "invalid CSRF token", http.StatusInternalServerError, nil) + incMetric(metricAdminErr) + return + } + if e.CertificateB64 == "" { + adminErrorResponse(w, "empty certificate", http.StatusInternalServerError, nil) + incMetric(metricAdminErr) + return + } + certificate, err := base64.StdEncoding.DecodeString(e.CertificateB64) + if err != nil { + adminErrorResponse(w, "error decoding certificate", http.StatusInternalServerError, err) + incMetric(metricAdminErr) + return + } + if err := envs.UpdateCertificate(environmentVar, string(certificate)); err != nil { + adminErrorResponse(w, "error saving certificate", http.StatusInternalServerError, err) + incMetric(metricAdminErr) + return } -send_response: // Serialize and send response if settingsmgr.DebugService(settings.ServiceAdmin) { log.Println("DebugService: Configuration response sent") } - utils.HTTPResponse(w, utils.JSONApplicationUTF8, responseCode, AdminResponse{Message: responseMessage}) + adminOKResponse(w, "enroll data saved") incMetric(metricAdminOK) } diff --git a/admin/handlers-tokens.go b/admin/handlers-tokens.go index e321b675..8e98d45d 100644 --- a/admin/handlers-tokens.go +++ b/admin/handlers-tokens.go @@ -2,6 +2,7 @@ package main import ( "encoding/json" + "fmt" "log" "net/http" @@ -30,25 +31,25 @@ func tokensGETHandler(w http.ResponseWriter, r *http.Request) { // Get context data ctx := r.Context().Value(contextKey("session")).(contextValue) // Check permissions - if !checkAdminLevel(ctx[ctxLevel]) { - log.Printf("%s has insuficient permissions", ctx[ctxUser]) - incMetric(metricTokenErr) + if !checkPermissions(ctx[ctxUser], false, false, false, "") { + adminErrorResponse(w, fmt.Sprintf("%s has insuficient permissions", ctx[ctxUser]), http.StatusForbidden, nil) + incMetric(metricAdminErr) return } vars := mux.Vars(r) // Extract username username, ok := vars["username"] if !ok { - log.Println("error getting username") - incMetric(metricTokenErr) + adminErrorResponse(w, "error getting username", http.StatusInternalServerError, nil) + incMetric(metricAdminErr) return } returned := TokenJSON{} if adminUsers.Exists(username) { user, err := adminUsers.Get(username) if err != nil { - log.Println("error getting user") - incMetric(metricTokenErr) + adminErrorResponse(w, "error getting user", http.StatusInternalServerError, err) + incMetric(metricAdminErr) return } // Prepare data to be returned @@ -70,17 +71,17 @@ func tokensPOSTHandler(w http.ResponseWriter, r *http.Request) { // Get context data ctx := r.Context().Value(contextKey("session")).(contextValue) // Check permissions - if !checkAdminLevel(ctx[ctxLevel]) { + if !checkPermissions(ctx[ctxUser], false, false, false, "") { adminErrorResponse(w, "insuficient permissions", http.StatusForbidden, nil) incMetric(metricTokenErr) return } vars := mux.Vars(r) - // Extract username + // Extract username and verify username, ok := vars["username"] - if !ok { - incMetric(metricTokenErr) + if !ok || !adminUsers.Exists(username) { adminErrorResponse(w, "error getting username", http.StatusInternalServerError, nil) + incMetric(metricAdminErr) return } // Parse request JSON body @@ -90,47 +91,44 @@ func tokensPOSTHandler(w http.ResponseWriter, r *http.Request) { var t TokenRequest var response TokenResponse if err := json.NewDecoder(r.Body).Decode(&t); err == nil { - // Check CSRF Token - if checkCSRFToken(ctx[ctxCSRF], t.CSRFToken) { - if adminUsers.Exists(username) { - user, err := adminUsers.Get(username) - if err != nil { - adminErrorResponse(w, "error getting user", http.StatusInternalServerError, err) - return - } - if settingsmgr.DebugService(settings.ServiceAdmin) { - log.Println("DebugService: Creating token") - } - token, exp, err := adminUsers.CreateToken(user.Username, jwtConfig.HoursToExpire, jwtConfig.JWTSecret) - if err != nil { - adminErrorResponse(w, "error creating token", http.StatusInternalServerError, err) - return - } - if settingsmgr.DebugService(settings.ServiceAdmin) { - log.Println("DebugService: Updating token") - } - if err := adminUsers.UpdateToken(user.Username, token, exp); err != nil { - adminErrorResponse(w, "error updating token", http.StatusInternalServerError, err) - return - } - response = TokenResponse{ - Token: token, - ExpirationTS: utils.TimeTimestamp(exp), - Expiration: utils.PastFutureTimes(exp), - } - } else { - adminErrorResponse(w, "user not found", http.StatusNotFound, nil) - return - } - } else { - adminErrorResponse(w, "invalid CSRF token", http.StatusForbidden, nil) - return - } - } else { - incMetric(metricTokenErr) - adminErrorResponse(w, "error parsing POST body", http.StatusInternalServerError, nil) + adminErrorResponse(w, "error parsing POST body", http.StatusInternalServerError, err) + incMetric(metricAdminErr) + return + } + // Check CSRF Token + if !checkCSRFToken(ctx[ctxCSRF], t.CSRFToken) { + adminErrorResponse(w, "invalid CSRF token", http.StatusInternalServerError, nil) + incMetric(metricAdminErr) return } + user, err := adminUsers.Get(username) + if err != nil { + adminErrorResponse(w, "error getting user", http.StatusInternalServerError, err) + incMetric(metricAdminErr) + return + } + if settingsmgr.DebugService(settings.ServiceAdmin) { + log.Println("DebugService: Creating token") + } + token, exp, err := adminUsers.CreateToken(user.Username, jwtConfig.HoursToExpire, jwtConfig.JWTSecret) + if err != nil { + adminErrorResponse(w, "error creating token", http.StatusInternalServerError, err) + incMetric(metricAdminErr) + return + } + if settingsmgr.DebugService(settings.ServiceAdmin) { + log.Println("DebugService: Updating token") + } + if err := adminUsers.UpdateToken(user.Username, token, exp); err != nil { + adminErrorResponse(w, "error updating token", http.StatusInternalServerError, err) + incMetric(metricAdminErr) + return + } + response = TokenResponse{ + Token: token, + ExpirationTS: utils.TimeTimestamp(exp), + Expiration: utils.PastFutureTimes(exp), + } // Serialize and serve JSON utils.HTTPResponse(w, utils.JSONApplicationUTF8, http.StatusOK, response) incMetric(metricTokenOK) diff --git a/admin/headers.go b/admin/headers.go index 9f1f8b87..81e2f603 100644 --- a/admin/headers.go +++ b/admin/headers.go @@ -24,7 +24,6 @@ func loadHeaders(file string) (types.JSONConfigurationHeaders, error) { if err != nil { return cfg, err } - // No errors! return cfg, nil } diff --git a/admin/json-carves.go b/admin/json-carves.go index b6aa775f..7bf80ee8 100644 --- a/admin/json-carves.go +++ b/admin/json-carves.go @@ -56,7 +56,7 @@ func jsonCarvesHandler(w http.ResponseWriter, r *http.Request) { // Get context data ctx := r.Context().Value(contextKey("session")).(contextValue) // Check permissions - if !checkAdminLevel(ctx[ctxLevel]) { + if !checkPermissions(ctx[ctxUser], false, true, false, "") { log.Printf("%s has insuficient permissions", ctx[ctxUser]) incMetric(metricJSONErr) return diff --git a/admin/json-logs.go b/admin/json-logs.go index 2d8fa124..32dac4da 100644 --- a/admin/json-logs.go +++ b/admin/json-logs.go @@ -78,6 +78,14 @@ func jsonLogsHandler(w http.ResponseWriter, r *http.Request) { incMetric(metricJSONErr) return } + // Get context data + ctx := r.Context().Value(contextKey("session")).(contextValue) + // Check permissions + if !checkPermissions(ctx[ctxUser], false, false, true, env) { + log.Printf("%s has insuficient permissions", ctx[ctxUser]) + incMetric(metricJSONErr) + return + } // Extract UUID // FIXME verify UUID UUID, ok := vars["uuid"] @@ -150,6 +158,14 @@ func jsonLogsHandler(w http.ResponseWriter, r *http.Request) { func jsonQueryLogsHandler(w http.ResponseWriter, r *http.Request) { incMetric(metricJSONReq) utils.DebugHTTPDump(r, settingsmgr.DebugHTTP(settings.ServiceAdmin), false) + // Get context data + ctx := r.Context().Value(contextKey("session")).(contextValue) + // Check permissions + if !checkPermissions(ctx[ctxUser], true, false, false, "") { + log.Printf("%s has insuficient permissions", ctx[ctxUser]) + incMetric(metricJSONErr) + return + } vars := mux.Vars(r) // Extract query name // FIXME verify name diff --git a/admin/json-nodes.go b/admin/json-nodes.go index a557ae47..fd996ed0 100644 --- a/admin/json-nodes.go +++ b/admin/json-nodes.go @@ -106,7 +106,7 @@ func jsonPlatformHandler(w http.ResponseWriter, r *http.Request) { // Get context data ctx := r.Context().Value(contextKey("session")).(contextValue) // Check permissions - if !checkAdminLevel(ctx[ctxLevel]) { + if !checkPermissions(ctx[ctxUser], false, false, false, "") { log.Printf("%s has insuficient permissions", ctx[ctxUser]) incMetric(metricJSONErr) return diff --git a/admin/json-queries.go b/admin/json-queries.go index 203b31b2..e78dafee 100644 --- a/admin/json-queries.go +++ b/admin/json-queries.go @@ -55,7 +55,7 @@ func jsonQueryHandler(w http.ResponseWriter, r *http.Request) { // Get context data ctx := r.Context().Value(contextKey("session")).(contextValue) // Check permissions - if !checkAdminLevel(ctx[ctxLevel]) { + if !checkPermissions(ctx[ctxUser], true, false, false, "") { log.Printf("%s has insuficient permissions", ctx[ctxUser]) incMetric(metricJSONErr) return diff --git a/admin/json-stats.go b/admin/json-stats.go index 2e74cea1..95b95248 100644 --- a/admin/json-stats.go +++ b/admin/json-stats.go @@ -58,7 +58,7 @@ func jsonStatsHandler(w http.ResponseWriter, r *http.Request) { } } else if target == "platform" { // Check permissions - if !checkAdminLevel(ctx[ctxLevel]) { + if !checkPermissions(ctx[ctxUser], false, false, false, "") { log.Printf("%s has insuficient permissions", ctx[ctxUser]) incMetric(metricJSONErr) return diff --git a/admin/main.go b/admin/main.go index 5319b811..cd00787f 100644 --- a/admin/main.go +++ b/admin/main.go @@ -381,11 +381,13 @@ func main() { // Admin: manage users routerAdmin.Handle("/users", handlerAuthCheck(http.HandlerFunc(usersGETHandler))).Methods("GET") routerAdmin.Handle("/users", handlerAuthCheck(http.HandlerFunc(usersPOSTHandler))).Methods("POST") + routerAdmin.Handle("/users/permissions/{username}", handlerAuthCheck(http.HandlerFunc(permissionsGETHandler))).Methods("GET") + routerAdmin.Handle("/users/permissions/{username}", handlerAuthCheck(http.HandlerFunc(permissionsPOSTHandler))).Methods("POST") // Admin: manage tokens routerAdmin.Handle("/tokens/{username}", handlerAuthCheck(http.HandlerFunc(tokensGETHandler))).Methods("GET") routerAdmin.Handle("/tokens/{username}/refresh", handlerAuthCheck(http.HandlerFunc(tokensPOSTHandler))).Methods("POST") // logout - routerAdmin.Handle("/logout", handlerAuthCheck(http.HandlerFunc(logoutHandler))).Methods("POST") + routerAdmin.Handle("/logout", handlerAuthCheck(http.HandlerFunc(logoutPOSTHandler))).Methods("POST") // SAML ACS if adminConfig.Auth == settings.AuthSAML { diff --git a/admin/static/js/functions.js b/admin/static/js/functions.js index eb9c2de2..3afd3d6b 100644 --- a/admin/static/js/functions.js +++ b/admin/static/js/functions.js @@ -1,3 +1,32 @@ +function sendGetRequest(req_url, _modal, _callback) { + $.ajax({ + url: req_url, + dataType: 'json', + type: 'GET', + contentType: 'application/json', + success: function (data, textStatus, jQxhr) { + console.log('OK'); + console.log(data); + if (_modal) { + $("#successModalMessage").text(data.message); + $("#successModal").modal(); + } + if (_callback) { + _callback(data); + } + }, + error: function (jqXhr, textStatus, errorThrown) { + var _clientmsg = 'Client: ' + errorThrown; + var _serverJSON = $.parseJSON(jqXhr.responseText); + var _servermsg = 'Server: ' + _serverJSON.message; + $("#errorModalMessageClient").text(_clientmsg); + console.log(_clientmsg); + $("#errorModalMessageServer").text(_servermsg); + $("#errorModal").modal(); + } + }); +} + function sendPostRequest(req_data, req_url, _redir, _modal, _callback) { $.ajax({ url: req_url, diff --git a/admin/static/js/users.js b/admin/static/js/users.js index 2d1c8560..c3e68ee0 100644 --- a/admin/static/js/users.js +++ b/admin/static/js/users.js @@ -15,6 +15,8 @@ function confirmAddUser() { var _email = $("#user_email").val(); var _fullname = $("#user_fullname").val(); var _password = $("#user_password").val(); + var _admin = $("#user_admin").is(':checked'); + var _token = $("#user_token").is(':checked'); var data = { csrftoken: _csrftoken, @@ -23,7 +25,8 @@ function confirmAddUser() { email: _email, fullname: _fullname, password: _password, - admin: false + admin: _admin, + token: _token }; sendPostRequest(data, _url, _url, false); } @@ -42,6 +45,12 @@ function changeAdminUser(_user) { var _csrftoken = $("#csrftoken").val(); var _value = $("#" + _user).is(':checked'); + if (_value) { + $('#permissions-button-' + _user).hide(); + } else { + $('#permissions-button-' + _user).show(); + } + var _url = window.location.pathname; var data = { @@ -91,3 +100,54 @@ function refreshUserToken() { $("#refreshTokenButton").text('Refresh'); }); } + +function showPermissions(_username) { + $("#username_permissions").val(_username); + sendGetRequest('/users/permissions/' + _username, false, function (data) { + $('.switch-env-permission').each(function () { + var _env = $(this).attr('id'); + if (data.environments) { + if (data.environments[_env]) { + $(this).attr('checked', true); + } else { + $(this).attr('checked', false); + } + } else { + $(this).attr('checked', false); + } + }); + if (data.query) { + $("#permission-queries").attr('checked', true); + } else { + $("#permission-queries").attr('checked', false); + } + if (data.carve) { + $("#permission-carves").attr('checked', true); + } else { + $("#permission-carves").attr('checked', false); + } + }); + $("#permissionsModal").modal(); +} + +function savePermissions() { + var _csrftoken = $("#csrftoken").val(); + var _username = $("#username_permissions").val(); + + var _queries = $("#permission-queries").is(':checked'); + var _carves = $("#permission-carves").is(':checked'); + + var _envs = {}; + $('.switch-env-permission').each(function () { + _envs[$(this).attr('id')] = $(this).prop('checked'); + }); + var data = { + csrftoken: _csrftoken, + environments: _envs, + query: _queries, + carve: _carves, + }; + sendPostRequest(data, '/users/permissions/' + _username, '', false, function (data) { + console.log(data); + }); +} diff --git a/admin/templates/users.html b/admin/templates/users.html index a5d00065..b0355e8d 100644 --- a/admin/templates/users.html +++ b/admin/templates/users.html @@ -62,13 +62,31 @@
{{ $e.Fullname }}