diff --git a/apps/assets/serializers.py b/apps/assets/serializers.py index 256b3e87e..be4183619 100644 --- a/apps/assets/serializers.py +++ b/apps/assets/serializers.py @@ -6,17 +6,17 @@ from common.mixins import BulkDeleteApiMixin from rest_framework_bulk import BulkListSerializer, BulkSerializerMixin -class AssetSerializer(BulkSerializerMixin, serializers.ModelSerializer): - - class Meta(object): - model = Asset - list_serializer_class = BulkListSerializer - - class AssetGroupSerializer(serializers.ModelSerializer): + assets_amount = serializers.SerializerMethodField() + assets = serializers.PrimaryKeyRelatedField(many=True, read_only=True) + class Meta: model = AssetGroup + @staticmethod + def get_assets_amount(obj): + return obj.assets.count() + class AdminUserSerializer(serializers.ModelSerializer): class Meta: @@ -31,6 +31,7 @@ class AdminUserSerializer(serializers.ModelSerializer): class SystemUserSerializer(serializers.ModelSerializer): class Meta: model = SystemUser + exclude = ('_password', '_private_key', '_public_key') def get_field_names(self, declared_fields, info): fields = super(SystemUserSerializer, self).get_field_names(declared_fields, info) @@ -38,6 +39,37 @@ class SystemUserSerializer(serializers.ModelSerializer): return fields +class AssetSerializer(BulkSerializerMixin, serializers.ModelSerializer): + system_users = SystemUserSerializer(many=True, read_only=True) + admin_user = AdminUserSerializer(many=False, read_only=True) + + class Meta(object): + model = Asset + list_serializer_class = BulkListSerializer + + +class AssetGrantedSerializer(serializers.ModelSerializer): + system_users = SystemUserSerializer(many=True, read_only=True) + is_inherited = serializers.SerializerMethodField() + system_users_join = serializers.SerializerMethodField() + + class Meta(object): + model = Asset + fields = ("id", "hostname", "ip", "port", "system_users", "is_inherited", + "is_active", "system_users_join", "comment") + + @staticmethod + def get_is_inherited(obj): + if getattr(obj, 'inherited', ''): + return True + else: + return False + + @staticmethod + def get_system_users_join(obj): + return ', '.join([system_user.username for system_user in obj.system_users.all()]) + + class IDCSerializer(serializers.ModelSerializer): assets_amount = serializers.SerializerMethodField() diff --git a/apps/jumpserver/settings.py b/apps/jumpserver/settings.py index 5893ee909..6f9880acc 100644 --- a/apps/jumpserver/settings.py +++ b/apps/jumpserver/settings.py @@ -284,6 +284,19 @@ BROKER_URL = 'redis://%(password)s%(host)s:%(port)s/3' % { } CELERY_RESULT_BACKEND = BROKER_URL + +# Cache use redis +CACHES = { + 'default': { + 'BACKEND': 'redis_cache.RedisCache', + 'LOCATION': 'redis://%(password)s%(host)s:%(port)s/4' % { + 'password': CONFIG.REDIS_PASSWORD + '@' if CONFIG.REDIS_PASSWORD else '', + 'host': CONFIG.REDIS_HOST or '127.0.0.1', + 'port': CONFIG.REDIS_PORT or 6379, + } + } +} + # Captcha settings, more see https://django-simple-captcha.readthedocs.io/en/latest/advanced.html CAPTCHA_IMAGE_SIZE = (75, 33) CAPTCHA_FOREGROUND_COLOR = '#001100' diff --git a/apps/perms/api.py b/apps/perms/api.py index 9b95a1a1f..eefb8a448 100644 --- a/apps/perms/api.py +++ b/apps/perms/api.py @@ -2,13 +2,13 @@ # from rest_framework.views import APIView, Response -from rest_framework.generics import ListCreateAPIView +from rest_framework.generics import ListAPIView from rest_framework import viewsets from users.backends import IsValidUser, IsSuperUser from common.utils import get_object_or_none from .utils import get_user_granted_assets, get_user_granted_asset_groups, get_user_asset_permissions from .models import AssetPermission -from .hands import User +from .hands import AssetGrantedSerializer, User, AssetGroup, Asset, AssetGroup from . import serializers @@ -21,7 +21,6 @@ class AssetPermissionViewSet(viewsets.ModelViewSet): queryset = super(AssetPermissionViewSet, self).get_queryset() user_id = self.request.query_params.get('user', '') if user_id and user_id.isdigit(): - from users.models import User self.user_id = user_id user = get_object_or_none(User, id=int(user_id)) if user: @@ -43,12 +42,8 @@ class RevokeUserAssetPermission(APIView): user_id = str(request.data.get('user_id', '')) if permission_id and user_id and permission_id.isdigit() and user_id.isdigit(): - permission_id = int(permission_id) - user_id = int(user_id) - asset_permission = get_object_or_none(AssetPermission, id=permission_id) - user = get_object_or_none(User, id=user_id) - print(asset_permission) - print(user) + asset_permission = get_object_or_none(AssetPermission, id=int(permission_id)) + user = get_object_or_none(User, id=int(user_id)) if asset_permission and user: asset_permission.users.remove(user) @@ -56,33 +51,16 @@ class RevokeUserAssetPermission(APIView): return Response({'msg': 'failed'}, status=404) -class UserAssetsApi(APIView): +class UserAssetsApi(ListAPIView): permission_classes = (IsValidUser,) + serializer_class = AssetGrantedSerializer - def get(self, request, *args, **kwargs): - assets_json = [] - user = request.user - + def get_queryset(self): + user = self.request.user if user: - assets = get_user_granted_assets(user) - - for asset, system_users in assets.items(): - assets_json.append({ - 'id': asset.id, - 'hostname': asset.hostname, - 'ip': asset.ip, - 'port': asset.port, - 'system_users': [ - { - 'id': system_user.id, - 'name': system_user.name, - 'username': system_user.username, - } for system_user in system_users - ], - 'comment': asset.comment - }) - - return Response(assets_json, status=200) + queryset = get_user_granted_assets(user) + return queryset + return [] class UserAssetsGroupsApi(APIView): @@ -97,46 +75,31 @@ class UserAssetsGroupsApi(APIView): for asset in assets: for asset_group in asset.groups.all(): if asset_group.id in asset_groups: - asset_groups[asset_group.id]['asset_num'] += 1 + asset_groups[asset_group.id]['asset_amount'] += 1 else: asset_groups[asset_group.id] = { 'id': asset_group.id, 'name': asset_group.name, 'comment': asset_group.comment, - 'asset_num': 1 + 'asset_amount': 1 } - asset_groups_json = asset_groups.values() return Response(asset_groups_json, status=200) -class UserAssetsGroupAssetsApi(APIView): +class UserAssetsGroupAssetsApi(ListAPIView): permission_classes = (IsValidUser,) + serializer_class = AssetGrantedSerializer - def get(self, request, *args, **kwargs): - # asset_group_id = request.query_params.get('asset_group_id', -1) - asset_group_id = kwargs.get('pk', -1) - # asset_group_name = request.query_params.get('asset_group_name', '') - user = request.user - assets_json = [] + def get_queryset(self): + queryset = [] + asset_group_id = self.kwargs.get('pk', -1) + user = self.request.user + asset_group = get_object_or_none(AssetGroup, id=asset_group_id) - if user: + if user and asset_group: assets = get_user_granted_assets(user) - for asset, system_users in assets.items(): - for asset_group in asset.groups.all(): - if str(asset_group.id) == asset_group_id: # and asset_group.name == asset_group_name: - assets_json.append({ - 'id': asset.id, - 'hostname': asset.hostname, - 'ip': asset.ip, - 'port': asset.port, - 'system_users': [ - { - 'id': system_user.id, - 'name': system_user.name, - 'username': system_user.username, - } for system_user in system_users - ], - 'comment': asset.comment - }) - return Response(assets_json, status=200) + for asset in assets: + if asset_group in asset.groups.all(): + queryset.append(asset) + return queryset diff --git a/apps/perms/hands.py b/apps/perms/hands.py index 735faecfd..714aa39d5 100644 --- a/apps/perms/hands.py +++ b/apps/perms/hands.py @@ -4,6 +4,7 @@ from users.utils import AdminUserRequiredMixin from users.models import User, UserGroup from assets.models import Asset, AssetGroup, SystemUser +from assets.serializers import AssetGrantedSerializer def associate_system_users_with_assets(system_users, assets, asset_groups): diff --git a/apps/perms/urls.py b/apps/perms/urls.py index faf51c737..10bb972cd 100644 --- a/apps/perms/urls.py +++ b/apps/perms/urls.py @@ -26,11 +26,11 @@ router = routers.DefaultRouter() router.register('v1/asset-permissions', api.AssetPermissionViewSet, 'api-asset-permission') urlpatterns += [ - url(r'^v1/user/assets/$', api.UserAssetsApi.as_view(), name='user-assets'), + url(r'^v1/user/assets/$', api.UserAssetsApi.as_view(), name='api-user-assets'), url(r'^v1/asset-permissions/user/revoke/', api.RevokeUserAssetPermission.as_view(), name='revoke-user-asset-permission'), - url(r'^v1/user/asset-groups/$', api.UserAssetsGroupsApi.as_view(), name='user-asset-groups'), - url(r'^v1/user/asset-groups/(?P[0-9]+)/assets/$', api.UserAssetsGroupAssetsApi.as_view(), + url(r'^v1/user/asset-groups/$', api.UserAssetsGroupsApi.as_view(), name='api-user-asset-groups'), + url(r'^v1/user/asset-group/(?P[0-9]+)/assets/$', api.UserAssetsGroupAssetsApi.as_view(), name='user-asset-groups-assets'), ] diff --git a/apps/perms/utils.py b/apps/perms/utils.py index 3bc9b246f..585b65808 100644 --- a/apps/perms/utils.py +++ b/apps/perms/utils.py @@ -8,7 +8,7 @@ def get_user_group_granted_asset_groups(user_group): """Return asset groups granted of the user group :param user_group: Instance of :class: ``UserGroup`` - :return: {asset_group1: {system_user1, }, asset_group2: {system_user1, system_user2]} + :return: {asset_group1: {system_user1, }, asset_group2: {system_user1, system_user2}} """ asset_groups = {} asset_permissions = user_group.asset_permissions.all() @@ -21,7 +21,6 @@ def get_user_group_granted_asset_groups(user_group): asset_groups[asset_group] |= set(asset_permission.system_users.all()) else: asset_groups[asset_group] = set(asset_permission.system_users.all()) - return asset_groups @@ -61,7 +60,7 @@ def get_user_granted_asset_groups_direct(user): if asset_group in asset_groups: asset_groups[asset_group] |= set(asset_permission.system_users.all()) else: - setattr(asset_group, 'is_inherit_from_user_group', False) + setattr(asset_group, 'inherited', False) asset_groups[asset_group] = set(asset_permission.system_users.all()) return asset_groups @@ -89,7 +88,7 @@ def get_user_granted_asset_groups_inherit_from_user_groups(user): if asset_group in asset_groups: asset_groups[asset_group] |= set(asset_permission.system_users.all()) else: - setattr(asset_group, 'is_inherit_from_user_group', True) + setattr(asset_group, 'inherited', True) asset_groups[asset_group] = set(asset_permission.system_users.all()) return asset_groups @@ -131,10 +130,8 @@ def get_user_granted_assets_direct(user): if asset in assets: assets[asset] |= set(asset_permission.system_users.all()) else: - setattr(asset, 'is_inherit_from_user_groups', False) - setattr(asset, 'is_inherit_from_user_groups', False) + setattr(asset, 'inherited', False) assets[asset] = set(asset_permission.system_users.all()) - return assets @@ -153,7 +150,7 @@ def get_user_granted_assets_inherit_from_user_groups(user): if asset in assets: assets[asset] |= assets_inherited[asset] else: - setattr(asset, 'is_inherit_from_user_groups', True) + setattr(asset, 'inherited', True) assets[asset] = assets_inherited[asset] return assets diff --git a/apps/users/backends.py b/apps/users/backends.py index 00061bdec..688adcace 100644 --- a/apps/users/backends.py +++ b/apps/users/backends.py @@ -78,6 +78,7 @@ class AccessTokenAuthentication(authentication.BaseAuthentication): def authenticate_credentials(self, token, request): user_id = cache.get(token) + print('Auth id: %s' % user_id) user = get_object_or_none(User, id=user_id) if not user: @@ -87,7 +88,6 @@ class AccessTokenAuthentication(authentication.BaseAuthentication): remote_addr = base64.b16encode(remote_addr).replace('=', '') cache.set(token, user_id, self.expiration) cache.set('%s_%s' % (user.id, remote_addr), token, self.expiration) - return user, None diff --git a/apps/users/templates/users/user_asset_permission.html b/apps/users/templates/users/user_asset_permission.html index 47cc45803..8c6eba155 100644 --- a/apps/users/templates/users/user_asset_permission.html +++ b/apps/users/templates/users/user_asset_permission.html @@ -28,16 +28,6 @@
  • {% trans 'Login history' %}
  • -
    @@ -86,38 +76,38 @@ {% trans 'Quick create permission for user' %}
    -{#
    #} -{# #} -{# #} -{# {% csrf_token %}#} -{# #} -{# #} -{# #} -{# #} -{# #} -{# #} -{# #} -{# #} -{# #} -{# #} -{# #} -{# #} -{# #} -{# #} -{# #} -{# #} -{#
    #} -{# {{ form.name|bootstrap }}#} -{#
    #} -{# {{ form.assets|bootstrap }}#} -{#
    #} -{# {{ form.asset_groups|bootstrap }}#} -{#
    #} -{# {{ form.system_users|bootstrap }}#} -{#
    #} -{# #} -{#
    #} -{#
    #} +
    + + + {% csrf_token %} + + + + + + + + + + + + + + + + +
    + {{ form.name|bootstrap }} +
    + {{ form.assets|bootstrap }} +
    + {{ form.asset_groups|bootstrap }} +
    + {{ form.system_users|bootstrap }} +
    + +
    +
    diff --git a/apps/users/templates/users/user_granted_asset.html b/apps/users/templates/users/user_granted_asset.html index 08feee6c1..7279231ff 100644 --- a/apps/users/templates/users/user_granted_asset.html +++ b/apps/users/templates/users/user_granted_asset.html @@ -17,34 +17,24 @@
    - +
    - - - + + - {% for asset_group, system_users in asset_groups %} - - - - - - - {% endfor %}
    {% trans 'Name' %}{% trans 'Asset count' %}{% trans 'System user' %} {% trans 'Name' %}{% trans 'Asset' %}
    - - {{ asset_group.name }} - - {{ asset_group.assets.count }}{{ system_users|join_attr:"name" }} - -
    @@ -161,25 +109,53 @@ {% endblock %} {% block custom_foot_js %} {% endblock %} \ No newline at end of file diff --git a/apps/users/urls.py b/apps/users/urls.py index dd39c87e9..07561e3ff 100644 --- a/apps/users/urls.py +++ b/apps/users/urls.py @@ -19,9 +19,9 @@ urlpatterns = [ url(r'^user/(?P[0-9]+)$', views.UserDetailView.as_view(), name='user-detail'), url(r'^user/(?P[0-9]+)/asset-permission$', views.UserAssetPermissionView.as_view(), name='user-asset-permission'), - # url(r'^user/(?P[0-9]+)/asset-permission/create$', views.UserAssetPermissionCreateView.as_view(), - # name='user-asset-permission-create'), - url(r'^user/(?P[0-9]+)/granted-asset', views.UserGrantedAssetView.as_view(), name='user-granted-asset'), + url(r'^user/(?P[0-9]+)/asset-permission/create$', views.UserAssetPermissionCreateView.as_view(), + name='user-asset-permission-create'), + url(r'^user/(?P[0-9]+)/assets', views.UserGrantedAssetView.as_view(), name='user-granted-asset'), url(r'^user/(?P[0-9]+)/login-history', views.UserDetailView.as_view(), name='user-login-history'), url(r'^first-login/$', views.UserFirstLoginView.as_view(), name='user-first-login'), url(r'^import/$', views.BulkImportUserView.as_view(), name='user-import'), diff --git a/apps/users/views.py b/apps/users/views.py index 5a07efbbc..212c2a262 100644 --- a/apps/users/views.py +++ b/apps/users/views.py @@ -341,33 +341,15 @@ class UserFirstLoginView(LoginRequiredMixin, SessionWizardView): return form -class UserAssetPermissionView(AdminUserRequiredMixin, DetailView): +class UserAssetPermissionView(AdminUserRequiredMixin, FormMixin, SingleObjectMixin, ListView): model = User template_name = 'users/user_asset_permission.html' context_object_name = 'user' + form_class = forms.UserPrivateAssetPermissionForm - # form_class = forms.UserPrivateAssetPermissionForm - - # def get(self, request, *args, **kwargs): - # self.object = self.get_object(queryset=User.objects.all()) - # return super(UserAssetPermissionView, self).get(request, *args, **kwargs) - - # def get_asset_permission_inherit_from_user_group(self): - # asset_permissions = set() - # user_groups = self.object.groups.all() - # - # for user_group in user_groups: - # for asset_permission in user_group.asset_permissions.all(): - # setattr(asset_permission, 'is_inherit_from_user_groups', True) - # setattr(asset_permission, 'inherit_from_user_groups', - # getattr(asset_permission, b'inherit_from_user_groups', set()).add(user_group)) - # asset_permissions.add(asset_permission) - # return asset_permissions - # - # def get_queryset(self): - # asset_permissions = set(self.object.asset_permissions.all()) \ - # | self.get_asset_permission_inherit_from_user_group() - # return list(asset_permissions) + def get(self, request, *args, **kwargs): + self.object = self.get_object(queryset=User.objects.all()) + return super(UserAssetPermissionView, self).get(request, *args, **kwargs) def get_context_data(self, **kwargs): context = { @@ -403,31 +385,19 @@ class UserAssetPermissionCreateView(AdminUserRequiredMixin, CreateView): return reverse('users:user-asset-permission', kwargs={'pk': self.user_object.id}) -class UserGrantedAssetView(AdminUserRequiredMixin, SingleObjectMixin, ListView): - paginate_by = settings.CONFIG.DISPLAY_PER_PAGE +class UserGrantedAssetView(AdminUserRequiredMixin, DetailView): + model = User template_name = 'users/user_granted_asset.html' - context_object_name = 'user_object' + context_object_name = 'user' def get(self, request, *args, **kwargs): self.object = self.get_object(queryset=User.objects.all()) return super(UserGrantedAssetView, self).get(request, *args, **kwargs) - def get_queryset(self): - # Convert format from {'asset': ['system_users'], ..} to - # [('asset', ['system_users']), ('asset', ['system_users'])) - # assets_granted = [(asset, system_users) for asset, system_users in - # get_user_granted_assets(self.object).items()] - - # return assets_granted - return [] - def get_context_data(self, **kwargs): - # asset_groups = [(asset_group, system_users) for asset_group, system_users in - # get_user_granted_asset_groups(self.object).items()] context = { 'app': 'User', 'action': 'User granted asset', - # 'asset_groups': asset_groups, } kwargs.update(context) return super(UserGrantedAssetView, self).get_context_data(**kwargs) diff --git a/requirements.txt b/requirements.txt index f4fcdac3a..a89fd6191 100644 --- a/requirements.txt +++ b/requirements.txt @@ -12,3 +12,4 @@ django-formtools==1.0 sshpubkeys==2.2.0 djangorestframework-bulk==0.2.1 paramiko==2.0.2 +django-redis-cache==1.7.1