فهرست منبع

setup middlleware permission checks

abhishek9686 1 سال پیش
والد
کامیت
e735024145
4فایلهای تغییر یافته به همراه112 افزوده شده و 17 حذف شده
  1. 0 1
      controllers/controller.go
  2. 78 0
      logic/security.go
  3. 5 0
      models/structs.go
  4. 29 16
      models/user_mgmt.go

+ 0 - 1
controllers/controller.go

@@ -40,7 +40,6 @@ func HandleRESTRequests(wg *sync.WaitGroup, ctx context.Context) {
 	defer wg.Done()
 
 	r := mux.NewRouter()
-
 	// Currently allowed dev origin is all. Should change in prod
 	// should consider analyzing the allowed methods further
 	headersOk := handlers.AllowedHeaders([]string{"Access-Control-Allow-Origin", "X-Requested-With", "Content-Type", "authorization", "From-Ui"})

+ 78 - 0
logic/security.go

@@ -1,6 +1,8 @@
 package logic
 
 import (
+	"errors"
+	"fmt"
 	"net/http"
 	"strings"
 
@@ -17,6 +19,82 @@ const (
 	Unauthorized_Err = models.Error(Unauthorized_Msg)
 )
 
+func networkPermissionsCheck(user models.User, r *http.Request) error {
+	// get info from header to determine the target rsrc
+	targetRsrc := r.Header.Get("TARGET_RSRC")
+	targetRsrcID := r.Header.Get("TARGET_RSRC_ID")
+	netID := r.Header.Get("NET_ID")
+	if targetRsrc == "" || targetRsrcID == "" {
+		return errors.New("target rsrc or rsrc id is missing")
+	}
+	if r.Method == "" {
+		r.Method = http.MethodGet
+	}
+	// check if user has scope for target resource
+	// TODO - differentitate between global scope and network scope apis
+	networkPermissionScope, ok := user.PermissionTemplate.DashBoardAcls.NetworkLevelAccess[models.NetworkID(netID)]
+	if !ok {
+		return errors.New("access denied")
+	}
+	if networkPermissionScope.FullAccess {
+		return nil
+	}
+	rsrcPermissionScope, ok := networkPermissionScope.NetworkRsrcPermissionsScope[models.RsrcType(targetRsrc)]
+	if !ok {
+		return fmt.Errorf("access denied to %s rsrc", targetRsrc)
+	}
+	if allRsrcsTypePermissionScope, ok := rsrcPermissionScope[models.RsrcID(fmt.Sprintf("all_%s", targetRsrc))]; ok {
+		return checkPermissionScopeWithReqMethod(allRsrcsTypePermissionScope, r.Method)
+
+	}
+	if scope, ok := rsrcPermissionScope[models.RsrcID(targetRsrcID)]; ok {
+		return checkPermissionScopeWithReqMethod(scope, r.Method)
+	}
+	return errors.New("access denied")
+}
+
+func globalPermissionsCheck(user models.User, r *http.Request) error {
+	targetRsrc := r.Header.Get("TARGET_RSRC")
+	targetRsrcID := r.Header.Get("TARGET_RSRC_ID")
+	if targetRsrc == "" || targetRsrcID == "" {
+		return errors.New("target rsrc or rsrc id is missing")
+	}
+	if r.Method == "" {
+		r.Method = http.MethodGet
+	}
+	if user.PermissionTemplate.DashBoardAcls.FullAccess {
+		return nil
+	}
+	rsrcPermissionScope, ok := user.PermissionTemplate.DashBoardAcls.GlobalLevelAccess[models.RsrcType(targetRsrc)]
+	if !ok {
+		return fmt.Errorf("access denied to %s rsrc", targetRsrc)
+	}
+	if allRsrcsTypePermissionScope, ok := rsrcPermissionScope[models.RsrcID(fmt.Sprintf("all_%s", targetRsrc))]; ok {
+		return checkPermissionScopeWithReqMethod(allRsrcsTypePermissionScope, r.Method)
+
+	}
+	if scope, ok := rsrcPermissionScope[models.RsrcID(targetRsrcID)]; ok {
+		return checkPermissionScopeWithReqMethod(scope, r.Method)
+	}
+	return errors.New("access denied")
+}
+
+func checkPermissionScopeWithReqMethod(scope models.RsrcPermissionScope, reqmethod string) error {
+	if reqmethod == http.MethodGet && scope.Read {
+		return nil
+	}
+	if (reqmethod == http.MethodPatch || reqmethod == http.MethodPut) && scope.Update {
+		return nil
+	}
+	if reqmethod == http.MethodDelete && scope.Delete {
+		return nil
+	}
+	if reqmethod == http.MethodPost && scope.Create {
+		return nil
+	}
+	return errors.New("operation not permitted")
+}
+
 // SecurityCheck - Check if user has appropriate permissions
 func SecurityCheck(reqAdmin bool, next http.Handler) http.HandlerFunc {
 

+ 5 - 0
models/structs.go

@@ -345,3 +345,8 @@ const (
 type GetClientConfReqDto struct {
 	PreferredIp string `json:"preferred_ip"`
 }
+
+type RsrcURLInfo struct {
+	Method string
+	Path   string
+}

+ 29 - 16
models/user_mgmt.go

@@ -7,18 +7,31 @@ import (
 )
 
 type NetworkID string
+type RsrcType string
 type RsrcID string
 type UserRole string
 
 const (
-	HostRsrcID           RsrcID = "all_host"
-	RelayRsrcID          RsrcID = "all_relay"
-	RemoteAccessGwRsrcID RsrcID = "all_remote_access_gw"
-	InetGwRsrcID         RsrcID = "all_inet_gw"
-	EgressGwRsrcID       RsrcID = "all_egress"
-	NetworkRsrcID        RsrcID = "all_network"
-	EnrollmentKeysRsrcID RsrcID = "all_enrollment_key"
-	UserRsrcID           RsrcID = "all_user"
+	HostRsrc           RsrcType = "host"
+	RelayRsrc          RsrcType = "relay"
+	RemoteAccessGwRsrc RsrcType = "remote_access_gw"
+	InetGwRsrc         RsrcType = "inet_gw"
+	EgressGwRsrc       RsrcType = "egress"
+	NetworkRsrc        RsrcType = "networks"
+	EnrollmentKeysRsrc RsrcType = "enrollment_key"
+	UserRsrc           RsrcType = "user"
+	AclRsrc            RsrcType = "acl"
+)
+
+const (
+	AllHostRsrcID           RsrcID = "all_host"
+	AllRelayRsrcID          RsrcID = "all_relay"
+	AllRemoteAccessGwRsrcID RsrcID = "all_remote_access_gw"
+	AllInetGwRsrcID         RsrcID = "all_inet_gw"
+	AllEgressGwRsrcID       RsrcID = "all_egress"
+	AllNetworkRsrcID        RsrcID = "all_network"
+	AllEnrollmentKeysRsrcID RsrcID = "all_enrollment_key"
+	AllUserRsrcID           RsrcID = "all_user"
 )
 
 // Pre-Defined User Roles
@@ -34,7 +47,7 @@ func (r UserRole) String() string {
 	return string(r)
 }
 
-type RsrcPermissions struct {
+type RsrcPermissionScope struct {
 	Create bool `json:"create"`
 	Read   bool `json:"read"`
 	Update bool `json:"update"`
@@ -42,16 +55,16 @@ type RsrcPermissions struct {
 }
 
 type NetworkAccessControls struct {
-	NetworkID                  string                     `json:"network_id"`
-	FullAccess                 bool                       `json:"full_access"`
-	NetworkRsrcPermissionsList map[RsrcID]RsrcPermissions `json:"network_permissions_list"`
+	NetworkID                   string                                      `json:"network_id"`
+	FullAccess                  bool                                        `json:"full_access"`
+	NetworkRsrcPermissionsScope map[RsrcType]map[RsrcID]RsrcPermissionScope `json:"network_permissions_list"`
 }
 
 type DashboardAccessControls struct {
-	FullAccess          bool                                `json:"full_access"`
-	DenyDashboardAccess bool                                `json:"deny_dashboard_access"`
-	NetworkLevelAccess  map[NetworkID]NetworkAccessControls `json:"network_access_controls"`
-	GlobalLevelAccess   map[RsrcID]RsrcPermissions          `json:"global_level_access"`
+	FullAccess          bool                                        `json:"full_access"`
+	DenyDashboardAccess bool                                        `json:"deny_dashboard_access"`
+	NetworkLevelAccess  map[NetworkID]NetworkAccessControls         `json:"network_access_controls"`
+	GlobalLevelAccess   map[RsrcType]map[RsrcID]RsrcPermissionScope `json:"global_level_access"`
 }
 
 type UserRolePermissionTemplate struct {