Repository: arenadata/adcm (language: python)

Issue:
ADCM-992 on load new bundle search license hash in all bundles, despite the name

ADCM-2700 fix reapply for object policy



Discussion / hints:

Fix patch:
diff --git a/python/api/action/views.py b/python/api/action/views.py
index b53d7057c6..6a19c38bce 100644
--- a/python/api/action/views.py
+++ b/python/api/action/views.py
@@ -10,21 +10,21 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+from django.contrib.contenttypes.models import ContentType
 from guardian.mixins import PermissionListMixin
 from rest_framework import permissions
 from rest_framework.response import Response
 
+from api.base_view import GenericUIView
+from api.job.serializers import RunTaskSerializer
 from api.utils import (
     ActionFilter,
     AdcmFilterBackend,
     create,
-    check_obj,
     filter_actions,
     permission_denied,
+    get_object_for_user,
 )
-from api.base_view import GenericUIView
-from api.job.serializers import RunTaskSerializer
-
 from cm.job import get_host_object
 from cm.models import (
     Host,
@@ -33,6 +33,7 @@
     HostComponent,
     get_model_by_type,
 )
+from rbac.viewsets import DjangoOnlyObjectPermissions
 from . import serializers
 
 
@@ -57,7 +58,6 @@ class ActionList(PermissionListMixin, GenericUIView):
     filterset_class = ActionFilter
     filterset_fields = ('name', 'button', 'button_is_null')
     filter_backends = (AdcmFilterBackend,)
-    permission_classes = (permissions.IsAuthenticated,)
     permission_required = ['cm.view_action']
 
     def get(self, request, *args, **kwargs):  # pylint: disable=too-many-locals
@@ -117,17 +117,25 @@ def get(self, request, *args, **kwargs):  # pylint: disable=too-many-locals
         return Response(serializer.data)
 
 
-class ActionDetail(GenericUIView):
+class ActionDetail(PermissionListMixin, GenericUIView):
     queryset = Action.objects.all()
     serializer_class = serializers.ActionDetailSerializer
     serializer_class_ui = serializers.ActionUISerializer
+    permission_classes = (DjangoOnlyObjectPermissions,)
+    permission_required = ['cm.view_action']
 
     def get(self, request, *args, **kwargs):
         """
         Show specified action
         """
-        obj, action_id = get_obj(**kwargs)
-        action = check_obj(Action, {'id': action_id}, 'ACTION_NOT_FOUND')
+        object_type, object_id, action_id = get_object_type_id(**kwargs)
+        model = get_model_by_type(object_type)
+        ct = ContentType.objects.get_for_model(model)
+        obj = get_object_for_user(
+            request.user, f'{ct.app_label}.view_{ct.model}', model, id=object_id
+        )
+        # TODO: we can access not only the actions of this object
+        action = get_object_for_user(request.user, 'cm.view_action', Action, id=action_id)
         if isinstance(obj, Host) and action.host_action:
             objects = {'host': obj}
         else:
@@ -162,8 +170,13 @@ def post(self, request, *args, **kwargs):
         """
         Ran specified action
         """
-        obj, action_id = get_obj(**kwargs)
-        action = check_obj(Action, {'id': action_id}, 'ACTION_NOT_FOUND')
+        object_type, object_id, action_id = get_object_type_id(**kwargs)
+        model = get_model_by_type(object_type)
+        ct = ContentType.objects.get_for_model(model)
+        obj = get_object_for_user(
+            request.user, f'{ct.app_label}.view_{ct.model}', model, id=object_id
+        )
+        action = get_object_for_user(request.user, 'cm.view_action', Action, id=action_id)
         self.check_action_perm(action, obj)
         serializer = self.get_serializer(data=request.data)
         return create(serializer, action=action, task_object=obj)
diff --git a/python/api/base_view.py b/python/api/base_view.py
index 56ce8dd27a..dab12ed5e3 100644
--- a/python/api/base_view.py
+++ b/python/api/base_view.py
@@ -16,15 +16,14 @@
 from django.core.exceptions import ObjectDoesNotExist, FieldError
 from rest_framework import serializers
 from rest_framework.generics import GenericAPIView
+from rest_framework.permissions import SAFE_METHODS, DjangoModelPermissions, DjangoObjectPermissions
 from rest_framework.response import Response
 from rest_framework.utils.urls import replace_query_param
 from rest_framework.viewsets import ViewSetMixin
-from rest_framework.permissions import SAFE_METHODS, DjangoModelPermissions
 
 from adcm.settings import REST_FRAMEWORK
 from api.utils import AdcmFilterBackend, AdcmOrderingFilter, getlist_from_querydict
 from cm.errors import AdcmEx
-from rbac.viewsets import DjangoObjectPerm
 
 
 class ModelPermOrReadOnlyForAuth(DjangoModelPermissions):
@@ -36,7 +35,6 @@ def has_permission(self, request, view):
                 queryset = self._queryset(view)
                 perms = self.get_required_permissions(request.method, queryset.model)
                 return request.user.has_perms(perms)
-
         return False
 
 
@@ -46,7 +44,7 @@ class GenericUIView(GenericAPIView):
     (switched by query parameter view=interface)
     """
 
-    permission_classes = (DjangoObjectPerm,)
+    permission_classes = (DjangoObjectPermissions,)
     serializer_class_post: serializers.Serializer = None
     serializer_class_ui: serializers.Serializer = None
     serializer_class: serializers.Serializer = None
diff --git a/python/api/cluster/views.py b/python/api/cluster/views.py
index d0eff63763..69a290e55a 100644
--- a/python/api/cluster/views.py
+++ b/python/api/cluster/views.py
@@ -21,16 +21,21 @@
 import cm.bundle
 import cm.job
 import cm.status_api
+from api.base_view import GenericUIView, DetailView, PaginatedView
+from api.stack.serializers import ImportSerializer, ServiceSerializer, BundleServiceUISerializer
 from api.utils import (
     AdcmOrderingFilter,
     check_custom_perm,
     check_obj,
     create,
     update,
+    get_object_for_user,
 )
-from api.base_view import GenericUIView, DetailView, PaginatedView
 from cm.errors import AdcmEx
 from cm.models import Cluster, HostComponent, Prototype, ClusterObject, Upgrade, ClusterBind
+from cm.status_api import make_ui_cluster_status
+from cm.upgrade import get_upgrade
+from rbac.viewsets import DjangoOnlyObjectPermissions
 from . import serializers
 
 
@@ -63,7 +68,6 @@ class ClusterList(PermissionListMixin, PaginatedView):
     serializer_class_post = serializers.ClusterDetailSerializer
     filterset_fields = ('name', 'prototype_id')
     ordering_fields = ('name', 'state', 'prototype__display_name', 'prototype__version_order')
-    permission_classes = (permissions.DjangoModelPermissions,)
     permission_required = ['cm.view_cluster']
 
     def post(self, request, *args, **kwargs):
@@ -71,13 +75,15 @@ def post(self, request, *args, **kwargs):
         return create(serializer)
 
 
-class ClusterDetail(DetailView):
+class ClusterDetail(PermissionListMixin, DetailView):
     """
     get:
     Show cluster
     """
 
     queryset = Cluster.objects.all()
+    permission_classes = (DjangoOnlyObjectPermissions,)
+    permission_required = ['cm.view_cluster']
     serializer_class = serializers.ClusterDetailSerializer
     serializer_class_ui = serializers.ClusterUISerializer
     lookup_field = 'id'
@@ -103,14 +109,17 @@ def delete(self, request, *args, **kwargs):
 
 class ClusterBundle(GenericUIView):
     queryset = Prototype.objects.filter(type='service')
-    serializer_class = api.stack.serializers.ServiceSerializer
-    serializer_class_ui = api.stack.serializers.BundleServiceUISerializer
+    serializer_class = ServiceSerializer
+    serializer_class_ui = BundleServiceUISerializer
 
-    def get(self, request, cluster_id):
+    def get(self, request, *args, **kwargs):
         """
         List all services of specified cluster of bundle
         """
-        cluster = check_obj(Cluster, cluster_id)
+        cluster = get_object_for_user(
+            request.user, 'cm.view_cluster', Cluster, id=kwargs['cluster_id']
+        )
+        check_custom_perm(request.user, 'add_service_to', 'cluster', cluster)
         bundle = self.get_queryset().filter(bundle=cluster.prototype.bundle)
         shared = self.get_queryset().filter(shared=True).exclude(bundle=cluster.prototype.bundle)
         serializer = self.get_serializer(
@@ -121,26 +130,29 @@ def get(self, request, cluster_id):
 
 class ClusterImport(GenericUIView):
     queryset = Prototype.objects.all()
-    serializer_class = api.stack.serializers.ImportSerializer
+    serializer_class = ImportSerializer
     serializer_class_post = serializers.PostImportSerializer
-    check_import_perm = check_custom_perm
     permission_classes = (permissions.IsAuthenticated,)
 
-    def get(self, request, cluster_id):
+    def get(self, request, *args, **kwargs):
         """
         List all imports avaliable for specified cluster
         """
-        cluster = check_obj(Cluster, cluster_id)
-        self.check_import_perm('view_import_of', 'cluster', cluster, 'view_clusterbind')
+        cluster = get_object_for_user(
+            request.user, 'cm.view_cluster', Cluster, id=kwargs['cluster_id']
+        )
+        check_custom_perm(request.user, 'view_import_of', 'cluster', cluster, 'view_clusterbind')
         res = cm.api.get_import(cluster)
         return Response(res)
 
-    def post(self, request, cluster_id):
+    def post(self, request, *args, **kwargs):
         """
         Update bind for cluster
         """
-        cluster = check_obj(Cluster, cluster_id)
-        self.check_import_perm('change_import_of', 'cluster', cluster)
+        cluster = get_object_for_user(
+            request.user, 'cm.view_cluster', Cluster, id=kwargs['cluster_id']
+        )
+        check_custom_perm(request.user, 'change_import_of', 'cluster', cluster)
         serializer = self.get_serializer(
             data=request.data, context={'request': request, 'cluster': cluster}
         )
@@ -154,25 +166,28 @@ class ClusterBindList(GenericUIView):
     queryset = ClusterBind.objects.all()
     serializer_class = serializers.ClusterBindSerializer
     serializer_class_post = serializers.DoBindSerializer
-    check_import_perm = check_custom_perm
     permission_classes = (permissions.IsAuthenticated,)
 
-    def get(self, request, cluster_id):
+    def get(self, request, *args, **kwargs):
         """
         List all binds of specified cluster
         """
-        cluster = check_obj(Cluster, cluster_id)
-        self.check_import_perm('view_import_of', 'cluster', cluster, 'view_clusterbind')
+        cluster = get_object_for_user(
+            request.user, 'cm.view_cluster', Cluster, id=kwargs['cluster_id']
+        )
+        check_custom_perm(request.user, 'view_import_of', 'cluster', cluster, 'view_clusterbind')
         obj = self.get_queryset().filter(cluster=cluster, service=None)
         serializer = self.get_serializer(obj, many=True)
         return Response(serializer.data)
 
-    def post(self, request, cluster_id):
+    def post(self, request, *args, **kwargs):
         """
         Bind two clusters
         """
-        cluster = check_obj(Cluster, cluster_id)
-        self.check_import_perm('change_import_of', 'cluster', cluster)
+        cluster = get_object_for_user(
+            request.user, 'cm.view_cluster', Cluster, id=kwargs['cluster_id']
+        )
+        check_custom_perm(request.user, 'change_import_of', 'cluster', cluster)
         serializer = self.get_serializer(data=request.data)
         return create(serializer, cluster=cluster)
 
@@ -180,28 +195,29 @@ def post(self, request, cluster_id):
 class ClusterBindDetail(GenericUIView):
     queryset = ClusterBind.objects.all()
     serializer_class = serializers.BindSerializer
-    check_import_perm = check_custom_perm
     permission_classes = (permissions.IsAuthenticated,)
 
-    def get_obj(self, cluster_id, bind_id):
-        cluster = check_obj(Cluster, cluster_id)
-        return cluster, check_obj(ClusterBind, {'cluster': cluster, 'id': bind_id})
-
-    def get(self, request, cluster_id, bind_id):
+    def get(self, request, *args, **kwargs):
         """
         Show specified bind of specified cluster
         """
-        cluster, obj = self.get_obj(cluster_id, bind_id)
-        self.check_import_perm('view_import_of', 'cluster', cluster, 'view_clusterbind')
-        serializer = self.get_serializer(obj)
+        cluster = get_object_for_user(
+            request.user, 'cm.view_cluster', Cluster, id=kwargs['cluster_id']
+        )
+        bind = check_obj(ClusterBind, {'cluster': cluster, 'id': kwargs['bind_id']})
+        check_custom_perm(request.user, 'view_import_of', 'cluster', cluster, 'view_clusterbind')
+        serializer = self.get_serializer(bind)
         return Response(serializer.data)
 
-    def delete(self, request, cluster_id, bind_id):
+    def delete(self, request, *args, **kwargs):
         """
         Unbind specified bind of specified cluster
         """
-        cluster, bind = self.get_obj(cluster_id, bind_id)
-        self.check_import_perm('change_import_of', 'cluster', cluster)
+        cluster = get_object_for_user(
+            request.user, 'cm.view_cluster', Cluster, id=kwargs['cluster_id']
+        )
+        bind = check_obj(ClusterBind, {'cluster': cluster, 'id': kwargs['bind_id']})
+        check_custom_perm(request.user, 'change_import_of', 'cluster', cluster)
         cm.api.unbind(bind)
         return Response(status=status.HTTP_204_NO_CONTENT)
 
@@ -209,20 +225,21 @@ def delete(self, request, cluster_id, bind_id):
 class ClusterUpgrade(GenericUIView):
     queryset = Upgrade.objects.all()
     serializer_class = api.serializers.UpgradeLinkSerializer
-    check_upgrade_perm = check_custom_perm
     permission_classes = (permissions.IsAuthenticated,)
 
-    def get_ordering(self, request, queryset, view):
+    def get_ordering(self):
         Order = AdcmOrderingFilter()
-        return Order.get_ordering(request, queryset, view)
+        return Order.get_ordering(self.request, self.get_queryset(), self)
 
-    def get(self, request, cluster_id):
+    def get(self, request, *args, **kwargs):
         """
         List all avaliable upgrades for specified cluster
         """
-        cluster = check_obj(Cluster, cluster_id)
-        self.check_upgrade_perm('view_upgrade_of', 'cluster', cluster)
-        obj = cm.upgrade.get_upgrade(cluster, self.get_ordering(request, self.queryset, self))
+        cluster = get_object_for_user(
+            request.user, 'cm.view_cluster', Cluster, id=kwargs['cluster_id']
+        )
+        check_custom_perm(request.user, 'view_upgrade_of', 'cluster', cluster)
+        obj = get_upgrade(cluster, self.get_ordering())
         serializer = self.serializer_class(
             obj, many=True, context={'cluster_id': cluster.id, 'request': request}
         )
@@ -232,16 +249,19 @@ def get(self, request, cluster_id):
 class ClusterUpgradeDetail(GenericUIView):
     queryset = Upgrade.objects.all()
     serializer_class = api.serializers.UpgradeLinkSerializer
-    check_upgrade_perm = check_custom_perm
     permission_classes = (permissions.IsAuthenticated,)
 
-    def get(self, request, cluster_id, upgrade_id):
+    def get(self, request, *args, **kwargs):
         """
         List all avaliable upgrades for specified cluster
         """
-        cluster = check_obj(Cluster, cluster_id)
-        self.check_upgrade_perm('view_upgrade_of', 'cluster', cluster)
-        obj = self.get_queryset().get(id=upgrade_id)
+        cluster = get_object_for_user(
+            request.user, 'cm.view_cluster', Cluster, id=kwargs['cluster_id']
+        )
+        check_custom_perm(request.user, 'view_upgrade_of', 'cluster', cluster)
+        obj = check_obj(
+            Upgrade, {'id': kwargs['upgrade_id'], 'bundle__name': cluster.prototype.bundle.name}
+        )
         serializer = self.serializer_class(
             obj, context={'cluster_id': cluster.id, 'request': request}
         )
@@ -251,33 +271,35 @@ def get(self, request, cluster_id, upgrade_id):
 class DoClusterUpgrade(GenericUIView):
     queryset = Upgrade.objects.all()
     serializer_class = api.serializers.DoUpgradeSerializer
-    check_upgrade_perm = check_custom_perm
     permission_classes = (permissions.IsAuthenticated,)
 
-    def post(self, request, cluster_id, upgrade_id):
+    def post(self, request, *args, **kwargs):
         """
         Do upgrade specified cluster
         """
-        cluster = check_obj(Cluster, cluster_id)
-        self.check_upgrade_perm('do_upgrade_of', 'cluster', cluster)
+        cluster = get_object_for_user(
+            request.user, 'cm.view_cluster', Cluster, id=kwargs['cluster_id']
+        )
+        check_custom_perm(request.user, 'do_upgrade_of', 'cluster', cluster)
         serializer = self.get_serializer(data=request.data)
-        return create(serializer, upgrade_id=int(upgrade_id), obj=cluster)
+        return create(serializer, upgrade_id=int(kwargs['upgrade_id']), obj=cluster)
 
 
 class StatusList(GenericUIView):
     permission_classes = (permissions.IsAuthenticated,)
     queryset = HostComponent.objects.all()
-    model_name = Cluster
     serializer_class = serializers.StatusSerializer
 
-    def get(self, request, cluster_id):
+    def get(self, request, *args, **kwargs):
         """
         Show all hosts and components in a specified cluster
         """
-        cluster = check_obj(Cluster, cluster_id)
+        cluster = get_object_for_user(
+            request.user, 'cm.view_cluster', Cluster, id=kwargs['cluster_id']
+        )
         host_components = self.get_queryset().filter(cluster=cluster)
         if self._is_for_ui():
-            return Response(cm.status_api.make_ui_cluster_status(cluster, host_components))
+            return Response(make_ui_cluster_status(cluster, host_components))
         else:
             serializer = self.get_serializer(host_components, many=True)
             return Response(serializer.data)
@@ -288,15 +310,18 @@ class HostComponentList(GenericUIView):
     serializer_class = serializers.HostComponentSerializer
     serializer_class_ui = serializers.HostComponentUISerializer
     serializer_class_post = serializers.HostComponentSaveSerializer
-    check_hc_perm = check_custom_perm
     permission_classes = (permissions.IsAuthenticated,)
 
-    def get(self, request, cluster_id):
+    def get(self, request, *args, **kwargs):
         """
         Show host <-> component map in a specified cluster
         """
-        cluster = check_obj(Cluster, cluster_id)
-        self.check_hc_perm('view_host_components_of', 'cluster', cluster, 'view_hostcomponent')
+        cluster = get_object_for_user(
+            request.user, 'cm.view_cluster', Cluster, id=kwargs['cluster_id']
+        )
+        check_custom_perm(
+            request.user, 'view_host_components_of', 'cluster', cluster, 'view_hostcomponent'
+        )
         hc = self.get_queryset().filter(cluster=cluster)
         if self._is_for_ui():
             ui_hc = HostComponent()
@@ -308,12 +333,14 @@ def get(self, request, cluster_id):
             serializer = self.get_serializer(hc, many=True)
         return Response(serializer.data)
 
-    def post(self, request, cluster_id):
+    def post(self, request, *args, **kwargs):
         """
         Create new mapping service:component <-> host in a specified cluster.
         """
-        cluster = check_obj(Cluster, cluster_id)
-        self.check_hc_perm('edit_host_components_of', 'cluster', cluster)
+        cluster = get_object_for_user(
+            request.user, 'cm.view_cluster', Cluster, id=kwargs['cluster_id']
+        )
+        check_custom_perm(request.user, 'edit_host_components_of', 'cluster', cluster)
         serializer = self.get_serializer(
             data=request.data,
             context={
@@ -333,18 +360,19 @@ def post(self, request, cluster_id):
 class HostComponentDetail(GenericUIView):
     queryset = HostComponent.objects.all()
     serializer_class = serializers.HostComponentSerializer
-    check_hc_perm = check_custom_perm
     permission_classes = (permissions.IsAuthenticated,)
 
     def get_obj(self, cluster_id, hs_id):
-        cluster = check_obj(Cluster, cluster_id)
-        self.check_hc_perm('view_host_components_of', 'cluster', cluster, 'view_hostcomponent')
+        cluster = get_object_for_user(self.request.user, 'cm.view_cluster', Cluster, id=cluster_id)
+        check_custom_perm(
+            self.request.user, 'view_host_components_of', 'cluster', cluster, 'view_hostcomponent'
+        )
         return check_obj(HostComponent, {'id': hs_id, 'cluster': cluster}, 'HOSTSERVICE_NOT_FOUND')
 
-    def get(self, request, cluster_id, hs_id):
+    def get(self, request, *args, **kwargs):
         """
         Show host <-> component link in a specified cluster
         """
-        obj = self.get_obj(cluster_id, hs_id)
+        obj = self.get_obj(kwargs['cluster_id'], kwargs['hs_id'])
         serializer = self.get_serializer(obj)
         return Response(serializer.data)
diff --git a/python/api/component/views.py b/python/api/component/views.py
index 33c9ff6130..9f2a32d612 100644
--- a/python/api/component/views.py
+++ b/python/api/component/views.py
@@ -14,67 +14,72 @@
 from rest_framework import permissions
 from rest_framework.response import Response
 
-import cm.status_api
-from api.utils import check_obj
-from api.base_view import GenericUIView, PaginatedView
+from api.base_view import GenericUIView, PaginatedView, DetailView
+from api.utils import get_object_for_user
 from cm.models import ServiceComponent, ClusterObject, Cluster, HostComponent
+from cm.status_api import make_ui_component_status
+from rbac.viewsets import DjangoOnlyObjectPermissions
 from . import serializers
 
 
+def get_component_queryset(queryset, user, kwargs):
+    if 'cluster_id' in kwargs:
+        cluster = get_object_for_user(user, 'cm.view_cluster', Cluster, id=kwargs['cluster_id'])
+        co = get_object_for_user(
+            user, 'cm.view_clusterobject', ClusterObject, cluster=cluster, id=kwargs['service_id']
+        )
+        queryset = queryset.filter(cluster=cluster, service=co)
+    elif 'service_id' in kwargs:
+        co = get_object_for_user(
+            user, 'cm.view_clusterobject', ClusterObject, id=kwargs['service_id']
+        )
+        queryset = queryset.filter(service=co)
+    return queryset
+
+
 class ComponentListView(PermissionListMixin, PaginatedView):
     queryset = ServiceComponent.objects.all()
     serializer_class = serializers.ComponentSerializer
     serializer_class_ui = serializers.ComponentUISerializer
     filterset_fields = ('cluster_id', 'service_id')
     ordering_fields = ('state', 'prototype__display_name', 'prototype__version_order')
-    permission_classes = (permissions.DjangoModelPermissions,)
     permission_required = ['cm.view_servicecomponent']
 
     def get_queryset(self):  # pylint: disable=arguments-differ
         queryset = super().get_queryset()
-        kwargs = self.kwargs
-        if 'cluster_id' in kwargs:
-            cluster = check_obj(Cluster, kwargs['cluster_id'], 'CLUSTER_NOT_FOUND')
-            co = check_obj(
-                ClusterObject, {'cluster': cluster, 'id': kwargs['service_id']}, 'SERVICE_NOT_FOUND'
-            )
-            queryset = queryset.filter(cluster=cluster, service=co)
-        elif 'service_id' in kwargs:
-            co = check_obj(ClusterObject, {'id': kwargs['service_id']}, 'SERVICE_NOT_FOUND')
-            queryset = queryset.filter(service=co)
-        return queryset
+        return get_component_queryset(queryset, self.request.user, self.kwargs)
 
 
-class ComponentDetailView(GenericUIView):
+class ComponentDetailView(PermissionListMixin, DetailView):
     queryset = ServiceComponent.objects.all()
     serializer_class = serializers.ComponentDetailSerializer
     serializer_class_ui = serializers.ComponentUISerializer
+    permission_classes = (DjangoOnlyObjectPermissions,)
+    permission_required = ['cm.view_servicecomponent']
+    lookup_url_kwarg = 'component_id'
+    error_code = ServiceComponent.__error_code__
 
-    def get(self, request, *args, **kwargs):
-        """
-        Show component
-        """
-        component = check_obj(
-            ServiceComponent, {'id': kwargs['component_id']}, 'COMPONENT_NOT_FOUND'
-        )
-        serializer = self.get_serializer(component)
-        return Response(serializer.data)
+    def get_queryset(self):  # pylint: disable=arguments-differ
+        queryset = super().get_queryset()
+        return get_component_queryset(queryset, self.request.user, self.kwargs)
 
 
 class StatusList(GenericUIView):
+    queryset = HostComponent.objects.all()
     permission_classes = (permissions.IsAuthenticated,)
     serializer_class = serializers.StatusSerializer
-    model_name = ServiceComponent
-    queryset = HostComponent.objects.all()
 
-    def get(self, request, component_id, cluster_id=None, service_id=None):
+    def get(self, request, *args, **kwargs):
         """
         Show all components in a specified host
         """
-        component = check_obj(ServiceComponent, component_id)
+        queryset = get_component_queryset(ServiceComponent.objects.all(), request.user, kwargs)
+        component = get_object_for_user(
+            request.user, 'cm.view_servicecomponent', queryset, id=kwargs['component_id']
+        )
         if self._is_for_ui():
             host_components = self.get_queryset().filter(component=component)
-            return Response(cm.status_api.make_ui_component_status(component, host_components))
+            return Response(make_ui_component_status(component, host_components))
         else:
             serializer = self.get_serializer(component)
             return Response(serializer.data)
diff --git a/python/api/config/views.py b/python/api/config/views.py
index 4afccbbd38..254e2f7281 100644
--- a/python/api/config/views.py
+++ b/python/api/config/views.py
@@ -10,26 +10,30 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+from guardian.mixins import PermissionListMixin
 from rest_framework import permissions
 from rest_framework.response import Response
 
-from api.utils import create, update, check_obj, permission_denied
 from api.base_view import GenericUIView
-
+from api.utils import create, update, check_obj, permission_denied
 from cm.adcm_config import ui_config
+from cm.errors import AdcmEx
 from cm.models import get_model_by_type, ConfigLog, ObjectConfig
-
+from rbac.viewsets import DjangoOnlyObjectPermissions
 from . import serializers
 
 
-def get_config_version(objconf, version):
+def get_config_version(queryset, objconf, version):
     if version == 'previous':
         ver = objconf.previous
     elif version == 'current':
         ver = objconf.current
     else:
         ver = version
-    cl = ConfigLog.obj.get(obj_ref=objconf, id=ver)
+    try:
+        cl = queryset.get(obj_ref=objconf, id=ver)
+    except ConfigLog.DoesNotExist:
+        raise AdcmEx('CONFIG_NOT_FOUND') from None
     return cl
 
 
@@ -47,8 +51,7 @@ def get_obj(object_type, object_id):
     model = get_model_by_type(object_type)
     obj = model.obj.get(id=object_id)
     oc = check_obj(ObjectConfig, {type_to_model(object_type): obj}, 'CONFIG_NOT_FOUND')
-    cl = ConfigLog.obj.get(obj_ref=oc, id=oc.current)
-    return obj, oc, cl
+    return obj, oc
 
 
 def get_object_type_id_version(**kwargs):
@@ -58,107 +61,111 @@ def get_object_type_id_version(**kwargs):
     return object_type, object_id, version
 
 
-def get_queryset(self):
-    return get_model_by_type(self.object_type).objects.all()
-
-
 def has_config_perm(user, action_type, object_type, obj):
     """
-    config_of_adcm checks permission to view/change config of any object
-    settings_of_adcm checks permission to view/change only ADCM settings
+    Checks permission to view/change config of any object
     """
     model = type_to_model(object_type)
     if user.has_perm(f'cm.{action_type}_config_of_{model}', obj):
         return True
-    if user.has_perm(f'cm.{action_type}_config_of_adcm'):
-        return True
-    if user.has_perm(f'cm.{action_type}_settings_of_adcm') and object_type == 'adcm':
+    if model == 'adcm' and user.has_perm(f'cm.{action_type}_settings_of_{model}'):
         return True
     return False
 
 
-def check_config_perm(self, action_type, object_type, obj):
-    if not has_config_perm(self.request.user, action_type, object_type, obj):
+def check_config_perm(user, action_type, object_type, obj):
+    if not has_config_perm(user, action_type, object_type, obj):
         permission_denied()
 
 
 class ConfigView(GenericUIView):
+    queryset = ConfigLog.objects.all()
     serializer_class = serializers.HistoryCurrentPreviousConfigSerializer
     permission_classes = (permissions.IsAuthenticated,)
-    check_config_perm = check_config_perm
-    get_queryset = get_queryset
-    object_type = None
 
     def get(self, request, *args, **kwargs):
         object_type, object_id, _ = get_object_type_id_version(**kwargs)
-        self.object_type = object_type
-        obj, _, _ = get_obj(object_type, object_id)
-        self.check_config_perm('view', object_type, obj)
-        serializer = self.get_serializer(
-            self.get_queryset().get(id=obj.id), context={'request': request, 'object': obj}
-        )
+        model = get_model_by_type(object_type)
+        obj = model.obj.get(id=object_id)
+        serializer = self.get_serializer(obj)
         return Response(serializer.data)
 
 
-class ConfigHistoryView(GenericUIView):
+class ConfigHistoryView(PermissionListMixin, GenericUIView):
+    queryset = ConfigLog.objects.all()
     serializer_class = serializers.ConfigHistorySerializer
     serializer_class_post = serializers.ObjectConfigUpdateSerializer
-    permission_classes = (permissions.IsAuthenticated,)
-    check_config_perm = check_config_perm
-    get_queryset = get_queryset
-    object_type = None
+    permission_required = ['cm.view_configlog']
+
+    def get_queryset(self, *args, **kwargs):
+        if self.request.user.has_perm('cm.view_settings_of_adcm'):
+            return super().get_queryset(*args, **kwargs) | ConfigLog.objects.filter(
+                obj_ref__adcm__isnull=False
+            )
+        else:
+            return super().get_queryset(*args, **kwargs).filter(obj_ref__adcm__isnull=True)
 
     def get(self, request, *args, **kwargs):
         object_type, object_id, _ = get_object_type_id_version(**kwargs)
-        self.object_type = object_type
-        obj, _, _ = get_obj(object_type, object_id)
-        self.check_config_perm('view', object_type, obj)
-        cl = ConfigLog.objects.filter(obj_ref=obj.config).order_by('-id')
+        obj, oc = get_obj(object_type, object_id)
+        cl = self.get_queryset().filter(obj_ref=oc).order_by('-id')
         serializer = self.get_serializer(cl, many=True, context={'request': request, 'object': obj})
         return Response(serializer.data)
 
     def post(self, request, *args, **kwargs):
         object_type, object_id, _ = get_object_type_id_version(**kwargs)
-        self.object_type = object_type
-        obj, _, cl = get_obj(object_type, object_id)
-        self.check_config_perm('change', object_type, obj)
-        serializer = self.get_serializer(
-            cl, data=request.data, context={'request': request, 'object': obj}
-        )
+        obj, oc = get_obj(object_type, object_id)
+        check_config_perm(request.user, 'change', object_type, obj)
+        try:
+            cl = self.get_queryset().get(obj_ref=oc, id=oc.current)
+        except ConfigLog.DoesNotExist:
+            raise AdcmEx('CONFIG_NOT_FOUND') from None
+        serializer = self.get_serializer(cl, data=request.data)
         return create(serializer, ui=self._is_for_ui(), obj=obj)
 
 
-class ConfigVersionView(GenericUIView):
+class ConfigVersionView(PermissionListMixin, GenericUIView):
+    queryset = ConfigLog.objects.all()
+    permission_classes = (DjangoOnlyObjectPermissions,)
     serializer_class = serializers.ObjectConfigSerializer
-    permission_classes = (permissions.IsAuthenticated,)
-    check_config_perm = check_config_perm
-    get_queryset = get_queryset
-    object_type = None
+    permission_required = ['cm.view_configlog']
+
+    def get_queryset(self, *args, **kwargs):
+        if self.request.user.has_perm('cm.view_settings_of_adcm'):
+            return super().get_queryset(*args, **kwargs) | ConfigLog.objects.filter(
+                obj_ref__adcm__isnull=False
+            )
+        else:
+            return super().get_queryset(*args, **kwargs).filter(obj_ref__adcm__isnull=True)
 
     def get(self, request, *args, **kwargs):
         object_type, object_id, version = get_object_type_id_version(**kwargs)
-        self.object_type = object_type
-        obj, oc, _ = get_obj(object_type, object_id)
-        self.check_config_perm('view', object_type, obj)
-        cl = get_config_version(oc, version)
+        obj, oc = get_obj(object_type, object_id)
+        cl = get_config_version(self.get_queryset(), oc, version)
         if self._is_for_ui():
             cl.config = ui_config(obj, cl)
         serializer = self.get_serializer(cl)
         return Response(serializer.data)
 
 
-class ConfigHistoryRestoreView(GenericUIView):
+class ConfigHistoryRestoreView(PermissionListMixin, GenericUIView):
+    queryset = ConfigLog.objects.all()
     serializer_class = serializers.ObjectConfigRestoreSerializer
-    permission_classes = (permissions.IsAuthenticated,)
-    check_config_perm = check_config_perm
-    get_queryset = get_queryset
-    object_type = None
+    permission_classes = (DjangoOnlyObjectPermissions,)
+    permission_required = ['cm.view_configlog']
+
+    def get_queryset(self, *args, **kwargs):
+        if self.request.user.has_perm('cm.view_settings_of_adcm'):
+            return super().get_queryset(*args, **kwargs) | ConfigLog.objects.filter(
+                obj_ref__adcm__isnull=False
+            )
+        else:
+            return super().get_queryset(*args, **kwargs).filter(obj_ref__adcm__isnull=True)
 
     def patch(self, request, *args, **kwargs):
         object_type, object_id, version = get_object_type_id_version(**kwargs)
-        self.object_type = object_type
-        obj, oc, _ = get_obj(object_type, object_id)
-        self.check_config_perm('change', object_type, obj)
-        cl = get_config_version(oc, version)
+        obj, oc = get_obj(object_type, object_id)
+        check_config_perm(request.user, 'change', object_type, obj)
+        cl = get_config_version(self.get_queryset(), oc, version)
         serializer = self.get_serializer(cl, data=request.data)
         return update(serializer)
diff --git a/python/api/config_log/views.py b/python/api/config_log/views.py
index 6f2a325748..58989e74e2 100644
--- a/python/api/config_log/views.py
+++ b/python/api/config_log/views.py
@@ -10,20 +10,47 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+from django.contrib.contenttypes.models import ContentType
+from guardian.mixins import PermissionListMixin
+from rest_framework import status
 from rest_framework.mixins import ListModelMixin, CreateModelMixin, RetrieveModelMixin
+from rest_framework.permissions import DjangoObjectPermissions
+from rest_framework.response import Response
 
 from api.base_view import GenericUIViewSet
+from api.config.views import check_config_perm
 from cm.models import ConfigLog
-from rbac.viewsets import DjangoObjectPerm
 from .serializers import ConfigLogSerializer, UIConfigLogSerializer
 
 
 class ConfigLogViewSet(  # pylint: disable=too-many-ancestors
-    CreateModelMixin, ListModelMixin, RetrieveModelMixin, GenericUIViewSet
+    PermissionListMixin, CreateModelMixin, ListModelMixin, RetrieveModelMixin, GenericUIViewSet
 ):
     queryset = ConfigLog.objects.all()
     serializer_class = ConfigLogSerializer
-    permission_classes = (DjangoObjectPerm,)
+    permission_classes = (DjangoObjectPermissions,)
     serializer_class_ui = UIConfigLogSerializer
+    permission_required = ['cm.view_configlog']
     filterset_fields = ('id', 'obj_ref')
     ordering_fields = ('id',)
+
+    def get_queryset(self, *args, **kwargs):
+        if self.request.user.has_perm('cm.view_settings_of_adcm'):
+            return super().get_queryset(*args, **kwargs) | ConfigLog.objects.filter(
+                obj_ref__adcm__isnull=False
+            )
+        else:
+            return super().get_queryset(*args, **kwargs).filter(obj_ref__adcm__isnull=True)
+
+    def create(self, request, *args, **kwargs):
+        serializer = self.get_serializer(data=request.data)
+        serializer.is_valid(raise_exception=True)
+
+        # check custom permissions
+        obj = serializer.validated_data['obj_ref'].object
+        object_type = ContentType.objects.get_for_model(obj).model
+        check_config_perm(request.user, 'change', object_type, obj)
+
+        self.perform_create(serializer)
+        headers = self.get_success_headers(serializer.data)
+        return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
diff --git a/python/api/group_config/views.py b/python/api/group_config/views.py
index 5cf6375d67..8262a3794b 100644
--- a/python/api/group_config/views.py
+++ b/python/api/group_config/views.py
@@ -13,6 +13,7 @@
 
 from django.contrib.contenttypes.models import ContentType
 from django_filters.rest_framework import FilterSet, CharFilter
+from guardian.mixins import PermissionListMixin
 from rest_framework import status, viewsets, permissions
 from rest_framework.mixins import (
     ListModelMixin,
@@ -31,15 +32,13 @@
 
 def has_config_perm(user, action_type, obj):
     model = type(obj).__name__.lower()
-    if user.has_perm(f'cm.{action_type}_configlog'):
-        return True
     if user.has_perm(f'cm.{action_type}_config_of_{model}', obj):
         return True
     return False
 
 
-def check_config_perm(self, action_type, obj):
-    if not has_config_perm(self.request.user, action_type, obj):
+def check_config_perm(user, action_type, obj):
+    if not has_config_perm(user, action_type, obj):
         permission_denied()
 
 
@@ -59,6 +58,7 @@ class Meta:
 
 
 class GroupConfigHostViewSet(
+    PermissionListMixin,
     NestedViewSetMixin,
     ListModelMixin,
     CreateModelMixin,
@@ -68,13 +68,12 @@ class GroupConfigHostViewSet(
 ):  # pylint: disable=too-many-ancestors
     queryset = Host.objects.all()
     serializer_class = serializers.GroupConfigHostSerializer
-    permission_classes = (permissions.IsAuthenticated,)
-    check_config_perm = check_config_perm
+    permission_classes = (permissions.DjangoObjectPermissions,)
+    permission_required = ['view_host']
     lookup_url_kwarg = 'host_id'
 
     def destroy(self, request, *args, **kwargs):
         group_config = GroupConfig.obj.get(id=self.kwargs.get('parent_lookup_group_config'))
-        self.check_config_perm('change', group_config.object)
         host = self.get_object()
         group_config.hosts.remove(host)
         return Response(status=status.HTTP_204_NO_CONTENT)
@@ -86,23 +85,22 @@ def get_serializer_context(self):
         group_config_id = self.kwargs.get('parent_lookup_group_config')
         if group_config_id is not None:
             group_config = GroupConfig.obj.get(id=group_config_id)
-            self.check_config_perm('view', group_config.object)
             context.update({'group_config': group_config})
         return context
 
 
 class GroupConfigHostCandidateViewSet(
-    NestedViewSetMixin, viewsets.ReadOnlyModelViewSet
+    PermissionListMixin, NestedViewSetMixin, viewsets.ReadOnlyModelViewSet
 ):  # pylint: disable=too-many-ancestors
     serializer_class = serializers.GroupConfigHostCandidateSerializer
-    permission_classes = (permissions.IsAuthenticated,)
-    check_config_perm = check_config_perm
+    permission_classes = (permissions.DjangoObjectPermissions,)
     lookup_url_kwarg = 'host_id'
+    permission_required = ['cm.view_host']
 
-    def get_queryset(self):
+    def get_queryset(self, *args, **kwargs):
         group_config_id = self.kwargs.get('parent_lookup_group_config')
         if group_config_id is None:
-            return None
+            return Host.objects.none()
         group_config = GroupConfig.obj.get(id=group_config_id)
         return group_config.host_candidate()
 
@@ -113,16 +111,17 @@ def get_serializer_context(self):
         group_config_id = self.kwargs.get('parent_lookup_group_config')
         if group_config_id is not None:
             group_config = GroupConfig.obj.get(id=group_config_id)
-            self.check_config_perm('view', group_config.object)
             context.update({'group_config': group_config})
         return context
 
 
-class GroupConfigConfigViewSet(NestedViewSetMixin, RetrieveModelMixin, viewsets.GenericViewSet):
+class GroupConfigConfigViewSet(
+    PermissionListMixin, NestedViewSetMixin, RetrieveModelMixin, viewsets.GenericViewSet
+):  # pylint: disable=too-many-ancestors
     queryset = ObjectConfig.objects.all()
     serializer_class = serializers.GroupConfigConfigSerializer
-    permission_classes = (permissions.IsAuthenticated,)
-    check_config_perm = check_config_perm
+    permission_classes = (permissions.DjangoObjectPermissions,)
+    permission_required = ['view_objectconfig']
 
     def get_serializer_context(self):
         context = super().get_serializer_context()
@@ -131,7 +130,6 @@ def get_serializer_context(self):
         group_config_id = self.kwargs.get('parent_lookup_group_config')
         if group_config_id is not None:
             group_config = GroupConfig.obj.get(id=group_config_id)
-            self.check_config_perm('view', group_config.object)
             context.update({'group_config': group_config})
             context.update({'obj_ref__group_config': group_config})
         obj_ref_id = self.kwargs.get('pk')
@@ -142,6 +140,7 @@ def get_serializer_context(self):
 
 
 class GroupConfigConfigLogViewSet(
+    PermissionListMixin,
     NestedViewSetMixin,
     RetrieveModelMixin,
     ListModelMixin,
@@ -150,12 +149,12 @@ class GroupConfigConfigLogViewSet(
 ):  # pylint: disable=too-many-ancestors
     serializer_class = serializers.GroupConfigConfigLogSerializer
     serializer_class_ui = serializers.UIGroupConfigConfigLogSerializer
-    permission_classes = (permissions.IsAuthenticated,)
-    check_config_perm = check_config_perm
+    permission_classes = (permissions.DjangoObjectPermissions,)
+    permission_required = ['view_configlog']
     filterset_fields = ('id',)
     ordering_fields = ('id',)
 
-    def get_queryset(self):
+    def get_queryset(self, *args, **kwargs):
         kwargs = {
             'obj_ref__group_config': self.kwargs.get('parent_lookup_obj_ref__group_config'),
             'obj_ref': self.kwargs.get('parent_lookup_obj_ref'),
@@ -169,7 +168,6 @@ def get_serializer_context(self):
         group_config_id = self.kwargs.get('parent_lookup_obj_ref__group_config')
         if group_config_id is not None:
             group_config = GroupConfig.obj.get(id=group_config_id)
-            self.check_config_perm('view', group_config.object)
             context.update({'obj_ref__group_config': group_config})
         obj_ref_id = self.kwargs.get('parent_lookup_obj_ref')
         if obj_ref_id is not None:
@@ -179,19 +177,49 @@ def get_serializer_context(self):
 
 
 class GroupConfigViewSet(
-    NestedViewSetMixin, viewsets.ModelViewSet
+    PermissionListMixin, NestedViewSetMixin, viewsets.ModelViewSet
 ):  # pylint: disable=too-many-ancestors
     queryset = GroupConfig.objects.all()
     serializer_class = serializers.GroupConfigSerializer
     filterset_class = GroupConfigFilterSet
-    permission_classes = (permissions.IsAuthenticated,)
-    check_config_perm = check_config_perm
+    permission_classes = (permissions.DjangoObjectPermissions,)
+    permission_required = ['cm.view_groupconfig']
+
+    def create(self, request, *args, **kwargs):
+        serializer = self.get_serializer(data=request.data)
+        serializer.is_valid(raise_exception=True)
 
-    def perform_create(self, serializer):
         model = serializer.validated_data['object_type'].model_class()
         obj = model.obj.get(id=serializer.validated_data['object_id'])
-        self.check_config_perm('change', obj)
-        serializer.save()
+        check_config_perm(self.request.user, 'change', obj)
+
+        self.perform_create(serializer)
+        headers = self.get_success_headers(serializer.data)
+        return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
+
+    def update(self, request, *args, **kwargs):
+        partial = kwargs.pop('partial', False)
+        instance = self.get_object()
+
+        check_config_perm(self.request.user, 'change', instance.object)
+
+        serializer = self.get_serializer(instance, data=request.data, partial=partial)
+        serializer.is_valid(raise_exception=True)
+        self.perform_update(serializer)
+
+        if getattr(instance, '_prefetched_objects_cache', None):
+            # If 'prefetch_related' has been applied to a queryset, we need to
+            # forcibly invalidate the prefetch cache on the instance.
+            # pylint: disable=protected-access
+            instance._prefetched_objects_cache = {}
+
+        return Response(serializer.data)
+
+    def destroy(self, request, *args, **kwargs):
+        instance = self.get_object()
+        check_config_perm(self.request.user, 'change', instance.object)
+        self.perform_destroy(instance)
+        return Response(status=status.HTTP_204_NO_CONTENT)
 
     def get_serializer_context(self):
         context = super().get_serializer_context()
@@ -199,6 +227,5 @@ def get_serializer_context(self):
             return context
         if self.kwargs:
             group_config = self.get_object()
-            self.check_config_perm('view', group_config.object)
             context.update({'group_config': group_config})
         return context
diff --git a/python/api/host/serializers.py b/python/api/host/serializers.py
index 74f65d766a..8bd05c9098 100644
--- a/python/api/host/serializers.py
+++ b/python/api/host/serializers.py
@@ -13,14 +13,16 @@
 from django.db import IntegrityError
 from rest_framework import serializers
 
-import cm
 from api.action.serializers import ActionShort
-from api.utils import hlink, check_obj, filter_actions, CommonAPIURL, ObjectURL
 from api.concern.serializers import ConcernItemSerializer, ConcernItemUISerializer
 from api.serializers import StringListSerializer
+from api.utils import hlink, check_obj, filter_actions, CommonAPIURL, ObjectURL
 from cm.adcm_config import get_main_info
+from cm.api import add_host
 from cm.errors import AdcmEx
 from cm.models import HostProvider, Prototype, Action
+from cm.stack import validate_name
+from cm.status_api import get_host_status
 
 
 class HostSerializer(serializers.Serializer):
@@ -40,11 +42,11 @@ def validate_provider_id(self, provider_id):
         return check_obj(HostProvider, provider_id)
 
     def validate_fqdn(self, name):
-        return cm.stack.validate_name(name, 'Host name')
+        return validate_name(name, 'Host name')
 
     def create(self, validated_data):
         try:
-            return cm.api.add_host(
+            return add_host(
                 validated_data.get('prototype_id'),
                 validated_data.get('provider_id'),
                 validated_data.get('fqdn'),
@@ -65,7 +67,7 @@ class HostDetailSerializer(HostSerializer):
     locked = serializers.BooleanField(read_only=True)
 
     def get_status(self, obj):
-        return cm.status_api.get_host_status(obj)
+        return get_host_status(obj)
 
 
 class ClusterHostSerializer(HostSerializer):
@@ -83,7 +85,7 @@ def create(self, validated_data):
         provider = check_obj(HostProvider, self.context.get('provider_id'))
         proto = Prototype.obj.get(bundle=provider.prototype.bundle, type='host')
         try:
-            return cm.api.add_host(
+            return add_host(
                 proto, provider, validated_data.get('fqdn'), validated_data.get('description', '')
             )
         except IntegrityError:
@@ -96,7 +98,7 @@ class StatusSerializer(serializers.Serializer):
     status = serializers.SerializerMethodField()
 
     def get_status(self, obj):
-        return cm.status_api.get_host_status(obj)
+        return get_host_status(obj)
 
 
 class HostUISerializer(HostDetailSerializer):
diff --git a/python/api/host/views.py b/python/api/host/views.py
index ff32eccfaa..3de39af3cd 100644
--- a/python/api/host/views.py
+++ b/python/api/host/views.py
@@ -16,12 +16,12 @@
 from rest_framework import status, permissions
 from rest_framework.response import Response
 
+from api.base_view import GenericUIView, PaginatedView, DetailView
 from api.utils import (
     create,
-    check_obj,
+    get_object_for_user,
     check_custom_perm,
 )
-from api.base_view import GenericUIView, PaginatedView
 from cm.api import remove_host_from_cluster, delete_host, add_host_to_cluster
 from cm.errors import AdcmEx
 from cm.models import (
@@ -34,6 +34,7 @@
     HostComponent,
 )
 from cm.status_api import make_ui_host_status
+from rbac.viewsets import DjangoOnlyObjectPermissions
 from . import serializers
 
 
@@ -80,6 +81,18 @@ class Meta:
         ]
 
 
+def get_host_queryset(queryset, user, kwargs):
+    if 'cluster_id' in kwargs:
+        cluster = get_object_for_user(user, 'cm.view_cluster', Cluster, id=kwargs['cluster_id'])
+        queryset = queryset.filter(cluster=cluster)
+    if 'provider_id' in kwargs:
+        provider = get_object_for_user(
+            user, 'cm.view_hostprovider', HostProvider, id=kwargs['provider_id']
+        )
+        queryset = queryset.filter(provider=provider)
+    return queryset
+
+
 class HostList(PermissionListMixin, PaginatedView):
     """
     get:
@@ -92,9 +105,7 @@ class HostList(PermissionListMixin, PaginatedView):
     queryset = Host.objects.all()
     serializer_class = serializers.HostSerializer
     serializer_class_ui = serializers.HostUISerializer
-    permission_classes = (permissions.IsAuthenticated,)
     permission_required = ['cm.view_host']
-    check_host_perm = check_custom_perm
     filterset_class = HostFilter
     filterset_fields = (
         'cluster_id',
@@ -117,15 +128,9 @@ class HostList(PermissionListMixin, PaginatedView):
         'prototype__version_order',
     )
 
-    def get_queryset(self):  # pylint: disable=arguments-differ
-        queryset = super().get_queryset()
-        kwargs = self.kwargs
-        if 'cluster_id' in kwargs:  # List cluster hosts
-            cluster = check_obj(Cluster, kwargs['cluster_id'])
-            queryset = queryset.filter(cluster=cluster)
-        if 'provider_id' in kwargs:  # List provider hosts
-            provider = check_obj(HostProvider, kwargs['provider_id'])
-            queryset = queryset.filter(provider=provider)
+    def get_queryset(self, *args, **kwargs):
+        queryset = super().get_queryset(*args, **kwargs)
+        queryset = get_host_queryset(queryset, self.request.user, self.kwargs)
         return get_objects_for_user(**self.get_get_objects_for_user_kwargs(queryset))
 
     def post(self, request, *args, **kwargs):
@@ -142,12 +147,15 @@ def post(self, request, *args, **kwargs):
         )
         if serializer.is_valid():
             if 'provider_id' in kwargs:  # List provider hosts
-                provider = check_obj(HostProvider, kwargs['provider_id'])
+                provider = get_object_for_user(
+                    request.user, 'cm.view_hostprovider', HostProvider, id=kwargs['provider_id']
+                )
             else:
-                provider = serializer.validated_data.get(
-                    'provider_id',
+                provider = serializer.validated_data.get('provider_id')
+                provider = get_object_for_user(
+                    request.user, 'cm.view_hostprovider', HostProvider, id=provider.id
                 )
-            self.check_host_perm('add_host_to', 'hostprovider', provider)
+            check_custom_perm(request.user, 'add_host_to', 'hostprovider', provider)
             return create(serializer)
         return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
 
@@ -158,17 +166,19 @@ class HostListProvider(HostList):
 
 class HostListCluster(HostList):
     serializer_class = serializers.ClusterHostSerializer
-    permission_classes = (permissions.IsAuthenticated,)
-    check_host_perm = check_custom_perm
 
     def post(self, request, *args, **kwargs):
         serializer = self.get_serializer(data=request.data)
         if serializer.is_valid(raise_exception=True):
             validated_data = serializer.validated_data
             if 'cluster_id' in kwargs:
-                cluster = check_obj(Cluster, kwargs['cluster_id'])
-            host = check_obj(Host, validated_data.get('id'))
-            self.check_host_perm('map_host_to', 'cluster', cluster)
+                cluster = get_object_for_user(
+                    request.user, 'cm.view_cluster', Cluster, id=kwargs['cluster_id']
+                )
+            host = get_object_for_user(
+                request.user, 'cm.view_host', Host, id=validated_data.get('id')
+            )
+            check_custom_perm(request.user, 'map_host_to', 'cluster', cluster)
             add_host_to_cluster(cluster, host)
             return Response(self.get_serializer(host).data, status=status.HTTP_201_CREATED)
         else:
@@ -181,7 +191,7 @@ def check_host(host, cluster):
         raise AdcmEx('FOREIGN_HOST', msg)
 
 
-class HostDetail(GenericUIView):
+class HostDetail(PermissionListMixin, DetailView):
     """
     get:
     Show host
@@ -190,51 +200,66 @@ class HostDetail(GenericUIView):
     queryset = Host.objects.all()
     serializer_class = serializers.HostDetailSerializer
     serializer_class_ui = serializers.HostUISerializer
-    permission_classes = (permissions.IsAuthenticated,)
-    check_host_perm = check_custom_perm
+    permission_classes = (DjangoOnlyObjectPermissions,)
+    permission_required = ['cm.view_host']
     lookup_field = 'id'
     lookup_url_kwarg = 'host_id'
     error_code = 'HOST_NOT_FOUND'
 
-    def get(self, request, host_id, **kwargs):
-        host = check_obj(Host, host_id)
-        if 'cluster_id' in kwargs:
-            cluster = check_obj(Cluster, kwargs['cluster_id'])
-            check_host(host, cluster)
-        serializer = self.get_serializer(host)
-        return Response(serializer.data)
+    def get_queryset(self, *args, **kwargs):
+        queryset = super().get_queryset(*args, **kwargs)
+        queryset = get_host_queryset(queryset, self.request.user, self.kwargs)
+        return get_objects_for_user(**self.get_get_objects_for_user_kwargs(queryset))
 
-    def delete(self, request, host_id, **kwargs):
+    def delete(self, request, *args, **kwargs):
         """
         Delete host
         """
-        host = check_obj(Host, host_id, 'HOST_NOT_FOUND')
+        host = self.get_object()
         if 'cluster_id' in kwargs:
             # Remove host from cluster
-            cluster = check_obj(Cluster, kwargs['cluster_id'])
+            cluster = get_object_for_user(
+                request.user, 'cm.view_cluster', Cluster, id=kwargs['cluster_id']
+            )
             check_host(host, cluster)
-            self.check_host_perm('unmap_host_from', 'cluster', cluster)
+            check_custom_perm(request.user, 'unmap_host_from', 'cluster', cluster)
             remove_host_from_cluster(host)
         else:
             # Delete host (and all corresponding host services:components)
-            self.check_host_perm('delete', 'host', host)
+            check_custom_perm(request.user, 'remove', 'host', host)
             delete_host(host)
         return Response(status=status.HTTP_204_NO_CONTENT)
 
 
 class StatusList(GenericUIView):
+    queryset = HostComponent.objects.all()
     permission_classes = (permissions.IsAuthenticated,)
     serializer_class = serializers.StatusSerializer
-    model_name = Host
-    queryset = HostComponent.objects.all()
 
-    def get(self, request, host_id, cluster_id=None):
+    def get(self, request, *args, **kwargs):
         """
         Show all components in a specified host
         """
-        host = check_obj(Host, host_id)
+        cluster = None
+        host = get_object_for_user(request.user, 'cm.view_host', Host, id=kwargs['host_id'])
+        if 'cluster_id' in kwargs:
+            cluster = get_object_for_user(
+                request.user, 'cm.view_cluster', Cluster, id=kwargs['cluster_id']
+            )
+        if 'provider_id' in kwargs:
+            provider = get_object_for_user(
+                request.user, 'cm.view_hostprovider', HostProvider, id=kwargs['provider_id']
+            )
+            host = get_object_for_user(
+                request.user,
+                'cm.view_host',
+                Host.objects.filter(provider=provider),
+                id=kwargs['host_id'],
+            )
         if self._is_for_ui():
             host_components = self.get_queryset().filter(host=host)
+            if cluster is not None:
+                host_components = self.get_queryset().filter(host=host, cluster=cluster)
             return Response(make_ui_host_status(host, host_components))
         else:
             serializer = self.get_serializer(host)
diff --git a/python/api/job/views.py b/python/api/job/views.py
index 6a49e40f66..66b5ba58b1 100644
--- a/python/api/job/views.py
+++ b/python/api/job/views.py
@@ -19,12 +19,13 @@
 from rest_framework.response import Response
 from rest_framework.reverse import reverse
 
-from api.utils import check_obj
 from api.base_view import GenericUIView, DetailView, PaginatedView
+from api.utils import get_object_for_user, check_custom_perm
 from cm import config
 from cm.errors import AdcmEx
 from cm.job import get_log, restart_task, cancel_task
 from cm.models import JobLog, TaskLog, LogStorage
+from rbac.viewsets import DjangoOnlyObjectPermissions
 from . import serializers
 
 
@@ -43,17 +44,18 @@ class JobList(PermissionListMixin, PaginatedView):
     permission_required = ['cm.view_joblog']
 
 
-class JobDetail(GenericUIView):
-    permission_classes = (permissions.IsAuthenticated,)
+class JobDetail(PermissionListMixin, GenericUIView):
     queryset = JobLog.objects.all()
+    permission_classes = (DjangoOnlyObjectPermissions,)
+    permission_required = ['cm.view_joblog']
     serializer_class = serializers.JobSerializer
 
-    def get(self, request, job_id):
+    def get(self, request, *args, **kwargs):
         """
         Show job
         """
-        job = check_obj(JobLog, job_id, 'JOB_NOT_FOUND')
-        job.log_dir = os.path.join(config.RUN_DIR, f'{job_id}')
+        job = get_object_for_user(request.user, 'cm.view_joblog', JobLog, id=kwargs['job_id'])
+        job.log_dir = os.path.join(config.RUN_DIR, f'{job.id}')
         logs = get_log(job)
         for lg in logs:
             log_id = lg['id']
@@ -72,29 +74,32 @@ def get(self, request, job_id):
 
 class LogStorageListView(PermissionListMixin, PaginatedView):
     queryset = LogStorage.objects.all()
+    permission_required = ['cm.view_logstorage']
     serializer_class = serializers.LogStorageListSerializer
     filterset_fields = ('name', 'type', 'format')
     ordering_fields = ('id', 'name')
-    permission_classes = (permissions.DjangoModelPermissions,)
-    permission_required = ['cm.view_logstorage']
 
-    def get(self, request, *args, **kwargs):
-        job_id = kwargs['job_id']
-        obj = self.filter_queryset(self.get_queryset().filter(job_id=job_id))
-        return self.get_page(obj, request)
+    def get_queryset(self, *args, **kwargs):
+        queryset = super().get_queryset(*args, **kwargs)
+        if 'job_id' not in self.kwargs:
+            return queryset
+        return queryset.filter(job_id=self.kwargs['job_id'])
 
 
-class LogStorageView(GenericUIView):
-    permission_classes = (permissions.IsAuthenticated,)
+class LogStorageView(PermissionListMixin, GenericUIView):
     queryset = LogStorage.objects.all()
+    permission_classes = (permissions.IsAuthenticated,)
+    permission_required = ['cm.view_logstorage']
     serializer_class = serializers.LogStorageSerializer
 
-    def get(self, request, job_id, log_id):
-        job = JobLog.obj.get(id=job_id)
+    def get(self, request, *args, **kwargs):
+        job = get_object_for_user(request.user, 'cm.view_joblog', JobLog, id=kwargs['job_id'])
         try:
-            log_storage = LogStorage.objects.get(id=log_id, job=job)
+            log_storage = self.get_queryset().get(id=kwargs['log_id'], job=job)
         except LogStorage.DoesNotExist:
-            raise AdcmEx('LOG_NOT_FOUND', f'log {log_id} not found for job {job_id}') from None
+            raise AdcmEx(
+                'LOG_NOT_FOUND', f'log {kwargs["log_id"]} not found for job {kwargs["job_id"]}'
+            ) from None
         serializer = self.get_serializer(log_storage)
         return Response(serializer.data)
 
@@ -155,21 +160,21 @@ class Task(PermissionListMixin, PaginatedView):
     """
 
     queryset = TaskLog.objects.order_by('-id')
+    permission_required = ['cm.view_tasklog']
     serializer_class = serializers.TaskListSerializer
     serializer_class_ui = serializers.TaskSerializer
     filterset_fields = ('action_id', 'pid', 'status', 'start_date', 'finish_date')
     ordering_fields = ('status', 'start_date', 'finish_date')
-    permission_classes = (permissions.DjangoModelPermissions,)
-    permission_required = ['cm.view_tasklog']
 
 
-class TaskDetail(DetailView):
+class TaskDetail(PermissionListMixin, DetailView):
     """
     get:
     Show task
     """
 
     queryset = TaskLog.objects.all()
+    permission_required = ['cm.view_tasklog']
     serializer_class = serializers.TaskSerializer
     lookup_field = 'id'
     lookup_url_kwarg = 'task_id'
@@ -177,22 +182,24 @@ class TaskDetail(DetailView):
 
 
 class TaskReStart(GenericUIView):
-    permission_classes = (permissions.IsAuthenticated,)
     queryset = TaskLog.objects.all()
+    permission_classes = (permissions.IsAuthenticated,)
     serializer_class = serializers.TaskSerializer
 
-    def put(self, request, task_id):
-        task = check_obj(TaskLog, task_id, 'TASK_NOT_FOUND')
+    def put(self, request, *args, **kwargs):
+        task = get_object_for_user(request.user, 'cm.view_tasklog', TaskLog, id=kwargs['task_id'])
+        check_custom_perm(request.user, 'change', TaskLog, task)
         restart_task(task)
         return Response(status=status.HTTP_200_OK)
 
 
 class TaskCancel(GenericUIView):
-    permission_classes = (permissions.IsAuthenticated,)
     queryset = TaskLog.objects.all()
+    permission_classes = (permissions.IsAuthenticated,)
     serializer_class = serializers.TaskSerializer
 
-    def put(self, request, task_id):
-        task = check_obj(TaskLog, task_id, 'TASK_NOT_FOUND')
+    def put(self, request, *args, **kwargs):
+        task = get_object_for_user(request.user, 'cm.view_tasklog', TaskLog, id=kwargs['task_id'])
+        check_custom_perm(request.user, 'change', TaskLog, task)
         cancel_task(task)
         return Response(status=status.HTTP_200_OK)
diff --git a/python/api/object_config/views.py b/python/api/object_config/views.py
index ad58097183..c09b37d1fe 100644
--- a/python/api/object_config/views.py
+++ b/python/api/object_config/views.py
@@ -10,15 +10,26 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+from guardian.mixins import PermissionListMixin
+from rest_framework.permissions import DjangoObjectPermissions
 from rest_framework.viewsets import ReadOnlyModelViewSet
 
 from cm.models import ObjectConfig
 from .serializers import ObjectConfigSerializer
 
-from rbac.viewsets import DjangoObjectPerm
 
-
-class ObjectConfigViewSet(ReadOnlyModelViewSet):  # pylint: disable=too-many-ancestors
+class ObjectConfigViewSet(
+    PermissionListMixin, ReadOnlyModelViewSet
+):  # pylint: disable=too-many-ancestors
     queryset = ObjectConfig.objects.all()
     serializer_class = ObjectConfigSerializer
-    permission_classes = (DjangoObjectPerm,)
+    permission_classes = (DjangoObjectPermissions,)
+    permission_required = ['cm.view_objectconfig']
+
+    def get_queryset(self, *args, **kwargs):
+        if self.request.user.has_perm('cm.view_settings_of_adcm'):
+            return super().get_queryset(*args, **kwargs) | ObjectConfig.objects.filter(
+                adcm__isnull=False
+            )
+        else:
+            return super().get_queryset(*args, **kwargs).filter(adcm__isnull=True)
diff --git a/python/api/provider/views.py b/python/api/provider/views.py
index 7cb9beb5cf..ab0809aeee 100644
--- a/python/api/provider/views.py
+++ b/python/api/provider/views.py
@@ -14,12 +14,19 @@
 from rest_framework import status, permissions
 from rest_framework.response import Response
 
-import cm
-from cm.models import HostProvider, Upgrade
-
-from api.utils import create, check_obj, check_custom_perm, AdcmFilterBackend, AdcmOrderingFilter
-from api.base_view import GenericUIView, DetailView, PaginatedView
 import api.serializers
+from api.base_view import GenericUIView, DetailView, PaginatedView
+from api.utils import (
+    create,
+    check_obj,
+    check_custom_perm,
+    AdcmFilterBackend,
+    AdcmOrderingFilter,
+    get_object_for_user,
+)
+from cm.api import delete_host_provider
+from cm.models import HostProvider, Upgrade
+from cm.upgrade import get_upgrade
 from . import serializers
 
 
@@ -38,7 +45,6 @@ class ProviderList(PermissionListMixin, PaginatedView):
     serializer_class_post = serializers.ProviderDetailSerializer
     filterset_fields = ('name', 'prototype_id')
     ordering_fields = ('name', 'state', 'prototype__display_name', 'prototype__version_order')
-    permission_classes = (permissions.DjangoModelPermissions,)
     permission_required = ['cm.view_hostprovider']
 
     def post(self, request, *args, **kwargs):
@@ -46,7 +52,7 @@ def post(self, request, *args, **kwargs):
         return create(serializer)
 
 
-class ProviderDetail(DetailView):
+class ProviderDetail(PermissionListMixin, DetailView):
     """
     get:
     Show host provider
@@ -55,37 +61,39 @@ class ProviderDetail(DetailView):
     queryset = HostProvider.objects.all()
     serializer_class = serializers.ProviderDetailSerializer
     serializer_class_ui = serializers.ProviderUISerializer
+    permission_required = ['cm.view_hostprovider']
     lookup_field = 'id'
     lookup_url_kwarg = 'provider_id'
     error_code = 'PROVIDER_NOT_FOUND'
 
-    def delete(self, request, provider_id):
+    def delete(self, request, *args, **kwargs):
         """
         Remove host provider
         """
-        provider = check_obj(HostProvider, provider_id, 'PROVIDER_NOT_FOUND')
-        cm.api.delete_host_provider(provider)
+        provider = self.get_object()
+        delete_host_provider(provider)
         return Response(status=status.HTTP_204_NO_CONTENT)
 
 
 class ProviderUpgrade(GenericUIView):
     queryset = Upgrade.objects.all()
     serializer_class = serializers.UpgradeProviderSerializer
-    check_upgrade_perm = check_custom_perm
     permission_classes = (permissions.IsAuthenticated,)
     filter_backends = (AdcmFilterBackend, AdcmOrderingFilter)
 
-    def get_ordering(self, request, queryset, view):
-        Order = AdcmOrderingFilter()
-        return Order.get_ordering(request, queryset, view)
+    def get_ordering(self):
+        order = AdcmOrderingFilter()
+        return order.get_ordering(self.request, self.get_queryset(), self)
 
-    def get(self, request, provider_id):
+    def get(self, request, *args, **kwargs):
         """
         List all avaliable upgrades for specified host provider
         """
-        provider = check_obj(HostProvider, provider_id, 'PROVIDER_NOT_FOUND')
-        self.check_upgrade_perm('view_upgrade_of', 'hostprovider', provider)
-        obj = cm.upgrade.get_upgrade(provider, self.get_ordering(request, self.queryset, self))
+        provider = get_object_for_user(
+            request.user, 'cm.view_hostprovider', HostProvider, id=kwargs['provider_id']
+        )
+        check_custom_perm(request.user, 'view_upgrade_of', 'hostprovider', provider)
+        obj = get_upgrade(provider, self.get_ordering())
         serializer = self.serializer_class(
             obj, many=True, context={'provider_id': provider.id, 'request': request}
         )
@@ -95,16 +103,19 @@ def get(self, request, provider_id):
 class ProviderUpgradeDetail(GenericUIView):
     queryset = Upgrade.objects.all()
     serializer_class = serializers.UpgradeProviderSerializer
-    check_upgrade_perm = check_custom_perm
     permission_classes = (permissions.IsAuthenticated,)
 
-    def get(self, request, provider_id, upgrade_id):
+    def get(self, request, *args, **kwargs):
         """
         List all avaliable upgrades for specified host provider
         """
-        provider = check_obj(HostProvider, provider_id, 'PROVIDER_NOT_FOUND')
-        self.check_upgrade_perm('view_upgrade_of', 'hostprovider', provider)
-        obj = self.get_queryset().get(id=upgrade_id)
+        provider = get_object_for_user(
+            request.user, 'cm.view_hostprovider', HostProvider, id=kwargs['provider_id']
+        )
+        check_custom_perm(request.user, 'view_upgrade_of', 'hostprovider', provider)
+        obj = check_obj(
+            Upgrade, {'id': kwargs['upgrade_id'], 'bundle__name': provider.prototype.bundle.name}
+        )
         serializer = self.serializer_class(
             obj, context={'provider_id': provider.id, 'request': request}
         )
@@ -114,14 +125,15 @@ def get(self, request, provider_id, upgrade_id):
 class DoProviderUpgrade(GenericUIView):
     queryset = Upgrade.objects.all()
     serializer_class = api.serializers.DoUpgradeSerializer
-    check_upgrade_perm = check_custom_perm
     permission_classes = (permissions.IsAuthenticated,)
 
-    def post(self, request, provider_id, upgrade_id):
+    def post(self, request, *args, **kwargs):
         """
         Do upgrade specified host provider
         """
-        provider = check_obj(HostProvider, provider_id, 'PROVIDER_NOT_FOUND')
-        self.check_upgrade_perm('do_upgrade_of', 'hostprovider', provider)
+        provider = get_object_for_user(
+            request.user, 'cm.view_hostprovider', HostProvider, id=kwargs['provider_id']
+        )
+        check_custom_perm(request.user, 'do_upgrade_of', 'hostprovider', provider)
         serializer = self.get_serializer(data=request.data)
-        return create(serializer, upgrade_id=int(upgrade_id), obj=provider)
+        return create(serializer, upgrade_id=int(kwargs['upgrade_id']), obj=provider)
diff --git a/python/api/service/views.py b/python/api/service/views.py
index e38fd6299a..fc7b987247 100644
--- a/python/api/service/views.py
+++ b/python/api/service/views.py
@@ -15,33 +15,33 @@
 from rest_framework.response import Response
 
 import cm.status_api
+from api.base_view import GenericUIView, PaginatedView, DetailView
+from api.cluster.serializers import BindSerializer
+from api.stack.serializers import ImportSerializer
 from api.utils import (
     create,
     check_obj,
     check_custom_perm,
+    get_object_for_user,
 )
-from api.base_view import GenericUIView, PaginatedView
-from api.stack.serializers import ImportSerializer
-from api.cluster.serializers import BindSerializer
-
 from cm.api import delete_service, get_import, unbind
 from cm.models import Cluster, ClusterObject, Prototype, ClusterBind, HostComponent
-
+from rbac.viewsets import DjangoOnlyObjectPermissions
 from . import serializers
 
 
-def check_service(kwargs):
-    service = check_obj(ClusterObject, kwargs['service_id'])
+def check_service(user, kwargs):
+    service = get_object_for_user(
+        user, 'cm.view_clusterobject', ClusterObject, id=kwargs['service_id']
+    )
     if 'cluster_id' in kwargs:
-        check_obj(Cluster, kwargs['cluster_id'])
+        get_object_for_user(user, 'cm.view_cluster', Cluster, id=kwargs['cluster_id'])
     return service
 
 
 class ServiceListView(PermissionListMixin, PaginatedView):
     queryset = ClusterObject.objects.all()
-    permission_classes = (permissions.IsAuthenticated,)
     permission_required = ['cm.view_clusterobject']
-    check_service_perm = check_custom_perm
     serializer_class = serializers.ServiceSerializer
     serializer_class_ui = serializers.ServiceUISerializer
     serializer_class_cluster = serializers.ClusterServiceSerializer
@@ -54,7 +54,9 @@ def get(self, request, *args, **kwargs):
         """
         queryset = self.get_queryset()
         if 'cluster_id' in kwargs:
-            cluster = check_obj(Cluster, kwargs['cluster_id'])
+            cluster = get_object_for_user(
+                request.user, 'cm.view_cluster', Cluster, id=kwargs['cluster_id']
+            )
             queryset = queryset.filter(cluster=cluster)
         return self.get_page(self.filter_queryset(queryset), request)
 
@@ -65,10 +67,14 @@ def post(self, request, *args, **kwargs):
         serializer_class = self.serializer_class
         if 'cluster_id' in kwargs:
             serializer_class = self.serializer_class_cluster
-            cluster = check_obj(Cluster, kwargs['cluster_id'])
+            cluster = get_object_for_user(
+                request.user, 'cm.view_cluster', Cluster, id=kwargs['cluster_id']
+            )
         else:
-            cluster = check_obj(Cluster, request.data['cluster_id'])
-        self.check_service_perm('add_service_to', 'cluster', cluster)
+            cluster = get_object_for_user(
+                request.user, 'cm.view_cluster', Cluster, id=request.data['cluster_id']
+            )
+        check_custom_perm(request.user, 'add_service_to', 'cluster', cluster)
         serializer = serializer_class(
             data=request.data,
             context={'request': request, 'cluster_id': kwargs.get('cluster_id', None)},
@@ -76,25 +82,30 @@ def post(self, request, *args, **kwargs):
         return create(serializer)
 
 
-class ServiceDetailView(GenericUIView):
+class ServiceDetailView(PermissionListMixin, DetailView):
     queryset = ClusterObject.objects.all()
     serializer_class = serializers.ServiceDetailSerializer
     serializer_class_ui = serializers.ServiceUISerializer
-
-    def get(self, request, *args, **kwargs):
-        """
-        Show service
-        """
-        service = check_service(kwargs)
-        serializer = self.get_serializer(service)
-        return Response(serializer.data)
+    permission_classes = (DjangoOnlyObjectPermissions,)
+    lookup_url_kwarg = 'service_id'
+    permission_required = ['cm.view_clusterobject']
+    error_code = ClusterObject.__error_code__
+
+    def get_queryset(self, *args, **kwargs):
+        queryset = super().get_queryset(*args, **kwargs)
+        if 'cluster_id' in self.kwargs:
+            cluster = get_object_for_user(
+                self.request.user, 'cm.view_cluster', Cluster, id=self.kwargs['cluster_id']
+            )
+            queryset = queryset.filter(cluster=cluster)
+        return queryset
 
     def delete(self, request, *args, **kwargs):
         """
         Remove service from cluster
         """
-        service = check_service(kwargs)
-        delete_service(service)
+        instance = self.get_object()
+        delete_service(instance)
         return Response(status=status.HTTP_204_NO_CONTENT)
 
 
@@ -102,21 +113,22 @@ class ServiceImportView(GenericUIView):
     queryset = Prototype.objects.all()
     serializer_class = ImportSerializer
     serializer_class_post = serializers.ImportPostSerializer
-    check_import_perm = check_custom_perm
     permission_classes = (permissions.IsAuthenticated,)
 
     def get(self, request, *args, **kwargs):
         """
         List all imports available for specified service
         """
-        service = check_service(kwargs)
-        self.check_import_perm('view_import_of', 'clusterobject', service, 'view_clusterbind')
+        service = check_service(request.user, kwargs)
+        check_custom_perm(
+            request.user, 'view_import_of', 'clusterobject', service, 'view_clusterbind'
+        )
         cluster = service.cluster
         return Response(get_import(cluster, service))
 
     def post(self, request, **kwargs):
-        service = check_service(kwargs)
-        self.check_import_perm('change_import_of', 'clusterobject', service)
+        service = check_service(request.user, kwargs)
+        check_custom_perm(request.user, 'change_import_of', 'clusterobject', service)
         cluster = service.cluster
         serializer = self.get_serializer(
             data=request.data, context={'request': request, 'cluster': cluster, 'service': service}
@@ -130,15 +142,16 @@ class ServiceBindView(GenericUIView):
     queryset = ClusterBind.objects.all()
     serializer_class = serializers.ServiceBindSerializer
     serializer_class_post = serializers.ServiceBindPostSerializer
-    check_import_perm = check_custom_perm
     permission_classes = (permissions.IsAuthenticated,)
 
     def get(self, request, *args, **kwargs):
         """
         List all binds of service
         """
-        service = check_service(kwargs)
-        self.check_import_perm('view_import_of', 'clusterobject', service, 'view_clusterbind')
+        service = check_service(request.user, kwargs)
+        check_custom_perm(
+            request.user, 'view_import_of', 'clusterobject', service, 'view_clusterbind'
+        )
         binds = self.get_queryset().filter(service=service)
         serializer = self.get_serializer(binds, many=True)
         return Response(serializer.data)
@@ -147,8 +160,8 @@ def post(self, request, **kwargs):
         """
         Bind two services
         """
-        service = check_service(kwargs)
-        self.check_import_perm('change_import_of', 'clusterobject', service)
+        service = check_service(request.user, kwargs)
+        check_custom_perm(request.user, 'change_import_of', 'clusterobject', service)
         cluster = service.cluster
         serializer = self.get_serializer(data=request.data)
         return create(serializer, cluster=cluster, service=service)
@@ -157,11 +170,10 @@ def post(self, request, **kwargs):
 class ServiceBindDetailView(GenericUIView):
     queryset = ClusterBind.objects.all()
     serializer_class = BindSerializer
-    check_import_perm = check_custom_perm
     permission_classes = (permissions.IsAuthenticated,)
 
     def get_obj(self, kwargs, bind_id):
-        service = check_service(kwargs)
+        service = check_service(self.request.user, kwargs)
         cluster = service.cluster
         return service, check_obj(ClusterBind, {'cluster': cluster, 'id': bind_id})
 
@@ -170,7 +182,9 @@ def get(self, request, *args, **kwargs):
         Show specified bind of service
         """
         service, bind = self.get_obj(kwargs, kwargs['bind_id'])
-        self.check_import_perm('view_import_of', 'clusterobject', service, 'view_clusterbind')
+        check_custom_perm(
+            request.user, 'view_import_of', 'clusterobject', service, 'view_clusterbind'
+        )
         serializer = self.get_serializer(bind)
         return Response(serializer.data)
 
@@ -179,7 +193,7 @@ def delete(self, request, *args, **kwargs):
         Unbind specified bind of service
         """
         service, bind = self.get_obj(kwargs, kwargs['bind_id'])
-        self.check_import_perm('change_import_of', 'clusterobject', service)
+        check_custom_perm(request.user, 'change_import_of', 'clusterobject', service)
         unbind(bind)
         return Response(status=status.HTTP_204_NO_CONTENT)
 
@@ -189,11 +203,11 @@ class StatusList(GenericUIView):
     queryset = HostComponent.objects.all()
     serializer_class = serializers.StatusSerializer
 
-    def get(self, request, service_id, cluster_id=None):
+    def get(self, request, *args, **kwargs):
         """
         Show all hosts and components in a specified cluster
         """
-        service = check_obj(ClusterObject, service_id)
+        service = check_service(request.user, kwargs)
         if self._is_for_ui():
             host_components = self.get_queryset().filter(service=service)
             return Response(cm.status_api.make_ui_service_status(service, host_components))
diff --git a/python/api/stack/views.py b/python/api/stack/views.py
index 88d9c82525..94764a5ccf 100644
--- a/python/api/stack/views.py
+++ b/python/api/stack/views.py
@@ -15,9 +15,9 @@
 from rest_framework.authentication import TokenAuthentication, SessionAuthentication
 from rest_framework.mixins import CreateModelMixin
 from rest_framework.parsers import MultiPartParser
+from rest_framework.permissions import IsAuthenticated
 from rest_framework.response import Response
 from rest_framework.reverse import reverse
-from rest_framework.permissions import IsAuthenticated
 
 import cm.api
 import cm.bundle
@@ -107,8 +107,8 @@ class BundleDetail(DetailView):
     lookup_url_kwarg = 'bundle_id'
     error_code = 'BUNDLE_NOT_FOUND'
 
-    def delete(self, request, bundle_id):
-        bundle = check_obj(Bundle, bundle_id, 'BUNDLE_NOT_FOUND')
+    def delete(self, request, *args, **kwargs):
+        bundle = self.get_object()
         cm.bundle.delete_bundle(bundle)
         return Response(status=status.HTTP_204_NO_CONTENT)
 
@@ -131,6 +131,7 @@ class BundleLicense(GenericUIView):
     action = 'retrieve'
     queryset = Bundle.objects.all()
     serializer_class = serializers.LicenseSerializer
+    permission_classes = (IsAuthenticated,)
 
     def get(self, request, bundle_id):
         bundle = check_obj(Bundle, bundle_id, 'BUNDLE_NOT_FOUND')
@@ -257,6 +258,7 @@ class ProviderTypeList(PaginatedView):
     serializer_class = serializers.ProviderTypeSerializer
     filterset_fields = ('name', 'bundle_id', 'display_name')
     ordering_fields = ('display_name', 'version_order')
+    permission_classes = (IsAuthenticated,)
 
 
 class ClusterTypeList(PaginatedView):
diff --git a/python/api/utils.py b/python/api/utils.py
index 57f2801c05..ed41336535 100644
--- a/python/api/utils.py
+++ b/python/api/utils.py
@@ -14,17 +14,34 @@
 
 from typing import List
 
+from django.core.exceptions import ObjectDoesNotExist
 from django.http.request import QueryDict
 from django_filters import rest_framework as drf_filters
+from guardian.shortcuts import get_objects_for_user
 from rest_framework import status, serializers, exceptions
 from rest_framework.filters import OrderingFilter
 from rest_framework.response import Response
 from rest_framework.reverse import reverse
 
 import cm.upgrade
+from cm.errors import AdcmEx
 from cm.models import Action, ADCMEntity, PrototypeConfig, ConcernType
 
 
+def get_object_for_user(user, perms, klass, **kwargs):
+    try:
+        queryset = get_objects_for_user(user, perms, klass)
+        return queryset.get(**kwargs)
+    except ObjectDoesNotExist:
+        model = klass
+        if not hasattr(klass, '_default_manager'):
+            model = klass.model
+        error_code = 'NO_MODEL_ERROR_CODE'
+        if hasattr(model, '__error_code__'):
+            error_code = model.__error_code__
+        raise AdcmEx(error_code) from None
+
+
 def check_obj(model, req, error=None):
     if isinstance(req, dict):
         kw = req
@@ -53,8 +70,8 @@ def has_custom_permission(user, action_type, model, obj, second_perm):
     return False
 
 
-def check_custom_perm(self, action_type, model, obj, second_perm=None):
-    if not has_custom_permission(self.request.user, action_type, model, obj, second_perm):
+def check_custom_perm(user, action_type, model, obj, second_perm=None):
+    if not has_custom_permission(user, action_type, model, obj, second_perm):
         permission_denied()
 
 
diff --git a/python/cm/api.py b/python/cm/api.py
index 1329e18260..80bb78f1a7 100644
--- a/python/cm/api.py
+++ b/python/cm/api.py
@@ -17,7 +17,6 @@
 from django.db import transaction
 from django.utils import timezone
 
-import rbac
 import cm.issue
 import cm.status_api
 from cm.adcm_config import (
@@ -52,6 +51,7 @@
     TaskLog,
 )
 from cm.upgrade import check_license, version_in
+from rbac.models import re_apply_object_policy
 
 
 def check_proto_type(proto, check_type):
@@ -131,7 +131,7 @@ def add_host(proto, provider, fqdn, desc=''):
         host.save()
         host.add_to_concerns(ctx.lock)
         cm.issue.update_hierarchy_issues(host)
-        rbac.models.re_apply_object_policy(provider)
+        re_apply_object_policy(provider)
     ctx.event.send_state()
     cm.status_api.post_event('create', 'host', host.id, 'provider', str(provider.id))
     load_service_map()
@@ -198,7 +198,7 @@ def add_host_to_cluster(cluster, host):
         host.save()
         host.add_to_concerns(ctx.lock)
         cm.issue.update_hierarchy_issues(host)
-        rbac.models.re_apply_object_policy(cluster)
+        re_apply_object_policy(cluster)
     cm.status_api.post_event('add', 'host', host.id, 'cluster', str(cluster.id))
     load_service_map()
     log.info('host #%s %s is added to cluster #%s %s', host.id, host.fqdn, cluster.id, cluster.name)
@@ -215,7 +215,7 @@ def get_cluster_and_host(cluster_id, fqdn, host_id):
         host = Host.obj.get(id=host_id)
     else:
         err('HOST_NOT_FOUND', 'fqdn or host_id is mandatory args')
-    return (cluster, host)
+    return cluster, host
 
 
 def add_host_to_cluster_by_id(cluster_id, fqdn, host_id):
@@ -321,7 +321,7 @@ def delete_service(service, cancel_tasks=True):
     cluster = service.cluster
     service.delete()
     cm.issue.update_hierarchy_issues(cluster)
-    rbac.models.re_apply_object_policy(cluster)
+    re_apply_object_policy(cluster)
     cm.status_api.post_event('delete', 'service', service_id)
     load_service_map()
     log.info(f'service #{service_id} is deleted')
@@ -349,7 +349,7 @@ def remove_host_from_cluster(host):
             cm.issue.update_hierarchy_issues(host)
         host.remove_from_concerns(ctx.lock)
         cm.issue.update_hierarchy_issues(cluster)
-        rbac.models.re_apply_object_policy(cluster)
+        re_apply_object_policy(cluster)
     ctx.event.send_state()
     cm.status_api.post_event('remove', 'host', host.id, 'cluster', str(cluster.id))
     load_service_map()
@@ -388,7 +388,7 @@ def add_service_to_cluster(cluster, proto):
         cs.save()
         add_components_to_service(cluster, cs)
         cm.issue.update_hierarchy_issues(cs)
-        rbac.models.re_apply_object_policy(cluster)
+        re_apply_object_policy(cluster)
     cm.status_api.post_event('add', 'service', cs.id, 'cluster', str(cluster.id))
     load_service_map()
     log.info(
@@ -449,6 +449,7 @@ def update_obj_config(obj_conf, conf, attr, desc=''):
     with transaction.atomic():
         cl = save_obj_config(obj_conf, new_conf, attr, desc)
         cm.issue.update_hierarchy_issues(obj)
+        re_apply_object_policy(obj)
     if hasattr(obj_conf, 'adcm'):
         prepare_social_auth(new_conf)
     if group is not None:
@@ -581,9 +582,9 @@ def save_hc(cluster, host_comp_list):  # pylint: disable=too-many-locals
     cm.issue.update_hierarchy_issues(cluster)
     load_service_map()
     for service in service_map:
-        rbac.models.re_apply_object_policy(service)
+        re_apply_object_policy(service)
     for hc in result:
-        rbac.models.re_apply_object_policy(hc.service)
+        re_apply_object_policy(hc.service)
     return result
 
 
diff --git a/python/rbac/endpoints/group/views.py b/python/rbac/endpoints/group/views.py
index 548d8fd7af..392191c552 100644
--- a/python/rbac/endpoints/group/views.py
+++ b/python/rbac/endpoints/group/views.py
@@ -13,12 +13,14 @@
 """Group view sets"""
 
 from adwp_base.errors import AdwpEx
+from guardian.mixins import PermissionListMixin
 from rest_flex_fields.serializers import FlexFieldsSerializerMixin
 from rest_framework import serializers, status
+from rest_framework.permissions import DjangoObjectPermissions
+from rest_framework.viewsets import ModelViewSet
 
 from rbac import models
 from rbac.services import group as group_services
-from rbac.viewsets import ModelPermViewSet
 
 
 class UserSerializer(serializers.Serializer):
@@ -87,11 +89,13 @@ def create(self, validated_data):
         return group_services.create(**validated_data)
 
 
-class GroupViewSet(ModelPermViewSet):  # pylint: disable=too-many-ancestors
+class GroupViewSet(PermissionListMixin, ModelViewSet):  # pylint: disable=too-many-ancestors
     """Group view set"""
 
     queryset = models.Group.objects.all()
     serializer_class = GroupSerializer
+    permission_classes = (DjangoObjectPermissions,)
+    permission_required = ['rbac.view_group']
     filterset_fields = ('id', 'name')
     ordering_fields = ('id', 'name')
     search_fields = ('name', 'description')
diff --git a/python/rbac/endpoints/policy/views.py b/python/rbac/endpoints/policy/views.py
index a18cb2bb9b..4c824178a8 100644
--- a/python/rbac/endpoints/policy/views.py
+++ b/python/rbac/endpoints/policy/views.py
@@ -11,17 +11,19 @@
 # limitations under the License.
 
 import jsonschema
+from guardian.mixins import PermissionListMixin
 from rest_flex_fields.serializers import FlexFieldsSerializerMixin
 from rest_framework import serializers
 from rest_framework import status
+from rest_framework.permissions import DjangoObjectPermissions
 from rest_framework.response import Response
 from rest_framework.validators import ValidationError
+from rest_framework.viewsets import ModelViewSet
 
 from cm.models import Cluster, ClusterObject, ServiceComponent, HostProvider, Host
 from rbac.models import Policy, User, Group, Role, RoleTypes
 from rbac.services.policy import policy_create, policy_update
 from rbac.utils import BaseRelatedSerializer
-from rbac.viewsets import ModelPermViewSet
 
 
 class ObjectField(serializers.JSONField):
@@ -128,9 +130,11 @@ def validate_role(self, role):
         return role
 
 
-class PolicyViewSet(ModelPermViewSet):  # pylint: disable=too-many-ancestors
+class PolicyViewSet(PermissionListMixin, ModelViewSet):  # pylint: disable=too-many-ancestors
     queryset = Policy.objects.all()
     serializer_class = PolicySerializer
+    permission_classes = (DjangoObjectPermissions,)
+    permission_required = ['rbac.view_policy']
     filterset_fields = ('id', 'name', 'built_in', 'role', 'user', 'group')
     ordering_fields = ('id', 'name', 'built_in', 'role')
 
diff --git a/python/rbac/endpoints/role/views.py b/python/rbac/endpoints/role/views.py
index f849390d14..943114e910 100644
--- a/python/rbac/endpoints/role/views.py
+++ b/python/rbac/endpoints/role/views.py
@@ -12,17 +12,19 @@
 
 from django.db.models import Q
 from django_filters import rest_framework as filters
+from guardian.mixins import PermissionListMixin
 from rest_flex_fields.serializers import FlexFieldsSerializerMixin
 from rest_framework import serializers
 from rest_framework import status
-from rest_framework.response import Response
 from rest_framework.decorators import action
+from rest_framework.permissions import DjangoObjectPermissions
+from rest_framework.response import Response
+from rest_framework.viewsets import ModelViewSet
 
 from cm.models import ProductCategory
 from rbac.models import Role
 from rbac.services.role import role_create, role_update
 from rbac.utils import BaseRelatedSerializer
-from rbac.viewsets import ModelPermViewSet
 
 
 class RoleChildSerializer(BaseRelatedSerializer):
@@ -86,10 +88,12 @@ class Meta:
         )
 
 
-class RoleView(ModelPermViewSet):  # pylint: disable=too-many-ancestors
+class RoleView(PermissionListMixin, ModelViewSet):  # pylint: disable=too-many-ancestors
 
     queryset = Role.objects.all()
     serializer_class = RoleSerializer
+    permission_classes = (DjangoObjectPermissions,)
+    permission_required = ['rbac.view_role']
     filterset_class = RoleFilter
     ordering_fields = ('id', 'name', 'display_name', 'built_in', 'type')
     search_fields = ('name', 'display_name')
diff --git a/python/rbac/endpoints/user/views.py b/python/rbac/endpoints/user/views.py
index a430f144a4..308666c10c 100644
--- a/python/rbac/endpoints/user/views.py
+++ b/python/rbac/endpoints/user/views.py
@@ -13,12 +13,14 @@
 """User view sets"""
 
 from adwp_base.errors import AdwpEx
+from guardian.mixins import PermissionListMixin
 from rest_flex_fields.serializers import FlexFieldsSerializerMixin
 from rest_framework import serializers, status
+from rest_framework.permissions import DjangoObjectPermissions
+from rest_framework.viewsets import ModelViewSet
 
 from rbac import models
 from rbac.services import user as user_services
-from rbac.viewsets import ModelPermViewSet
 
 
 class PasswordField(serializers.CharField):
@@ -95,11 +97,13 @@ def create(self, validated_data):
         return user_services.create(**validated_data)
 
 
-class UserViewSet(ModelPermViewSet):  # pylint: disable=too-many-ancestors
+class UserViewSet(PermissionListMixin, ModelViewSet):  # pylint: disable=too-many-ancestors
     """User view set"""
 
     queryset = models.User.objects.all()
     serializer_class = UserSerializer
+    permission_classes = (DjangoObjectPermissions,)
+    permission_required = ['rbac.view_user']
     filterset_fields = (
         'id',
         'username',
diff --git a/python/rbac/models.py b/python/rbac/models.py
index 735da0a803..7c8b8266c1 100644
--- a/python/rbac/models.py
+++ b/python/rbac/models.py
@@ -23,7 +23,7 @@
 from guardian.models import UserObjectPermission, GroupObjectPermission
 from rest_framework.exceptions import ValidationError
 
-from cm.models import Bundle, ProductCategory
+from cm.models import Bundle, ProductCategory, HostComponent
 
 
 class ObjectType(models.TextChoices):
@@ -249,13 +249,36 @@ def apply(self):
             self.role.apply(self, None, group=group)
 
 
-def re_apply_object_policy(obj):
+def get_objects_for_policy(obj):
+    obj_type_map = {}
+    obj_type = obj.prototype.type
+    if obj_type == 'component':
+        object_list = [obj, obj.service, obj.cluster]
+    elif obj_type == 'service':
+        object_list = [obj, obj.cluster]
+    elif obj_type == 'host':
+        if obj.cluster:
+            object_list = [obj, obj.provider, obj.cluster]
+            for hc in HostComponent.objects.filter(cluster=obj.cluster, host=obj):
+                object_list.append(hc.service)
+                object_list.append(hc.component)
+        else:
+            object_list = [obj, obj.provider]
+    else:
+        object_list = [obj]
+    for policy_object in object_list:
+        obj_type_map[policy_object] = ContentType.objects.get_for_model(policy_object)
+    return obj_type_map
+
+
+def re_apply_object_policy(apply_object):
     """
     This function search for polices linked with specified object and re apply them
     """
-    content = ContentType.objects.get_for_model(obj)
-    for policy in Policy.objects.filter(object__object_id=obj.id, object__content_type=content):
-        policy.apply()
+    obj_type_map = get_objects_for_policy(apply_object)
+    for obj, ct in obj_type_map.items():
+        for policy in Policy.objects.filter(object__object_id=obj.id, object__content_type=ct):
+            policy.apply()
 
 
 def re_apply_all_polices():
diff --git a/python/rbac/roles.py b/python/rbac/roles.py
index 5aaab31a7c..3496cb46e7 100644
--- a/python/rbac/roles.py
+++ b/python/rbac/roles.py
@@ -12,21 +12,27 @@
 
 """RBAC Role classes"""
 
+from adwp_base.errors import raise_AdwpEx as err
 from django.apps import apps
 from django.contrib.contenttypes.models import ContentType
+from django.db import transaction
+from django.utils import timezone
 from guardian.models import UserObjectPermission, GroupObjectPermission
-from adwp_base.errors import raise_AdwpEx as err
-from rbac.models import Policy, PolicyPermission, Role, User, Group, Permission, RoleTypes
+
 from cm.models import (
     Action,
     ClusterObject,
     ServiceComponent,
     Host,
     HostComponent,
+    GroupConfig,
     TaskLog,
     JobLog,
     LogStorage,
+    DummyData,
 )
+from rbac.models import Policy, PolicyPermission, Role, User, Group, Permission
+from rbac.models import RoleTypes, get_objects_for_policy
 
 
 class AbstractRole:
@@ -70,12 +76,14 @@ def apply(self, policy: Policy, role: Role, user: User, group: Group, param_obj=
 
 
 def assign_user_or_group_perm(user, group, policy, perm, obj):
-    if user is not None:
-        uop = UserObjectPermission.objects.assign_perm(perm, user, obj)
-        policy.user_object_perm.add(uop)
-    if group is not None:
-        gop = GroupObjectPermission.objects.assign_perm(perm, group, obj)
-        policy.group_object_perm.add(gop)
+    with transaction.atomic():
+        DummyData.objects.filter(id=1).update(date=timezone.now())
+        if user is not None:
+            uop = UserObjectPermission.objects.assign_perm(perm, user, obj)
+            policy.user_object_perm.add(uop)
+        if group is not None:
+            gop = GroupObjectPermission.objects.assign_perm(perm, group, obj)
+            policy.group_object_perm.add(gop)
 
 
 class ObjectRole(AbstractRole):
@@ -126,43 +134,22 @@ def apply(self, policy, role, user, group, param_obj=None):
                 apply_jobs(task, policy, user, group)
 
 
-def get_perm_for_model(model):
+def get_perm_for_model(model, action='view'):
     ct = ContentType.objects.get_for_model(model)
-    codename = f'view_{model.__name__.lower()}'
+    codename = f'{action}_{model.__name__.lower()}'
     perm, _ = Permission.objects.get_or_create(content_type=ct, codename=codename)
     return perm
 
 
 def apply_jobs(task: TaskLog, policy: Policy, user: User, group: Group = None):
     assign_user_or_group_perm(user, group, policy, get_perm_for_model(TaskLog), task)
+    assign_user_or_group_perm(user, group, policy, get_perm_for_model(TaskLog, 'change'), task)
     for job in JobLog.objects.filter(task=task):
         assign_user_or_group_perm(user, group, policy, get_perm_for_model(JobLog), job)
         for log in LogStorage.objects.filter(job=job):
             assign_user_or_group_perm(user, group, policy, get_perm_for_model(LogStorage), log)
 
 
-def get_objects_for_policy(obj):
-    obj_type_map = {}
-    obj_type = obj.prototype.type
-    if obj_type == 'component':
-        object_list = [obj, obj.service, obj.cluster]
-    elif obj_type == 'service':
-        object_list = [obj, obj.cluster]
-    elif obj_type == 'host':
-        if obj.cluster:
-            object_list = [obj, obj.provider, obj.cluster]
-            for hc in HostComponent.objects.filter(cluster=obj.cluster, host=obj):
-                object_list.append(hc.service)
-                object_list.append(hc.component)
-        else:
-            object_list = [obj, obj.provider]
-    else:
-        object_list = [obj]
-    for policy_object in object_list:
-        obj_type_map[policy_object] = ContentType.objects.get_for_model(policy_object)
-    return obj_type_map
-
-
 def re_apply_policy_for_jobs(action_object, task):
     obj_type_map = get_objects_for_policy(action_object)
     object_model = action_object.__class__.__name__.lower()
@@ -206,12 +193,44 @@ def re_apply_policy_for_jobs(action_object, task):
                     apply_jobs(task, policy, None, group)
 
 
+class ConfigRole(AbstractRole):
+    """This Role apply permission to view and add config object"""
+
+    def apply(self, policy: Policy, role: Role, user: User, group: Group, param_obj=None):
+        for obj in policy.get_objects(param_obj):
+            if obj.config is None:
+                continue
+
+            object_type = ContentType.objects.get_for_model(obj)
+            config_groups = GroupConfig.objects.filter(object_type=object_type, object_id=obj.id)
+
+            for perm in role.get_permissions():
+
+                if perm.content_type.model == 'objectconfig':
+                    assign_user_or_group_perm(user, group, policy, perm, obj.config)
+                    for cg in config_groups:
+                        assign_user_or_group_perm(user, group, policy, perm, cg.config)
+
+                if perm.content_type.model == 'configlog':
+                    for config in obj.config.configlog_set.all():
+                        assign_user_or_group_perm(user, group, policy, perm, config)
+                    for cg in config_groups:
+                        for config in cg.config.configlog_set.all():
+                            assign_user_or_group_perm(user, group, policy, perm, config)
+
+                if perm.content_type.model == 'groupconfig':
+                    for cg in config_groups:
+                        assign_user_or_group_perm(user, group, policy, perm, cg)
+
+
 class ParentRole(AbstractRole):
     """This Role is used for complex Roles that can include other Roles"""
 
     def find_and_apply(self, obj, policy, role, user, group=None):
         """Find Role of appropriate type and apply it to specified object"""
-        for r in role.child.filter(class_name__in=['ObjectRole', 'ActionRole', 'TaskRole']):
+        for r in role.child.filter(
+            class_name__in=['ObjectRole', 'ActionRole', 'TaskRole', 'ConfigRole']
+        ):
             if obj.prototype.type in r.parametrized_by_type:
                 r.apply(policy, user, group, obj)
 
@@ -227,6 +246,9 @@ def apply(
             parametrized_by.update(set(r.parametrized_by_type))
 
         for obj in policy.get_objects(param_obj):
+            view_cluster_perm = Permission.objects.get(codename='view_cluster')
+            view_service_perm = Permission.objects.get(codename='view_clusterobject')
+
             self.find_and_apply(obj, policy, role, user, group)
 
             if obj.prototype.type == 'cluster':
@@ -247,7 +269,7 @@ def apply(
                 if 'host' in parametrized_by:
                     for hc in HostComponent.obj.filter(cluster=obj.cluster, service=obj):
                         self.find_and_apply(hc.host, policy, role, user, group)
-                self.find_and_apply(obj.cluster, policy, role, user, group)
+                assign_user_or_group_perm(user, group, policy, view_cluster_perm, obj.cluster)
 
             elif obj.prototype.type == 'component':
                 if 'host' in parametrized_by:
@@ -255,8 +277,8 @@ def apply(
                         cluster=obj.cluster, service=obj.service, component=obj
                     ):
                         self.find_and_apply(hc.host, policy, role, user, group)
-                self.find_and_apply(obj.cluster, policy, role, user, group)
-                self.find_and_apply(obj.service, policy, role, user, group)
+                assign_user_or_group_perm(user, group, policy, view_cluster_perm, obj.cluster)
+                assign_user_or_group_perm(user, group, policy, view_service_perm, obj.service)
 
             elif obj.prototype.type == 'provider':
                 if 'host' in parametrized_by:
diff --git a/python/rbac/upgrade/role.py b/python/rbac/upgrade/role.py
index 32654748e9..9526f187df 100644
--- a/python/rbac/upgrade/role.py
+++ b/python/rbac/upgrade/role.py
@@ -92,7 +92,7 @@ def upgrade_role(role: dict, data: dict) -> Role:
     """Upgrade single role"""
     perm_list = get_role_permissions(role, data['roles'])
     try:
-        new_role = Role.objects.get(name=role['name'])
+        new_role = Role.objects.get(name=role['name'], built_in=True)
         new_role.permissions.clear()
     except Role.DoesNotExist:
         new_role = Role(name=role['name'])
@@ -155,7 +155,7 @@ def get_role_spec(data: str, schema: str) -> dict:
 def prepare_hidden_roles(bundle: Bundle):
     """Prepares hidden roles"""
     hidden_roles = {}
-
+    get_host_object_role = Role.objects.get(name='Get host object', built_in=True)
     for act in Action.objects.filter(prototype__bundle=bundle):
         name_prefix = f'{act.prototype.type} action:'.title()
         name = f'{name_prefix} {act.display_name}'
@@ -203,6 +203,8 @@ def prepare_hidden_roles(bundle: Bundle):
         if name not in hidden_roles:
             hidden_roles[name] = {'parametrized_by_type': act.prototype.type, 'children': []}
         hidden_roles[name]['children'].append(role)
+        if act.host_action and get_host_object_role not in hidden_roles[name]['children']:
+            hidden_roles[name]['children'].append(get_host_object_role)
     return hidden_roles
 
 
@@ -295,13 +297,14 @@ def init_roles():
     if rm is None:
         rm = RoleMigration(version=0)
     if role_data['version'] > rm.version:
-        upgrade(role_data)
-        rm.version = role_data['version']
-        rm.save()
-        update_all_bundle_roles()
-        re_apply_all_polices()
-        msg = f'Roles are upgraded to version {rm.version}'
-        log.info(msg)
+        with transaction.atomic():
+            upgrade(role_data)
+            rm.version = role_data['version']
+            rm.save()
+            update_all_bundle_roles()
+            re_apply_all_polices()
+            msg = f'Roles are upgraded to version {rm.version}'
+            log.info(msg)
     else:
         msg = f'Roles are already at version {rm.version}'
 
diff --git a/python/rbac/upgrade/role_schema.yaml b/python/rbac/upgrade/role_schema.yaml
index 536077ec31..b08f94921c 100644
--- a/python/rbac/upgrade/role_schema.yaml
+++ b/python/rbac/upgrade/role_schema.yaml
@@ -46,6 +46,7 @@ class_name:
     - ModelRole
     - ObjectRole
     - ParentRole
+    - ConfigRole
 
 type:
   match: set
diff --git a/python/rbac/upgrade/role_spec.yaml b/python/rbac/upgrade/role_spec.yaml
index 849e564353..22792309e1 100644
--- a/python/rbac/upgrade/role_spec.yaml
+++ b/python/rbac/upgrade/role_spec.yaml
@@ -3,9 +3,35 @@
 version: 2
 
 roles:
-    - name: Create host
+    - name: Add host
       description: The ability to add new host
-      type: business
+      type: hidden
+      module_name: rbac.roles
+      class_name: ModelRole
+      apps:
+        - label: cm
+          models:
+            - name: host
+              codenames:
+                - add
+
+    - name: Delete host
+      description: The ability to delete host
+      type: hidden
+      module_name: rbac.roles
+      class_name: ObjectRole
+      parametrized_by:
+        - host
+      apps:
+        - label: cm
+          models:
+            - name: host
+              codenames:
+                - delete
+
+    - name: Add host to provider
+      description: The ability to add host to provider
+      type: hidden
       module_name: rbac.roles
       class_name: ObjectRole
       parametrized_by:
@@ -13,14 +39,27 @@ roles:
       init_params:
         app_name: cm
         model: HostProvider
-      any_category: false
       apps:
         - label: cm
           models:
             - name: hostprovider
               codenames:
+                - view
                 - add_host_to
 
+    - name: Create host
+      description: The ability to add new host
+      type: business
+      module_name: rbac.roles
+      class_name: ParentRole
+      parametrized_by:
+        - provider
+      any_category: false
+      child:
+        - Add host
+        - Add host to provider
+        - Get host object
+
     - name: Create provider
       description: The ability to add new provider
       type: business
@@ -93,16 +132,19 @@ roles:
       parametrized_by:
         - cluster
       module_name: rbac.roles
-      class_name: ObjectRole
-      init_params:
-        app_name: cm
-        model: Cluster
+      class_name: ConfigRole
       apps:
         - label: cm
           models:
-            - name: cluster
+            - name: objectconfig
+              codenames:
+                - view
+            - name: configlog
+              codenames:
+                - view
+            - name: groupconfig
               codenames:
-                - view_config_of
+                - view
 
     - name: View cluster configurations
       description: The ability to view the cluster configuration page
@@ -118,8 +160,6 @@ roles:
       child:
         - Get cluster object
         - View cluster config
-        - View config endpoints
-
 
     - name: View service config
       description: The ability to view the service configuration page
@@ -127,16 +167,19 @@ roles:
       parametrized_by:
         - service
       module_name: rbac.roles
-      class_name: ObjectRole
-      init_params:
-        app_name: cm
-        model: ClusterObject
+      class_name: ConfigRole
       apps:
         - label: cm
           models:
-            - name: clusterobject
+            - name: objectconfig
+              codenames:
+                - view
+            - name: configlog
               codenames:
-                - view_config_of
+                - view
+            - name: groupconfig
+              codenames:
+                - view
 
     - name: View service configurations
       description: The ability to view the service configuration page
@@ -150,10 +193,8 @@ roles:
         app_name: cm
         model: ClusterObject
       child:
-        - Get cluster object
         - Get service object
         - View service config
-        - View config endpoints
 
     - name: View component config
       description: The ability to view the component configuration page
@@ -161,16 +202,19 @@ roles:
       parametrized_by:
         - component
       module_name: rbac.roles
-      class_name: ObjectRole
-      init_params:
-        app_name: cm
-        model: ServiceComponent
+      class_name: ConfigRole
       apps:
         - label: cm
           models:
-            - name: servicecomponent
+            - name: objectconfig
               codenames:
-                - view_config_of
+                - view
+            - name: configlog
+              codenames:
+                - view
+            - name: groupconfig
+              codenames:
+                - view
 
     - name: View component configurations
       description: The ability to view the component configuration page
@@ -185,11 +229,9 @@ roles:
         app_name: cm
         model: ServiceComponent
       child:
-        - Get cluster object
         - Get service object
         - Get component object
         - View component config
-        - View config endpoints
 
     - name: View provider config
       description: The ability to view the provider configuration page
@@ -197,16 +239,19 @@ roles:
       parametrized_by:
         - provider
       module_name: rbac.roles
-      class_name: ObjectRole
-      init_params:
-        app_name: cm
-        model: HostProvider
+      class_name: ConfigRole
       apps:
         - label: cm
           models:
-            - name: hostprovider
+            - name: objectconfig
+              codenames:
+                - view
+            - name: configlog
               codenames:
-                - view_config_of
+                - view
+            - name: groupconfig
+              codenames:
+                - view
 
     - name: View provider configurations
       description: The ability to view the provider configuration page
@@ -222,7 +267,6 @@ roles:
       child:
         - Get provider object
         - View provider config
-        - View config endpoints
 
     - name: View host config
       description: The ability to view the host configuration page
@@ -230,16 +274,19 @@ roles:
       parametrized_by:
         - host
       module_name: rbac.roles
-      class_name: ObjectRole
-      init_params:
-        app_name: cm
-        model: Host
+      class_name: ConfigRole
       apps:
         - label: cm
           models:
-            - name: host
+            - name: objectconfig
+              codenames:
+                - view
+            - name: configlog
+              codenames:
+                - view
+            - name: groupconfig
               codenames:
-                - view_config_of
+                - view
 
     - name: View host configurations
       description: The ability to view the host configuration page
@@ -255,22 +302,6 @@ roles:
       child:
         - Get host object
         - View host config
-        - View config endpoints
-
-    - name: View config endpoints
-      description: The ability to view list of all configs separatly
-      type: hidden
-      module_name: rbac.roles
-      class_name: ModelRole
-      apps:
-      - label: cm
-        models:
-          - name: objectconfig
-            codenames:
-              - view
-          - name: configlog
-            codenames:
-              - view
 
     - name: View any object configuration
       description: The ability to view config page of all objects except ADCM settings
@@ -281,9 +312,6 @@ roles:
       apps:
         - label: cm
           models:
-            - name: adcm
-              codenames:
-                - view_config_of
             - name: cluster
               codenames:
                 - view
@@ -305,6 +333,30 @@ roles:
             - name: configlog
               codenames:
                 - view
+            - name: groupconfig
+              codenames:
+                - view
+
+    - name: Edit config
+      description: The abiluty to change and add configuration
+      type: hidden
+      module_name: rbac.roles
+      class_name: ModelRole
+      apps:
+        - label: cm
+          models:
+            - name: objectconfig
+              codenames:
+                - change
+            - name: configlog
+              codenames:
+                - add
+                - change
+            - name: groupconfig
+              codenames:
+                - add
+                - change
+                - delete
 
     - name: Edit cluster config
       description: The ability to change and add new cluster configuration
@@ -321,7 +373,6 @@ roles:
           models:
             - name: cluster
               codenames:
-                - view_config_of
                 - change_config_of
 
     - name: Edit cluster configurations
@@ -337,8 +388,9 @@ roles:
         model: Cluster
       child:
         - Get cluster object
+        - View cluster config
+        - Edit config
         - Edit cluster config
-        - Edit config endpoints
 
     - name: Edit service config
       description: The ability to change and add new service configuration
@@ -355,7 +407,6 @@ roles:
           models:
             - name: clusterobject
               codenames:
-                - view_config_of
                 - change_config_of
 
     - name: Edit service configurations
@@ -370,10 +421,10 @@ roles:
         app_name: cm
         model: ClusterObject
       child:
-        - Get cluster object
         - Get service object
+        - View service config
+        - Edit config
         - Edit service config
-        - Edit config endpoints
 
     - name: Edit component config
       description: The ability to change and add new component configuration
@@ -390,7 +441,6 @@ roles:
           models:
             - name: servicecomponent
               codenames:
-                - view_config_of
                 - change_config_of
 
     - name: Edit component configurations
@@ -406,11 +456,11 @@ roles:
         app_name: cm
         model: ServiceComponent
       child:
-        - Get cluster object
         - Get service object
         - Get component object
+        - View component config
+        - Edit config
         - Edit component config
-        - Edit config endpoints
 
     - name: Edit provider config
       description: The ability to change and add new provider configuration
@@ -427,7 +477,6 @@ roles:
           models:
             - name: hostprovider
               codenames:
-                - view_config_of
                 - change_config_of
 
     - name: Edit provider configurations
@@ -443,8 +492,9 @@ roles:
         model: HostProvider
       child:
         - Get provider object
+        - View provider config
+        - Edit config
         - Edit provider config
-        - Edit config endpoints
 
     - name: Edit host config
       description: The ability to change and add new host configuration
@@ -461,7 +511,6 @@ roles:
           models:
             - name: host
               codenames:
-                - view_config_of
                 - change_config_of
 
     - name: Edit host configurations
@@ -477,25 +526,9 @@ roles:
         model: Host
       child:
         - Get host object
+        - View host config
+        - Edit config
         - Edit host config
-        - Edit config endpoints
-
-    - name: Edit config endpoints
-      description: The ability to edit list of all configs separatly
-      type: hidden
-      module_name: rbac.roles
-      class_name: ModelRole
-      apps:
-        - label: cm
-          models:
-            - name: objectconfig
-              codenames:
-                - view
-                - change
-            - name: configlog
-              codenames:
-                - view
-                - change
 
     - name: View cluster imports
       description: The ability to view the cluster import page
@@ -616,9 +649,21 @@ roles:
         - Manage cluster imports
         - Manage service imports
 
-    - name: Add service
+    - name: Create service
+      description: The ability to add new service
+      type: hidden
+      module_name: rbac.roles
+      class_name: ModelRole
+      apps:
+        - label: cm
+          models:
+            - name: clusterobject
+              codenames:
+                - add
+
+    - name: Add service hidden
       description: The ability to add service to cluster
-      type: business
+      type: hidden
       parametrized_by:
         - cluster
       module_name: rbac.roles
@@ -626,7 +671,6 @@ roles:
       init_params:
         app_name: cm
         model: Cluster
-      any_category: true
       apps:
         - label: cm
           models:
@@ -635,6 +679,19 @@ roles:
                 - add_service_to
                 - view
 
+    - name: Add service
+      description: The ability to add service to cluster
+      type: business
+      parametrized_by:
+        - cluster
+      module_name: rbac.roles
+      class_name: ParentRole
+      any_category: true
+      child:
+        - Create service
+        - Add service hidden
+        - Get service object
+
     - name: Remove service hidden
       description: The ability to remove service from cluster
       type: hidden
@@ -668,6 +725,21 @@ roles:
         - Remove service hidden
         - Get cluster object
 
+    - name: Remove hosts hidden
+      display_name: Remove hosts hidden
+      description: The ability to remove host hidden
+      type: hidden
+      parametrized_by:
+        - host
+      module_name: rbac.roles
+      class_name: ObjectRole
+      apps:
+        - label: cm
+          models:
+            - name: host
+              codenames:
+                - remove
+
     - name: Remove hosts
       display_name: Remove host
       description: The ability to remove host
@@ -675,18 +747,31 @@ roles:
       parametrized_by:
         - host
       module_name: rbac.roles
+      class_name: ParentRole
+      any_category: true
+      child:
+        - Get host object
+        - Delete host
+        - Remove hosts hidden
+
+    - name: Map hosts hidden
+      display_name: Add hosts to the Cluster hidden
+      description: The ability to map hosts to the Cluster
+      type: hidden
+      parametrized_by:
+        - cluster
+      module_name: rbac.roles
       class_name: ObjectRole
       init_params:
         app_name: cm
-        model: Host
-      any_category: true
+        model: Cluster
       apps:
         - label: cm
           models:
-            - name: host
+            - name: cluster
               codenames:
                 - view
-                - delete
+                - map_host_to
 
     - name: Map hosts
       display_name: Add hosts to the Cluster
@@ -695,8 +780,21 @@ roles:
       parametrized_by:
         - cluster
       module_name: rbac.roles
-      class_name: ObjectRole
+      class_name: ParentRole
       any_category: true
+      child:
+        - Add host
+        - Get host
+        - Map hosts hidden
+
+    - name: Unmap hosts hidden
+      display_name: Remove hosts from the Cluster hidden
+      description: The ability to unmap hosts from the Cluster
+      type: hidden
+      parametrized_by:
+        - cluster
+      module_name: rbac.roles
+      class_name: ObjectRole
       init_params:
         app_name: cm
         model: Cluster
@@ -706,7 +804,7 @@ roles:
             - name: cluster
               codenames:
                 - view
-                - map_host_to
+                - unmap_host_from
 
     - name: Unmap hosts
       display_name: Remove hosts from the Cluster
@@ -715,18 +813,26 @@ roles:
       parametrized_by:
         - cluster
       module_name: rbac.roles
-      class_name: ObjectRole
+      class_name: ParentRole
       any_category: true
-      init_params:
-        app_name: cm
-        model: Cluster
+      child:
+        - Get host object
+        - Delete host
+        - Unmap hosts hidden
+
+    - name: View host-components hidden
+      description: The ability to view exact cluster's host-component page
+      type: hidden
+      parametrized_by:
+        - cluster
+      module_name: rbac.roles
+      class_name: ObjectRole
       apps:
         - label: cm
           models:
             - name: cluster
               codenames:
-                - view
-                - unmap_host_from
+                - view_host_components_of
 
     - name: View host-components
       description: The ability to view exact cluster's host-component page
@@ -734,18 +840,14 @@ roles:
       parametrized_by:
         - cluster
       module_name: rbac.roles
-      class_name: ObjectRole
+      class_name: ParentRole
       any_category: true
-      init_params:
-        app_name: cm
-        model: Cluster
-      apps:
-        - label: cm
-          models:
-            - name: cluster
-              codenames:
-                - view
-                - view_host_components_of
+      child:
+        - Get cluster object
+        - Get service object
+        - Get component object
+        - Get host object
+        - View host-components hidden
 
     - name: View any object host-components
       description: The ability to view host-components page of all clusters
@@ -756,33 +858,52 @@ roles:
       apps:
         - label: cm
           models:
-            - name: hostcomponent
+            - name: cluster
               codenames:
                 - view
-            - name: cluster
+            - name: clusterobject
+              codenames:
+                - view
+            - name: servicecomponent
+              codenames:
+                - view
+            - name: host
+              codenames:
+                - view
+            - name: hostcomponent
               codenames:
                 - view
 
-    - name: Edit host-components
+    - name: Edit host-components hidden
       description: The ability to edit exact cluster's host-component page
-      type: business
+      type: hidden
       parametrized_by:
         - cluster
       module_name: rbac.roles
       class_name: ObjectRole
-      any_category: true
-      init_params:
-        app_name: cm
-        model: Cluster
       apps:
         - label: cm
           models:
             - name: cluster
               codenames:
-                - view
-                - view_host_components_of
                 - edit_host_components_of
 
+    - name: Edit host-components
+      description: The ability to edit exact cluster's host-component page
+      type: business
+      parametrized_by:
+        - cluster
+      module_name: rbac.roles
+      class_name: ParentRole
+      any_category: true
+      child:
+        - Get cluster object
+        - Get service object
+        - Get component object
+        - Get host object
+        - View host-components hidden
+        - Edit host-components hidden
+
     - name: Upgrade cluster bundle
       description: Update the cluster bundle
       type: business
@@ -872,7 +993,6 @@ roles:
           models:
             - name: bundle
               codenames:
-                - view
                 - delete
 
     - name: View ADCM settings
@@ -886,7 +1006,6 @@ roles:
           models:
             - name: adcm
               codenames:
-                - view
                 - view_settings_of
 
     - name: Edit ADCM settings
@@ -900,7 +1019,6 @@ roles:
           models:
             - name: adcm
               codenames:
-                - view
                 - view_settings_of
                 - change_settings_of
 
@@ -930,6 +1048,7 @@ roles:
           models:
             - name: user
               codenames:
+                - view
                 - add
 
     - name: Edit user
@@ -945,6 +1064,7 @@ roles:
           models:
             - name: user
               codenames:
+                - view
                 - change
 
     - name: Remove user
@@ -960,6 +1080,7 @@ roles:
           models:
             - name: user
               codenames:
+                - view
                 - delete
 
     - name: View roles
@@ -988,6 +1109,7 @@ roles:
           models:
             - name: role
               codenames:
+                - view
                 - add
 
     - name: Edit role
@@ -1003,6 +1125,7 @@ roles:
           models:
             - name: role
               codenames:
+                - view
                 - change
 
     - name: Remove roles
@@ -1018,6 +1141,7 @@ roles:
           models:
             - name: role
               codenames:
+                - view
                 - delete
 
     - name: View group
@@ -1046,6 +1170,7 @@ roles:
           models:
             - name: group
               codenames:
+                - view
                 - add
 
     - name: Edit group
@@ -1061,6 +1186,7 @@ roles:
           models:
             - name: group
               codenames:
+                - view
                 - change
 
     - name: Remove group
@@ -1076,6 +1202,7 @@ roles:
           models:
             - name: group
               codenames:
+                - view
                 - delete
 
     - name: View policy
@@ -1104,6 +1231,7 @@ roles:
           models:
             - name: policy
               codenames:
+                - view
                 - add
 
     - name: Edit policy
@@ -1119,6 +1247,7 @@ roles:
           models:
             - name: policy
               codenames:
+                - view
                 - change
 
     - name: Remove policy
@@ -1133,20 +1262,9 @@ roles:
         - label: rbac
           models:
             - name: policy
-              codenames:
-                - delete
-
-    - name: Get ADCM object
-      description: Read access to ADCM
-      type: hidden
-      module_name: rbac.roles
-      class_name: ModelRole
-      apps:
-        - label: cm
-          models:
-            - name: adcm
               codenames:
                 - view
+                - delete
 
     - name: Get provider
       display_name: Get all providers
@@ -1317,45 +1435,6 @@ roles:
               codenames:
                 - view
 
-    - name: Get stack
-      description: Read access to all Bundle
-      type: hidden
-      module_name: rbac.roles
-      class_name: ModelRole
-      apps:
-        - label: cm
-          models:
-            - name: bundle
-              codenames:
-                - view
-            - name: prototype
-              codenames:
-                - view
-
-    - name: Get bundle
-      description: Read access to all Bundle
-      type: hidden
-      module_name: rbac.roles
-      class_name: ModelRole
-      apps:
-        - label: cm
-          models:
-            - name: bundle
-              codenames:
-                - view
-
-    - name: Get concerns
-      description: Read access to all concerns
-      type: hidden
-      module_name: rbac.roles
-      class_name: ModelRole
-      apps:
-        - label: cm
-          models:
-            - name: concernitem
-              codenames:
-                - view
-
     - name: ADCM User
       type: role
       module_name: rbac.roles
@@ -1381,7 +1460,6 @@ roles:
       module_name: rbac.roles
       class_name: ParentRole
       child:
-        - Get cluster object
         - Get service object
         - Get component object
         - Get host object
diff --git a/python/rbac/viewsets.py b/python/rbac/viewsets.py
index d69c80d12b..2887fc7f7a 100644
--- a/python/rbac/viewsets.py
+++ b/python/rbac/viewsets.py
@@ -12,36 +12,14 @@
 
 """RBAC Permissions classes"""
 
-from guardian.shortcuts import get_objects_for_user
-from rest_framework import viewsets
-from rest_framework.permissions import DjangoModelPermissions, DjangoObjectPermissions
+from rest_framework.permissions import DjangoObjectPermissions
 
 
-class DjangoModelPerm(DjangoModelPermissions):
-    """
-    Similar to `DjangoModelPermissions`, but adding 'view' permissions.
-    """
-
-    perms_map = {
-        'GET': ['%(app_label)s.view_%(model_name)s'],
-        'OPTIONS': ['%(app_label)s.view_%(model_name)s'],
-        'HEAD': ['%(app_label)s.view_%(model_name)s'],
-        'POST': ['%(app_label)s.add_%(model_name)s'],
-        'PUT': ['%(app_label)s.change_%(model_name)s'],
-        'PATCH': ['%(app_label)s.change_%(model_name)s'],
-        'DELETE': ['%(app_label)s.delete_%(model_name)s'],
-    }
-
-
-class DjangoObjectPerm(DjangoObjectPermissions):
-    """
-    Similar to `DjangoObjectPermissions`, but adding 'view' permissions.
-    """
-
+class DjangoOnlyObjectPermissions(DjangoObjectPermissions):
     perms_map = {
-        'GET': ['%(app_label)s.view_%(model_name)s'],
-        'OPTIONS': ['%(app_label)s.view_%(model_name)s'],
-        'HEAD': ['%(app_label)s.view_%(model_name)s'],
+        'GET': [],
+        'OPTIONS': [],
+        'HEAD': [],
         'POST': ['%(app_label)s.add_%(model_name)s'],
         'PUT': ['%(app_label)s.change_%(model_name)s'],
         'PATCH': ['%(app_label)s.change_%(model_name)s'],
@@ -49,24 +27,4 @@ class DjangoObjectPerm(DjangoObjectPermissions):
     }
 
     def has_permission(self, request, view):
-        model_cls = self._queryset(view).model
-        model_perms = self.get_required_permissions(request.method, model_cls)
-        objects = get_objects_for_user(request.user, model_perms)
-        if objects:
-            return True
-        return super().has_permission(request, view)
-
-    def has_object_permission(self, request, view, obj):
-        model_cls = self._queryset(view).model
-        user = request.user
-        model_perms = self.get_required_permissions(request.method, model_cls)
-        object_perms = self.get_required_object_permissions(request.method, model_cls)
-        if user.has_perms(object_perms, obj) or user.has_perms(model_perms):
-            return True
-        return False
-
-
-class ModelPermViewSet(viewsets.ModelViewSet):  # pylint: disable=too-many-ancestors
-    """Replace of DRF ModelViewSet with view permission"""
-
-    permission_classes = (DjangoObjectPerm,)
+        return True


Test patch:
diff --git a/python/rbac/tests/tests_api/test_policy.py b/python/rbac/tests/tests_api/test_policy.py
index f08b59a6dd..068cc0a856 100644
--- a/python/rbac/tests/tests_api/test_policy.py
+++ b/python/rbac/tests/tests_api/test_policy.py
@@ -112,49 +112,49 @@ def test_create_policy(admin_api_client):
             },
         ),
         (
-            {"name": "test", "role": {"id": 1}},
+            {"name": "test", "role": {"id": 5}},
             {
                 "role": ["Role with type \"business\" could not be used in policy"],
                 "object": ["This field is required."],
             },
         ),
         (
-            {"name": "test", "role": {"id": 5}},
+            {"name": "test", "role": {"id": 1}},
             {
                 "role": ["Role with type \"hidden\" could not be used in policy"],
                 "object": ["This field is required."],
             },
         ),
         (
-            {"name": "test", "role": {"id": 85}, "user": None},
+            {"name": "test", "role": {"id": 90}, "user": None},
             {
                 "user": ["This field may not be null."],
                 "object": ["This field is required."],
             },
         ),
         (
-            {"name": "test", "role": {"id": 85}, "user": 1},
+            {"name": "test", "role": {"id": 90}, "user": 1},
             {
                 "user": {"non_field_errors": ["Expected a list of items but got type \"int\"."]},
                 "object": ["This field is required."],
             },
         ),
         (
-            {"name": "test", "role": {"id": 85}, "user": "string"},
+            {"name": "test", "role": {"id": 90}, "user": "string"},
             {
                 "user": {"non_field_errors": ["Expected a list of items but got type \"str\"."]},
                 "object": ["This field is required."],
             },
         ),
         (
-            {"name": "test", "role": {"id": 85}, "user": {}},
+            {"name": "test", "role": {"id": 90}, "user": {}},
             {
                 "user": {"non_field_errors": ["Expected a list of items but got type \"dict\"."]},
                 "object": ["This field is required."],
             },
         ),
         (
-            {"name": "test", "role": {"id": 85}, "user": [1]},
+            {"name": "test", "role": {"id": 90}, "user": [1]},
             {
                 "user": [
                     {"non_field_errors": ["Invalid data. Expected a dictionary, but got int."]}
@@ -163,7 +163,7 @@ def test_create_policy(admin_api_client):
             },
         ),
         (
-            {"name": "test", "role": {"id": 85}, "user": ["string"]},
+            {"name": "test", "role": {"id": 90}, "user": ["string"]},
             {
                 "user": [
                     {"non_field_errors": ["Invalid data. Expected a dictionary, but got str."]}
@@ -172,63 +172,63 @@ def test_create_policy(admin_api_client):
             },
         ),
         (
-            {"name": "test", "role": {"id": 85}, "user": [{}]},
+            {"name": "test", "role": {"id": 90}, "user": [{}]},
             {
                 "user": [{"id": ["This field is required."]}],
                 "object": ["This field is required."],
             },
         ),
         (
-            {"name": "test", "role": {"id": 85}, "user": [{"id": None}]},
+            {"name": "test", "role": {"id": 90}, "user": [{"id": None}]},
             {
                 "user": [{"id": ["This field may not be null."]}],
                 "object": ["This field is required."],
             },
         ),
         (
-            {"name": "test", "role": {"id": 85}, "user": [{"id": "string"}]},
+            {"name": "test", "role": {"id": 90}, "user": [{"id": "string"}]},
             {
                 "user": [{"id": ["Incorrect type. Expected pk value, received str."]}],
                 "object": ["This field is required."],
             },
         ),
         (
-            {"name": "test", "role": {"id": 85}, "user": [{"id": 1000}]},
+            {"name": "test", "role": {"id": 90}, "user": [{"id": 1000}]},
             {
                 "user": [{"id": ["Invalid pk \"1000\" - object does not exist."]}],
                 "object": ["This field is required."],
             },
         ),
         (
-            {"name": "test", "role": {"id": 85}, "user": [{"id": 2}], "object": None},
+            {"name": "test", "role": {"id": 90}, "user": [{"id": 2}], "object": None},
             {"object": ["This field may not be null."]},
         ),
         (
-            {"name": "test", "role": {"id": 85}, "user": [{"id": 2}], "object": 1},
+            {"name": "test", "role": {"id": 90}, "user": [{"id": 2}], "object": 1},
             {"object": ["the field does not match the scheme"]},
         ),
         (
-            {"name": "test", "role": {"id": 85}, "user": [{"id": 2}], "object": "string"},
+            {"name": "test", "role": {"id": 90}, "user": [{"id": 2}], "object": "string"},
             {"object": ["the field does not match the scheme"]},
         ),
         (
-            {"name": "test", "role": {"id": 85}, "user": [{"id": 2}], "object": {}},
+            {"name": "test", "role": {"id": 90}, "user": [{"id": 2}], "object": {}},
             {"object": ["the field does not match the scheme"]},
         ),
         (
-            {"name": "test", "role": {"id": 85}, "user": [{"id": 2}], "object": [1]},
+            {"name": "test", "role": {"id": 90}, "user": [{"id": 2}], "object": [1]},
             {"object": ["the field does not match the scheme"]},
         ),
         (
-            {"name": "test", "role": {"id": 85}, "user": [{"id": 2}], "object": ["string"]},
+            {"name": "test", "role": {"id": 90}, "user": [{"id": 2}], "object": ["string"]},
             {"object": ["the field does not match the scheme"]},
         ),
         (
-            {"name": "test", "role": {"id": 85}, "user": [{"id": 2}], "object": [{}]},
+            {"name": "test", "role": {"id": 90}, "user": [{"id": 2}], "object": [{}]},
             {"object": ["the field does not match the scheme"]},
         ),
         (
-            {"name": "test", "role": {"id": 85}, "user": [{"id": 2}], "object": [{"id": 1}]},
+            {"name": "test", "role": {"id": 90}, "user": [{"id": 2}], "object": [{"id": 1}]},
             {"object": ["the field does not match the scheme"]},
         ),
     ]
diff --git a/python/rbac/tests/tests_model/conftest.py b/python/rbac/tests/tests_model/conftest.py
new file mode 100644
index 0000000000..c357ddffaf
--- /dev/null
+++ b/python/rbac/tests/tests_model/conftest.py
@@ -0,0 +1,306 @@
+import pytest
+from django.contrib.auth.models import Permission
+from django.contrib.contenttypes.models import ContentType
+
+from cm.models import (
+    Bundle,
+    Prototype,
+    Cluster,
+    ClusterObject,
+    ServiceComponent,
+    HostProvider,
+    Host,
+)
+from rbac.models import Role, User, Group
+
+
+def cook_role(name, class_name, obj_type=None):
+    if obj_type is None:
+        obj_type = []
+    return Role.objects.create(
+        name=name,
+        display_name=name,
+        module_name='rbac.roles',
+        class_name=class_name,
+        parametrized_by_type=obj_type,
+    )
+
+
+def cook_user(name):
+    return User.objects.create(username=name, is_active=True, is_superuser=False)
+
+
+def cook_group(name):
+    return Group.objects.create(name=name)
+
+
+def cook_perm(app, codename, model):
+    content, _ = ContentType.objects.get_or_create(app_label=app, model=model)
+    perm, _ = Permission.objects.get_or_create(codename=f'{codename}_{model}', content_type=content)
+    return perm
+
+
+def get_bundle(number):
+    bundle, _ = Bundle.objects.get_or_create(name=f'bundle_{number}', version='1.0')
+    return bundle
+
+
+def get_cluster(bundle, number):
+    cp, _ = Prototype.objects.get_or_create(bundle=bundle, type='cluster', name=f'cluster_{number}')
+    cluster, _ = Cluster.objects.get_or_create(name=f'Cluster {number}', prototype=cp)
+    return cluster
+
+
+def get_service(cluster, bundle, number):
+    sp, _ = Prototype.objects.get_or_create(bundle=bundle, type='service', name=f'service_{number}')
+    service, _ = ClusterObject.objects.get_or_create(cluster=cluster, prototype=sp)
+    return service
+
+
+def get_component(cluster, service, bundle, number):
+    cp, _ = Prototype.objects.get_or_create(
+        bundle=bundle, type='component', name=f'component_{number}', parent=service.prototype
+    )
+    component, _ = ServiceComponent.objects.get_or_create(
+        cluster=cluster, service=service, prototype=cp
+    )
+    return component
+
+
+def get_provider():
+    bundle, _ = Bundle.objects.get_or_create(name='provider', version='1.0')
+    pp, _ = Prototype.objects.get_or_create(bundle=bundle, type='provider', name='provider')
+    p, _ = HostProvider.objects.get_or_create(name='provider', prototype=pp)
+    return p, bundle
+
+
+def get_host(b, p, number):
+    hp, _ = Prototype.objects.get_or_create(bundle=b, type='host', name='host')
+    host, _ = Host.objects.get_or_create(prototype=hp, provider=p, fqdn=f'host_{number}')
+    return host
+
+
+@pytest.fixture()
+def bundle1():
+    bundle = get_bundle(1)
+    return bundle
+
+
+@pytest.fixture()
+def cluster1():
+    bundle = get_bundle(1)
+    cluster = get_cluster(bundle, 1)
+    return cluster
+
+
+@pytest.fixture()
+def service1():
+    bundle = get_bundle(1)
+    cluster = get_cluster(bundle, 1)
+    service = get_service(cluster, bundle, 1)
+    return service
+
+
+@pytest.fixture()
+def service2():
+    bundle = get_bundle(1)
+    cluster = get_cluster(bundle, 1)
+    service = get_service(cluster, bundle, 2)
+    return service
+
+
+@pytest.fixture()
+def component11():
+    bundle = get_bundle(1)
+    cluster = get_cluster(bundle, 1)
+    service = get_service(cluster, bundle, 1)
+    component = get_component(cluster, service, bundle, 1)
+    return component
+
+
+@pytest.fixture()
+def component12():
+    bundle = get_bundle(1)
+    cluster = get_cluster(bundle, 1)
+    service = get_service(cluster, bundle, 1)
+    component = get_component(cluster, service, bundle, 2)
+    return component
+
+
+@pytest.fixture()
+def component21():
+    bundle = get_bundle(1)
+    cluster = get_cluster(bundle, 1)
+    service = get_service(cluster, bundle, 2)
+    component = get_component(cluster, service, bundle, 1)
+    return component
+
+
+@pytest.fixture()
+def cluster2():
+    bundle = get_bundle(2)
+    cluster = get_cluster(bundle, 2)
+    return cluster
+
+
+@pytest.fixture()
+def provider():
+    p, _ = get_provider()
+    return p
+
+
+@pytest.fixture()
+def host1():
+    p, bundle = get_provider()
+    host = get_host(bundle, p, 1)
+    return host
+
+
+@pytest.fixture()
+def host2():
+    p, bundle = get_provider()
+    host = get_host(bundle, p, 2)
+    return host
+
+
+@pytest.fixture()
+def host3():
+    p, bundle = get_provider()
+    host = get_host(bundle, p, 3)
+    return host
+
+
+@pytest.fixture
+def object_role():
+    return cook_role('object role', 'ObjectRole')
+
+
+@pytest.fixture()
+def model_role():
+    return cook_role('model role', 'ModelRole')
+
+
+@pytest.fixture()
+def user():
+    return cook_user('user')
+
+
+@pytest.fixture()
+def user1():
+    return cook_user('user1')
+
+
+@pytest.fixture()
+def group():
+    return cook_group('group')
+
+
+@pytest.fixture()
+def group1():
+    return cook_group('group1')
+
+
+@pytest.fixture()
+def add_host_perm():
+    return cook_perm('cm', 'add', 'host')
+
+
+@pytest.fixture()
+def view_cluster_perm():
+    return cook_perm('cm', 'view', 'cluster')
+
+
+@pytest.fixture()
+def object_role_view_perm_cluster():
+    cluster_role = cook_role('view_cluster', 'ObjectRole', ['cluster'])
+    cluster_role.permissions.add(cook_perm('cm', 'view', 'cluster'))
+    role = cook_role('view', 'ParentRole')
+    role.child.add(cluster_role)
+    return role
+
+
+@pytest.fixture()
+def object_role_custom_perm_cluster_service():
+    cluster_role = cook_role('cluster_change_config', 'ObjectRole', ['cluster'])
+    cluster_role.permissions.add(cook_perm('cm', 'change_config_of', 'cluster'))
+    service_role = cook_role('service_change_config', 'ObjectRole', ['service'])
+    service_role.permissions.add(cook_perm('cm', 'change_config_of', 'clusterobject'))
+    role = cook_role('change_config', 'ParentRole')
+    role.child.add(cluster_role, service_role)
+    return role
+
+
+@pytest.fixture()
+def object_role_custom_perm_cluster_service_component():
+    cluster_role = cook_role('cluster_change_config', 'ObjectRole', ['cluster'])
+    cluster_role.permissions.add(cook_perm('cm', 'change_config_of', 'cluster'))
+    service_role = cook_role('service_change_config', 'ObjectRole', ['service'])
+    service_role.permissions.add(cook_perm('cm', 'change_config_of', 'clusterobject'))
+    component_role = cook_role('component_change_config', 'ObjectRole', ['component'])
+    component_role.permissions.add(cook_perm('cm', 'change_config_of', 'servicecomponent'))
+    role = cook_role('change_config', 'ParentRole')
+    role.child.add(cluster_role, service_role, component_role)
+    return role
+
+
+@pytest.fixture()
+def object_role_custom_perm_service_component_host():
+    service_role = cook_role('service_change_config', 'ObjectRole', ['service'])
+    service_role.permissions.add(cook_perm('cm', 'change_config_of', 'clusterobject'))
+    component_role = cook_role('component_change_config', 'ObjectRole', ['component'])
+    component_role.permissions.add(cook_perm('cm', 'change_config_of', 'servicecomponent'))
+    host_role = cook_role('host_change_config', 'ObjectRole', ['host'])
+    host_role.permissions.add(cook_perm('cm', 'change_config_of', 'host'))
+    role = cook_role('change_config', 'ParentRole')
+    role.child.add(service_role, component_role, host_role)
+    return role
+
+
+@pytest.fixture()
+def object_role_custom_perm_cluster_host():
+    cluster_role = cook_role('cluster_change_config', 'ObjectRole', ['cluster'])
+    cluster_role.permissions.add(cook_perm('cm', 'change_config_of', 'cluster'))
+    host_role = cook_role('host_change_config', 'ObjectRole', ['host'])
+    host_role.permissions.add(cook_perm('cm', 'change_config_of', 'host'))
+    role = cook_role('change_config', 'ParentRole')
+    role.child.add(cluster_role, host_role)
+    return role
+
+
+@pytest.fixture()
+def object_role_custom_perm_cluster_service_component_host():
+    cluster_role = cook_role('cluster_change_config', 'ObjectRole', ['cluster'])
+    cluster_role.permissions.add(cook_perm('cm', 'change_config_of', 'cluster'))
+    service_role = cook_role('service_change_config', 'ObjectRole', ['service'])
+    service_role.permissions.add(cook_perm('cm', 'change_config_of', 'clusterobject'))
+    component_role = cook_role('component_change_config', 'ObjectRole', ['component'])
+    component_role.permissions.add(cook_perm('cm', 'change_config_of', 'servicecomponent'))
+    host_role = cook_role('host_change_config', 'ObjectRole', ['host'])
+    host_role.permissions.add(cook_perm('cm', 'change_config_of', 'host'))
+    role = cook_role('change_config', 'ParentRole')
+    role.child.add(cluster_role, service_role, component_role, host_role)
+    return role
+
+
+@pytest.fixture()
+def object_role_custom_perm_provider_host():
+    provider_role = cook_role('provider_change_config', 'ObjectRole', ['provider'])
+    provider_role.permissions.add(cook_perm('cm', 'change_config_of', 'hostprovider'))
+    host_role = cook_role('host_change_config', 'ObjectRole', ['host'])
+    host_role.permissions.add(cook_perm('cm', 'change_config_of', 'host'))
+    role = cook_role('change_config', 'ParentRole')
+    role.child.add(provider_role, host_role)
+    return role
+
+
+@pytest.fixture()
+def model_role_view_cluster_service_component_perm():
+    cluster_role = cook_role('view_cluster', 'ModelRole')
+    cluster_role.permissions.add(cook_perm('cm', 'view', 'cluster'))
+    service_role = cook_role('view_service', 'ModelRole')
+    service_role.permissions.add(cook_perm('cm', 'view', 'clusterobject'))
+    component_role = cook_role('view_component', 'ModelRole')
+    component_role.permissions.add(cook_perm('cm', 'view', 'servicecomponent'))
+    role = cook_role('view_objects', 'ParentRole')
+    role.child.add(cluster_role, service_role, component_role)
+    return role
diff --git a/python/rbac/tests/tests_model/test_policy.py b/python/rbac/tests/tests_model/test_policy.py
index 330623b6b8..893f6120e7 100644
--- a/python/rbac/tests/tests_model/test_policy.py
+++ b/python/rbac/tests/tests_model/test_policy.py
@@ -11,15 +11,12 @@
 # limitations under the License.
 
 import pytest
-
-from django.contrib.contenttypes.models import ContentType
 from adwp_base.errors import AdwpEx
 
-from rbac.models import Role, Policy, User, Group, Permission
-from rbac.roles import ModelRole
-from cm.models import Bundle, Prototype, Action, Cluster, ClusterObject, ServiceComponent
-from cm.models import HostProvider, HostComponent
 from cm import api
+from cm.models import Bundle, Prototype, Action
+from rbac.models import Role, Policy
+from rbac.roles import ModelRole
 
 
 @pytest.mark.django_db
@@ -39,32 +36,6 @@ def test_role_class():
     assert isinstance(obj, ModelRole)
 
 
-def cook_user(name):
-    return User.objects.create(username=name, is_active=True, is_superuser=False)
-
-
-def cook_group(name):
-    return Group.objects.create(name=name)
-
-
-def cook_perm(app, codename, model):
-    content, _ = ContentType.objects.get_or_create(app_label=app, model=model)
-    perm, _ = Permission.objects.get_or_create(codename=f'{codename}_{model}', content_type=content)
-    return perm
-
-
-def cook_role(name, class_name, obj_type=None):
-    if obj_type is None:
-        obj_type = []
-    return Role.objects.create(
-        name=name,
-        display_name=name,
-        module_name='rbac.roles',
-        class_name=class_name,
-        parametrized_by_type=obj_type,
-    )
-
-
 def clear_perm_cache(user):
     if hasattr(user, '_perm_cache'):
         delattr(user, '_perm_cache')
@@ -75,546 +46,502 @@ def clear_perm_cache(user):
 
 
 @pytest.mark.django_db
-def test_model_policy():
-    user = cook_user('Joe')
-    r = cook_role('add', 'ModelRole')
-    perm = cook_perm('adcm', 'add', 'host')
-    r.permissions.add(perm)
+def test_model_policy(user, model_role, add_host_perm):
 
-    p = Policy.objects.create(name='MyPolicy', role=r)
+    model_role.permissions.add(add_host_perm)
+
+    p = Policy.objects.create(name='MyPolicy', role=model_role)
     p.user.add(user)
 
-    assert perm not in user.user_permissions.all()
-    assert not user.has_perm('adcm.add_host')
+    assert add_host_perm not in user.user_permissions.all()
+    assert not user.has_perm('cm.add_host')
     clear_perm_cache(user)
 
     p.apply()
-    assert perm in user.user_permissions.all()
-    assert user.has_perm('adcm.add_host')
+    assert add_host_perm in user.user_permissions.all()
+    assert user.has_perm('cm.add_host')
 
     clear_perm_cache(user)
     p.apply()
-    assert user.has_perm('adcm.add_host')
+    assert user.has_perm('cm.add_host')
 
 
 @pytest.mark.django_db
-def test_model_policy4group():
-    group = cook_group('Ops')
-    user = cook_user('Joe')
+def test_model_policy4group(user, group, model_role, add_host_perm):
     group.user_set.add(user)
+    model_role.permissions.add(add_host_perm)
 
-    r = cook_role('add', 'ModelRole')
-    perm = cook_perm('adcm', 'add', 'host')
-    r.permissions.add(perm)
-
-    p = Policy.objects.create(name='MyPolicy', role=r)
+    p = Policy.objects.create(name='MyPolicy', role=model_role)
     p.group.add(group)
 
-    assert perm not in group.permissions.all()
-    assert not user.has_perm('adcm.add_host')
+    assert add_host_perm not in group.permissions.all()
+    assert not user.has_perm('cm.add_host')
     clear_perm_cache(user)
 
     p.apply()
-    assert perm in group.permissions.all()
-    assert user.has_perm('adcm.add_host')
+    assert add_host_perm in group.permissions.all()
+    assert user.has_perm('cm.add_host')
 
     clear_perm_cache(user)
     p.apply()
-    assert user.has_perm('adcm.add_host')
+    assert user.has_perm('cm.add_host')
 
 
 @pytest.mark.django_db
-def test_object_policy():
-    user = cook_user('Joe')
-    r = cook_role('view', 'ObjectRole')
-    r.permissions.add(cook_perm('cm', 'view', 'bundle'))
+def test_object_policy(user, cluster1, cluster2, object_role_view_perm_cluster):
 
-    p = Policy.objects.create(name='MyPolicy', role=r)
+    p = Policy.objects.create(name='MyPolicy', role=object_role_view_perm_cluster)
     p.user.add(user)
 
-    b1 = Bundle.objects.create(name='ADH', version='1.0')
-    b2 = Bundle.objects.create(name='ADH', version='2.0')
-
-    p.add_object(b1)
-    assert not user.has_perm('cm.view_bundle', b1)
-
-    p.apply()
-
-    assert user.has_perm('cm.view_bundle', b1)
-    assert not user.has_perm('cm.view_bundle', b2)
+    assert not user.has_perm('cm.view_cluster', cluster1)
+    assert not user.has_perm('cm.view_cluster', cluster2)
 
+    p.add_object(cluster1)
     p.apply()
 
-    assert user.has_perm('cm.view_bundle', b1)
-    assert not user.has_perm('cm.view_bundle', b2)
+    assert user.has_perm('cm.view_cluster', cluster1)
+    assert not user.has_perm('cm.view_cluster', cluster2)
 
 
 @pytest.mark.django_db
-def test_object_policy_remove_user():
-    user = cook_user('Joe')
-    r = cook_role('view', 'ObjectRole')
-    r.permissions.add(cook_perm('cm', 'view', 'bundle'))
+def test_object_policy_remove_user(user, cluster1, cluster2, object_role, view_cluster_perm):
 
-    p = Policy.objects.create(name='MyPolicy', role=r)
-    p.user.add(user)
-
-    b1 = Bundle.objects.create(name='ADH', version='1.0')
-    b2 = Bundle.objects.create(name='ADH', version='2.0')
+    object_role.permissions.add(view_cluster_perm)
 
-    p.add_object(b1)
-    assert not user.has_perm('cm.view_bundle', b1)
+    p = Policy.objects.create(name='MyPolicy', role=object_role)
+    p.user.add(user)
+    p.add_object(cluster1)
+    assert not user.has_perm('cm.view_cluster', cluster1)
 
     p.apply()
 
-    assert user.has_perm('cm.view_bundle', b1)
-    assert not user.has_perm('cm.view_bundle', b2)
+    assert user.has_perm('cm.view_cluster', cluster1)
+    assert not user.has_perm('cm.view_cluster', cluster2)
 
     p.user.remove(user)
     p.apply()
 
-    assert not user.has_perm('cm.view_bundle', b1)
-    assert not user.has_perm('cm.view_bundle', b2)
+    assert not user.has_perm('cm.view_cluster', cluster1)
+    assert not user.has_perm('cm.view_cluster', cluster2)
 
 
 @pytest.mark.django_db
-def test_object_policy4group():
-    group = cook_group('Ops')
-    user = cook_user('Joe')
+def test_object_policy4group(user, group, cluster1, cluster2, object_role, view_cluster_perm):
     group.user_set.add(user)
 
-    r = cook_role('view', 'ObjectRole')
-    r.permissions.add(cook_perm('cm', 'view', 'bundle'))
+    object_role.permissions.add(view_cluster_perm)
 
-    p = Policy.objects.create(name='MyPolicy', role=r)
+    p = Policy.objects.create(name='MyPolicy', role=object_role)
     p.group.add(group)
 
-    b1 = Bundle.objects.create(name='ADH', version='1.0')
-    b2 = Bundle.objects.create(name='ADH', version='2.0')
-
-    p.add_object(b1)
-    assert not user.has_perm('cm.view_bundle', b1)
+    p.add_object(cluster1)
+    assert not user.has_perm('cm.view_cluster', cluster1)
 
     p.apply()
 
-    assert user.has_perm('cm.view_bundle', b1)
-    assert not user.has_perm('cm.view_bundle', b2)
-
-    p.apply()
-
-    assert user.has_perm('cm.view_bundle', b1)
-    assert not user.has_perm('cm.view_bundle', b2)
-
-
-def cook_conf_role():
-    r_cluster = cook_role('cluster_conf', 'ObjectRole', ['cluster'])
-    r_cluster.permissions.add(cook_perm('cm', 'edit_conf', 'cluster'))
-
-    r_service = cook_role('service_conf', 'ObjectRole', ['service'])
-    r_service.permissions.add(cook_perm('cm', 'edit_conf', 'clusterobject'))
-
-    r_comp = cook_role('component_conf', 'ObjectRole', ['component'])
-    r_comp.permissions.add(cook_perm('cm', 'edit_conf', 'servicecomponent'))
-
-    r_provider = cook_role('provider_conf', 'ObjectRole', ['provider'])
-    r_provider.permissions.add(cook_perm('cm', 'edit_conf', 'hostprovider'))
-
-    r_host = cook_role('host_conf', 'ObjectRole', ['host'])
-    r_host.permissions.add(cook_perm('cm', 'edit_conf', 'host'))
-
-    r = cook_role('all_conf', 'ParentRole')
-    r.child.add(r_cluster, r_service, r_comp, r_provider, r_host)
-
-    return r
-
-
-def cook_cluster1():
-    b = Bundle.obj.create(name='Adh', version='1.0')
-    cp = Prototype.obj.create(bundle=b, type='cluster', name='ADH')
-    cluster = Cluster.obj.create(name='Yukon', prototype=cp)
-
-    sp1 = Prototype.obj.create(bundle=b, type='service', name='Hadoop')
-    service1 = ClusterObject.obj.create(cluster=cluster, prototype=sp1)
-    cp11 = Prototype.obj.create(bundle=b, type='component', name='server')
-    comp11 = ServiceComponent.obj.create(cluster=cluster, service=service1, prototype=cp11)
-    cp12 = Prototype.obj.create(bundle=b, type='component', name='node')
-    comp12 = ServiceComponent.obj.create(cluster=cluster, service=service1, prototype=cp12)
-
-    sp2 = Prototype.obj.create(bundle=b, type='service', name='Kafka')
-    service2 = ClusterObject.obj.create(cluster=cluster, prototype=sp2)
-    cp21 = Prototype.obj.create(bundle=b, type='component', name='node2')
-    comp21 = ServiceComponent.obj.create(cluster=cluster, service=service2, prototype=cp21)
-
-    return (cluster, service1, service2, comp11, comp12, comp21, b)
-
-
-def cook_hosts():
-    b = Bundle.obj.create(name='ssh', version='1.0')
-    hpp = Prototype.obj.create(bundle=b, type='provider', name='Cloud')
-    provider = HostProvider.obj.create(name='Fort', prototype=hpp)
-    hp = Prototype.obj.create(bundle=b, type='host', name='Simple')
-
-    host1 = api.add_host(hp, provider, 'host1.net')
-    host2 = api.add_host(hp, provider, 'host2.net')
-    host3 = api.add_host(hp, provider, 'host3.net')
-
-    return (provider, host1, host2, host3)
+    assert user.has_perm('cm.view_cluster', cluster1)
+    assert not user.has_perm('cm.view_cluster', cluster2)
 
 
 @pytest.mark.django_db
-def test_parent_policy4cluster():
-    user = cook_user('Joe')
-    cluster, service1, service2, comp11, comp12, comp21, _ = cook_cluster1()
-
-    p = Policy.objects.create(role=cook_conf_role())
+def test_parent_policy4cluster(
+    user,
+    cluster1,
+    service1,
+    service2,
+    component11,
+    component21,
+    object_role_custom_perm_cluster_service_component,
+):
+
+    p = Policy.objects.create(role=object_role_custom_perm_cluster_service_component)
     p.user.add(user)
-    p.add_object(cluster)
+    p.add_object(cluster1)
 
-    assert not user.has_perm('cm.edit_conf_cluster', cluster)
-    assert not user.has_perm('cm.edit_conf_clusterobject', service1)
-    assert not user.has_perm('cm.edit_conf_clusterobject', service2)
-    assert not user.has_perm('cm.edit_conf_servicecomponent', comp11)
-    assert not user.has_perm('cm.edit_conf_servicecomponent', comp12)
-    assert not user.has_perm('cm.edit_conf_servicecomponent', comp21)
+    assert not user.has_perm('cm.change_config_of_cluster', cluster1)
+    assert not user.has_perm('cm.change_config_of_clusterobject', service1)
+    assert not user.has_perm('cm.change_config_of_clusterobject', service2)
+    assert not user.has_perm('cm.change_config_of_servicecomponent', component11)
+    assert not user.has_perm('cm.change_config_of_servicecomponent', component21)
 
     p.apply()
 
-    assert user.has_perm('cm.edit_conf_cluster', cluster)
-    assert user.has_perm('cm.edit_conf_clusterobject', service1)
-    assert user.has_perm('cm.edit_conf_clusterobject', service2)
-    assert user.has_perm('cm.edit_conf_servicecomponent', comp11)
-    assert user.has_perm('cm.edit_conf_servicecomponent', comp12)
-    assert user.has_perm('cm.edit_conf_servicecomponent', comp21)
+    assert user.has_perm('cm.change_config_of_cluster', cluster1)
+    assert user.has_perm('cm.change_config_of_clusterobject', service1)
+    assert user.has_perm('cm.change_config_of_clusterobject', service2)
+    assert user.has_perm('cm.change_config_of_servicecomponent', component11)
+    assert user.has_perm('cm.change_config_of_servicecomponent', component21)
 
 
 @pytest.mark.django_db
-def test_parent_policy4service():
-    user = cook_user('Joe')
-    cluster, service1, service2, comp11, comp12, comp21, _ = cook_cluster1()
-    p = Policy.objects.create(role=cook_conf_role())
+def test_parent_policy4service(
+    user,
+    cluster1,
+    service1,
+    service2,
+    component11,
+    component21,
+    object_role_custom_perm_cluster_service_component,
+):
+    p = Policy.objects.create(role=object_role_custom_perm_cluster_service_component)
     p.user.add(user)
-
     p.add_object(service1)
 
-    assert not user.has_perm('cm.edit_conf_cluster', cluster)
-    assert not user.has_perm('cm.edit_conf_clusterobject', service1)
-    assert not user.has_perm('cm.edit_conf_clusterobject', service2)
-    assert not user.has_perm('cm.edit_conf_servicecomponent', comp11)
-    assert not user.has_perm('cm.edit_conf_servicecomponent', comp12)
-    assert not user.has_perm('cm.edit_conf_servicecomponent', comp21)
+    assert not user.has_perm('cm.change_config_of_cluster', cluster1)
+    assert not user.has_perm('cm.change_config_of_clusterobject', service1)
+    assert not user.has_perm('cm.change_config_of_clusterobject', service2)
+    assert not user.has_perm('cm.change_config_of_servicecomponent', component11)
+    assert not user.has_perm('cm.change_config_of_servicecomponent', component21)
 
     p.apply()
 
-    assert user.has_perm('cm.edit_conf_cluster', cluster)
-    assert user.has_perm('cm.edit_conf_clusterobject', service1)
-    assert not user.has_perm('cm.edit_conf_clusterobject', service2)
-    assert user.has_perm('cm.edit_conf_servicecomponent', comp11)
-    assert user.has_perm('cm.edit_conf_servicecomponent', comp12)
-    assert not user.has_perm('cm.edit_conf_servicecomponent', comp21)
+    assert user.has_perm('cm.view_cluster', cluster1)
+
+    assert not user.has_perm('cm.change_config_of_cluster', cluster1)
+    assert user.has_perm('cm.change_config_of_clusterobject', service1)
+    assert not user.has_perm('cm.change_config_of_clusterobject', service2)
+    assert user.has_perm('cm.change_config_of_servicecomponent', component11)
+    assert not user.has_perm('cm.change_config_of_servicecomponent', component21)
 
 
 @pytest.mark.django_db
-def test_parent_policy4service2():
-    user = cook_user('Joe')
-    cluster, service1, service2, comp11, comp12, comp21, _ = cook_cluster1()
-    p = Policy.objects.create(role=cook_conf_role())
+def test_parent_policy4service2(
+    user,
+    cluster1,
+    service1,
+    service2,
+    component11,
+    component21,
+    object_role_custom_perm_cluster_service_component,
+):
+    p = Policy.objects.create(role=object_role_custom_perm_cluster_service_component)
     p.user.add(user)
-
     p.add_object(service2)
 
-    assert not user.has_perm('cm.edit_conf_cluster', cluster)
-    assert not user.has_perm('cm.edit_conf_clusterobject', service1)
-    assert not user.has_perm('cm.edit_conf_clusterobject', service2)
-    assert not user.has_perm('cm.edit_conf_servicecomponent', comp11)
-    assert not user.has_perm('cm.edit_conf_servicecomponent', comp12)
-    assert not user.has_perm('cm.edit_conf_servicecomponent', comp21)
+    assert not user.has_perm('cm.view_cluster', cluster1)
+    assert not user.has_perm('cm.change_config_of_cluster', cluster1)
+    assert not user.has_perm('cm.change_config_of_clusterobject', service1)
+    assert not user.has_perm('cm.change_config_of_clusterobject', service2)
+    assert not user.has_perm('cm.change_config_of_servicecomponent', component11)
+    assert not user.has_perm('cm.change_config_of_servicecomponent', component21)
 
     p.apply()
 
-    assert user.has_perm('cm.edit_conf_cluster', cluster)
-    assert not user.has_perm('cm.edit_conf_clusterobject', service1)
-    assert user.has_perm('cm.edit_conf_clusterobject', service2)
-    assert not user.has_perm('cm.edit_conf_servicecomponent', comp11)
-    assert not user.has_perm('cm.edit_conf_servicecomponent', comp12)
-    assert user.has_perm('cm.edit_conf_servicecomponent', comp21)
+    assert user.has_perm('cm.view_cluster', cluster1)
+    assert not user.has_perm('cm.change_config_of_cluster', cluster1)
+    assert not user.has_perm('cm.change_config_of_clusterobject', service1)
+    assert user.has_perm('cm.change_config_of_clusterobject', service2)
+    assert not user.has_perm('cm.change_config_of_servicecomponent', component11)
+    assert user.has_perm('cm.change_config_of_servicecomponent', component21)
 
 
 @pytest.mark.django_db
-def test_parent_policy4component():
-    user = cook_user('Joe')
-    cluster, service1, service2, comp11, comp12, comp21, _ = cook_cluster1()
-    p = Policy.objects.create(role=cook_conf_role())
+def test_parent_policy4component(
+    user,
+    cluster1,
+    service1,
+    service2,
+    component11,
+    component21,
+    object_role_custom_perm_cluster_service_component,
+):
+    p = Policy.objects.create(role=object_role_custom_perm_cluster_service_component)
     p.user.add(user)
-
-    p.add_object(comp12)
-
-    assert not user.has_perm('cm.edit_conf_cluster', cluster)
-    assert not user.has_perm('cm.edit_conf_clusterobject', service1)
-    assert not user.has_perm('cm.edit_conf_clusterobject', service2)
-    assert not user.has_perm('cm.edit_conf_servicecomponent', comp11)
-    assert not user.has_perm('cm.edit_conf_servicecomponent', comp12)
-    assert not user.has_perm('cm.edit_conf_servicecomponent', comp21)
+    p.add_object(component11)
+    assert not user.has_perm('cm.view_cluster', cluster1)
+    assert not user.has_perm('cm.view_clusterobject', service1)
+    assert not user.has_perm('cm.change_config_of_cluster', cluster1)
+    assert not user.has_perm('cm.change_config_of_clusterobject', service1)
+    assert not user.has_perm('cm.change_config_of_clusterobject', service2)
+    assert not user.has_perm('cm.change_config_of_servicecomponent', component11)
+    assert not user.has_perm('cm.change_config_of_servicecomponent', component21)
 
     p.apply()
 
-    assert user.has_perm('cm.edit_conf_cluster', cluster)
-    assert user.has_perm('cm.edit_conf_clusterobject', service1)
-    assert not user.has_perm('cm.edit_conf_clusterobject', service2)
-    assert not user.has_perm('cm.edit_conf_servicecomponent', comp11)
-    assert user.has_perm('cm.edit_conf_servicecomponent', comp12)
-    assert not user.has_perm('cm.edit_conf_servicecomponent', comp21)
+    assert user.has_perm('cm.view_cluster', cluster1)
+    assert user.has_perm('cm.view_clusterobject', service1)
+    assert not user.has_perm('cm.change_config_of_cluster', cluster1)
+    assert not user.has_perm('cm.change_config_of_clusterobject', service1)
+    assert not user.has_perm('cm.change_config_of_clusterobject', service2)
+    assert user.has_perm('cm.change_config_of_servicecomponent', component11)
+    assert not user.has_perm('cm.change_config_of_servicecomponent', component21)
 
 
 @pytest.mark.django_db
-def test_parent_policy4host_in_cluster():
-    user = cook_user('Joe')
-    cluster, _, _, _, _, _, _ = cook_cluster1()
-    _, host1, host2, host3 = cook_hosts()
-    api.add_host_to_cluster(cluster, host1)
-    api.add_host_to_cluster(cluster, host2)
-
-    p = Policy.objects.create(role=cook_conf_role())
+def test_parent_policy4host_in_cluster(
+    user, cluster1, host1, host2, host3, object_role_custom_perm_cluster_host
+):
+    api.add_host_to_cluster(cluster1, host1)
+    api.add_host_to_cluster(cluster1, host2)
+    p = Policy.objects.create(role=object_role_custom_perm_cluster_host)
     p.user.add(user)
-    p.add_object(cluster)
+    p.add_object(cluster1)
 
-    assert not user.has_perm('cm.edit_conf_cluster', cluster)
-    assert not user.has_perm('cm.edit_conf_host', host1)
-    assert not user.has_perm('cm.edit_conf_host', host2)
-    assert not user.has_perm('cm.edit_conf_host', host3)
+    assert not user.has_perm('cm.change_config_of_cluster', cluster1)
+    assert not user.has_perm('cm.change_config_of_host', host1)
+    assert not user.has_perm('cm.change_config_of_host', host2)
+    assert not user.has_perm('cm.change_config_of_host', host3)
 
     p.apply()
 
-    assert user.has_perm('cm.edit_conf_cluster', cluster)
-    assert user.has_perm('cm.edit_conf_host', host1)
-    assert user.has_perm('cm.edit_conf_host', host2)
-    assert not user.has_perm('cm.edit_conf_host', host3)
+    assert user.has_perm('cm.change_config_of_cluster', cluster1)
+    assert user.has_perm('cm.change_config_of_host', host1)
+    assert user.has_perm('cm.change_config_of_host', host2)
+    assert not user.has_perm('cm.change_config_of_host', host3)
 
 
 @pytest.mark.django_db
-def test_parent_policy4host_in_service():
-    user = cook_user('Joe')
-    cluster, service1, service2, comp11, comp12, comp21, _ = cook_cluster1()
-    _, host1, host2, host3 = cook_hosts()
-    api.add_host_to_cluster(cluster, host1)
-    api.add_host_to_cluster(cluster, host2)
-    api.add_host_to_cluster(cluster, host3)
+# pylint: disable=too-many-arguments
+def test_parent_policy4host_in_service(
+    user,
+    cluster1,
+    service1,
+    service2,
+    component11,
+    component21,
+    host1,
+    host2,
+    object_role_custom_perm_cluster_service_component_host,
+):
+    api.add_host_to_cluster(cluster1, host1)
+    api.add_host_to_cluster(cluster1, host2)
     api.add_hc(
-        cluster,
+        cluster1,
         [
-            {"service_id": service1.id, "component_id": comp11.id, "host_id": host1.id},
-            {"service_id": service1.id, "component_id": comp12.id, "host_id": host2.id},
-            {"service_id": service2.id, "component_id": comp21.id, "host_id": host3.id},
+            {"service_id": service1.id, "component_id": component11.id, "host_id": host1.id},
+            {"service_id": service2.id, "component_id": component21.id, "host_id": host2.id},
         ],
     )
-
-    p = Policy.objects.create(role=cook_conf_role())
+    p = Policy.objects.create(role=object_role_custom_perm_cluster_service_component_host)
     p.user.add(user)
     p.add_object(service1)
 
-    assert not user.has_perm('cm.edit_conf_cluster', cluster)
-    assert not user.has_perm('cm.edit_conf_clusterobject', service1)
-    assert not user.has_perm('cm.edit_conf_host', host1)
-    assert not user.has_perm('cm.edit_conf_host', host2)
-    assert not user.has_perm('cm.edit_conf_host', host3)
+    assert not user.has_perm('cm.change_config_of_cluster', cluster1)
+    assert not user.has_perm('cm.change_config_of_clusterobject', service1)
+    assert not user.has_perm('cm.change_config_of_clusterobject', service2)
+    assert not user.has_perm('cm.change_config_of_servicecomponent', component11)
+    assert not user.has_perm('cm.change_config_of_servicecomponent', component21)
+    assert not user.has_perm('cm.change_config_of_host', host1)
+    assert not user.has_perm('cm.change_config_of_host', host2)
 
     p.apply()
 
-    assert user.has_perm('cm.edit_conf_cluster', cluster)
-    assert user.has_perm('cm.edit_conf_clusterobject', service1)
-    assert user.has_perm('cm.edit_conf_host', host1)
-    assert user.has_perm('cm.edit_conf_host', host2)
-    assert not user.has_perm('cm.edit_conf_host', host3)
+    assert not user.has_perm('cm.change_confing_of_cluster', cluster1)
+    assert user.has_perm('cm.change_config_of_clusterobject', service1)
+    assert not user.has_perm('cm.change_config_of_clusterobject', service2)
+    assert user.has_perm('cm.change_config_of_servicecomponent', component11)
+    assert not user.has_perm('cm.change_config_of_servicecomponent', component21)
+    assert user.has_perm('cm.change_config_of_host', host1)
+    assert not user.has_perm('cm.change_config_of_host', host2)
 
 
 @pytest.mark.django_db
-def test_parent_policy4host_in_component():
-    user = cook_user('Joe')
-    cluster, service1, service2, comp11, _, comp21, _ = cook_cluster1()
-    _, host1, host2, host3 = cook_hosts()
-    api.add_host_to_cluster(cluster, host1)
-    api.add_host_to_cluster(cluster, host2)
-    api.add_host_to_cluster(cluster, host3)
-    HostComponent.obj.create(cluster=cluster, service=service2, component=comp21, host=host1)
-    HostComponent.obj.create(cluster=cluster, service=service2, component=comp21, host=host2)
-    HostComponent.obj.create(cluster=cluster, service=service1, component=comp11, host=host3)
-
-    p = Policy.objects.create(role=cook_conf_role())
+# pylint: disable=too-many-arguments
+def test_parent_policy4host_in_component(
+    user,
+    cluster1,
+    service1,
+    service2,
+    component11,
+    component21,
+    host1,
+    host2,
+    host3,
+    object_role_custom_perm_cluster_service_component_host,
+):
+    api.add_host_to_cluster(cluster1, host1)
+    api.add_host_to_cluster(cluster1, host2)
+    api.add_host_to_cluster(cluster1, host3)
+    api.add_hc(
+        cluster1,
+        [
+            {'service_id': service2.id, 'component_id': component21.id, 'host_id': host1.id},
+            {'service_id': service2.id, 'component_id': component21.id, 'host_id': host2.id},
+            {'service_id': service1.id, 'component_id': component11.id, 'host_id': host3.id},
+        ],
+    )
+
+    p = Policy.objects.create(role=object_role_custom_perm_cluster_service_component_host)
     p.user.add(user)
-    p.add_object(comp21)
+    p.add_object(component21)
 
-    assert not user.has_perm('cm.edit_conf_cluster', cluster)
-    assert not user.has_perm('cm.edit_conf_clusterobject', service1)
-    assert not user.has_perm('cm.edit_conf_clusterobject', service2)
-    assert not user.has_perm('cm.edit_conf_servicecomponent', comp21)
-    assert not user.has_perm('cm.edit_conf_host', host1)
-    assert not user.has_perm('cm.edit_conf_host', host2)
-    assert not user.has_perm('cm.edit_conf_host', host3)
+    assert not user.has_perm('cm.change_config_of_cluster', cluster1)
+    assert not user.has_perm('cm.change_config_of_clusterobject', service1)
+    assert not user.has_perm('cm.change_config_of_clusterobject', service2)
+    assert not user.has_perm('cm.change_config_of_servicecomponent', component11)
+    assert not user.has_perm('cm.change_config_of_servicecomponent', component21)
+    assert not user.has_perm('cm.change_config_of_host', host1)
+    assert not user.has_perm('cm.change_config_of_host', host2)
+    assert not user.has_perm('cm.change_config_of_host', host3)
 
     p.apply()
 
-    assert user.has_perm('cm.edit_conf_cluster', cluster)
-    assert not user.has_perm('cm.edit_conf_clusterobject', service1)
-    assert user.has_perm('cm.edit_conf_clusterobject', service2)
-    assert user.has_perm('cm.edit_conf_servicecomponent', comp21)
-    assert user.has_perm('cm.edit_conf_host', host1)
-    assert user.has_perm('cm.edit_conf_host', host2)
-    assert not user.has_perm('cm.edit_conf_host', host3)
+    assert not user.has_perm('cm.change_config_of_cluster', cluster1)
+    assert not user.has_perm('cm.change_config_of_clusterobject', service1)
+    assert not user.has_perm('cm.change_config_of_clusterobject', service2)
+    assert not user.has_perm('cm.change_config_of_servicecomponent', component11)
+    assert user.has_perm('cm.change_config_of_servicecomponent', component21)
+    assert user.has_perm('cm.change_config_of_host', host1)
+    assert user.has_perm('cm.change_config_of_host', host2)
+    assert not user.has_perm('cm.change_config_of_host', host3)
 
 
 @pytest.mark.django_db
-def test_parent_policy4provider():
-    user = cook_user('Joe')
-    provider, host1, host2, host3 = cook_hosts()
-
-    p = Policy.objects.create(role=cook_conf_role())
+def test_parent_policy4provider(
+    user, provider, host1, host2, host3, object_role_custom_perm_provider_host
+):
+    p = Policy.objects.create(role=object_role_custom_perm_provider_host)
     p.user.add(user)
     p.add_object(provider)
 
-    assert not user.has_perm('cm.edit_conf_hostprovider', provider)
-    assert not user.has_perm('cm.edit_conf_host', host1)
-    assert not user.has_perm('cm.edit_conf_host', host2)
-    assert not user.has_perm('cm.edit_conf_host', host3)
+    assert not user.has_perm('cm.change_config_of_hostprovider', provider)
+    assert not user.has_perm('cm.change_config_of_host', host1)
+    assert not user.has_perm('cm.change_config_of_host', host2)
+    assert not user.has_perm('cm.change_config_of_host', host3)
 
     p.apply()
 
-    assert user.has_perm('cm.edit_conf_hostprovider', provider)
-    assert user.has_perm('cm.edit_conf_host', host1)
-    assert user.has_perm('cm.edit_conf_host', host2)
-    assert user.has_perm('cm.edit_conf_host', host3)
+    assert user.has_perm('cm.change_config_of_hostprovider', provider)
+    assert user.has_perm('cm.change_config_of_host', host1)
+    assert user.has_perm('cm.change_config_of_host', host2)
+    assert user.has_perm('cm.change_config_of_host', host3)
 
 
 @pytest.mark.django_db
-def test_simple_parent_policy():
-    user = cook_user('Joe')
-
-    cluster = cook_role('change_cluster', 'ModelRole')
-    cluster.permissions.add(cook_perm('cm', 'change', 'cluster'))
-
-    service = cook_role('change_service', 'ModelRole')
-    service.permissions.add(cook_perm('cm', 'change', 'clusterobject'))
-
-    comp = cook_role('change_component', 'ModelRole')
-    comp.permissions.add(cook_perm('cm', 'change', 'servicecomponent'))
-
-    r = cook_role('all', 'ParentRole')
-    r.child.add(cluster, service, comp)
+def test_simple_parent_policy(user, model_role_view_cluster_service_component_perm):
 
-    p = Policy.objects.create(role=r)
+    p = Policy.objects.create(role=model_role_view_cluster_service_component_perm)
     p.user.add(user)
 
-    assert not user.has_perm('cm.change_cluster')
-    assert not user.has_perm('cm.change_clusterobject')
-    assert not user.has_perm('cm.change_servicecomponent')
+    assert not user.has_perm('cm.view_cluster')
+    assert not user.has_perm('cm.view_clusterobject')
+    assert not user.has_perm('cm.view_servicecomponent')
 
     clear_perm_cache(user)
     p.apply()
 
-    assert user.has_perm('cm.change_cluster')
-    assert user.has_perm('cm.change_clusterobject')
-    assert user.has_perm('cm.change_servicecomponent')
-
-
-@pytest.mark.django_db
-def test_empty_parent_policy():
-    user = cook_user('Joe')
-    _, _, service2, _, _, _, _ = cook_cluster1()
-
-    r = cook_role('all', 'ParentRole', ['service'])
-    p = Policy.objects.create(role=r)
-    p.user.add(user)
-    p.add_object(service2)
-
-    p.apply()
+    assert user.has_perm('cm.view_cluster')
+    assert user.has_perm('cm.view_clusterobject')
+    assert user.has_perm('cm.view_servicecomponent')
 
 
 @pytest.mark.django_db
-def test_add_service():
-    user = cook_user('Joe')
-    cluster, service1, service2, _, _, _, b = cook_cluster1()
-    sp3 = Prototype.obj.create(bundle=b, type='service', name='Hive')
+def test_add_service(
+    user, bundle1, cluster1, service1, service2, object_role_custom_perm_cluster_service
+):
+    sp3 = Prototype.obj.create(bundle=bundle1, type='service', name='service_3')
 
-    p = Policy.objects.create(role=cook_conf_role())
+    p = Policy.objects.create(role=object_role_custom_perm_cluster_service)
     p.user.add(user)
-    p.add_object(cluster)
+    p.add_object(cluster1)
 
-    assert not user.has_perm('cm.edit_conf_cluster', cluster)
-    assert not user.has_perm('cm.edit_conf_clusterobject', service1)
-    assert not user.has_perm('cm.edit_conf_clusterobject', service2)
+    assert not user.has_perm('cm.change_config_of_cluster', cluster1)
+    assert not user.has_perm('cm.change_config_of_clusterobject', service1)
+    assert not user.has_perm('cm.change_config_of_clusterobject', service2)
 
     p.apply()
 
-    assert user.has_perm('cm.edit_conf_cluster', cluster)
-    assert user.has_perm('cm.edit_conf_clusterobject', service1)
-    assert user.has_perm('cm.edit_conf_clusterobject', service2)
+    assert user.has_perm('cm.change_config_of_cluster', cluster1)
+    assert user.has_perm('cm.change_config_of_clusterobject', service1)
+    assert user.has_perm('cm.change_config_of_clusterobject', service2)
 
-    service3 = api.add_service_to_cluster(cluster, sp3)
-    assert user.has_perm('cm.edit_conf_clusterobject', service3)
+    service3 = api.add_service_to_cluster(cluster1, sp3)
+    assert user.has_perm('cm.change_config_of_clusterobject', service3)
 
 
 @pytest.mark.django_db
-def test_add_host():
-    user = cook_user('Joe')
-    cluster, service1, _, comp11, comp12, _, _ = cook_cluster1()
-    _, host1, host2, host3 = cook_hosts()
-    api.add_host_to_cluster(cluster, host1)
-    api.add_host_to_cluster(cluster, host2)
-    HostComponent.obj.create(cluster=cluster, service=service1, component=comp11, host=host1)
-    HostComponent.obj.create(cluster=cluster, service=service1, component=comp12, host=host2)
-
-    p = Policy.objects.create(role=cook_conf_role())
+def test_add_host(
+    user,
+    cluster1,
+    service1,
+    component11,
+    host1,
+    host2,
+    object_role_custom_perm_cluster_service_component_host,
+):
+    api.add_host_to_cluster(cluster1, host1)
+    api.add_hc(
+        cluster1, [{'service_id': service1.id, 'component_id': component11.id, 'host_id': host1.id}]
+    )
+
+    p = Policy.objects.create(role=object_role_custom_perm_cluster_service_component_host)
     p.user.add(user)
-    p.add_object(cluster)
+    p.add_object(cluster1)
 
-    assert not user.has_perm('cm.edit_conf_cluster', cluster)
-    assert not user.has_perm('cm.edit_conf_host', host1)
-    assert not user.has_perm('cm.edit_conf_host', host2)
-    assert not user.has_perm('cm.edit_conf_host', host3)
+    assert not user.has_perm('cm.change_config_of_cluster', cluster1)
+    assert not user.has_perm('cm.change_config_of_clusterobject', service1)
+    assert not user.has_perm('cm.change_config_of_servicecomponent', component11)
+    assert not user.has_perm('cm.change_config_of_host', host1)
+    assert not user.has_perm('cm.change_config_of_host', host2)
 
     p.apply()
 
-    assert user.has_perm('cm.edit_conf_cluster', cluster)
-    assert user.has_perm('cm.edit_conf_host', host1)
-    assert user.has_perm('cm.edit_conf_host', host2)
-    assert not user.has_perm('cm.edit_conf_host', host3)
+    assert user.has_perm('cm.change_config_of_cluster', cluster1)
+    assert user.has_perm('cm.change_config_of_clusterobject', service1)
+    assert user.has_perm('cm.change_config_of_servicecomponent', component11)
+    assert user.has_perm('cm.change_config_of_host', host1)
+    assert not user.has_perm('cm.change_config_of_host', host2)
 
-    api.add_host_to_cluster(cluster, host3)
+    api.add_host_to_cluster(cluster1, host2)
 
-    assert user.has_perm('cm.edit_conf_host', host3)
+    assert user.has_perm('cm.change_config_of_cluster', cluster1)
+    assert user.has_perm('cm.change_config_of_clusterobject', service1)
+    assert user.has_perm('cm.change_config_of_servicecomponent', component11)
+    assert user.has_perm('cm.change_config_of_host', host1)
+    assert user.has_perm('cm.change_config_of_host', host2)
 
 
 @pytest.mark.django_db
-def test_add_hc():
-    user = cook_user('Joe')
-    cluster, service1, _, comp11, comp12, _, _ = cook_cluster1()
-    _, host1, host2, host3 = cook_hosts()
-    api.add_host_to_cluster(cluster, host1)
-    HostComponent.obj.create(cluster=cluster, service=service1, component=comp11, host=host1)
-
-    p = Policy.objects.create(role=cook_conf_role())
+# pylint: disable=too-many-arguments
+def test_add_hc(
+    user,
+    cluster1,
+    service1,
+    component11,
+    component12,
+    host1,
+    host2,
+    object_role_custom_perm_service_component_host,
+):
+    api.add_host_to_cluster(cluster1, host1)
+    api.add_hc(
+        cluster1, [{'service_id': service1.id, 'component_id': component11.id, 'host_id': host1.id}]
+    )
+    p = Policy.objects.create(role=object_role_custom_perm_service_component_host)
     p.user.add(user)
     p.add_object(service1)
 
-    assert not user.has_perm('cm.edit_conf_cluster', cluster)
-    assert not user.has_perm('cm.edit_conf_host', host1)
-    assert not user.has_perm('cm.edit_conf_host', host2)
-    assert not user.has_perm('cm.edit_conf_host', host3)
+    assert not user.has_perm('cm.change_config_of_cluster', cluster1)
+    assert not user.has_perm('cm.change_config_of_clusterobject', service1)
+    assert not user.has_perm('cm.change_config_of_servicecomponent', component11)
+    assert not user.has_perm('cm.change_config_of_servicecomponent', component12)
+    assert not user.has_perm('cm.change_config_of_host', host1)
+    assert not user.has_perm('cm.change_config_of_host', host2)
 
     p.apply()
 
-    assert user.has_perm('cm.edit_conf_clusterobject', service1)
-    assert user.has_perm('cm.edit_conf_host', host1)
-    assert not user.has_perm('cm.edit_conf_host', host2)
-    assert not user.has_perm('cm.edit_conf_host', host3)
+    assert not user.has_perm('cm.change_config_of_cluster', cluster1)
+    assert user.has_perm('cm.change_config_of_clusterobject', service1)
+    assert user.has_perm('cm.change_config_of_servicecomponent', component11)
+    assert user.has_perm('cm.change_config_of_servicecomponent', component12)
+    assert user.has_perm('cm.change_config_of_host', host1)
+    assert not user.has_perm('cm.change_config_of_host', host2)
 
-    api.add_host_to_cluster(cluster, host2)
+    api.add_host_to_cluster(cluster1, host2)
     api.add_hc(
-        cluster,
+        cluster1,
         [
-            {"service_id": service1.id, "component_id": comp11.id, "host_id": host1.id},
-            {"service_id": service1.id, "component_id": comp12.id, "host_id": host2.id},
+            {'service_id': service1.id, 'component_id': component11.id, 'host_id': host1.id},
+            {"service_id": service1.id, "component_id": component12.id, "host_id": host2.id},
         ],
     )
 
-    assert user.has_perm('cm.edit_conf_host', host2)
+    assert not user.has_perm('cm.change_config_of_cluster', cluster1)
+    assert user.has_perm('cm.change_config_of_clusterobject', service1)
+    assert user.has_perm('cm.change_config_of_servicecomponent', component11)
+    assert user.has_perm('cm.change_config_of_servicecomponent', component12)
+    assert user.has_perm('cm.change_config_of_host', host1)
+    assert user.has_perm('cm.change_config_of_host', host2)
 
 
 @pytest.mark.django_db