Skip to content

Commit

Permalink
Merge pull request #53 from jmpsec/permissions-templates
Browse files Browse the repository at this point in the history
Permissions in templates and refactor
  • Loading branch information
javuto authored Mar 20, 2020
2 parents c957573 + 2ed5dd7 commit 71b9445
Show file tree
Hide file tree
Showing 12 changed files with 139 additions and 114 deletions.
87 changes: 25 additions & 62 deletions admin/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"context"
"log"
"net/http"
"strconv"
"strings"

"github.com/jmpsec/osctrl/settings"
Expand All @@ -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
Expand All @@ -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"])
Expand Down Expand Up @@ -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"])
Expand All @@ -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)
Expand All @@ -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
}
55 changes: 31 additions & 24 deletions admin/handlers-get.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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 {
Expand All @@ -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,
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down
Loading

0 comments on commit 71b9445

Please sign in to comment.