Skip to content
63 changes: 55 additions & 8 deletions api/cluster/ClusterRestHandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"github.com/devtron-labs/devtron/pkg/cluster/rbac"
"net/http"
"strconv"
"strings"
"time"

"github.com/devtron-labs/devtron/pkg/auth/authorisation/casbin"
Expand Down Expand Up @@ -377,7 +378,7 @@ func (impl ClusterRestHandlerImpl) FindNoteByClusterId(w http.ResponseWriter, r
}
// RBAC enforcer applying
token := r.Header.Get("token")
authenticated, err := impl.clusterRbacService.CheckAuthorization(bean.ClusterName, bean.ClusterId, token, userId, false)
authenticated, err := impl.clusterRbacService.CheckAuthorization(bean.ClusterName, bean.ClusterId, token, userId, true)
if err != nil {
impl.logger.Errorw("error in checking rbac for cluster", "err", err, "clusterId", bean.ClusterId)
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
Expand Down Expand Up @@ -477,7 +478,8 @@ func (impl ClusterRestHandlerImpl) UpdateClusterDescription(w http.ResponseWrite
return
}
// RBAC enforcer applying
if ok := impl.enforcer.Enforce(token, casbin.ResourceCluster, casbin.ActionUpdate, clusterDescription.ClusterName); !ok {
authenticated := impl.clusterRbacService.CheckAuthorisationForAllK8sPermissions(token, clusterDescription.ClusterName, casbin.ActionUpdate)
if !authenticated {
common.WriteJsonResp(w, errors.New("unauthorized"), nil, http.StatusForbidden)
return
}
Expand Down Expand Up @@ -521,7 +523,8 @@ func (impl ClusterRestHandlerImpl) UpdateClusterNote(w http.ResponseWriter, r *h
return
}
// RBAC enforcer applying
if ok := impl.enforcer.Enforce(token, casbin.ResourceCluster, casbin.ActionUpdate, clusterDescription.ClusterName); !ok {
authenticated := impl.clusterRbacService.CheckAuthorisationForAllK8sPermissions(token, clusterDescription.ClusterName, casbin.ActionUpdate)
if !authenticated {
common.WriteJsonResp(w, errors.New("unauthorized"), nil, http.StatusForbidden)
return
}
Expand Down Expand Up @@ -622,17 +625,61 @@ func (impl ClusterRestHandlerImpl) DeleteCluster(w http.ResponseWriter, r *http.

func (impl ClusterRestHandlerImpl) GetAllClusterNamespaces(w http.ResponseWriter, r *http.Request) {
token := r.Header.Get("token")
userId, err := impl.userService.GetLoggedInUser(r)
if userId == 0 || err != nil {
impl.logger.Errorw("err, GetAllClusterNamespaces", "error", err, "userId", userId)
common.WriteJsonResp(w, err, "Unauthorized User", http.StatusUnauthorized)
return
}
clusterNamespaces := impl.clusterService.GetAllClusterNamespaces()

// RBAC enforcer applying
for clusterName, _ := range clusterNamespaces {
if ok := impl.enforcer.Enforce(token, casbin.ResourceCluster, casbin.ActionGet, clusterName); !ok {
delete(clusterNamespaces, clusterName)
}
filteredClusterNamespaces, err := impl.HandleRbacForClusterNamespace(userId, token, clusterNamespaces)
if err != nil {
impl.logger.Errorw("error in GetAllClusterNamespaces", "err", err)
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
return
}
//RBAC enforcer Ends

common.WriteJsonResp(w, nil, clusterNamespaces, http.StatusOK)
common.WriteJsonResp(w, nil, filteredClusterNamespaces, http.StatusOK)
}

func (impl ClusterRestHandlerImpl) HandleRbacForClusterNamespace(userId int32, token string, clusterNamespaces map[string][]string) (map[string][]string, error) {
filteredClusterNamespaces := make(map[string][]string)
if ok := impl.enforcer.Enforce(token, casbin.ResourceGlobal, casbin.ActionGet, "*"); ok {
return clusterNamespaces, nil
}
roles, err := impl.clusterService.FetchRolesFromGroup(userId)
if err != nil {
impl.logger.Errorw("error on fetching user roles for cluster list", "err", err)
return nil, err
}

clusterAndNameSpaceVsAllowedMap := make(map[string]bool, len(roles))
clusterNameVsAllAllowedMap := make(map[string]bool, len(roles))
for _, role := range roles {
clusterAndNameSpaceVsAllowedMap[strings.ToLower(role.Cluster+"_"+role.Namespace)] = true
if role.Namespace == "" {
clusterNameVsAllAllowedMap[role.Cluster] = true
} else {
clusterNameVsAllAllowedMap[role.Cluster] = false
}
}

for clusterName, allNamespaces := range clusterNamespaces {
if val, exist := clusterNameVsAllAllowedMap[clusterName]; val {
filteredClusterNamespaces[clusterName] = allNamespaces
} else if exist {
for _, namespace := range allNamespaces {
if val2, exist2 := clusterAndNameSpaceVsAllowedMap[strings.ToLower(clusterName+"_"+namespace)]; exist2 && val2 {
filteredClusterNamespaces[clusterName] = append(filteredClusterNamespaces[clusterName], namespace)
}
}
}
}
return filteredClusterNamespaces, nil

}

func (impl ClusterRestHandlerImpl) GetClusterNamespaces(w http.ResponseWriter, r *http.Request) {
Expand Down
3 changes: 2 additions & 1 deletion api/k8s/application/k8sApplicationRestHandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -816,7 +816,8 @@ func (handler *K8sApplicationRestHandlerImpl) GetTerminalSession(w http.Response

} else if resourceRequestBean.AppIdentifier == nil && resourceRequestBean.DevtronAppIdentifier == nil && resourceRequestBean.ExternalFluxAppIdentifier == nil && resourceRequestBean.ExternalArgoApplicationName == "" && resourceRequestBean.ClusterId > 0 {
//RBAC enforcer applying for Resource Browser
if !handler.handleRbac(r, w, *resourceRequestBean, token, casbin.ActionUpdate) {
resource, object := handler.enforcerUtil.GetRbacResourceAndObjectForNodeByClusterId(resourceRequestBean.ClusterId, bean2.ALL)
if !(handler.enforcer.Enforce(token, resource, casbin.ActionUpdate, object) || handler.handleRbac(r, w, *resourceRequestBean, token, casbin.ActionUpdate)) {
return
}
//RBAC enforcer Ends
Expand Down
56 changes: 38 additions & 18 deletions api/k8s/capacity/k8sCapacityRestHandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ func (handler *K8sCapacityRestHandlerImpl) GetClusterDetail(w http.ResponseWrite
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
return
}
authenticated, err := handler.clusterRbacService.CheckAuthorization(cluster.ClusterName, cluster.Id, token, userId, false)
authenticated, err := handler.clusterRbacService.CheckAuthorization(cluster.ClusterName, cluster.Id, token, userId, true)
if err != nil {
handler.logger.Errorw("error in checking rbac for cluster", "err", err, "clusterId", clusterId)
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
Expand Down Expand Up @@ -219,12 +219,7 @@ func (handler *K8sCapacityRestHandlerImpl) GetNodeList(w http.ResponseWriter, r
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
return
}
authenticated, err := handler.clusterRbacService.CheckAuthorization(cluster.ClusterName, cluster.Id, token, userId, false)
if err != nil {
handler.logger.Errorw("error in checking rbac for cluster", "err", err, "clusterId", clusterId)
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
return
}
authenticated := handler.clusterRbacService.CheckAuthorisationForNode(token, cluster.ClusterName, "", casbin.ActionGet)
if !authenticated {
common.WriteJsonResp(w, errors.New("unauthorized"), nil, http.StatusForbidden)
return
Expand Down Expand Up @@ -265,12 +260,7 @@ func (handler *K8sCapacityRestHandlerImpl) GetNodeDetail(w http.ResponseWriter,
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
return
}
authenticated, err := handler.clusterRbacService.CheckAuthorization(cluster.ClusterName, cluster.Id, token, userId, false)
if err != nil {
handler.logger.Errorw("error in checking rbac for cluster", "err", err, "clusterId", clusterId)
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
return
}
authenticated := handler.clusterRbacService.CheckAuthorisationForNode(token, cluster.ClusterName, name, casbin.ActionGet)
if !authenticated {
common.WriteJsonResp(w, errors.New("unauthorized"), nil, http.StatusForbidden)
return
Expand Down Expand Up @@ -300,7 +290,13 @@ func (handler *K8sCapacityRestHandlerImpl) UpdateNodeManifest(w http.ResponseWri
}
// RBAC enforcer applying
token := r.Header.Get("token")
if ok := handler.enforcer.Enforce(token, casbin.ResourceGlobal, casbin.ActionUpdate, "*"); !ok {
authenticated, err := handler.clusterRbacService.CheckAuthorisationForNodeWithClusterId(token, manifestUpdateReq.ClusterId, manifestUpdateReq.Name, casbin.ActionUpdate)
if err != nil {
handler.logger.Errorw("error in checking rbac for cluster", "err", err, "clusterId", manifestUpdateReq.ClusterId)
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
return
}
if !authenticated {
common.WriteJsonResp(w, errors.New("unauthorized"), nil, http.StatusForbidden)
return
}
Expand Down Expand Up @@ -329,7 +325,13 @@ func (handler *K8sCapacityRestHandlerImpl) DeleteNode(w http.ResponseWriter, r *
}
// RBAC enforcer applying
token := r.Header.Get("token")
if ok := handler.enforcer.Enforce(token, casbin.ResourceGlobal, casbin.ActionDelete, "*"); !ok {
authenticated, err := handler.clusterRbacService.CheckAuthorisationForNodeWithClusterId(token, nodeDelReq.ClusterId, nodeDelReq.Name, casbin.ActionDelete)
if err != nil {
handler.logger.Errorw("error in checking rbac for cluster", "err", err, "clusterId", nodeDelReq.ClusterId)
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
return
}
if !authenticated {
common.WriteJsonResp(w, errors.New("unauthorized"), nil, http.StatusForbidden)
return
}
Expand Down Expand Up @@ -367,7 +369,13 @@ func (handler *K8sCapacityRestHandlerImpl) CordonOrUnCordonNode(w http.ResponseW
}
// RBAC enforcer applying
token := r.Header.Get("token")
if ok := handler.enforcer.Enforce(token, casbin.ResourceGlobal, casbin.ActionUpdate, "*"); !ok {
authenticated, err := handler.clusterRbacService.CheckAuthorisationForNodeWithClusterId(token, nodeCordonReq.ClusterId, nodeCordonReq.Name, casbin.ActionUpdate)
if err != nil {
handler.logger.Errorw("error in checking rbac for cluster", "err", err, "clusterId", nodeCordonReq.ClusterId)
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
return
}
if !authenticated {
common.WriteJsonResp(w, errors.New("unauthorized"), nil, http.StatusForbidden)
return
}
Expand Down Expand Up @@ -396,7 +404,13 @@ func (handler *K8sCapacityRestHandlerImpl) DrainNode(w http.ResponseWriter, r *h
}
// RBAC enforcer applying
token := r.Header.Get("token")
if ok := handler.enforcer.Enforce(token, casbin.ResourceGlobal, casbin.ActionUpdate, "*"); !ok {
authenticated, err := handler.clusterRbacService.CheckAuthorisationForNodeWithClusterId(token, nodeDrainReq.ClusterId, nodeDrainReq.Name, casbin.ActionUpdate)
if err != nil {
handler.logger.Errorw("error in checking rbac for cluster", "err", err, "clusterId", nodeDrainReq.ClusterId)
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
return
}
if !authenticated {
common.WriteJsonResp(w, errors.New("unauthorized"), nil, http.StatusForbidden)
return
}
Expand Down Expand Up @@ -425,7 +439,13 @@ func (handler *K8sCapacityRestHandlerImpl) EditNodeTaints(w http.ResponseWriter,
}
// RBAC enforcer applying
token := r.Header.Get("token")
if ok := handler.enforcer.Enforce(token, casbin.ResourceGlobal, casbin.ActionUpdate, "*"); !ok {
authenticated, err := handler.clusterRbacService.CheckAuthorisationForNodeWithClusterId(token, nodeTaintReq.ClusterId, nodeTaintReq.Name, casbin.ActionUpdate)
if err != nil {
handler.logger.Errorw("error in checking rbac for cluster", "err", err, "clusterId", nodeTaintReq.ClusterId)
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
return
}
if !authenticated {
common.WriteJsonResp(w, errors.New("unauthorized"), nil, http.StatusForbidden)
return
}
Expand Down
Loading
Loading