Commit c94998ac authored by peijianbo's avatar peijianbo
Browse files

完善rbac

parent 68b387b8
Showing with 60 additions and 38 deletions
+60 -38
# Generated by Django 2.2.13 on 2020-10-22 10:45
# Generated by Django 2.2.13 on 2020-10-26 02:53
from django.db import migrations, models
import django.db.models.deletion
......@@ -243,10 +243,12 @@ class Migration(migrations.Migration):
('date_updated', models.DateTimeField(auto_now=True, verbose_name='Date updated')),
('id', models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False)),
('org_id', models.CharField(blank=True, db_index=True, default='', max_length=36, verbose_name='Organization')),
('name', models.CharField(max_length=256, verbose_name='Name')),
('username', models.CharField(blank=True, max_length=256, null=True, verbose_name='Username')),
('address', models.CharField(max_length=1024, verbose_name='Address')),
('name', models.CharField(max_length=1024, verbose_name='Name')),
('username', models.CharField(blank=True, max_length=1024, null=True, verbose_name='Username')),
('secret', models.TextField(verbose_name='Secret')),
('address', models.CharField(max_length=1024, verbose_name='Address')),
('port', models.IntegerField(null=True, verbose_name='Port')),
('privileged', models.BooleanField(default=True, verbose_name='Privileged')),
('extra_props', jsonfield.fields.JSONField(default=dict)),
('is_active', models.BooleanField(default=True, verbose_name='Is active')),
('comment', models.TextField(default='', verbose_name='Comment')),
......
......@@ -17,7 +17,7 @@ class Account(models.JMSModel, OrgModelMixin):
username = models.CharField(max_length=1024, null=True, blank=True, verbose_name=_('Username'))
secret = models.TextField(verbose_name=_('Secret'))
address = models.CharField(max_length=1024, verbose_name=_('Address'))
port = models.IntegerField(null=True, verbose_name=_('Address'))
port = models.IntegerField(null=True, verbose_name=_('Port'))
type = models.ForeignKey('accounts.AccountType', on_delete=models.PROTECT, verbose_name=_('Type'))
privileged = models.BooleanField(default=True, verbose_name=_('Privileged'))
extra_props = jsonfield.JSONField()
......
......@@ -14,9 +14,10 @@ class AccountSerializer(serializers.ModelSerializer):
class Meta:
model = Account
fields = (
'id', 'name', 'username', 'address', 'secret', 'secret_type', 'type',
'type_display', 'extra_props', 'namespace', 'namespace_display',
'is_active', 'comment', 'created_by', 'date_created', 'date_updated',
'id', 'name', 'username', 'address', 'secret', 'secret_type',
'port', 'type', 'privileged', 'type_display', 'extra_props',
'namespace', 'namespace_display', 'is_active', 'comment',
'created_by', 'date_created', 'date_updated',
)
read_only_fields = ('id', 'type_display', 'namespace_display', 'created_by')
extra_kwargs = {
......@@ -64,9 +65,10 @@ class AccountWithSecretSerializer(AccountSerializer):
class Meta:
model = Account
fields = (
'id', 'name', 'username', 'address', 'secret', 'secret_type', 'type',
'type_display', 'extra_props', 'namespace', 'namespace_display',
'is_active', 'comment', 'created_by', 'date_created', 'date_updated',
'id', 'name', 'username', 'address', 'secret', 'secret_type',
'port', 'type', 'privileged', 'type_display', 'extra_props',
'namespace', 'namespace_display', 'is_active', 'comment',
'created_by', 'date_created', 'date_updated'
)
def to_representation(self, instance):
......
......@@ -2,17 +2,17 @@ from django.db.models import Q
from django.utils.translation import ugettext as _
from rest_framework import status
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet
from rbac.models import NamespaceRoleBinding, OrgRoleBinding
from namespaces.models import Namespace
from namespaces.permissions import NamespacePermission
from namespaces.serializers import NamespaceSerializer
class NamespaceViewSet(ModelViewSet):
permission_classes = (IsAuthenticated,)
permission_classes = (NamespacePermission,)
filter_fields = ('name',)
search_fields = filter_fields
ordering_fields = ('name', 'date_created')
......
from django.core.exceptions import PermissionDenied
from rest_framework.permissions import BasePermission
from orgs.permissions import OrgRBACPermission
class NamespaceRBACPermission(OrgRBACPermission):
@staticmethod
def default_get_rbac_namespace_id(view):
action = getattr(view, 'action', '')
request = view.request
if action in ['update', 'retrieve', 'partial_update', 'destroy']:
if view.detail:
obj = view.get_object()
return obj.namespace.id
if action in ['create']:
nid = request.data.get('namespace_id', '')
return nid
if action in ['list']:
# nid = view.kwargs.get('nid', '')
nid = request.query_params.get('namespace_id', '')
return nid
return ''
nid = obj.namespace.id
else:
nid = request.data.get('namespace', '') or request.query_params.get('namespace_id', '')
if not nid:
raise PermissionDenied
return nid
def get_namespace_id(self, view):
if hasattr(view, 'get_rbac_namespace_id') and callable(view.get_rbac_namespace_id):
......@@ -26,7 +25,7 @@ class NamespaceRBACPermission(OrgRBACPermission):
return namespace_id
def get_namespace_required_permissions(self, view, model_cls):
perms = self.get_action_required_permissions(view, model_cls)
perms = self.get_org_required_permissions(view, model_cls)
namespace_id = self.get_namespace_id(view)
perms = [f'ns:{namespace_id}|{p}' for p in perms]
return set(perms)
......@@ -37,3 +36,19 @@ class NamespaceRBACPermission(OrgRBACPermission):
queryset = self._queryset(view)
perms = self.get_namespace_required_permissions(view, queryset.model)
return request.user.has_perms(perms)
class NamespacePermission(BasePermission):
@staticmethod
def has_handle_object_permission(request, view):
if request.user.is_sys_admin:
return True
return False
def has_permission(self, request, view):
if request.user.is_anonymous:
return False
if request.method in ['DELETE', 'PUT', 'PATCH', 'POST']:
return self.has_handle_object_permission(request, view)
return True
......@@ -8,9 +8,13 @@ class RBACBackend(ModelBackend):
def format_perms(perms):
return ["%s.%s" % (ct, codename) for ct, codename in perms]
def get_namespace_permissions(self, user_obj, namespace_id):
def get_namespace_permissions(self, user_obj, namespace_id, org_id):
perms = []
bindings = NamespaceRoleBinding.objects.filter(user=user_obj, namespace=namespace_id).all()
if org_id == 'DEFAULT':
bindings = NamespaceRoleBinding.objects.filter(user=user_obj, namespace=namespace_id).all()
else:
bindings = NamespaceRoleBinding.objects.\
filter(user=user_obj, namespace=namespace_id, namespace__org_id=org_id).all()
for i in bindings:
perms += i.role.permissions.all().values_list('content_type__app_label', 'codename')
return self.format_perms(perms)
......@@ -61,13 +65,13 @@ class RBACBackend(ModelBackend):
return False
scoped_perm = self.parse_perm(perm)
namespace = scoped_perm.get('ns')
org = scoped_perm.get('org')
namespace_id = scoped_perm.get('ns')
org_id = scoped_perm.get('org')
perm = scoped_perm.get('perm')
if namespace:
return perm in self.get_namespace_permissions(user_obj, namespace)
if org:
return perm in self.get_org_permissions(user_obj, org)
if namespace_id:
return perm in self.get_namespace_permissions(user_obj, namespace_id, org_id)
if org_id:
return perm in self.get_org_permissions(user_obj, org_id)
return perm in self.get_system_permissions(user_obj)
def has_module_perms(self, user_obj, app_label):
......
# Generated by Django 2.2.13 on 2020-10-22 14:54
# Generated by Django 2.2.13 on 2020-10-26 02:42
from django.conf import settings
from django.db import migrations, models
......@@ -11,10 +11,10 @@ class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('auth', '0011_update_proxy_permissions'),
('namespaces', '0001_initial'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('orgs', '0009_auto_20201022_2247'),
('auth', '0011_update_proxy_permissions'),
]
operations = [
......@@ -48,7 +48,6 @@ class Migration(migrations.Migration):
],
options={
'verbose_name': 'Role Org Binding',
'unique_together': {('user', 'role')},
},
),
migrations.CreateModel(
......
......@@ -65,7 +65,7 @@ class OrgRoleBindingSerializer(serializers.ModelSerializer):
model = OrgRoleBinding
fields = (
'id', 'user', 'user_info', 'role', 'role_info',
'orgs', 'org_info', 'created_by', 'updated_by',
'org', 'org_info', 'created_by', 'updated_by',
'date_created', 'date_updated'
)
read_only_fields = ('id', 'created_by', 'updated_by')
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment