mirror of https://github.com/jumpserver/jumpserver
Finish user detail
parent
69f2bf664b
commit
f70abec5ef
|
@ -6,17 +6,17 @@ from common.mixins import BulkDeleteApiMixin
|
||||||
from rest_framework_bulk import BulkListSerializer, BulkSerializerMixin
|
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):
|
class AssetGroupSerializer(serializers.ModelSerializer):
|
||||||
|
assets_amount = serializers.SerializerMethodField()
|
||||||
|
assets = serializers.PrimaryKeyRelatedField(many=True, read_only=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = AssetGroup
|
model = AssetGroup
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_assets_amount(obj):
|
||||||
|
return obj.assets.count()
|
||||||
|
|
||||||
|
|
||||||
class AdminUserSerializer(serializers.ModelSerializer):
|
class AdminUserSerializer(serializers.ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
|
@ -31,6 +31,7 @@ class AdminUserSerializer(serializers.ModelSerializer):
|
||||||
class SystemUserSerializer(serializers.ModelSerializer):
|
class SystemUserSerializer(serializers.ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = SystemUser
|
model = SystemUser
|
||||||
|
exclude = ('_password', '_private_key', '_public_key')
|
||||||
|
|
||||||
def get_field_names(self, declared_fields, info):
|
def get_field_names(self, declared_fields, info):
|
||||||
fields = super(SystemUserSerializer, self).get_field_names(declared_fields, info)
|
fields = super(SystemUserSerializer, self).get_field_names(declared_fields, info)
|
||||||
|
@ -38,6 +39,37 @@ class SystemUserSerializer(serializers.ModelSerializer):
|
||||||
return fields
|
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):
|
class IDCSerializer(serializers.ModelSerializer):
|
||||||
assets_amount = serializers.SerializerMethodField()
|
assets_amount = serializers.SerializerMethodField()
|
||||||
|
|
||||||
|
|
|
@ -284,6 +284,19 @@ BROKER_URL = 'redis://%(password)s%(host)s:%(port)s/3' % {
|
||||||
}
|
}
|
||||||
CELERY_RESULT_BACKEND = BROKER_URL
|
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 settings, more see https://django-simple-captcha.readthedocs.io/en/latest/advanced.html
|
||||||
CAPTCHA_IMAGE_SIZE = (75, 33)
|
CAPTCHA_IMAGE_SIZE = (75, 33)
|
||||||
CAPTCHA_FOREGROUND_COLOR = '#001100'
|
CAPTCHA_FOREGROUND_COLOR = '#001100'
|
||||||
|
|
|
@ -2,13 +2,13 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
from rest_framework.views import APIView, Response
|
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 rest_framework import viewsets
|
||||||
from users.backends import IsValidUser, IsSuperUser
|
from users.backends import IsValidUser, IsSuperUser
|
||||||
from common.utils import get_object_or_none
|
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 .utils import get_user_granted_assets, get_user_granted_asset_groups, get_user_asset_permissions
|
||||||
from .models import AssetPermission
|
from .models import AssetPermission
|
||||||
from .hands import User
|
from .hands import AssetGrantedSerializer, User, AssetGroup, Asset, AssetGroup
|
||||||
from . import serializers
|
from . import serializers
|
||||||
|
|
||||||
|
|
||||||
|
@ -21,7 +21,6 @@ class AssetPermissionViewSet(viewsets.ModelViewSet):
|
||||||
queryset = super(AssetPermissionViewSet, self).get_queryset()
|
queryset = super(AssetPermissionViewSet, self).get_queryset()
|
||||||
user_id = self.request.query_params.get('user', '')
|
user_id = self.request.query_params.get('user', '')
|
||||||
if user_id and user_id.isdigit():
|
if user_id and user_id.isdigit():
|
||||||
from users.models import User
|
|
||||||
self.user_id = user_id
|
self.user_id = user_id
|
||||||
user = get_object_or_none(User, id=int(user_id))
|
user = get_object_or_none(User, id=int(user_id))
|
||||||
if user:
|
if user:
|
||||||
|
@ -43,12 +42,8 @@ class RevokeUserAssetPermission(APIView):
|
||||||
user_id = str(request.data.get('user_id', ''))
|
user_id = str(request.data.get('user_id', ''))
|
||||||
|
|
||||||
if permission_id and user_id and permission_id.isdigit() and user_id.isdigit():
|
if permission_id and user_id and permission_id.isdigit() and user_id.isdigit():
|
||||||
permission_id = int(permission_id)
|
asset_permission = get_object_or_none(AssetPermission, id=int(permission_id))
|
||||||
user_id = int(user_id)
|
user = get_object_or_none(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)
|
|
||||||
|
|
||||||
if asset_permission and user:
|
if asset_permission and user:
|
||||||
asset_permission.users.remove(user)
|
asset_permission.users.remove(user)
|
||||||
|
@ -56,33 +51,16 @@ class RevokeUserAssetPermission(APIView):
|
||||||
return Response({'msg': 'failed'}, status=404)
|
return Response({'msg': 'failed'}, status=404)
|
||||||
|
|
||||||
|
|
||||||
class UserAssetsApi(APIView):
|
class UserAssetsApi(ListAPIView):
|
||||||
permission_classes = (IsValidUser,)
|
permission_classes = (IsValidUser,)
|
||||||
|
serializer_class = AssetGrantedSerializer
|
||||||
|
|
||||||
def get(self, request, *args, **kwargs):
|
def get_queryset(self):
|
||||||
assets_json = []
|
user = self.request.user
|
||||||
user = request.user
|
|
||||||
|
|
||||||
if user:
|
if user:
|
||||||
assets = get_user_granted_assets(user)
|
queryset = get_user_granted_assets(user)
|
||||||
|
return queryset
|
||||||
for asset, system_users in assets.items():
|
return []
|
||||||
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)
|
|
||||||
|
|
||||||
|
|
||||||
class UserAssetsGroupsApi(APIView):
|
class UserAssetsGroupsApi(APIView):
|
||||||
|
@ -97,46 +75,31 @@ class UserAssetsGroupsApi(APIView):
|
||||||
for asset in assets:
|
for asset in assets:
|
||||||
for asset_group in asset.groups.all():
|
for asset_group in asset.groups.all():
|
||||||
if asset_group.id in asset_groups:
|
if asset_group.id in asset_groups:
|
||||||
asset_groups[asset_group.id]['asset_num'] += 1
|
asset_groups[asset_group.id]['asset_amount'] += 1
|
||||||
else:
|
else:
|
||||||
asset_groups[asset_group.id] = {
|
asset_groups[asset_group.id] = {
|
||||||
'id': asset_group.id,
|
'id': asset_group.id,
|
||||||
'name': asset_group.name,
|
'name': asset_group.name,
|
||||||
'comment': asset_group.comment,
|
'comment': asset_group.comment,
|
||||||
'asset_num': 1
|
'asset_amount': 1
|
||||||
}
|
}
|
||||||
|
|
||||||
asset_groups_json = asset_groups.values()
|
asset_groups_json = asset_groups.values()
|
||||||
return Response(asset_groups_json, status=200)
|
return Response(asset_groups_json, status=200)
|
||||||
|
|
||||||
|
|
||||||
class UserAssetsGroupAssetsApi(APIView):
|
class UserAssetsGroupAssetsApi(ListAPIView):
|
||||||
permission_classes = (IsValidUser,)
|
permission_classes = (IsValidUser,)
|
||||||
|
serializer_class = AssetGrantedSerializer
|
||||||
|
|
||||||
def get(self, request, *args, **kwargs):
|
def get_queryset(self):
|
||||||
# asset_group_id = request.query_params.get('asset_group_id', -1)
|
queryset = []
|
||||||
asset_group_id = kwargs.get('pk', -1)
|
asset_group_id = self.kwargs.get('pk', -1)
|
||||||
# asset_group_name = request.query_params.get('asset_group_name', '')
|
user = self.request.user
|
||||||
user = request.user
|
asset_group = get_object_or_none(AssetGroup, id=asset_group_id)
|
||||||
assets_json = []
|
|
||||||
|
|
||||||
if user:
|
if user and asset_group:
|
||||||
assets = get_user_granted_assets(user)
|
assets = get_user_granted_assets(user)
|
||||||
for asset, system_users in assets.items():
|
for asset in assets:
|
||||||
for asset_group in asset.groups.all():
|
if asset_group in asset.groups.all():
|
||||||
if str(asset_group.id) == asset_group_id: # and asset_group.name == asset_group_name:
|
queryset.append(asset)
|
||||||
assets_json.append({
|
return queryset
|
||||||
'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)
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
from users.utils import AdminUserRequiredMixin
|
from users.utils import AdminUserRequiredMixin
|
||||||
from users.models import User, UserGroup
|
from users.models import User, UserGroup
|
||||||
from assets.models import Asset, AssetGroup, SystemUser
|
from assets.models import Asset, AssetGroup, SystemUser
|
||||||
|
from assets.serializers import AssetGrantedSerializer
|
||||||
|
|
||||||
|
|
||||||
def associate_system_users_with_assets(system_users, assets, asset_groups):
|
def associate_system_users_with_assets(system_users, assets, asset_groups):
|
||||||
|
|
|
@ -26,11 +26,11 @@ router = routers.DefaultRouter()
|
||||||
router.register('v1/asset-permissions', api.AssetPermissionViewSet, 'api-asset-permission')
|
router.register('v1/asset-permissions', api.AssetPermissionViewSet, 'api-asset-permission')
|
||||||
|
|
||||||
urlpatterns += [
|
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(),
|
url(r'^v1/asset-permissions/user/revoke/', api.RevokeUserAssetPermission.as_view(),
|
||||||
name='revoke-user-asset-permission'),
|
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/$', api.UserAssetsGroupsApi.as_view(), name='api-user-asset-groups'),
|
||||||
url(r'^v1/user/asset-groups/(?P<pk>[0-9]+)/assets/$', api.UserAssetsGroupAssetsApi.as_view(),
|
url(r'^v1/user/asset-group/(?P<pk>[0-9]+)/assets/$', api.UserAssetsGroupAssetsApi.as_view(),
|
||||||
name='user-asset-groups-assets'),
|
name='user-asset-groups-assets'),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ def get_user_group_granted_asset_groups(user_group):
|
||||||
"""Return asset groups granted of the user group
|
"""Return asset groups granted of the user group
|
||||||
|
|
||||||
:param user_group: Instance of :class: ``UserGroup``
|
: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_groups = {}
|
||||||
asset_permissions = user_group.asset_permissions.all()
|
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())
|
asset_groups[asset_group] |= set(asset_permission.system_users.all())
|
||||||
else:
|
else:
|
||||||
asset_groups[asset_group] = set(asset_permission.system_users.all())
|
asset_groups[asset_group] = set(asset_permission.system_users.all())
|
||||||
|
|
||||||
return asset_groups
|
return asset_groups
|
||||||
|
|
||||||
|
|
||||||
|
@ -61,7 +60,7 @@ def get_user_granted_asset_groups_direct(user):
|
||||||
if asset_group in asset_groups:
|
if asset_group in asset_groups:
|
||||||
asset_groups[asset_group] |= set(asset_permission.system_users.all())
|
asset_groups[asset_group] |= set(asset_permission.system_users.all())
|
||||||
else:
|
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())
|
asset_groups[asset_group] = set(asset_permission.system_users.all())
|
||||||
|
|
||||||
return asset_groups
|
return asset_groups
|
||||||
|
@ -89,7 +88,7 @@ def get_user_granted_asset_groups_inherit_from_user_groups(user):
|
||||||
if asset_group in asset_groups:
|
if asset_group in asset_groups:
|
||||||
asset_groups[asset_group] |= set(asset_permission.system_users.all())
|
asset_groups[asset_group] |= set(asset_permission.system_users.all())
|
||||||
else:
|
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())
|
asset_groups[asset_group] = set(asset_permission.system_users.all())
|
||||||
|
|
||||||
return asset_groups
|
return asset_groups
|
||||||
|
@ -131,10 +130,8 @@ def get_user_granted_assets_direct(user):
|
||||||
if asset in assets:
|
if asset in assets:
|
||||||
assets[asset] |= set(asset_permission.system_users.all())
|
assets[asset] |= set(asset_permission.system_users.all())
|
||||||
else:
|
else:
|
||||||
setattr(asset, 'is_inherit_from_user_groups', False)
|
setattr(asset, 'inherited', False)
|
||||||
setattr(asset, 'is_inherit_from_user_groups', False)
|
|
||||||
assets[asset] = set(asset_permission.system_users.all())
|
assets[asset] = set(asset_permission.system_users.all())
|
||||||
|
|
||||||
return assets
|
return assets
|
||||||
|
|
||||||
|
|
||||||
|
@ -153,7 +150,7 @@ def get_user_granted_assets_inherit_from_user_groups(user):
|
||||||
if asset in assets:
|
if asset in assets:
|
||||||
assets[asset] |= assets_inherited[asset]
|
assets[asset] |= assets_inherited[asset]
|
||||||
else:
|
else:
|
||||||
setattr(asset, 'is_inherit_from_user_groups', True)
|
setattr(asset, 'inherited', True)
|
||||||
assets[asset] = assets_inherited[asset]
|
assets[asset] = assets_inherited[asset]
|
||||||
|
|
||||||
return assets
|
return assets
|
||||||
|
|
|
@ -78,6 +78,7 @@ class AccessTokenAuthentication(authentication.BaseAuthentication):
|
||||||
|
|
||||||
def authenticate_credentials(self, token, request):
|
def authenticate_credentials(self, token, request):
|
||||||
user_id = cache.get(token)
|
user_id = cache.get(token)
|
||||||
|
print('Auth id: %s' % user_id)
|
||||||
user = get_object_or_none(User, id=user_id)
|
user = get_object_or_none(User, id=user_id)
|
||||||
|
|
||||||
if not user:
|
if not user:
|
||||||
|
@ -87,7 +88,6 @@ class AccessTokenAuthentication(authentication.BaseAuthentication):
|
||||||
remote_addr = base64.b16encode(remote_addr).replace('=', '')
|
remote_addr = base64.b16encode(remote_addr).replace('=', '')
|
||||||
cache.set(token, user_id, self.expiration)
|
cache.set(token, user_id, self.expiration)
|
||||||
cache.set('%s_%s' % (user.id, remote_addr), token, self.expiration)
|
cache.set('%s_%s' % (user.id, remote_addr), token, self.expiration)
|
||||||
|
|
||||||
return user, None
|
return user, None
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -28,16 +28,6 @@
|
||||||
<li>
|
<li>
|
||||||
<a href="{% url 'users:user-login-history' pk=user.id %}" class="text-center"><i class="fa fa-calculator-o"></i> {% trans 'Login history' %}</a>
|
<a href="{% url 'users:user-login-history' pk=user.id %}" class="text-center"><i class="fa fa-calculator-o"></i> {% trans 'Login history' %}</a>
|
||||||
</li>
|
</li>
|
||||||
<form id="search_form" method="get" action="" class="pull-right mail-search">
|
|
||||||
<div class="input-group">
|
|
||||||
<input type="text" class="form-control input-sm" name="keyword" placeholder="Search" value="{{ keyword }}">
|
|
||||||
<div class="input-group-btn">
|
|
||||||
<button id="search_btn" type="submit" class="btn btn-sm btn-primary">
|
|
||||||
搜索
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="tab-content">
|
<div class="tab-content">
|
||||||
|
@ -86,38 +76,38 @@
|
||||||
<i class="fa fa-info-circle"></i> {% trans 'Quick create permission for user' %}
|
<i class="fa fa-info-circle"></i> {% trans 'Quick create permission for user' %}
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
{# <form method="post" action="{% url 'users:user-asset-permission-create' pk=user.id %}">#}
|
<form method="post" action="{% url 'users:user-asset-permission-create' pk=user.id %}">
|
||||||
{# <table class="table">#}
|
<table class="table">
|
||||||
{# <tbody>#}
|
<tbody>
|
||||||
{# {% csrf_token %}#}
|
{% csrf_token %}
|
||||||
{# <tr class="no-borders-tr">#}
|
<tr class="no-borders-tr">
|
||||||
{# <td colspan="1" style="padding-top: 0">#}
|
<td colspan="1" style="padding-top: 0">
|
||||||
{# {{ form.name|bootstrap }}#}
|
{{ form.name|bootstrap }}
|
||||||
{# </td>#}
|
</td>
|
||||||
{# </tr>#}
|
</tr>
|
||||||
{# <tr class="no-borders-tr">#}
|
<tr class="no-borders-tr">
|
||||||
{# <td colspan="1" style="padding-top: 0">#}
|
<td colspan="1" style="padding-top: 0">
|
||||||
{# {{ form.assets|bootstrap }}#}
|
{{ form.assets|bootstrap }}
|
||||||
{# </td>#}
|
</td>
|
||||||
{# </tr>#}
|
</tr>
|
||||||
{# <tr class="no-borders-tr">#}
|
<tr class="no-borders-tr">
|
||||||
{# <td colspan="1" style="padding-top: 0">#}
|
<td colspan="1" style="padding-top: 0">
|
||||||
{# {{ form.asset_groups|bootstrap }}#}
|
{{ form.asset_groups|bootstrap }}
|
||||||
{# </td>#}
|
</td>
|
||||||
{# </tr>#}
|
</tr>
|
||||||
{# <tr class="no-borders-tr">#}
|
<tr class="no-borders-tr">
|
||||||
{# <td colspan="1" style="padding-top: 0">#}
|
<td colspan="1" style="padding-top: 0">
|
||||||
{# {{ form.system_users|bootstrap }}#}
|
{{ form.system_users|bootstrap }}
|
||||||
{# </td>#}
|
</td>
|
||||||
{# </tr>#}
|
</tr>
|
||||||
{# <tr class="no-borders-tr">#}
|
<tr class="no-borders-tr">
|
||||||
{# <td>#}
|
<td>
|
||||||
{# <button type="submit" class="btn btn-primary btn-sm">{% trans 'Submit' %}</button>#}
|
<button type="submit" class="btn btn-primary btn-sm">{% trans 'Submit' %}</button>
|
||||||
{# </td>#}
|
</td>
|
||||||
{# </tr>#}
|
</tr>
|
||||||
{# </tbody>#}
|
</tbody>
|
||||||
{# </table>#}
|
</table>
|
||||||
{# </form>#}
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -17,34 +17,24 @@
|
||||||
<div class="panel-options">
|
<div class="panel-options">
|
||||||
<ul class="nav nav-tabs">
|
<ul class="nav nav-tabs">
|
||||||
<li>
|
<li>
|
||||||
<a href="{% url 'users:user-detail' pk=user_object.id %}" class="text-center"><i class="fa fa-laptop"></i> {% trans 'User detail' %} </a>
|
<a href="{% url 'users:user-detail' pk=user.id %}" class="text-center"><i class="fa fa-laptop"></i> {% trans 'User detail' %} </a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href="{% url 'users:user-asset-permission' pk=user_object.id %}" class="text-center"><i class="fa fa-bar-chart-o"></i> {% trans 'Asset permission' %}</a>
|
<a href="{% url 'users:user-asset-permission' pk=user.id %}" class="text-center"><i class="fa fa-bar-chart-o"></i> {% trans 'Asset permission' %}</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="active">
|
<li class="active">
|
||||||
<a href="{% url 'users:user-granted-asset' pk=user_object.id %}" class="text-center"><i class="fa fa-cubes"></i> {% trans 'Asset granted' %}</a>
|
<a href="{% url 'users:user-granted-asset' pk=user.id %}" class="text-center"><i class="fa fa-cubes"></i> {% trans 'Asset granted' %}</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href="{% url 'users:user-login-history' pk=user_object.id %}" class="text-center"><i class="fa fa-calculator-o"></i> {% trans 'Login history' %}</a>
|
<a href="{% url 'users:user-login-history' pk=user.id %}" class="text-center"><i class="fa fa-calculator-o"></i> {% trans 'Login history' %}</a>
|
||||||
</li>
|
</li>
|
||||||
<form id="search_form" method="get" action="" class="pull-right mail-search">
|
|
||||||
<div class="input-group">
|
|
||||||
<input type="text" class="form-control input-sm" name="keyword" placeholder="Search" value="{{ keyword }}">
|
|
||||||
<div class="input-group-btn">
|
|
||||||
<button id="search_btn" type="submit" class="btn btn-sm btn-primary">
|
|
||||||
搜索
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="tab-content">
|
<div class="tab-content">
|
||||||
<div class="col-sm-7" style="padding-left: 0;">
|
<div class="col-sm-7" style="padding-left: 0;">
|
||||||
<div class="ibox float-e-margins">
|
<div class="ibox float-e-margins">
|
||||||
<div class="ibox-title">
|
<div class="ibox-title">
|
||||||
<span style="float: left">{% trans 'Granted assets of ' %} <b>{{ user_object.name }}</b></span>
|
<span style="float: left">{% trans 'Assets granted of ' %} <b>{{ user.name }}</b></span>
|
||||||
<div class="ibox-tools">
|
<div class="ibox-tools">
|
||||||
<a class="collapse-link">
|
<a class="collapse-link">
|
||||||
<i class="fa fa-chevron-up"></i>
|
<i class="fa fa-chevron-up"></i>
|
||||||
|
@ -60,54 +50,27 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="ibox-content">
|
<div class="ibox-content">
|
||||||
<table class="table table-hover">
|
<table class="table table-hover " id="user_assets_table" >
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th class="text-center"><a href="{% url 'perms:asset-permission-list' %}?sort=name">{% trans 'Hostname' %}</a></th>
|
<th class="text-center"></th>
|
||||||
<th class="text-center">{% trans 'IP' %}</th>
|
<th>{% trans 'Hostname' %}</th>
|
||||||
<th class="text-center">{% trans 'Port' %}</th>
|
<th>{% trans 'IP' %}</th>
|
||||||
<th class="text-center">{% trans 'System user' %}</th>
|
<th>{% trans 'Port' %}</th>
|
||||||
<th class="text-center">
|
<th>{% trans 'System user' %}</th>
|
||||||
<a href="#">{% trans 'Is valid' %}</a>
|
<th>{% trans 'Valid' %}</th>
|
||||||
</th>
|
|
||||||
<th></th>
|
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for asset, system_users in object_list %}
|
|
||||||
<tr class="gradeX">
|
|
||||||
<td class="text-center">
|
|
||||||
<a href="{% url 'assets:asset-detail' pk=asset.id %}">
|
|
||||||
{{ asset.hostname }}
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
<td class="text-center">{{ asset.ip }}</td>
|
|
||||||
<td class="text-center">{{ asset.port }}</td>
|
|
||||||
<td class="text-center">{{ system_users|join_attr:"name" }}</td>
|
|
||||||
<td class="text-center">
|
|
||||||
{% if asset.is_valid %}
|
|
||||||
<i class="fa fa-check text-navy"></i>
|
|
||||||
{% else %}
|
|
||||||
<i class="fa fa-times text-danger"></i>
|
|
||||||
{% endif %}
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<button class="btn btn-danger btn-xs btn_delete_user_group {% if asset.is_inherit_from_user_groups or asset.is_inherit_from_asset_groups %} disabled {% endif %}" type="button" style="float: right;"><i class="fa fa-minus"></i></button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<div class="row">
|
|
||||||
{% include '_pagination.html' %}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-5" style="padding-left: 0;padding-right: 0">
|
<div class="col-sm-5" style="padding-left: 0;padding-right: 0">
|
||||||
<div class="ibox float-e-margins">
|
<div class="ibox float-e-margins">
|
||||||
<div class="ibox-title">
|
<div class="ibox-title">
|
||||||
<span style="float: left">{% trans 'Asset groups granted of ' %} <b>{{ user_object.name }}</b></span>
|
<span style="float: left">{% trans 'Asset groups granted of ' %} <b>{{ user.name }}</b></span>
|
||||||
<div class="ibox-tools">
|
<div class="ibox-tools">
|
||||||
<a class="collapse-link">
|
<a class="collapse-link">
|
||||||
<i class="fa fa-chevron-up"></i>
|
<i class="fa fa-chevron-up"></i>
|
||||||
|
@ -123,30 +86,15 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="ibox-content">
|
<div class="ibox-content">
|
||||||
<table class="table table-hover">
|
<table class="table table-hover " id="user_asset_groups_table" >
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th class="text-center">{% trans 'Name' %}</th>
|
|
||||||
<th class="text-center">{% trans 'Asset count' %}</th>
|
|
||||||
<th class="text-center">{% trans 'System user' %}</th>
|
|
||||||
<th></th>
|
<th></th>
|
||||||
|
<th>{% trans 'Name' %}</th>
|
||||||
|
<th>{% trans 'Asset' %}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for asset_group, system_users in asset_groups %}
|
|
||||||
<tr class="gradeX">
|
|
||||||
<td class="text-center">
|
|
||||||
<a href="{% url 'assets:asset-group-detail' pk=asset_group.id %}">
|
|
||||||
{{ asset_group.name }}
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
<td class="text-center">{{ asset_group.assets.count }}</td>
|
|
||||||
<td class="text-center">{{ system_users|join_attr:"name" }}</td>
|
|
||||||
<td>
|
|
||||||
<button class="btn btn-danger btn-xs btn_delete_user_group {% if not asset_group.is_inherit_from_user_groups %} disabled {% endif %}" type="button" style="float: right;"><i class="fa fa-minus"></i></button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
@ -161,25 +109,53 @@
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block custom_foot_js %}
|
{% block custom_foot_js %}
|
||||||
<script>
|
<script>
|
||||||
{# function switch_user_status(obj) {#}
|
|
||||||
{# var status = $(obj).prop('checked');#}
|
|
||||||
{##}
|
|
||||||
{# $.ajax({#}
|
|
||||||
{# url: "{% url 'users:user-active-api' pk=user_object.id %}",#}
|
|
||||||
{# type: "PUT",#}
|
|
||||||
{# data: {#}
|
|
||||||
{# 'is_active': status#}
|
|
||||||
{# },#}
|
|
||||||
{# success: function (data, status) {#}
|
|
||||||
{# console.log(data)#}
|
|
||||||
{# },#}
|
|
||||||
{# error: function () {#}
|
|
||||||
{# console.log('error')#}
|
|
||||||
{# }#}
|
|
||||||
{# })#}
|
|
||||||
{# }#}
|
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
$('.select2').select2();
|
$('.select2').select2();
|
||||||
|
var options = {
|
||||||
|
ele: $('#user_assets_table'),
|
||||||
|
buttons: [],
|
||||||
|
order: [],
|
||||||
|
select: [],
|
||||||
|
columnDefs: [
|
||||||
|
{targets: 1, createdCell: function (td, cellData, rowData) {
|
||||||
|
var detail_btn = '<a href="{% url "assets:asset-detail" pk=99991937 %}">' + cellData + '</a>';
|
||||||
|
$(td).html(detail_btn.replace('99991937', rowData.id));
|
||||||
|
}},
|
||||||
|
{targets: 4, createdCell: function (td, cellData, rowData) {
|
||||||
|
if (cellData.length > 10){
|
||||||
|
$(td).html(cellData.substring(1, 10) + '..')
|
||||||
|
} else {
|
||||||
|
$(td).html(cellData)
|
||||||
|
}
|
||||||
|
}},
|
||||||
|
{targets: 5, createdCell: function (td, cellData) {
|
||||||
|
if (!cellData) {
|
||||||
|
$(td).html('<i class="fa fa-times text-danger"></i>')
|
||||||
|
} else {
|
||||||
|
$(td).html('<i class="fa fa-check text-navy"></i>')
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
],
|
||||||
|
ajax_url: '{% url "perms:api-user-assets" %}',
|
||||||
|
columns: [{data: function(){return ""}}, {data: "hostname" }, {data: "ip" }, {data: "port"},
|
||||||
|
{data: "system_users_join"}, {data: "is_active"}]
|
||||||
|
};
|
||||||
|
var options2 = {
|
||||||
|
ele: $('#user_asset_groups_table'),
|
||||||
|
buttons: [],
|
||||||
|
order: [],
|
||||||
|
select: [],
|
||||||
|
columnDefs: [
|
||||||
|
{targets: 1, createdCell: function (td, cellData, rowData) {
|
||||||
|
var detail_btn = '<a href="{% url "assets:asset-group-detail" pk=99991937 %}">' + cellData + '</a>';
|
||||||
|
$(td).html(detail_btn.replace('99991937', rowData.id));
|
||||||
|
}}
|
||||||
|
],
|
||||||
|
ajax_url: '{% url "perms:api-user-asset-groups" %}',
|
||||||
|
columns: [{data: function(){return ""}}, {data: "name" }, {data: "asset_amount" }]
|
||||||
|
};
|
||||||
|
jumpserver.initDataTable(options);
|
||||||
|
jumpserver.initDataTable(options2);
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
|
@ -19,9 +19,9 @@ urlpatterns = [
|
||||||
url(r'^user/(?P<pk>[0-9]+)$', views.UserDetailView.as_view(), name='user-detail'),
|
url(r'^user/(?P<pk>[0-9]+)$', views.UserDetailView.as_view(), name='user-detail'),
|
||||||
url(r'^user/(?P<pk>[0-9]+)/asset-permission$', views.UserAssetPermissionView.as_view(),
|
url(r'^user/(?P<pk>[0-9]+)/asset-permission$', views.UserAssetPermissionView.as_view(),
|
||||||
name='user-asset-permission'),
|
name='user-asset-permission'),
|
||||||
# url(r'^user/(?P<pk>[0-9]+)/asset-permission/create$', views.UserAssetPermissionCreateView.as_view(),
|
url(r'^user/(?P<pk>[0-9]+)/asset-permission/create$', views.UserAssetPermissionCreateView.as_view(),
|
||||||
# name='user-asset-permission-create'),
|
name='user-asset-permission-create'),
|
||||||
url(r'^user/(?P<pk>[0-9]+)/granted-asset', views.UserGrantedAssetView.as_view(), name='user-granted-asset'),
|
url(r'^user/(?P<pk>[0-9]+)/assets', views.UserGrantedAssetView.as_view(), name='user-granted-asset'),
|
||||||
url(r'^user/(?P<pk>[0-9]+)/login-history', views.UserDetailView.as_view(), name='user-login-history'),
|
url(r'^user/(?P<pk>[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'^first-login/$', views.UserFirstLoginView.as_view(), name='user-first-login'),
|
||||||
url(r'^import/$', views.BulkImportUserView.as_view(), name='user-import'),
|
url(r'^import/$', views.BulkImportUserView.as_view(), name='user-import'),
|
||||||
|
|
|
@ -341,33 +341,15 @@ class UserFirstLoginView(LoginRequiredMixin, SessionWizardView):
|
||||||
return form
|
return form
|
||||||
|
|
||||||
|
|
||||||
class UserAssetPermissionView(AdminUserRequiredMixin, DetailView):
|
class UserAssetPermissionView(AdminUserRequiredMixin, FormMixin, SingleObjectMixin, ListView):
|
||||||
model = User
|
model = User
|
||||||
template_name = 'users/user_asset_permission.html'
|
template_name = 'users/user_asset_permission.html'
|
||||||
context_object_name = 'user'
|
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())
|
||||||
# def get(self, request, *args, **kwargs):
|
return super(UserAssetPermissionView, self).get(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_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
context = {
|
context = {
|
||||||
|
@ -403,31 +385,19 @@ class UserAssetPermissionCreateView(AdminUserRequiredMixin, CreateView):
|
||||||
return reverse('users:user-asset-permission', kwargs={'pk': self.user_object.id})
|
return reverse('users:user-asset-permission', kwargs={'pk': self.user_object.id})
|
||||||
|
|
||||||
|
|
||||||
class UserGrantedAssetView(AdminUserRequiredMixin, SingleObjectMixin, ListView):
|
class UserGrantedAssetView(AdminUserRequiredMixin, DetailView):
|
||||||
paginate_by = settings.CONFIG.DISPLAY_PER_PAGE
|
model = User
|
||||||
template_name = 'users/user_granted_asset.html'
|
template_name = 'users/user_granted_asset.html'
|
||||||
context_object_name = 'user_object'
|
context_object_name = 'user'
|
||||||
|
|
||||||
def get(self, request, *args, **kwargs):
|
def get(self, request, *args, **kwargs):
|
||||||
self.object = self.get_object(queryset=User.objects.all())
|
self.object = self.get_object(queryset=User.objects.all())
|
||||||
return super(UserGrantedAssetView, self).get(request, *args, **kwargs)
|
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):
|
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 = {
|
context = {
|
||||||
'app': 'User',
|
'app': 'User',
|
||||||
'action': 'User granted asset',
|
'action': 'User granted asset',
|
||||||
# 'asset_groups': asset_groups,
|
|
||||||
}
|
}
|
||||||
kwargs.update(context)
|
kwargs.update(context)
|
||||||
return super(UserGrantedAssetView, self).get_context_data(**kwargs)
|
return super(UserGrantedAssetView, self).get_context_data(**kwargs)
|
||||||
|
|
|
@ -12,3 +12,4 @@ django-formtools==1.0
|
||||||
sshpubkeys==2.2.0
|
sshpubkeys==2.2.0
|
||||||
djangorestframework-bulk==0.2.1
|
djangorestframework-bulk==0.2.1
|
||||||
paramiko==2.0.2
|
paramiko==2.0.2
|
||||||
|
django-redis-cache==1.7.1
|
||||||
|
|
Loading…
Reference in New Issue