mirror of
https://github.com/gravitl/netmaker.git
synced 2024-09-20 15:26:04 +08:00
196 lines
5.8 KiB
Go
196 lines
5.8 KiB
Go
package logic
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"net/http"
|
|
|
|
"github.com/gravitl/netmaker/logger"
|
|
"github.com/gravitl/netmaker/logic"
|
|
"github.com/gravitl/netmaker/models"
|
|
)
|
|
|
|
func NetworkPermissionsCheck(username string, r *http.Request) error {
|
|
// at this point global checks should be completed
|
|
user, err := logic.GetUser(username)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
logger.Log(0, "NET MIDDL----> 1")
|
|
userRole, err := logic.GetRole(user.PlatformRoleID)
|
|
if err != nil {
|
|
return errors.New("access denied")
|
|
}
|
|
if userRole.FullAccess {
|
|
return nil
|
|
}
|
|
logger.Log(0, "NET MIDDL----> 2")
|
|
// 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 == "" {
|
|
return errors.New("target rsrc is missing")
|
|
}
|
|
if netID == "" {
|
|
return errors.New("network id is missing")
|
|
}
|
|
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
|
|
// check for global network role
|
|
if netRoles, ok := user.NetworkRoles[models.AllNetworks]; ok {
|
|
for netRoleID := range netRoles {
|
|
err = checkNetworkAccessPermissions(netRoleID, username, r.Method, targetRsrc, targetRsrcID, netID)
|
|
if err == nil {
|
|
return nil
|
|
}
|
|
}
|
|
}
|
|
netRoles := user.NetworkRoles[models.NetworkID(netID)]
|
|
for netRoleID := range netRoles {
|
|
err = checkNetworkAccessPermissions(netRoleID, username, r.Method, targetRsrc, targetRsrcID, netID)
|
|
if err == nil {
|
|
return nil
|
|
}
|
|
}
|
|
for groupID := range user.UserGroups {
|
|
userG, err := GetUserGroup(groupID)
|
|
if err == nil {
|
|
netRoles := userG.NetworkRoles[models.NetworkID(netID)]
|
|
for netRoleID := range netRoles {
|
|
err = checkNetworkAccessPermissions(netRoleID, username, r.Method, targetRsrc, targetRsrcID, netID)
|
|
if err == nil {
|
|
return nil
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return errors.New("access denied")
|
|
}
|
|
|
|
func checkNetworkAccessPermissions(netRoleID models.UserRoleID, username, reqScope, targetRsrc, targetRsrcID, netID string) error {
|
|
networkPermissionScope, err := logic.GetRole(netRoleID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
logger.Log(0, "NET MIDDL----> 3", string(netRoleID))
|
|
if networkPermissionScope.FullAccess {
|
|
return nil
|
|
}
|
|
rsrcPermissionScope, ok := networkPermissionScope.NetworkLevelAccess[models.RsrcType(targetRsrc)]
|
|
if targetRsrc == models.HostRsrc.String() && !ok {
|
|
rsrcPermissionScope, ok = networkPermissionScope.NetworkLevelAccess[models.RemoteAccessGwRsrc]
|
|
}
|
|
if !ok {
|
|
return errors.New("access denied")
|
|
}
|
|
logger.Log(0, "NET MIDDL----> 4", string(netRoleID))
|
|
if allRsrcsTypePermissionScope, ok := rsrcPermissionScope[models.RsrcID(fmt.Sprintf("all_%s", targetRsrc))]; ok {
|
|
// handle extclient apis here
|
|
if models.RsrcType(targetRsrc) == models.ExtClientsRsrc && allRsrcsTypePermissionScope.SelfOnly && targetRsrcID != "" {
|
|
extclient, err := logic.GetExtClient(targetRsrcID, netID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if !logic.IsUserAllowedAccessToExtClient(username, extclient) {
|
|
return errors.New("access denied")
|
|
}
|
|
}
|
|
err = checkPermissionScopeWithReqMethod(allRsrcsTypePermissionScope, reqScope)
|
|
if err == nil {
|
|
return nil
|
|
}
|
|
|
|
}
|
|
if targetRsrc == models.HostRsrc.String() {
|
|
if allRsrcsTypePermissionScope, ok := rsrcPermissionScope[models.RsrcID(fmt.Sprintf("all_%s", models.RemoteAccessGwRsrc))]; ok {
|
|
err = checkPermissionScopeWithReqMethod(allRsrcsTypePermissionScope, reqScope)
|
|
if err == nil {
|
|
return nil
|
|
}
|
|
}
|
|
}
|
|
logger.Log(0, "NET MIDDL----> 5", string(netRoleID))
|
|
if targetRsrcID == "" {
|
|
return errors.New("target rsrc id is empty")
|
|
}
|
|
if scope, ok := rsrcPermissionScope[models.RsrcID(targetRsrcID)]; ok {
|
|
err = checkPermissionScopeWithReqMethod(scope, reqScope)
|
|
if err == nil {
|
|
return nil
|
|
}
|
|
}
|
|
logger.Log(0, "NET MIDDL----> 6", string(netRoleID))
|
|
return errors.New("access denied")
|
|
}
|
|
|
|
func GlobalPermissionsCheck(username string, r *http.Request) error {
|
|
user, err := logic.GetUser(username)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
userRole, err := logic.GetRole(user.PlatformRoleID)
|
|
if err != nil {
|
|
return errors.New("access denied")
|
|
}
|
|
if userRole.FullAccess {
|
|
return nil
|
|
}
|
|
targetRsrc := r.Header.Get("TARGET_RSRC")
|
|
targetRsrcID := r.Header.Get("TARGET_RSRC_ID")
|
|
if targetRsrc == "" {
|
|
return errors.New("target rsrc is missing")
|
|
}
|
|
if r.Method == "" {
|
|
r.Method = http.MethodGet
|
|
}
|
|
if targetRsrc == models.MetricRsrc.String() {
|
|
return nil
|
|
}
|
|
if (targetRsrc == models.HostRsrc.String() || targetRsrc == models.NetworkRsrc.String()) && r.Method == http.MethodGet && targetRsrcID == "" {
|
|
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)
|
|
}
|
|
if allRsrcsTypePermissionScope, ok := rsrcPermissionScope[models.RsrcID(fmt.Sprintf("all_%s", targetRsrc))]; ok {
|
|
return checkPermissionScopeWithReqMethod(allRsrcsTypePermissionScope, r.Method)
|
|
|
|
}
|
|
if targetRsrcID == "" {
|
|
return errors.New("target rsrc id is missing")
|
|
}
|
|
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")
|
|
}
|