Forráskód Böngészése

validate user groups, add check for metrics api in middleware

abhishek9686 1 éve
szülő
commit
3371c822d0
4 módosított fájl, 47 hozzáadás és 6 törlés
  1. 6 2
      controllers/middleware.go
  2. 17 1
      logic/security.go
  3. 22 3
      logic/user_mgmt.go
  4. 2 0
      models/user_mgmt.go

+ 6 - 2
controllers/middleware.go

@@ -11,6 +11,7 @@ import (
 func userMiddleWare(handler http.Handler) http.Handler {
 	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 		var params = mux.Vars(r)
+		r.Header.Set("IS_GLOBAL_ACCESS", "no")
 		r.Header.Set("NET_ID", params["network"])
 		if strings.Contains(r.URL.Path, "hosts") || strings.Contains(r.URL.Path, "nodes") {
 			r.Header.Set("TARGET_RSRC", models.HostRsrc.String())
@@ -46,6 +47,9 @@ func userMiddleWare(handler http.Handler) http.Handler {
 			r.Header.Set("TARGET_RSRC", models.EnrollmentKeysRsrc.String())
 			r.Header.Set("RSRC_TYPE", models.EnrollmentKeysRsrc.String())
 		}
+		if strings.Contains(r.URL.Path, "metrics") {
+			r.Header.Set("RSRC_TYPE", models.MetricRsrc.String())
+		}
 		if keyID, ok := params["keyID"]; ok {
 			r.Header.Set("TARGET_RSRC_ID", keyID)
 		}
@@ -68,9 +72,9 @@ func userMiddleWare(handler http.Handler) http.Handler {
 		if userID, ok := params["username"]; ok {
 			r.Header.Set("TARGET_RSRC_ID", userID)
 		}
-		if r.Header.Get("TARGET_RSRC_ID") == "" ||
+		if r.Header.Get("NET_ID") == "" && (r.Header.Get("TARGET_RSRC_ID") == "" ||
 			r.Header.Get("TARGET_RSRC") == models.EnrollmentKeysRsrc.String() ||
-			r.Header.Get("TARGET_RSRC") == models.UserRsrc.String() {
+			r.Header.Get("TARGET_RSRC") == models.UserRsrc.String()) {
 			r.Header.Set("IS_GLOBAL_ACCESS", "yes")
 		}
 		handler.ServeHTTP(w, r)

+ 17 - 1
logic/security.go

@@ -34,6 +34,13 @@ func networkPermissionsCheck(username string, r *http.Request) error {
 	if err != nil {
 		return err
 	}
+	userRole, err := GetRole(user.PlatformRoleID)
+	if err != nil {
+		return errors.New("access denied")
+	}
+	if userRole.FullAccess {
+		return nil
+	}
 	// get info from header to determine the target rsrc
 	targetRsrc := r.Header.Get("TARGET_RSRC")
 	targetRsrcID := r.Header.Get("TARGET_RSRC_ID")
@@ -47,6 +54,9 @@ func networkPermissionsCheck(username string, r *http.Request) error {
 	if r.Method == "" {
 		r.Method = http.MethodGet
 	}
+	if targetRsrc == models.MetricRsrc.String() {
+		return nil
+	}
 	// check if user has scope for target resource
 	// TODO - differentitate between global scope and network scope apis
 	netRoles := user.NetworkRoles[models.NetworkID(netID)]
@@ -123,6 +133,12 @@ func globalPermissionsCheck(username string, r *http.Request) error {
 	if r.Method == "" {
 		r.Method = http.MethodGet
 	}
+	if targetRsrc == models.MetricRsrc.String() {
+		return nil
+	}
+	if targetRsrc == models.UserRsrc.String() && username == targetRsrcID && (r.Method != http.MethodDelete) {
+		return nil
+	}
 	rsrcPermissionScope, ok := userRole.GlobalLevelAccess[models.RsrcType(targetRsrc)]
 	if !ok {
 		return fmt.Errorf("access denied to %s rsrc", targetRsrc)
@@ -161,8 +177,8 @@ func SecurityCheck(reqAdmin bool, next http.Handler) http.HandlerFunc {
 
 	return func(w http.ResponseWriter, r *http.Request) {
 		r.Header.Set("ismaster", "no")
-		bearerToken := r.Header.Get("Authorization")
 		isGlobalAccesss := r.Header.Get("IS_GLOBAL_ACCESS") == "yes"
+		bearerToken := r.Header.Get("Authorization")
 		username, err := GetUserNameFromToken(bearerToken)
 		if err != nil {
 			ReturnErrorResponse(w, r, FormatError(err, err.Error()))

+ 22 - 3
logic/user_mgmt.go

@@ -235,22 +235,38 @@ func DeleteRole(rid models.UserRole) error {
 
 func ValidateCreateGroupReq(g models.UserGroup) error {
 	// check platform role is valid
-	_, err := GetRole(g.PlatformRole)
+	role, err := GetRole(g.PlatformRole)
 	if err != nil {
 		err = fmt.Errorf("invalid platform role")
 		return err
 	}
+	if role.NetworkID != "" {
+		return errors.New("network role cannot be used as platform role")
+	}
 	// check if network roles are valid
-
+	for _, roleMap := range g.NetworkRoles {
+		for roleID := range roleMap {
+			role, err := GetRole(roleID)
+			if err != nil {
+				return fmt.Errorf("invalid network role %s", roleID)
+			}
+			if role.NetworkID == "" {
+				return errors.New("platform role cannot be used as network role")
+			}
+		}
+	}
 	return nil
 }
 func ValidateUpdateGroupReq(g models.UserGroup) error {
 	// check platform role is valid
-	_, err := GetRole(g.PlatformRole)
+	role, err := GetRole(g.PlatformRole)
 	if err != nil {
 		err = fmt.Errorf("invalid platform role")
 		return err
 	}
+	if role.NetworkID != "" {
+		return errors.New("network role cannot be used as platform role")
+	}
 	for networkID := range g.NetworkRoles {
 		userRolesMap := g.NetworkRoles[networkID]
 		for roleID := range userRolesMap {
@@ -259,6 +275,9 @@ func ValidateUpdateGroupReq(g models.UserGroup) error {
 				err = fmt.Errorf("invalid network role")
 				return err
 			}
+			if role.NetworkID == "" {
+				return errors.New("platform role cannot be used as network role")
+			}
 		}
 	}
 	return nil

+ 2 - 0
models/user_mgmt.go

@@ -48,6 +48,7 @@ const (
 	AclRsrc            RsrcType = "acl"
 	DnsRsrc            RsrcType = "dns"
 	FailOverRsrc       RsrcType = "fail_over"
+	MetricRsrc         RsrcType = "metrics"
 )
 
 const (
@@ -90,6 +91,7 @@ type RsrcPermissionScope struct {
 	Update    bool `json:"update"`
 	Delete    bool `json:"delete"`
 	VPNaccess bool `json:"vpn_access"`
+	SelfOnly  bool `json:"self_only"`
 }
 
 type UserRolePermissionTemplate struct {