diff --git a/admin/auth.go b/admin/auth.go index cf3affed..4df7fb9e 100644 --- a/admin/auth.go +++ b/admin/auth.go @@ -4,7 +4,6 @@ import ( "context" "log" "net/http" - "strconv" "strings" "github.com/jmpsec/osctrl/settings" @@ -14,65 +13,37 @@ import ( const ( adminLevel string = "admin" userLevel string = "user" + queryLevel string = "query" + carveLevel string = "carve" ) const ( ctxUser = "user" ctxEmail = "email" ctxCSRF = "csrftoken" - ctxAdmin = "admin" - ctxLevel = "user" + ctxLevel = "level" ) -// Helper to verify if user is an admin -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 +// Helper to convert permissions for a user to a level for context +func levelPermissions(user users.AdminUser) string { if user.Admin { - return true + return adminLevel } perms, err := adminUsers.ConvertPermissions(user.Permissions.RawMessage) if err != nil { log.Printf("error converting permissions %v", err) - return false + return userLevel } // Check for query access - if query { - return checkQueryLevel(perms) + if perms.Query { + return queryLevel } // Check for carve access - if carve { - return checkCarveLevel(perms) - } - // Check for environment access - if env { - return checkEnvironmentLevel(perms, environment) + if perms.Carve { + return carveLevel } // At this point, no access granted - return false + return userLevel } // Handler to check access to a resource based on the authentication enabled @@ -88,13 +59,9 @@ func handlerAuthCheck(h http.Handler) http.Handler { } // Set middleware values s := make(contextValue) - s["user"] = session.Username - s["csrftoken"] = session.Values["csrftoken"].(string) - if session.Values["admin"].(bool) { - s["level"] = adminLevel - } else { - s["level"] = userLevel - } + s[ctxUser] = session.Username + s[ctxCSRF] = session.Values[ctxCSRF].(string) + s[ctxLevel] = session.Values[ctxLevel].(string) ctx := context.WithValue(r.Context(), contextKey("session"), s) // Update metadata for the user err := adminUsers.UpdateMetadata(session.IPAddress, session.UserAgent, session.Username, s["csrftoken"]) @@ -142,13 +109,9 @@ func handlerAuthCheck(h http.Handler) http.Handler { } // Set middleware values s := make(contextValue) - s["user"] = session.Username - s["csrftoken"] = session.Values["csrftoken"].(string) - if session.Values["admin"].(bool) { - s["level"] = adminLevel - } else { - s["level"] = userLevel - } + s[ctxUser] = session.Username + s[ctxCSRF] = session.Values[ctxCSRF].(string) + s[ctxLevel] = session.Values[ctxLevel].(string) ctx := context.WithValue(r.Context(), contextKey("session"), s) // Update metadata for the user err = adminUsers.UpdateMetadata(session.IPAddress, session.UserAgent, session.Username, s["csrftoken"]) @@ -172,24 +135,24 @@ func handlerAuthCheck(h http.Handler) http.Handler { } // Set middleware values s := make(contextValue) - s["user"] = username - s["csrftoken"] = generateCSRF() + s[ctxUser] = username + s[ctxCSRF] = generateCSRF() for _, group := range groups { if group == headersConfig.AdminGroup { - s["level"] = adminLevel + s[ctxLevel] = adminLevel // We can break because there is no greater permission level break } else if group == headersConfig.UserGroup { - s["level"] = userLevel + s[ctxLevel] = userLevel // We can't break because we might still find a higher permission level } } // This user didn't present a group that has permission to use the service - if _, ok := s["level"]; !ok { + if _, ok := s[ctxLevel]; !ok { http.Redirect(w, r, forbiddenPath, http.StatusForbidden) return } - newUser, err := adminUsers.New(username, "", email, fullname, (s["level"] == adminLevel)) + newUser, err := adminUsers.New(username, "", email, fullname, (s[ctxLevel] == adminLevel)) if err != nil { log.Printf("Error with new user %s: %v", username, err) http.Redirect(w, r, forbiddenPath, http.StatusFound) @@ -215,6 +178,6 @@ func prepareContext(user users.AdminUser) contextValue { s[ctxUser] = user.Username s[ctxEmail] = user.Email s[ctxCSRF] = user.CSRFToken - s[ctxAdmin] = strconv.FormatBool(user.Admin) + s[ctxLevel] = levelPermissions(user) return s } diff --git a/admin/handlers-get.go b/admin/handlers-get.go index eef8e966..6b37f3cd 100644 --- a/admin/handlers-get.go +++ b/admin/handlers-get.go @@ -12,6 +12,7 @@ import ( "github.com/jmpsec/osctrl/carves" "github.com/jmpsec/osctrl/environments" "github.com/jmpsec/osctrl/settings" + "github.com/jmpsec/osctrl/users" "github.com/jmpsec/osctrl/utils" "github.com/gorilla/mux" @@ -104,7 +105,7 @@ func environmentHandler(w http.ResponseWriter, r *http.Request) { // Get context data ctx := r.Context().Value(contextKey("session")).(contextValue) // Check permissions - if !checkPermissions(ctx[ctxUser], false, false, true, env) { + if !adminUsers.CheckPermissions(ctx[ctxUser], users.EnvLevel, env) { log.Printf("%s has insuficient permissions", ctx[ctxUser]) incMetric(metricTokenErr) return @@ -185,7 +186,7 @@ func platformHandler(w http.ResponseWriter, r *http.Request) { // Get context data ctx := r.Context().Value(contextKey("session")).(contextValue) // Check permissions - if !checkPermissions(ctx[ctxUser], false, false, false, "") { + if !adminUsers.CheckPermissions(ctx[ctxUser], users.AdminLevel, users.NoEnvironment) { log.Printf("%s has insuficient permissions", ctx[ctxUser]) incMetric(metricTokenErr) return @@ -246,7 +247,7 @@ func queryRunGETHandler(w http.ResponseWriter, r *http.Request) { // Get context data ctx := r.Context().Value(contextKey("session")).(contextValue) // Check permissions - if !checkPermissions(ctx[ctxUser], true, false, false, "") { + if !adminUsers.CheckPermissions(ctx[ctxUser], users.QueryLevel, users.NoEnvironment) { log.Printf("%s has insuficient permissions", ctx[ctxUser]) incMetric(metricAdminErr) return @@ -322,7 +323,7 @@ func queryListGETHandler(w http.ResponseWriter, r *http.Request) { // Get context data ctx := r.Context().Value(contextKey("session")).(contextValue) // Check permissions - if !checkPermissions(ctx[ctxUser], true, false, false, "") { + if !adminUsers.CheckPermissions(ctx[ctxUser], users.QueryLevel, users.NoEnvironment) { log.Printf("%s has insuficient permissions", ctx[ctxUser]) incMetric(metricAdminErr) return @@ -375,7 +376,7 @@ func carvesRunGETHandler(w http.ResponseWriter, r *http.Request) { // Get context data ctx := r.Context().Value(contextKey("session")).(contextValue) // Check permissions - if !checkPermissions(ctx[ctxUser], false, true, false, "") { + if !adminUsers.CheckPermissions(ctx[ctxUser], users.CarveLevel, users.NoEnvironment) { log.Printf("%s has insuficient permissions", ctx[ctxUser]) incMetric(metricAdminErr) return @@ -445,7 +446,7 @@ func carvesListGETHandler(w http.ResponseWriter, r *http.Request) { // Get context data ctx := r.Context().Value(contextKey("session")).(contextValue) // Check permissions - if !checkPermissions(ctx[ctxUser], false, true, false, "") { + if !adminUsers.CheckPermissions(ctx[ctxUser], users.CarveLevel, users.NoEnvironment) { log.Printf("%s has insuficient permissions", ctx[ctxUser]) incMetric(metricAdminErr) return @@ -498,7 +499,7 @@ func queryLogsHandler(w http.ResponseWriter, r *http.Request) { // Get context data ctx := r.Context().Value(contextKey("session")).(contextValue) // Check permissions - if !checkPermissions(ctx[ctxUser], true, false, false, "") { + if !adminUsers.CheckPermissions(ctx[ctxUser], users.QueryLevel, users.NoEnvironment) { log.Printf("%s has insuficient permissions", ctx[ctxUser]) incMetric(metricAdminErr) return @@ -580,7 +581,7 @@ func carvesDetailsHandler(w http.ResponseWriter, r *http.Request) { // Get context data ctx := r.Context().Value(contextKey("session")).(contextValue) // Check permissions - if !checkPermissions(ctx[ctxUser], false, true, false, "") { + if !adminUsers.CheckPermissions(ctx[ctxUser], users.CarveLevel, users.NoEnvironment) { log.Printf("%s has insuficient permissions", ctx[ctxUser]) incMetric(metricAdminErr) return @@ -691,7 +692,7 @@ func confGETHandler(w http.ResponseWriter, r *http.Request) { // Get context data ctx := r.Context().Value(contextKey("session")).(contextValue) // Check permissions - if !checkPermissions(ctx[ctxUser], false, false, true, envVar) { + if !adminUsers.CheckPermissions(ctx[ctxUser], users.EnvLevel, envVar) { log.Printf("%s has insuficient permissions", ctx[ctxUser]) incMetric(metricAdminErr) return @@ -765,7 +766,7 @@ func enrollGETHandler(w http.ResponseWriter, r *http.Request) { // Get context data ctx := r.Context().Value(contextKey("session")).(contextValue) // Check permissions - if !checkPermissions(ctx[ctxUser], false, false, true, envVar) { + if !adminUsers.CheckPermissions(ctx[ctxUser], users.EnvLevel, envVar) { log.Printf("%s has insuficient permissions", ctx[ctxUser]) incMetric(metricAdminErr) return @@ -860,6 +861,21 @@ func nodeHandler(w http.ResponseWriter, r *http.Request) { log.Printf("error getting table template: %v", err) return } + // Get node by UUID + node, err := nodesmgr.GetByUUID(uuid) + if err != nil { + incMetric(metricAdminErr) + log.Printf("error getting node %v", err) + return + } + // Get context data + ctx := r.Context().Value(contextKey("session")).(contextValue) + // Check permissions + if !adminUsers.CheckPermissions(ctx[ctxUser], users.EnvLevel, node.Environment) { + log.Printf("%s has insuficient permissions", ctx[ctxUser]) + incMetric(metricAdminErr) + return + } // Get all environments envAll, err := envs.All() if err != nil { @@ -874,15 +890,6 @@ func nodeHandler(w http.ResponseWriter, r *http.Request) { log.Printf("error getting platforms: %v", err) return } - // Get node by UUID - node, err := nodesmgr.GetByUUID(uuid) - if err != nil { - incMetric(metricAdminErr) - log.Printf("error getting node %v", err) - return - } - // Get context data - ctx := r.Context().Value(contextKey("session")).(contextValue) // Prepare template data templateData := NodeTemplateData{ Title: "Node View " + node.Hostname, @@ -910,7 +917,7 @@ func envsGETHandler(w http.ResponseWriter, r *http.Request) { // Get context data ctx := r.Context().Value(contextKey("session")).(contextValue) // Check permissions - if !checkPermissions(ctx[ctxUser], false, false, false, "") { + if !adminUsers.CheckPermissions(ctx[ctxUser], users.AdminLevel, users.NoEnvironment) { log.Printf("%s has insuficient permissions", ctx[ctxUser]) incMetric(metricAdminErr) return @@ -963,7 +970,7 @@ func settingsGETHandler(w http.ResponseWriter, r *http.Request) { // Get context data ctx := r.Context().Value(contextKey("session")).(contextValue) // Check permissions - if !checkPermissions(ctx[ctxUser], false, false, false, "") { + if !adminUsers.CheckPermissions(ctx[ctxUser], users.AdminLevel, users.NoEnvironment) { log.Printf("%s has insuficient permissions", ctx[ctxUser]) incMetric(metricAdminErr) return @@ -1043,7 +1050,7 @@ func usersGETHandler(w http.ResponseWriter, r *http.Request) { // Get context data ctx := r.Context().Value(contextKey("session")).(contextValue) // Check permissions - if !checkPermissions(ctx[ctxUser], false, false, false, "") { + if !adminUsers.CheckPermissions(ctx[ctxUser], users.AdminLevel, users.NoEnvironment) { log.Printf("%s has insuficient permissions", ctx[ctxUser]) incMetric(metricAdminErr) return @@ -1117,7 +1124,7 @@ func permissionsGETHandler(w http.ResponseWriter, r *http.Request) { // Get context data ctx := r.Context().Value(contextKey("session")).(contextValue) // Check permissions - if !checkPermissions(ctx[ctxUser], false, false, false, "") { + if !adminUsers.CheckPermissions(ctx[ctxUser], users.AdminLevel, users.NoEnvironment) { log.Printf("%s has insuficient permissions", ctx[ctxUser]) incMetric(metricAdminErr) return @@ -1141,7 +1148,7 @@ func carvesDownloadHandler(w http.ResponseWriter, r *http.Request) { // Get context data ctx := r.Context().Value(contextKey("session")).(contextValue) // Check permissions - if !checkPermissions(ctx[ctxUser], false, true, false, "") { + if !adminUsers.CheckPermissions(ctx[ctxUser], users.CarveLevel, users.NoEnvironment) { log.Printf("%s has insuficient permissions", ctx[ctxUser]) incMetric(metricAdminErr) return diff --git a/admin/handlers-post.go b/admin/handlers-post.go index 9ffd355b..81c768f1 100644 --- a/admin/handlers-post.go +++ b/admin/handlers-post.go @@ -101,7 +101,7 @@ func queryRunPOSTHandler(w http.ResponseWriter, r *http.Request) { // Get context data ctx := r.Context().Value(contextKey("session")).(contextValue) // Check permissions for query - if !checkPermissions(ctx[ctxUser], true, false, false, "") { + if !adminUsers.CheckPermissions(ctx[ctxUser], users.QueryLevel, users.NoEnvironment) { adminErrorResponse(w, fmt.Sprintf("%s has insuficient permissions", ctx[ctxUser]), http.StatusForbidden, nil) incMetric(metricAdminErr) return @@ -230,7 +230,7 @@ func carvesRunPOSTHandler(w http.ResponseWriter, r *http.Request) { // Get context data ctx := r.Context().Value(contextKey("session")).(contextValue) // Check permissions - if !checkPermissions(ctx[ctxUser], false, true, false, "") { + if !adminUsers.CheckPermissions(ctx[ctxUser], users.CarveLevel, users.NoEnvironment) { adminErrorResponse(w, fmt.Sprintf("%s has insuficient permissions", ctx[ctxUser]), http.StatusForbidden, nil) incMetric(metricAdminErr) return @@ -370,7 +370,7 @@ func queryActionsPOSTHandler(w http.ResponseWriter, r *http.Request) { // Get context data ctx := r.Context().Value(contextKey("session")).(contextValue) // Check permissions for query - if !checkPermissions(ctx[ctxUser], true, false, false, "") { + if !adminUsers.CheckPermissions(ctx[ctxUser], users.QueryLevel, users.NoEnvironment) { adminErrorResponse(w, fmt.Sprintf("%s has insuficient permissions", ctx[ctxUser]), http.StatusForbidden, nil) incMetric(metricAdminErr) return @@ -434,7 +434,7 @@ func carvesActionsPOSTHandler(w http.ResponseWriter, r *http.Request) { // Get context data ctx := r.Context().Value(contextKey("session")).(contextValue) // Check permissions - if !checkPermissions(ctx[ctxUser], false, true, false, "") { + if !adminUsers.CheckPermissions(ctx[ctxUser], users.CarveLevel, users.NoEnvironment) { adminErrorResponse(w, fmt.Sprintf("%s has insuficient permissions", ctx[ctxUser]), http.StatusForbidden, nil) incMetric(metricAdminErr) return @@ -493,7 +493,7 @@ func confPOSTHandler(w http.ResponseWriter, r *http.Request) { // Get context data ctx := r.Context().Value(contextKey("session")).(contextValue) // Check permissions - if !checkPermissions(ctx[ctxUser], false, false, true, environmentVar) { + if !adminUsers.CheckPermissions(ctx[ctxUser], users.EnvLevel, environmentVar) { adminErrorResponse(w, fmt.Sprintf("%s has insuficient permissions", ctx[ctxUser]), http.StatusForbidden, nil) incMetric(metricAdminErr) return @@ -559,7 +559,7 @@ func intervalsPOSTHandler(w http.ResponseWriter, r *http.Request) { // Get context data ctx := r.Context().Value(contextKey("session")).(contextValue) // Check permissions - if !checkPermissions(ctx[ctxUser], false, false, true, environmentVar) { + if !adminUsers.CheckPermissions(ctx[ctxUser], users.EnvLevel, environmentVar) { adminErrorResponse(w, fmt.Sprintf("%s has insuficient permissions", ctx[ctxUser]), http.StatusForbidden, nil) incMetric(metricAdminErr) return @@ -621,7 +621,7 @@ func expirationPOSTHandler(w http.ResponseWriter, r *http.Request) { // Get context data ctx := r.Context().Value(contextKey("session")).(contextValue) // Check permissions - if !checkPermissions(ctx[ctxUser], false, false, true, environmentVar) { + if !adminUsers.CheckPermissions(ctx[ctxUser], users.EnvLevel, environmentVar) { adminErrorResponse(w, fmt.Sprintf("%s has insuficient permissions", ctx[ctxUser]), http.StatusForbidden, nil) incMetric(metricAdminErr) return @@ -691,6 +691,12 @@ func nodeActionsPOSTHandler(w http.ResponseWriter, r *http.Request) { var m NodeMultiActionRequest // Get context data ctx := r.Context().Value(contextKey("session")).(contextValue) + // Check permissions + if !adminUsers.CheckPermissions(ctx[ctxUser], users.AdminLevel, users.NoEnvironment) { + 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") @@ -747,6 +753,12 @@ func envsPOSTHandler(w http.ResponseWriter, r *http.Request) { var c EnvironmentsRequest // Get context data ctx := r.Context().Value(contextKey("session")).(contextValue) + // Check permissions + if !adminUsers.CheckPermissions(ctx[ctxUser], users.AdminLevel, users.NoEnvironment) { + 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") @@ -843,7 +855,7 @@ func settingsPOSTHandler(w http.ResponseWriter, r *http.Request) { // Get context data ctx := r.Context().Value(contextKey("session")).(contextValue) // Check permissions - if !checkPermissions(ctx[ctxUser], false, false, false, "") { + if !adminUsers.CheckPermissions(ctx[ctxUser], users.AdminLevel, users.NoEnvironment) { adminErrorResponse(w, fmt.Sprintf("%s has insuficient permissions", ctx[ctxUser]), http.StatusForbidden, nil) incMetric(metricAdminErr) return @@ -929,7 +941,7 @@ func usersPOSTHandler(w http.ResponseWriter, r *http.Request) { // Get context data ctx := r.Context().Value(contextKey("session")).(contextValue) // Check permissions - if !checkPermissions(ctx[ctxUser], false, false, false, "") { + if !adminUsers.CheckPermissions(ctx[ctxUser], users.AdminLevel, users.NoEnvironment) { adminErrorResponse(w, fmt.Sprintf("%s has insuficient permissions", ctx[ctxUser]), http.StatusForbidden, nil) incMetric(metricAdminErr) return @@ -1091,7 +1103,7 @@ func permissionsPOSTHandler(w http.ResponseWriter, r *http.Request) { // Get context data ctx := r.Context().Value(contextKey("session")).(contextValue) // Check permissions - if !checkPermissions(ctx[ctxUser], false, false, false, "") { + if !adminUsers.CheckPermissions(ctx[ctxUser], users.AdminLevel, users.NoEnvironment) { adminErrorResponse(w, fmt.Sprintf("%s has insuficient permissions", ctx[ctxUser]), http.StatusForbidden, nil) incMetric(metricAdminErr) return @@ -1146,7 +1158,7 @@ func enrollPOSTHandler(w http.ResponseWriter, r *http.Request) { // Get context data ctx := r.Context().Value(contextKey("session")).(contextValue) // Check permissions - if !checkPermissions(ctx[ctxUser], false, false, true, environmentVar) { + if !adminUsers.CheckPermissions(ctx[ctxUser], users.EnvLevel, environmentVar) { adminErrorResponse(w, fmt.Sprintf("%s has insuficient permissions", ctx[ctxUser]), http.StatusForbidden, nil) incMetric(metricAdminErr) return diff --git a/admin/handlers-tokens.go b/admin/handlers-tokens.go index 8e98d45d..c9588787 100644 --- a/admin/handlers-tokens.go +++ b/admin/handlers-tokens.go @@ -8,6 +8,7 @@ import ( "github.com/gorilla/mux" "github.com/jmpsec/osctrl/settings" + "github.com/jmpsec/osctrl/users" "github.com/jmpsec/osctrl/utils" ) @@ -31,7 +32,7 @@ func tokensGETHandler(w http.ResponseWriter, r *http.Request) { // Get context data ctx := r.Context().Value(contextKey("session")).(contextValue) // Check permissions - if !checkPermissions(ctx[ctxUser], false, false, false, "") { + if !adminUsers.CheckPermissions(ctx[ctxUser], users.AdminLevel, users.NoEnvironment) { adminErrorResponse(w, fmt.Sprintf("%s has insuficient permissions", ctx[ctxUser]), http.StatusForbidden, nil) incMetric(metricAdminErr) return @@ -71,7 +72,7 @@ func tokensPOSTHandler(w http.ResponseWriter, r *http.Request) { // Get context data ctx := r.Context().Value(contextKey("session")).(contextValue) // Check permissions - if !checkPermissions(ctx[ctxUser], false, false, false, "") { + if !adminUsers.CheckPermissions(ctx[ctxUser], users.AdminLevel, users.NoEnvironment) { adminErrorResponse(w, "insuficient permissions", http.StatusForbidden, nil) incMetric(metricTokenErr) return diff --git a/admin/json-carves.go b/admin/json-carves.go index 7bf80ee8..811e0355 100644 --- a/admin/json-carves.go +++ b/admin/json-carves.go @@ -8,6 +8,7 @@ import ( "github.com/jmpsec/osctrl/carves" "github.com/jmpsec/osctrl/queries" "github.com/jmpsec/osctrl/settings" + "github.com/jmpsec/osctrl/users" "github.com/jmpsec/osctrl/utils" ) @@ -56,7 +57,7 @@ func jsonCarvesHandler(w http.ResponseWriter, r *http.Request) { // Get context data ctx := r.Context().Value(contextKey("session")).(contextValue) // Check permissions - if !checkPermissions(ctx[ctxUser], false, true, false, "") { + if !adminUsers.CheckPermissions(ctx[ctxUser], users.CarveLevel, users.NoEnvironment) { log.Printf("%s has insuficient permissions", ctx[ctxUser]) incMetric(metricJSONErr) return diff --git a/admin/json-logs.go b/admin/json-logs.go index 32dac4da..bd1f056b 100644 --- a/admin/json-logs.go +++ b/admin/json-logs.go @@ -7,6 +7,7 @@ import ( "github.com/gorilla/mux" "github.com/jmpsec/osctrl/settings" + "github.com/jmpsec/osctrl/users" "github.com/jmpsec/osctrl/utils" ) @@ -81,7 +82,7 @@ func jsonLogsHandler(w http.ResponseWriter, r *http.Request) { // Get context data ctx := r.Context().Value(contextKey("session")).(contextValue) // Check permissions - if !checkPermissions(ctx[ctxUser], false, false, true, env) { + if !adminUsers.CheckPermissions(ctx[ctxUser], users.EnvLevel, env) { log.Printf("%s has insuficient permissions", ctx[ctxUser]) incMetric(metricJSONErr) return @@ -161,7 +162,7 @@ func jsonQueryLogsHandler(w http.ResponseWriter, r *http.Request) { // Get context data ctx := r.Context().Value(contextKey("session")).(contextValue) // Check permissions - if !checkPermissions(ctx[ctxUser], true, false, false, "") { + if !adminUsers.CheckPermissions(ctx[ctxUser], users.QueryLevel, users.NoEnvironment) { log.Printf("%s has insuficient permissions", ctx[ctxUser]) incMetric(metricJSONErr) return diff --git a/admin/json-nodes.go b/admin/json-nodes.go index fd996ed0..e001c4f4 100644 --- a/admin/json-nodes.go +++ b/admin/json-nodes.go @@ -6,6 +6,7 @@ import ( "github.com/gorilla/mux" "github.com/jmpsec/osctrl/settings" + "github.com/jmpsec/osctrl/users" "github.com/jmpsec/osctrl/utils" ) @@ -54,6 +55,14 @@ func jsonEnvironmentHandler(w http.ResponseWriter, r *http.Request) { incMetric(metricJSONErr) return } + // Get context data + ctx := r.Context().Value(contextKey("session")).(contextValue) + // Check permissions + if !adminUsers.CheckPermissions(ctx[ctxUser], users.EnvLevel, env) { + log.Printf("%s has insuficient permissions", ctx[ctxUser]) + incMetric(metricJSONErr) + return + } // Extract target target, ok := vars["target"] if !ok { @@ -106,7 +115,7 @@ func jsonPlatformHandler(w http.ResponseWriter, r *http.Request) { // Get context data ctx := r.Context().Value(contextKey("session")).(contextValue) // Check permissions - if !checkPermissions(ctx[ctxUser], false, false, false, "") { + if !adminUsers.CheckPermissions(ctx[ctxUser], users.AdminLevel, users.NoEnvironment) { log.Printf("%s has insuficient permissions", ctx[ctxUser]) incMetric(metricJSONErr) return diff --git a/admin/json-queries.go b/admin/json-queries.go index e78dafee..598803c4 100644 --- a/admin/json-queries.go +++ b/admin/json-queries.go @@ -7,6 +7,7 @@ import ( "github.com/gorilla/mux" "github.com/jmpsec/osctrl/queries" "github.com/jmpsec/osctrl/settings" + "github.com/jmpsec/osctrl/users" "github.com/jmpsec/osctrl/utils" ) @@ -55,7 +56,7 @@ func jsonQueryHandler(w http.ResponseWriter, r *http.Request) { // Get context data ctx := r.Context().Value(contextKey("session")).(contextValue) // Check permissions - if !checkPermissions(ctx[ctxUser], true, false, false, "") { + if !adminUsers.CheckPermissions(ctx[ctxUser], users.QueryLevel, users.NoEnvironment) { log.Printf("%s has insuficient permissions", ctx[ctxUser]) incMetric(metricJSONErr) return diff --git a/admin/json-stats.go b/admin/json-stats.go index 95b95248..997d1a0c 100644 --- a/admin/json-stats.go +++ b/admin/json-stats.go @@ -7,6 +7,7 @@ import ( "github.com/gorilla/mux" "github.com/jmpsec/osctrl/nodes" "github.com/jmpsec/osctrl/settings" + "github.com/jmpsec/osctrl/users" "github.com/jmpsec/osctrl/utils" ) @@ -50,6 +51,12 @@ func jsonStatsHandler(w http.ResponseWriter, r *http.Request) { var stats nodes.StatsData var err error if target == "environment" { + // Check permissions + if !adminUsers.CheckPermissions(ctx[ctxUser], users.EnvLevel, name) { + log.Printf("%s has insuficient permissions", ctx[ctxUser]) + incMetric(metricJSONErr) + return + } stats, err = nodesmgr.GetStatsByEnv(name, settingsmgr.InactiveHours()) if err != nil { incMetric(metricAdminErr) @@ -58,7 +65,7 @@ func jsonStatsHandler(w http.ResponseWriter, r *http.Request) { } } else if target == "platform" { // Check permissions - if !checkPermissions(ctx[ctxUser], false, false, false, "") { + if !adminUsers.CheckPermissions(ctx[ctxUser], users.AdminLevel, users.NoEnvironment) { log.Printf("%s has insuficient permissions", ctx[ctxUser]) incMetric(metricJSONErr) return diff --git a/admin/sessions.go b/admin/sessions.go index 8e93caff..284f1acd 100644 --- a/admin/sessions.go +++ b/admin/sessions.go @@ -110,7 +110,7 @@ func (sm *SessionManager) GetByUsername(username string) ([]UserSession, error) } // New creates a session with name without adding it to the registry. -func (sm *SessionManager) New(r *http.Request, username string, admin bool) (UserSession, error) { +func (sm *SessionManager) New(r *http.Request, username, level string) (UserSession, error) { session := UserSession{ Username: username, IPAddress: r.Header.Get("X-Real-IP"), @@ -119,9 +119,9 @@ func (sm *SessionManager) New(r *http.Request, username string, admin bool) (Use } values := make(sessionValues) values["auth"] = true - values["admin"] = admin - values["username"] = username - values["csrftoken"] = generateCSRF() + values[ctxLevel] = level + values[ctxUser] = username + values[ctxCSRF] = generateCSRF() session.Values = values cookie, err := securecookie.EncodeMulti(defaultCookieName, session.Values, sm.Codecs...) if err != nil { @@ -156,14 +156,14 @@ func (sm *SessionManager) Destroy(r *http.Request) error { func (sm *SessionManager) Save(r *http.Request, w http.ResponseWriter, user users.AdminUser) (UserSession, error) { var s UserSession if cookie, err := r.Cookie(defaultCookieName); err != nil { - s, err = sm.New(r, user.Username, user.Admin) + s, err = sm.New(r, user.Username, levelPermissions(user)) if err != nil { return s, err } } else { s, err = sm.Get(cookie.Value) if err != nil { - s, err = sm.New(r, user.Username, user.Admin) + s, err = sm.New(r, user.Username, levelPermissions(user)) if err != nil { return s, err } diff --git a/admin/templates/components/page-aside-left.html b/admin/templates/components/page-aside-left.html index 5eb8507b..88ef3c80 100644 --- a/admin/templates/components/page-aside-left.html +++ b/admin/templates/components/page-aside-left.html @@ -229,7 +229,7 @@
  • - {{ if eq .Level "admin" }} + {{ if or (eq .Level "query") (eq .Level "admin") }}
  • - + {{end }} + {{ if or (eq .Level "carve") (eq .Level "admin") }}