mirror of https://github.com/jumpserver/jumpserver
[Bugfix] 修改users模块一些bug
parent
e1163895e2
commit
a308000d2e
|
@ -1,5 +1,4 @@
|
|||
# ~*~ coding: utf-8 ~*~
|
||||
|
||||
# Copyright (C) 2014-2017 Beijing DuiZhan Technology Co.,Ltd. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the GNU General Public License v2.0 (the "License");
|
||||
|
@ -22,7 +21,7 @@ from django.shortcuts import get_object_or_404
|
|||
|
||||
from common.mixins import IDInFilterMixin
|
||||
from common.utils import get_object_or_none
|
||||
from .hands import IsSuperUser, IsAppUser, IsValidUser, IsSuperUserOrAppUser, \
|
||||
from .hands import IsSuperUser, IsValidUser, IsSuperUserOrAppUser, \
|
||||
get_user_granted_assets, push_users
|
||||
from .models import AssetGroup, Asset, Cluster, SystemUser, AdminUser
|
||||
from . import serializers
|
||||
|
@ -58,63 +57,80 @@ class AssetViewSet(IDInFilterMixin, BulkModelViewSet):
|
|||
|
||||
|
||||
class AssetGroupViewSet(IDInFilterMixin, BulkModelViewSet):
|
||||
"""Asset group api set, for add,delete,update,list,retrieve resource"""
|
||||
"""
|
||||
Asset group api set, for add,delete,update,list,retrieve resource
|
||||
"""
|
||||
queryset = AssetGroup.objects.all()
|
||||
serializer_class = serializers.AssetGroupSerializer
|
||||
permission_classes = (IsSuperUser,)
|
||||
|
||||
|
||||
class AssetUpdateGroupApi(generics.RetrieveUpdateAPIView):
|
||||
"""Asset update it's group api"""
|
||||
"""
|
||||
Asset update it's group api
|
||||
"""
|
||||
queryset = Asset.objects.all()
|
||||
serializer_class = serializers.AssetUpdateGroupSerializer
|
||||
permission_classes = (IsSuperUser,)
|
||||
|
||||
|
||||
class AssetGroupUpdateApi(generics.RetrieveUpdateAPIView):
|
||||
"""Asset group, update it's asset member"""
|
||||
"""
|
||||
Asset group, update it's asset member
|
||||
"""
|
||||
queryset = AssetGroup.objects.all()
|
||||
serializer_class = serializers.AssetGroupUpdateSerializer
|
||||
permission_classes = (IsSuperUser,)
|
||||
|
||||
|
||||
class AssetGroupUpdateSystemUserApi(generics.RetrieveUpdateAPIView):
|
||||
"""Asset group push system user"""
|
||||
"""
|
||||
Asset group push system user
|
||||
"""
|
||||
queryset = AssetGroup.objects.all()
|
||||
serializer_class = serializers.AssetGroupUpdateSystemUserSerializer
|
||||
permission_classes = (IsSuperUser,)
|
||||
|
||||
|
||||
class ClusterUpdateAssetsApi(generics.RetrieveUpdateAPIView):
|
||||
"""Cluster update asset member"""
|
||||
"""
|
||||
Cluster update asset member
|
||||
"""
|
||||
queryset = Cluster.objects.all()
|
||||
serializer_class = serializers.ClusterUpdateAssetsSerializer
|
||||
permission_classes = (IsSuperUser,)
|
||||
|
||||
|
||||
class ClusterViewSet(IDInFilterMixin, BulkModelViewSet):
|
||||
"""Cluster api set, for add,delete,update,list,retrieve resource"""
|
||||
"""
|
||||
Cluster api set, for add,delete,update,list,retrieve resource
|
||||
"""
|
||||
queryset = Cluster.objects.all()
|
||||
serializer_class = serializers.ClusterSerializer
|
||||
permission_classes = (IsSuperUser,)
|
||||
|
||||
|
||||
class AdminUserViewSet(IDInFilterMixin, BulkModelViewSet):
|
||||
"""Admin user api set, for add,delete,update,list,retrieve resource"""
|
||||
"""
|
||||
Admin user api set, for add,delete,update,list,retrieve resource
|
||||
"""
|
||||
queryset = AdminUser.objects.all()
|
||||
serializer_class = serializers.AdminUserSerializer
|
||||
permission_classes = (IsSuperUser,)
|
||||
|
||||
|
||||
class SystemUserViewSet(IDInFilterMixin, BulkModelViewSet):
|
||||
"""System user api set, for add,delete,update,list,retrieve resource"""
|
||||
"""
|
||||
System user api set, for add,delete,update,list,retrieve resource
|
||||
"""
|
||||
queryset = SystemUser.objects.all()
|
||||
serializer_class = serializers.SystemUserSerializer
|
||||
permission_classes = (IsSuperUserOrAppUser,)
|
||||
|
||||
|
||||
class SystemUserUpdateApi(generics.RetrieveUpdateAPIView):
|
||||
"""Asset update it's system user
|
||||
"""
|
||||
Asset update it's system user
|
||||
|
||||
when update then push system user to asset.
|
||||
"""
|
||||
|
@ -134,28 +150,36 @@ class SystemUserUpdateApi(generics.RetrieveUpdateAPIView):
|
|||
|
||||
|
||||
class SystemUserUpdateAssetsApi(generics.RetrieveUpdateAPIView):
|
||||
"""System user update it's assets"""
|
||||
"""
|
||||
System user update it's assets
|
||||
"""
|
||||
queryset = SystemUser.objects.all()
|
||||
serializer_class = serializers.SystemUserUpdateAssetsSerializer
|
||||
permission_classes = (IsSuperUser,)
|
||||
|
||||
|
||||
class SystemUserUpdateAssetGroupApi(generics.RetrieveUpdateAPIView):
|
||||
"""System user update asset group"""
|
||||
"""
|
||||
System user update asset group
|
||||
"""
|
||||
queryset = SystemUser.objects.all()
|
||||
serializer_class = serializers.SystemUserUpdateAssetGroupSerializer
|
||||
permission_classes = (IsSuperUser,)
|
||||
|
||||
|
||||
class AssetListUpdateApi(IDInFilterMixin, ListBulkCreateUpdateDestroyAPIView):
|
||||
"""Asset bulk update api"""
|
||||
"""
|
||||
Asset bulk update api
|
||||
"""
|
||||
queryset = Asset.objects.all()
|
||||
serializer_class = serializers.AssetSerializer
|
||||
permission_classes = (IsSuperUser,)
|
||||
|
||||
|
||||
class SystemUserAuthInfoApi(generics.RetrieveAPIView):
|
||||
"""Get system user auth info"""
|
||||
"""
|
||||
Get system user auth info
|
||||
"""
|
||||
queryset = SystemUser.objects.all()
|
||||
permission_classes = (IsSuperUserOrAppUser,)
|
||||
|
||||
|
@ -172,7 +196,9 @@ class SystemUserAuthInfoApi(generics.RetrieveAPIView):
|
|||
|
||||
|
||||
class AssetRefreshHardwareView(generics.RetrieveAPIView):
|
||||
"""Refresh asset hardware info"""
|
||||
"""
|
||||
Refresh asset hardware info
|
||||
"""
|
||||
queryset = Asset.objects.all()
|
||||
serializer_class = serializers.AssetSerializer
|
||||
permission_classes = (IsSuperUser,)
|
||||
|
@ -181,7 +207,6 @@ class AssetRefreshHardwareView(generics.RetrieveAPIView):
|
|||
asset_id = kwargs.get('pk')
|
||||
asset = get_object_or_404(Asset, pk=asset_id)
|
||||
summary = update_assets_hardware_info([asset])
|
||||
print(summary)
|
||||
if summary.get('dark'):
|
||||
return Response(summary['dark'].values(), status=501)
|
||||
else:
|
||||
|
@ -189,7 +214,9 @@ class AssetRefreshHardwareView(generics.RetrieveAPIView):
|
|||
|
||||
|
||||
class AssetAdminUserTestView(AssetRefreshHardwareView):
|
||||
"""Test asset admin user connectivity"""
|
||||
"""
|
||||
Test asset admin user connectivity
|
||||
"""
|
||||
queryset = Asset.objects.all()
|
||||
permission_classes = (IsSuperUser,)
|
||||
|
||||
|
@ -204,7 +231,9 @@ class AssetAdminUserTestView(AssetRefreshHardwareView):
|
|||
|
||||
|
||||
class AssetGroupPushSystemUserView(generics.UpdateAPIView):
|
||||
"""Asset group push system user api"""
|
||||
"""
|
||||
Asset group push system user api
|
||||
"""
|
||||
queryset = AssetGroup.objects.all()
|
||||
permission_classes = (IsSuperUser,)
|
||||
serializer_class = serializers.AssetSerializer
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from django.core.cache import cache
|
||||
from rest_framework import viewsets, serializers, generics
|
||||
from rest_framework import serializers
|
||||
from rest_framework_bulk.serializers import BulkListSerializer
|
||||
|
||||
from common.mixins import BulkSerializerMixin
|
||||
|
@ -9,6 +9,9 @@ from .const import ADMIN_USER_CONN_CACHE_KEY, SYSTEM_USER_CONN_CACHE_KEY
|
|||
|
||||
|
||||
class AssetGroupSerializer(BulkSerializerMixin, serializers.ModelSerializer):
|
||||
"""
|
||||
资产组序列化数据模型
|
||||
"""
|
||||
assets_amount = serializers.SerializerMethodField()
|
||||
assets = serializers.PrimaryKeyRelatedField(many=True, queryset=Asset.objects.all())
|
||||
|
||||
|
@ -23,6 +26,9 @@ class AssetGroupSerializer(BulkSerializerMixin, serializers.ModelSerializer):
|
|||
|
||||
|
||||
class AssetUpdateGroupSerializer(serializers.ModelSerializer):
|
||||
"""
|
||||
资产更新自己所在资产组的请求数据结构定义
|
||||
"""
|
||||
groups = serializers.PrimaryKeyRelatedField(many=True, queryset=AssetGroup.objects.all())
|
||||
|
||||
class Meta:
|
||||
|
@ -31,6 +37,9 @@ class AssetUpdateGroupSerializer(serializers.ModelSerializer):
|
|||
|
||||
|
||||
class AssetUpdateSystemUserSerializer(serializers.ModelSerializer):
|
||||
"""
|
||||
资产更新其系统用户请求的数据结构定义
|
||||
"""
|
||||
system_users = serializers.PrimaryKeyRelatedField(many=True, queryset=SystemUser.objects.all())
|
||||
|
||||
class Meta:
|
||||
|
@ -39,7 +48,9 @@ class AssetUpdateSystemUserSerializer(serializers.ModelSerializer):
|
|||
|
||||
|
||||
class AssetGroupUpdateSerializer(serializers.ModelSerializer):
|
||||
"""update the asset group, and add or delete the asset to the group"""
|
||||
"""
|
||||
资产组更新需要的数据结构
|
||||
"""
|
||||
assets = serializers.PrimaryKeyRelatedField(many=True, queryset=Asset.objects.all())
|
||||
|
||||
class Meta:
|
||||
|
@ -48,6 +59,9 @@ class AssetGroupUpdateSerializer(serializers.ModelSerializer):
|
|||
|
||||
|
||||
class AssetGroupUpdateSystemUserSerializer(serializers.ModelSerializer):
|
||||
"""
|
||||
资产组更新系统用户定义的数据结构
|
||||
"""
|
||||
system_users = serializers.PrimaryKeyRelatedField(many=True, queryset=SystemUser.objects.all())
|
||||
|
||||
class Meta:
|
||||
|
@ -56,6 +70,9 @@ class AssetGroupUpdateSystemUserSerializer(serializers.ModelSerializer):
|
|||
|
||||
|
||||
class ClusterUpdateAssetsSerializer(serializers.ModelSerializer):
|
||||
"""
|
||||
集群更新资产数据结构
|
||||
"""
|
||||
assets = serializers.PrimaryKeyRelatedField(many=True, queryset=Asset.objects.all())
|
||||
|
||||
class Meta:
|
||||
|
@ -64,6 +81,9 @@ class ClusterUpdateAssetsSerializer(serializers.ModelSerializer):
|
|||
|
||||
|
||||
class AdminUserSerializer(serializers.ModelSerializer):
|
||||
"""
|
||||
管理用户
|
||||
"""
|
||||
assets_amount = serializers.SerializerMethodField()
|
||||
unreachable_amount = serializers.SerializerMethodField()
|
||||
|
||||
|
@ -89,6 +109,9 @@ class AdminUserSerializer(serializers.ModelSerializer):
|
|||
|
||||
|
||||
class SystemUserSerializer(serializers.ModelSerializer):
|
||||
"""
|
||||
系统用户
|
||||
"""
|
||||
unreachable_amount = serializers.SerializerMethodField()
|
||||
assets_amount = serializers.SerializerMethodField()
|
||||
|
||||
|
@ -113,12 +136,18 @@ class SystemUserSerializer(serializers.ModelSerializer):
|
|||
|
||||
|
||||
class AssetSystemUserSerializer(serializers.ModelSerializer):
|
||||
"""
|
||||
查看授权的资产系统用户的数据结构,这个和AssetSerializer不同,字段少
|
||||
"""
|
||||
class Meta:
|
||||
model = SystemUser
|
||||
fields = ('id', 'name', 'username', 'priority', 'protocol', 'comment',)
|
||||
|
||||
|
||||
class SystemUserUpdateAssetsSerializer(serializers.ModelSerializer):
|
||||
"""
|
||||
系统用户更新关联资产的数据结构
|
||||
"""
|
||||
assets = serializers.PrimaryKeyRelatedField(many=True, queryset=Asset.objects.all())
|
||||
|
||||
class Meta:
|
||||
|
@ -127,6 +156,9 @@ class SystemUserUpdateAssetsSerializer(serializers.ModelSerializer):
|
|||
|
||||
|
||||
class SystemUserUpdateAssetGroupSerializer(serializers.ModelSerializer):
|
||||
"""
|
||||
系统用户更新资产组的api
|
||||
"""
|
||||
asset_groups = serializers.PrimaryKeyRelatedField(many=True, queryset=AssetGroup.objects.all())
|
||||
|
||||
class Meta:
|
||||
|
@ -135,12 +167,18 @@ class SystemUserUpdateAssetGroupSerializer(serializers.ModelSerializer):
|
|||
|
||||
|
||||
class SystemUserSimpleSerializer(serializers.ModelSerializer):
|
||||
"""
|
||||
系统用户最基本信息的数据结构
|
||||
"""
|
||||
class Meta:
|
||||
model = SystemUser
|
||||
fields = ('id', 'name', 'username')
|
||||
|
||||
|
||||
class AssetSerializer(BulkSerializerMixin, serializers.ModelSerializer):
|
||||
"""
|
||||
资产的数据结构
|
||||
"""
|
||||
class Meta(object):
|
||||
model = Asset
|
||||
list_serializer_class = BulkListSerializer
|
||||
|
@ -157,6 +195,9 @@ class AssetSerializer(BulkSerializerMixin, serializers.ModelSerializer):
|
|||
|
||||
|
||||
class AssetGrantedSerializer(serializers.ModelSerializer):
|
||||
"""
|
||||
被授权资产的数据结构
|
||||
"""
|
||||
system_users_granted = AssetSystemUserSerializer(many=True, read_only=True)
|
||||
is_inherited = serializers.SerializerMethodField()
|
||||
system_users_join = serializers.SerializerMethodField()
|
||||
|
@ -180,7 +221,9 @@ class AssetGrantedSerializer(serializers.ModelSerializer):
|
|||
|
||||
|
||||
class MyAssetGrantedSerializer(AssetGrantedSerializer):
|
||||
"""Remove ip and port from asset for security"""
|
||||
"""
|
||||
普通用户获取授权的资产定义的数据结构
|
||||
"""
|
||||
|
||||
class Meta(object):
|
||||
model = Asset
|
||||
|
@ -189,6 +232,9 @@ class MyAssetGrantedSerializer(AssetGrantedSerializer):
|
|||
|
||||
|
||||
class ClusterSerializer(BulkSerializerMixin, serializers.ModelSerializer):
|
||||
"""
|
||||
cluster
|
||||
"""
|
||||
assets_amount = serializers.SerializerMethodField()
|
||||
admin_user_name = serializers.SerializerMethodField()
|
||||
assets = serializers.PrimaryKeyRelatedField(many=True, queryset=Asset.objects.all())
|
||||
|
@ -210,6 +256,9 @@ class ClusterSerializer(BulkSerializerMixin, serializers.ModelSerializer):
|
|||
|
||||
|
||||
class AssetGroupGrantedSerializer(BulkSerializerMixin, serializers.ModelSerializer):
|
||||
"""
|
||||
授权资产组
|
||||
"""
|
||||
assets_granted = AssetGrantedSerializer(many=True, read_only=True)
|
||||
assets_amount = serializers.SerializerMethodField()
|
||||
|
||||
|
@ -224,6 +273,9 @@ class AssetGroupGrantedSerializer(BulkSerializerMixin, serializers.ModelSerializ
|
|||
|
||||
|
||||
class MyAssetGroupGrantedSerializer(serializers.ModelSerializer):
|
||||
"""
|
||||
普通用户授权资产组结构
|
||||
"""
|
||||
assets_granted = MyAssetGrantedSerializer(many=True, read_only=True)
|
||||
assets_amount = serializers.SerializerMethodField()
|
||||
|
||||
|
|
|
@ -16,7 +16,6 @@ urlpatterns = [
|
|||
url(r'^users/', include('users.urls.views_urls', namespace='users')),
|
||||
url(r'^assets/', include('assets.urls.views_urls', namespace='assets')),
|
||||
url(r'^perms/', include('perms.urls.views_urls', namespace='perms')),
|
||||
# url(r'^audits/', include('audits.urls.views_urls', namespace='audits')),
|
||||
url(r'^terminal/', include('terminal.urls.views_urls', namespace='terminal')),
|
||||
url(r'^ops/', include('ops.urls.view_urls', namespace='ops')),
|
||||
|
||||
|
@ -24,9 +23,10 @@ urlpatterns = [
|
|||
url(r'^api/users/', include('users.urls.api_urls', namespace='api-users')),
|
||||
url(r'^api/assets/', include('assets.urls.api_urls', namespace='api-assets')),
|
||||
url(r'^api/perms/', include('perms.urls.api_urls', namespace='api-perms')),
|
||||
# url(r'^api/audits/', include('audits.urls.api_urls', namespace='api-audits')),
|
||||
url(r'^api/terminal/', include('terminal.urls.api_urls', namespace='api-terminal')),
|
||||
url(r'^api/ops/', include('ops.urls.api_urls', namespace='api-ops')),
|
||||
|
||||
# External apps url
|
||||
url(r'^captcha/', include('captcha.urls')),
|
||||
|
||||
]
|
||||
|
|
|
@ -4,17 +4,12 @@ from django.db import models
|
|||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils import timezone
|
||||
|
||||
from common.utils import date_expired_default, combine_seq
|
||||
from common.utils import date_expired_default
|
||||
|
||||
|
||||
class AssetPermission(models.Model):
|
||||
from users.models import User, UserGroup
|
||||
from assets.models import Asset, AssetGroup, SystemUser
|
||||
# PRIVATE_FOR_CHOICE = (
|
||||
# ('N', 'None'),
|
||||
# ('U', 'user'),
|
||||
# ('G', 'user group'),
|
||||
# )
|
||||
id = models.UUIDField(default=uuid.uuid4, primary_key=True)
|
||||
name = models.CharField(
|
||||
max_length=128, unique=True, verbose_name=_('Name'))
|
||||
|
@ -38,14 +33,14 @@ class AssetPermission(models.Model):
|
|||
auto_now_add=True, verbose_name=_('Date created'))
|
||||
comment = models.TextField(verbose_name=_('Comment'), blank=True)
|
||||
|
||||
def __unicode__(self):
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
@property
|
||||
def is_valid(self):
|
||||
if self.date_expired < timezone.now() and self.is_active:
|
||||
return True
|
||||
return True
|
||||
return False
|
||||
|
||||
def get_granted_users(self):
|
||||
return list(set(self.users.all()) | self.get_granted_user_groups_member())
|
||||
|
@ -73,8 +68,8 @@ class AssetPermission(models.Model):
|
|||
assets.add(asset)
|
||||
return assets
|
||||
|
||||
class Meta:
|
||||
db_table = 'asset_permission'
|
||||
# class Meta:
|
||||
# db_table = 'asset_permission'
|
||||
|
||||
|
||||
# def change_permission(sender, **kwargs):
|
||||
|
|
|
@ -13,9 +13,9 @@ logger = get_logger(__file__)
|
|||
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}}
|
||||
:param user_group: Instance of :class: ``UserGroup``
|
||||
:return: {asset_group1: {system_user1, },
|
||||
asset_group2: {system_user1, system_user2}}
|
||||
"""
|
||||
asset_groups = {}
|
||||
asset_permissions = user_group.asset_permissions.all()
|
||||
|
@ -168,22 +168,6 @@ def get_user_granted_system_users(user):
|
|||
return system_users_dict
|
||||
|
||||
|
||||
def get_user_groups_granted_in_asset(asset):
|
||||
pass
|
||||
|
||||
|
||||
def get_users_granted_in_asset(asset):
|
||||
pass
|
||||
|
||||
|
||||
def get_user_groups_granted_in_asset_group(asset):
|
||||
pass
|
||||
|
||||
|
||||
def get_users_granted_in_asset_group(asset):
|
||||
pass
|
||||
|
||||
|
||||
def push_system_user(assets, system_user):
|
||||
logger.info('Push system user %s' % system_user.name)
|
||||
for asset in assets:
|
||||
|
|
|
@ -245,7 +245,8 @@ jumpserver.initDataTable = function (options) {
|
|||
// buttons: ['excel', 'pdf', 'print'],
|
||||
// columnDefs: [{target: 0, createdCell: ()=>{}}, ...],
|
||||
// uc_html: '<a>header button</a>',
|
||||
// op_html: 'div.btn-group?'
|
||||
// op_html: 'div.btn-group?',
|
||||
// paging: true
|
||||
// }
|
||||
var ele = options.ele || $('.dataTable');
|
||||
var columnDefs = [
|
||||
|
|
|
@ -8,17 +8,18 @@ import os
|
|||
from rest_framework import viewsets, serializers
|
||||
from rest_framework.views import APIView, Response
|
||||
from rest_framework.permissions import AllowAny
|
||||
from django.shortcuts import get_object_or_404
|
||||
from django.shortcuts import get_object_or_404, redirect
|
||||
from django.utils import timezone
|
||||
from django.conf import settings
|
||||
from django.core.files.storage import default_storage
|
||||
from django.http import HttpResponseNotFound
|
||||
|
||||
from common.utils import get_object_or_none
|
||||
from .models import Terminal, Status, Session, Task
|
||||
from .serializers import TerminalSerializer, StatusSerializer, \
|
||||
SessionSerializer, TaskSerializer
|
||||
SessionSerializer, TaskSerializer, ReplaySerializer
|
||||
from .hands import IsSuperUserOrAppUser, IsAppUser, \
|
||||
IsSuperUserOrAppUserOrUserReadonly
|
||||
from .backends import get_command_store, get_replay_store, SessionCommandSerializer
|
||||
from .backends import get_command_store, SessionCommandSerializer
|
||||
|
||||
logger = logging.getLogger(__file__)
|
||||
|
||||
|
@ -149,46 +150,6 @@ class TaskViewSet(viewsets.ModelViewSet):
|
|||
serializer_class = TaskSerializer
|
||||
permission_classes = (IsSuperUserOrAppUser,)
|
||||
|
||||
# def get_queryset(self):
|
||||
# terminal_id = self.kwargs.get("terminal", None)
|
||||
# if terminal_id:
|
||||
# terminal = get_object_or_404(Terminal, id=terminal_id)
|
||||
# self.queryset = terminal.status_set.all()
|
||||
#
|
||||
# if hasattr(self.request.user, "terminal"):
|
||||
# terminal = self.request.user.terminal
|
||||
# self.queryset = terminal.status_set.all()
|
||||
# return self.queryset
|
||||
|
||||
|
||||
class SessionReplayAPI(APIView):
|
||||
permission_classes = (IsSuperUserOrAppUser,)
|
||||
|
||||
def post(self, request, **kwargs):
|
||||
session_id = kwargs.get("pk", None)
|
||||
session = get_object_or_404(Session, id=session_id)
|
||||
record_dir = settings.CONFIG.SESSION_RECORDE_DIR
|
||||
date = session.date_start.strftime("%Y-%m-%d")
|
||||
record_dir = os.path.join(record_dir, date, str(session.id))
|
||||
record_filename = os.path.join(record_dir, "replay.tar.gz2")
|
||||
|
||||
if not os.path.isdir(record_dir):
|
||||
try:
|
||||
os.makedirs(record_dir)
|
||||
except FileExistsError:
|
||||
pass
|
||||
|
||||
archive_stream = request.data.get("archive")
|
||||
if not archive_stream:
|
||||
return Response("None file upload", status=400)
|
||||
|
||||
with open(record_filename, 'wb') as f:
|
||||
for chunk in archive_stream.chunks():
|
||||
f.write(chunk)
|
||||
session.has_replay = True
|
||||
session.save()
|
||||
return Response({"session_id": session.id}, status=201)
|
||||
|
||||
|
||||
class CommandViewSet(viewsets.ViewSet):
|
||||
"""接受app发送来的command log, 格式如下
|
||||
|
@ -208,7 +169,7 @@ class CommandViewSet(viewsets.ViewSet):
|
|||
permission_classes = (IsSuperUserOrAppUser,)
|
||||
|
||||
def get_queryset(self):
|
||||
self.command_store.filter(**dict(self.request.data))
|
||||
self.command_store.filter(**dict(self.request.query_params))
|
||||
|
||||
def create(self, request, *args, **kwargs):
|
||||
serializer = self.serializer_class(data=request.data, many=True)
|
||||
|
@ -227,3 +188,43 @@ class CommandViewSet(viewsets.ViewSet):
|
|||
queryset = list(self.command_store.all())
|
||||
serializer = self.serializer_class(queryset, many=True)
|
||||
return Response(serializer.data)
|
||||
|
||||
|
||||
class SessionReplayViewSet(viewsets.ViewSet):
|
||||
serializer_class = ReplaySerializer
|
||||
permission_classes = ()
|
||||
session = None
|
||||
|
||||
def gen_session_path(self):
|
||||
date = self.session.date_start.strftime('%Y-%m-%d')
|
||||
return os.path.join(date, str(self.session.id)+'.gz')
|
||||
|
||||
def create(self, request, *args, **kwargs):
|
||||
session_id = kwargs.get('pk')
|
||||
self.session = get_object_or_404(Session, id=session_id)
|
||||
serializer = self.serializer_class(data=request.data)
|
||||
|
||||
if serializer.is_valid():
|
||||
file = serializer.validated_data['file']
|
||||
file_path = self.gen_session_path()
|
||||
try:
|
||||
default_storage.save(file_path, file)
|
||||
return Response({'url': default_storage.url(file_path)},
|
||||
status=201)
|
||||
except IOError:
|
||||
return Response("Save error", status=500)
|
||||
else:
|
||||
logger.error(
|
||||
'Update load data invalid: {}'.format(serializer.errors))
|
||||
return Response({'msg': serializer.errors}, status=401)
|
||||
|
||||
def retrieve(self, request, *args, **kwargs):
|
||||
session_id = kwargs.get('pk')
|
||||
self.session = get_object_or_404(Session, id=session_id)
|
||||
path = self.gen_session_path()
|
||||
|
||||
if default_storage.exists(path):
|
||||
url = default_storage.url(path)
|
||||
return redirect(url)
|
||||
else:
|
||||
return HttpResponseNotFound()
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
from importlib import import_module
|
||||
|
||||
from django.conf import settings
|
||||
|
||||
from .command.serializers import SessionCommandSerializer
|
||||
|
||||
|
||||
|
@ -10,8 +8,3 @@ def get_command_store():
|
|||
command_store = command_engine.CommandStore()
|
||||
return command_store
|
||||
|
||||
|
||||
def get_replay_store():
|
||||
replay_engine = import_module(settings.REPLAY_STORE_BACKEND)
|
||||
replay_store = replay_engine.ReplayStore()
|
||||
return replay_store
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
# ~*~ coding: utf-8 ~*~
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
# coding: utf-8
|
||||
import abc
|
||||
|
||||
|
||||
class ReplayBase(object):
|
||||
__metaclass__ = abc.ABCMeta
|
||||
|
||||
@abc.abstractmethod
|
||||
def save(self, proxy_log_id, output, timestamp):
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def filter(self, date_from_ts=None, proxy_log_id=None):
|
||||
pass
|
|
@ -1,8 +0,0 @@
|
|||
# ~*~ coding: utf-8 ~*~
|
||||
|
||||
from .base import ReplayBase
|
||||
|
||||
|
||||
class ReplayStore(ReplayBase):
|
||||
pass
|
||||
|
|
@ -62,3 +62,8 @@ class TaskSerializer(serializers.ModelSerializer):
|
|||
class Meta:
|
||||
fields = '__all__'
|
||||
model = Task
|
||||
|
||||
|
||||
class ReplaySerializer(serializers.Serializer):
|
||||
file = serializers.FileField()
|
||||
|
||||
|
|
|
@ -11,13 +11,15 @@ app_name = 'terminal'
|
|||
|
||||
router = routers.DefaultRouter()
|
||||
router.register(r'v1/terminal/(?P<terminal>[a-zA-Z0-9\-]{36})?/?status', api.StatusViewSet, 'terminal-status')
|
||||
router.register(r'v1/terminal/(?P<terminal>a-zA-Z0-9\-]{36})?/?sessions', api.SessionViewSet, 'terminal-sessions')
|
||||
router.register(r'v1/terminal/(?P<terminal>[a-zA-Z0-9\-]{36})?/?sessions', api.SessionViewSet, 'terminal-sessions')
|
||||
router.register(r'v1/tasks', api.TaskViewSet, 'tasks')
|
||||
router.register(r'v1/terminal', api.TerminalViewSet, 'terminal')
|
||||
router.register(r'v1/command', api.CommandViewSet, 'command')
|
||||
|
||||
urlpatterns = [
|
||||
url(r'^v1/sessions/(?P<pk>[0-9a-zA-Z\-_]+)/replay/$', api.SessionReplayAPI.as_view(), name='session-replay'),
|
||||
url(r'^v1/sessions/(?P<pk>[0-9a-zA-Z\-]{36})/replay/$',
|
||||
api.SessionReplayViewSet.as_view({'get': 'retrieve', 'post': 'create'}),
|
||||
name='session-replay'),
|
||||
]
|
||||
|
||||
urlpatterns += router.urls
|
||||
|
|
|
@ -21,7 +21,7 @@ logger = get_logger(__name__)
|
|||
|
||||
|
||||
class UserViewSet(BulkModelViewSet):
|
||||
queryset = User.objects.all()
|
||||
queryset = User.objects.exclude(role="App")
|
||||
# queryset = User.objects.all().exclude(role="App").order_by("date_joined")
|
||||
serializer_class = UserSerializer
|
||||
permission_classes = (IsSuperUser,)
|
||||
|
|
|
@ -13,17 +13,23 @@ from .models import User, UserGroup
|
|||
class UserLoginForm(AuthenticationForm):
|
||||
username = forms.CharField(label=_('Username'), max_length=100)
|
||||
password = forms.CharField(
|
||||
label=_('Password'), widget=forms.PasswordInput, max_length=100,
|
||||
strip=False)
|
||||
label=_('Password'), widget=forms.PasswordInput,
|
||||
max_length=128, strip=False
|
||||
)
|
||||
captcha = CaptchaField()
|
||||
|
||||
|
||||
class UserCreateUpdateForm(forms.ModelForm):
|
||||
password = forms.CharField(
|
||||
label=_('Password'), widget=forms.PasswordInput,
|
||||
max_length=128, strip=False, required=False,
|
||||
)
|
||||
|
||||
class Meta:
|
||||
model = User
|
||||
fields = [
|
||||
'username', 'name', 'email', 'groups', 'wechat',
|
||||
'phone', 'enable_otp', 'role', 'date_expired', 'comment',
|
||||
'phone', 'role', 'date_expired', 'comment', 'password'
|
||||
]
|
||||
help_texts = {
|
||||
'username': '* required',
|
||||
|
@ -36,6 +42,14 @@ class UserCreateUpdateForm(forms.ModelForm):
|
|||
'data-placeholder': _('Join user groups')}),
|
||||
}
|
||||
|
||||
def save(self, commit=True):
|
||||
user = super().save(commit=commit)
|
||||
password = self.cleaned_data.get('password')
|
||||
if password:
|
||||
user.set_password(password)
|
||||
user.save()
|
||||
return user
|
||||
|
||||
|
||||
class UserProfileForm(forms.ModelForm):
|
||||
class Meta:
|
||||
|
@ -115,15 +129,11 @@ class UserPublicKeyForm(forms.Form):
|
|||
|
||||
|
||||
class UserBulkUpdateForm(forms.ModelForm):
|
||||
role = forms.ChoiceField(
|
||||
label=_('Role'),
|
||||
choices=[('Admin', 'Administrator'), ('User', 'User')],
|
||||
)
|
||||
users = forms.MultipleChoiceField(
|
||||
required=True,
|
||||
help_text='* required',
|
||||
label=_('Select users'),
|
||||
# choices=[(user.id, user.name) for user in User.objects.all()],
|
||||
choices=[(user.id, user.name) for user in User.objects.all()],
|
||||
widget=forms.SelectMultiple(
|
||||
attrs={
|
||||
'class': 'select2',
|
||||
|
@ -134,18 +144,26 @@ class UserBulkUpdateForm(forms.ModelForm):
|
|||
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ['users', 'role', 'groups', 'date_expired', 'is_active', 'enable_otp']
|
||||
fields = ['users', 'role', 'groups', 'date_expired', 'is_active']
|
||||
widgets = {
|
||||
'groups': forms.SelectMultiple(
|
||||
attrs={'class': 'select2',
|
||||
'data-placeholder': _('Select user groups')}),
|
||||
"groups": forms.SelectMultiple(
|
||||
attrs={
|
||||
'class': 'select2',
|
||||
'data-placeholder': _('Select users')
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
def save(self, commit=True):
|
||||
cleaned_data = {k: v for k, v in self.cleaned_data.items() if
|
||||
v is not None}
|
||||
users_id = cleaned_data.pop('users')
|
||||
groups = cleaned_data.pop('groups')
|
||||
changed_fields = []
|
||||
for field in self._meta.fields:
|
||||
if self.data.get(field) is not None:
|
||||
changed_fields.append(field)
|
||||
|
||||
cleaned_data = {k: v for k, v in self.cleaned_data.items()
|
||||
if k in changed_fields}
|
||||
users_id = cleaned_data.pop('users', '')
|
||||
groups = cleaned_data.pop('groups', [])
|
||||
users = User.objects.filter(id__in=users_id)
|
||||
users.update(**cleaned_data)
|
||||
if groups:
|
||||
|
@ -155,42 +173,42 @@ class UserBulkUpdateForm(forms.ModelForm):
|
|||
|
||||
|
||||
class UserGroupForm(forms.ModelForm):
|
||||
users = forms.ModelMultipleChoiceField(
|
||||
queryset=User.objects.all(),
|
||||
widget=forms.SelectMultiple(
|
||||
attrs={
|
||||
'class': 'select2',
|
||||
'data-placeholder': _('Select users')
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
instance = kwargs.get('instance')
|
||||
if instance:
|
||||
initial = kwargs.get('initial', {})
|
||||
initial.update({
|
||||
'users': instance.users.all(),
|
||||
})
|
||||
kwargs['initial'] = initial
|
||||
super().__init__(**kwargs)
|
||||
|
||||
def save(self, commit=True):
|
||||
group = super().save(commit=commit)
|
||||
users = self.cleaned_data['users']
|
||||
group.users.set(users)
|
||||
return group
|
||||
|
||||
class Meta:
|
||||
model = UserGroup
|
||||
fields = [
|
||||
'name', 'comment'
|
||||
'name', 'users', 'comment'
|
||||
]
|
||||
help_texts = {
|
||||
'name': '* required'
|
||||
}
|
||||
|
||||
|
||||
class UserPrivateAssetPermissionForm(forms.ModelForm):
|
||||
def save(self, commit=True):
|
||||
self.instance = super(UserPrivateAssetPermissionForm, self)\
|
||||
.save(commit=commit)
|
||||
self.instance.users = [self.user]
|
||||
self.instance.save()
|
||||
return self.instance
|
||||
|
||||
class Meta:
|
||||
model = AssetPermission
|
||||
fields = [
|
||||
'assets', 'asset_groups', 'system_users', 'name',
|
||||
]
|
||||
widgets = {
|
||||
'assets': forms.SelectMultiple(
|
||||
attrs={'class': 'select2',
|
||||
'data-placeholder': _('Select assets')}),
|
||||
'asset_groups': forms.SelectMultiple(
|
||||
attrs={'class': 'select2',
|
||||
'data-placeholder': _('Select asset groups')}),
|
||||
'system_users': forms.SelectMultiple(
|
||||
attrs={'class': 'select2',
|
||||
'data-placeholder': _('Select system users')}),
|
||||
}
|
||||
|
||||
|
||||
class UserGroupPrivateAssetPermissionForm(forms.ModelForm):
|
||||
def save(self, commit=True):
|
||||
self.instance = super(UserGroupPrivateAssetPermissionForm, self)\
|
||||
|
|
|
@ -69,44 +69,3 @@ class UserGroupUpdateMemeberSerializer(serializers.ModelSerializer):
|
|||
model = UserGroup
|
||||
fields = ['id', 'users']
|
||||
|
||||
|
||||
# class GroupDetailSerializer(serializers.ModelSerializer):
|
||||
# class Meta:
|
||||
# model = UserGroup
|
||||
# fields = ['id', 'name', 'comment', 'date_created', 'created_by', 'users']
|
||||
|
||||
|
||||
# class UserBulkUpdateSerializer(BulkSerializerMixin, serializers.ModelSerializer):
|
||||
# group_display = serializers.SerializerMethodField()
|
||||
# active_display = serializers.SerializerMethodField()
|
||||
# groups = serializers.PrimaryKeyRelatedField(many=True, queryset=UserGroup.objects.all())
|
||||
#
|
||||
# class Meta(object):
|
||||
# model = User
|
||||
# list_serializer_class = BulkListSerializer
|
||||
# fields = ['id', 'is_active', 'username', 'name', 'email', 'role', 'avatar',
|
||||
# 'enable_otp', 'comment', 'groups', 'get_role_display',
|
||||
# 'group_display', 'active_display']
|
||||
#
|
||||
# @staticmethod
|
||||
# def get_group_display(obj):
|
||||
# return " ".join([group.name for group in obj.groups.all()])
|
||||
#
|
||||
# @staticmethod
|
||||
# def get_active_display(obj):
|
||||
# TODO: user active state
|
||||
# return not (obj.is_expired and obj.is_active)
|
||||
#
|
||||
#
|
||||
# class GroupBulkUpdateSerializer(BulkSerializerMixin, serializers.ModelSerializer):
|
||||
# user_amount = serializers.SerializerMethodField()
|
||||
#
|
||||
# class Meta:
|
||||
# model = UserGroup
|
||||
# list_serializer_class = BulkListSerializer
|
||||
# fields = ['id', 'name', 'comment', 'user_amount']
|
||||
#
|
||||
# @staticmethod
|
||||
# def get_user_amount(obj):
|
||||
# return obj.users.count()
|
||||
#
|
||||
|
|
|
@ -6,7 +6,7 @@ from django.dispatch import Signal, receiver
|
|||
from common.utils import get_logger
|
||||
|
||||
logger = get_logger(__file__)
|
||||
on_user_created = Signal(providing_args=['user'])
|
||||
on_user_created = Signal(providing_args=['user', 'request'])
|
||||
|
||||
|
||||
@receiver(on_user_created)
|
||||
|
|
|
@ -32,12 +32,12 @@
|
|||
<span class="help-block ">{{ form.date_expired.errors }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="{{ form.enable_otp.id_for_label }}" class="col-sm-2 control-label">{% trans 'Enable OTP' %}</label>
|
||||
<div class="col-sm-8">
|
||||
{{ form.enable_otp }}
|
||||
</div>
|
||||
</div>
|
||||
{# <div class="form-group">#}
|
||||
{# <label for="{{ form.enable_otp.id_for_label }}" class="col-sm-2 control-label">{% trans 'Enable OTP' %}</label>#}
|
||||
{# <div class="col-sm-8">#}
|
||||
{# {{ form.enable_otp }}#}
|
||||
{# </div>#}
|
||||
{# </div>#}
|
||||
<div class="hr-line-dashed"></div>
|
||||
<h3>{% trans 'Profile' %}</h3>
|
||||
{% bootstrap_field form.phone layout="horizontal" %}
|
||||
|
|
|
@ -1,182 +0,0 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load bootstrap3 %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block custom_head_css_js %}
|
||||
<link href="{% static "css/plugins/select2/select2.min.css" %}" rel="stylesheet">
|
||||
<script src="{% static "js/plugins/select2/select2.full.min.js" %}"></script>
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
<div class="wrapper wrapper-content animated fadeInRight">
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<div class="ibox float-e-margins">
|
||||
<div class="panel-options">
|
||||
<ul class="nav nav-tabs">
|
||||
<li>
|
||||
<a href="{% url 'users:user-detail' pk=user.id %}" class="text-center"><i class="fa fa-laptop"></i> {% trans 'User detail' %} </a>
|
||||
</li>
|
||||
<li class="active">
|
||||
<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>
|
||||
<a href="{% url 'users:user-granted-asset' pk=user.id %}" class="text-center"><i class="fa fa-cubes"></i> {% trans 'Asset granted' %}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="tab-content">
|
||||
<div class="col-sm-8" style="padding-left: 0;">
|
||||
<div class="ibox float-e-margins">
|
||||
<div class="ibox-title">
|
||||
<span style="float: left">{% trans 'Asset permission of ' %} <b>{{ user.name }}</b></span>
|
||||
<div class="ibox-tools">
|
||||
<a class="collapse-link">
|
||||
<i class="fa fa-chevron-up"></i>
|
||||
</a>
|
||||
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
|
||||
<i class="fa fa-wrench"></i>
|
||||
</a>
|
||||
<ul class="dropdown-menu dropdown-user">
|
||||
</ul>
|
||||
<a class="close-link">
|
||||
<i class="fa fa-times"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ibox-content">
|
||||
<table class="table table-hover " id="user_permissions_table" >
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="text-center">
|
||||
<input type="checkbox" id="check_all" class="ipt_check_all" >
|
||||
</th>
|
||||
<th>{% trans 'Name' %}</th>
|
||||
<th>{% trans 'Asset' %}</th>
|
||||
<th>{% trans 'Asset group' %}</th>
|
||||
<th>{% trans 'System user' %}</th>
|
||||
<th>{% trans 'Valid' %}</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-4" style="padding-left: 0;padding-right: 0">
|
||||
<div class="panel panel-primary">
|
||||
<div class="panel-heading">
|
||||
<i class="fa fa-info-circle"></i> {% trans 'Quick create permission for user' %}
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<form method="post" action="{% url 'users:user-asset-permission-create' pk=user.id %}">
|
||||
<table class="table">
|
||||
<tbody>
|
||||
{% csrf_token %}
|
||||
<tr class="no-borders-tr">
|
||||
<td colspan="1" style="padding-top: 0">
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="no-borders-tr">
|
||||
<td colspan="1" style="padding-top: 0">
|
||||
{% bootstrap_field form.assets %}
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="no-borders-tr">
|
||||
<td colspan="1" style="padding-top: 0">
|
||||
{% bootstrap_field form.asset_groups %}
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="no-borders-tr">
|
||||
<td colspan="1" style="padding-top: 0">
|
||||
{% bootstrap_field form.system_users %}
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="no-borders-tr">
|
||||
<td>
|
||||
<button type="submit" class="btn btn-primary btn-sm">{% trans 'Submit' %}</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
{% block custom_foot_js %}
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
$('.select2').select2();
|
||||
var options = {
|
||||
ele: $('#user_permissions_table'),
|
||||
buttons: [],
|
||||
order: [],
|
||||
select: [],
|
||||
columnDefs: [
|
||||
{targets: 1, createdCell: function (td, cellData, rowData) {
|
||||
var detail_btn = '<a href="{% url "perms:asset-permission-detail" pk=DEFAULT_PK %}">' + cellData + '</a>';
|
||||
$(td).html(detail_btn.replace('{{ DEFAULT_PK }}', rowData.id));
|
||||
}},
|
||||
{targets: 2, createdCell: function (td, cellData, rowData) {
|
||||
var dataLength = cellData.length;
|
||||
$(td).html(dataLength);
|
||||
}},
|
||||
{targets: 3, createdCell: function (td, cellData, rowData) {
|
||||
var dataLength = cellData.length;
|
||||
$(td).html(dataLength);
|
||||
}},
|
||||
{targets: 4, createdCell: function (td, cellData, rowData) {
|
||||
var dataLength = cellData.length;
|
||||
$(td).html(dataLength);
|
||||
}},
|
||||
{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>')
|
||||
}
|
||||
}},
|
||||
{targets: 6, createdCell: function (td, cellData, rowData) {
|
||||
var btn = '<button class="btn btn-danger btn-xs btn_del_permission disabled" id="{{ DEFAULT_PK }}" type="button" style="float: right;"><i class="fa fa-minus"></i></button>';
|
||||
if (rowData.is_inherited) {
|
||||
$(td).html(btn)
|
||||
} else {
|
||||
btn = btn.replace('{{ DEFAULT_PK }}', cellData);
|
||||
$(td).html(btn.replace('disabled', ''));
|
||||
}
|
||||
}}
|
||||
],
|
||||
ajax_url: '{% url "api-perms:asset-permission-list" %}?user={{ user.id }}',
|
||||
columns: [{data: function(){return ""}}, {data: "name" }, {data: "assets" }, {data: "asset_groups"},
|
||||
{data: "system_users"}, {data: "is_active"}, {data: "id"}]
|
||||
};
|
||||
jumpserver.initDataTable(options);
|
||||
}).on('click', '.btn_del_permission', function () {
|
||||
var $this = $(this);
|
||||
var body = {
|
||||
id: $this.attr('id'),
|
||||
user_id: {{ user.id }}
|
||||
};
|
||||
var the_url = "{% url 'api-perms:revoke-user-asset-permission' %}";
|
||||
var success = function () {
|
||||
$this.closest('tr').remove();
|
||||
};
|
||||
APIUpdateAttr({
|
||||
url: the_url,
|
||||
body: JSON.stringify(body),
|
||||
method: 'PUT',
|
||||
success_message: '{% trans "Revoke Successfully!" %}',
|
||||
success: success
|
||||
});
|
||||
})
|
||||
</script>
|
||||
{% endblock %}
|
|
@ -6,7 +6,7 @@
|
|||
{# {% bootstrap_field form.username layout="horizontal" %}#}
|
||||
{#{% endblock %}#}
|
||||
{% block password %}
|
||||
<h3>{% trans 'Password' %}</h3>
|
||||
<h3>{% trans 'Auth' %}</h3>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-2 control-label">{% trans 'Password' %}</label>
|
||||
<div class="col-sm-8 controls" >
|
||||
|
|
|
@ -18,9 +18,6 @@
|
|||
<li class="active">
|
||||
<a href="{% url 'users:user-detail' pk=user_object.id %}" class="text-center"><i class="fa fa-laptop"></i> {% trans 'User detail' %} </a>
|
||||
</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>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{% url 'users:user-granted-asset' pk=user_object.id %}" class="text-center"><i class="fa fa-cubes"></i> {% trans 'Asset granted' %}</a>
|
||||
</li>
|
||||
|
@ -35,7 +32,7 @@
|
|||
</ul>
|
||||
</div>
|
||||
<div class="tab-content">
|
||||
<div class="col-sm-7" style="padding-left: 0">
|
||||
<div class="col-sm-8" style="padding-left: 0">
|
||||
<div class="ibox float-e-margins">
|
||||
<div class="ibox-title">
|
||||
<span class="label"><b>{{ user_object.name }}</b></span>
|
||||
|
@ -118,7 +115,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-5" style="padding-left: 0;padding-right: 0">
|
||||
<div class="col-sm-4" style="padding-left: 0;padding-right: 0">
|
||||
<div class="panel panel-primary">
|
||||
<div class="panel-heading">
|
||||
<i class="fa fa-info-circle"></i> {% trans 'Quick modify' %}
|
||||
|
@ -140,34 +137,34 @@
|
|||
</div>
|
||||
</span></td>
|
||||
</tr>
|
||||
{# <tr>#}
|
||||
{# <td>{% trans 'Enable OTP' %}:</td>#}
|
||||
{# <td><span class="pull-right">#}
|
||||
{# <div class="switch">#}
|
||||
{# <div class="onoffswitch">#}
|
||||
{# <input type="checkbox" class="onoffswitch-checkbox" {% if user_object.enable_otp %} checked {% endif %}#}
|
||||
{# id="enable_otp">#}
|
||||
{# <label class="onoffswitch-label" for="enable_otp">#}
|
||||
{# <span class="onoffswitch-inner"></span>#}
|
||||
{# <span class="onoffswitch-switch"></span>#}
|
||||
{# </label>#}
|
||||
{# </div>#}
|
||||
{# </div>#}
|
||||
{# </span></td>#}
|
||||
{# </tr>#}
|
||||
<tr>
|
||||
<td>{% trans 'Enable OTP' %}:</td>
|
||||
<td><span class="pull-right">
|
||||
<div class="switch">
|
||||
<div class="onoffswitch">
|
||||
<input type="checkbox" class="onoffswitch-checkbox" {% if user_object.enable_otp %} checked {% endif %}
|
||||
id="enable_otp">
|
||||
<label class="onoffswitch-label" for="enable_otp">
|
||||
<span class="onoffswitch-inner"></span>
|
||||
<span class="onoffswitch-switch"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{% trans 'Reset password' %}:</td>
|
||||
<td>{% trans 'Send reset password mail' %}:</td>
|
||||
<td>
|
||||
<span class="pull-right">
|
||||
<button type="button" class="btn btn-primary btn-xs" id="btn_reset_password" style="width: 54px">{% trans 'Reset' %}</button>
|
||||
<button type="button" class="btn btn-primary btn-xs" id="btn_reset_password" style="width: 54px">{% trans 'Send' %}</button>
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{% trans 'Reset ssh key' %}:</td>
|
||||
<td>{% trans 'Send reset ssh key mail' %}:</td>
|
||||
<td>
|
||||
<span class="pull-right">
|
||||
<button type="button" class="btn btn-primary btn-xs" id="btn_reset_pk" style="width: 54px;">{% trans 'Reset' %}</button>
|
||||
<button type="button" class="btn btn-primary btn-xs" id="btn_reset_pk" style="width: 54px;">{% trans 'Send' %}</button>
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -188,7 +185,7 @@
|
|||
<td colspan="2" class="no-borders">
|
||||
<select data-placeholder="{% trans 'Join user groups' %}" id="groups_selected" class="select2" style="width: 100%" multiple="" tabindex="4">
|
||||
{% for group in groups %}
|
||||
<option value="{{ group.id }}" id="opt_{{ group.id }}">{{ group.name }}</option>
|
||||
<option value="{{ group.id }}" id="opt_{{ group.id }}" >{{ group.name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</td>
|
||||
|
@ -263,7 +260,7 @@ $(document).ready(function() {
|
|||
})
|
||||
.on('select2:unselect', function(evt) {
|
||||
var data = evt.params.data;
|
||||
delete jumpserver.groups_selected[data.id]
|
||||
delete jumpserver.groups_selected[data.id];
|
||||
})
|
||||
})
|
||||
.on('click', '#is_active', function() {
|
||||
|
@ -279,20 +276,20 @@ $(document).ready(function() {
|
|||
success_message: success
|
||||
});
|
||||
})
|
||||
.on('click', '#enable_otp', function() {
|
||||
var the_url = "{% url 'api-users:user-detail' pk=user_object.id %}";
|
||||
var checked = $(this).prop('checked');
|
||||
var body = {
|
||||
'enable_otp': checked
|
||||
};
|
||||
var success = '{% trans "Update successfully!" %}';
|
||||
APIUpdateAttr({
|
||||
url: the_url,
|
||||
body: JSON.stringify(body),
|
||||
success_message: success
|
||||
});
|
||||
})
|
||||
.on('click', '#btn_join_group', function() {
|
||||
{#.on('click', '#enable_otp', function() {#}
|
||||
{# var the_url = "{% url 'api-users:user-detail' pk=user_object.id %}";#}
|
||||
{# var checked = $(this).prop('checked');#}
|
||||
{# var body = {#}
|
||||
{# 'enable_otp': checked#}
|
||||
{# };#}
|
||||
{# var success = '{% trans "Update successfully!" %}';#}
|
||||
{# APIUpdateAttr({#}
|
||||
{# url: the_url,#}
|
||||
{# body: JSON.stringify(body),#}
|
||||
{# success_message: success#}
|
||||
{# });#}
|
||||
{# });#}
|
||||
.on('click', '#btn_join_group', function() {
|
||||
if (Object.keys(jumpserver.groups_selected).length === 0) {
|
||||
return false;
|
||||
}
|
||||
|
@ -300,7 +297,7 @@ $(document).ready(function() {
|
|||
return $(this).data('gid');
|
||||
}).get();
|
||||
$.map(jumpserver.groups_selected, function(value, index) {
|
||||
groups.push(parseInt(index));
|
||||
groups.push(index);
|
||||
$('#opt_' + index).remove();
|
||||
});
|
||||
updateUserGroups(groups)
|
||||
|
@ -368,7 +365,7 @@ $(document).ready(function() {
|
|||
}, function() {
|
||||
doReset();
|
||||
});
|
||||
}).on('click', '#btn_user_update_pk', function(){
|
||||
}).on('click', '#btn-user-update-pk', function(){
|
||||
var $this = $(this);
|
||||
var pk = $('#txt_pk').val();
|
||||
var the_url = '{% url "api-users:user-public-key-reset" pk=user.id %}';
|
||||
|
|
|
@ -17,9 +17,6 @@
|
|||
<li>
|
||||
<a href="{% url 'users:user-detail' pk=user.id %}" class="text-center"><i class="fa fa-laptop"></i> {% trans 'User detail' %} </a>
|
||||
</li>
|
||||
<li>
|
||||
<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 class="active">
|
||||
<a href="{% url 'users:user-granted-asset' pk=user.id %}" class="text-center"><i class="fa fa-cubes"></i> {% trans 'Asset granted' %}</a>
|
||||
</li>
|
||||
|
@ -48,12 +45,9 @@
|
|||
<table class="table table-hover " id="user_assets_table" >
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="text-center"></th>
|
||||
<th>{% trans 'Hostname' %}</th>
|
||||
<th>{% trans 'IP' %}</th>
|
||||
<th>{% trans 'Port' %}</th>
|
||||
<th>{% trans 'System user' %}</th>
|
||||
<th>{% trans 'Valid' %}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
@ -84,7 +78,6 @@
|
|||
<table class="table table-hover" id="user_asset_groups_table" >
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th>{% trans 'Name' %}</th>
|
||||
<th>{% trans 'Asset' %}</th>
|
||||
</tr>
|
||||
|
@ -112,28 +105,15 @@
|
|||
order: [],
|
||||
select: [],
|
||||
columnDefs: [
|
||||
{targets: 1, createdCell: function (td, cellData, rowData) {
|
||||
{targets: 0, createdCell: function (td, cellData, rowData) {
|
||||
var detail_btn = '<a href="{% url "assets:asset-detail" pk=DEFAULT_PK %}">' + cellData + '</a>';
|
||||
$(td).html(detail_btn.replace('{{ DEFAULT_PK }}', 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 "api-perms:user-assets" pk=user.id %}',
|
||||
columns: [{data: function(){return ""}}, {data: "hostname" }, {data: "ip" }, {data: "port"},
|
||||
{data: "system_users_join"}, {data: "is_active"}]
|
||||
columns: [{data: "hostname" }, {data: "ip" },
|
||||
{data: "system_users_join"}
|
||||
]
|
||||
};
|
||||
var options2 = {
|
||||
ele: $('#user_asset_groups_table'),
|
||||
|
@ -141,13 +121,14 @@
|
|||
order: [],
|
||||
select: [],
|
||||
columnDefs: [
|
||||
{targets: 1, createdCell: function (td, cellData, rowData) {
|
||||
{targets: 0, createdCell: function (td, cellData, rowData) {
|
||||
var detail_btn = '<a href="{% url "assets:asset-group-detail" pk=DEFAULT_PK %}">' + cellData + '</a>';
|
||||
$(td).html(detail_btn.replace('{{ DEFAULT_PK }}', rowData.id));
|
||||
}}
|
||||
],
|
||||
ajax_url: '{% url "api-perms:user-asset-groups" pk=user.id %}',
|
||||
columns: [{data: function(){return ""}}, {data: "name" }, {data: "assets_amount" }]
|
||||
columns: [{data: "name" }, {data: "assets_amount" }],
|
||||
paging: false
|
||||
};
|
||||
jumpserver.initDataTable(options);
|
||||
jumpserver.initDataTable(options2);
|
||||
|
|
|
@ -1,181 +0,0 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load bootstrap3 %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block custom_head_css_js %}
|
||||
<link href="{% static "css/plugins/select2/select2.min.css" %}" rel="stylesheet">
|
||||
<script src="{% static "js/plugins/select2/select2.full.min.js" %}"></script>
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
<div class="wrapper wrapper-content animated fadeInRight">
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<div class="ibox float-e-margins">
|
||||
<div class="panel-options">
|
||||
<ul class="nav nav-tabs">
|
||||
<li>
|
||||
<a href="{% url 'users:user-group-detail' pk=user_group.id %}" class="text-center"><i class="fa fa-laptop"></i> {% trans 'User detail' %} </a>
|
||||
</li>
|
||||
<li class="active">
|
||||
<a href="{% url 'users:user-group-asset-permission' pk=user_group.id %}" class="text-center"><i class="fa fa-bar-chart-o"></i> {% trans 'Asset permission' %}</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{% url 'users:user-group-granted-asset' pk=user_group.id %}" class="text-center"><i class="fa fa-cubes"></i> {% trans 'Asset granted' %}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="tab-content">
|
||||
<div class="col-sm-7" style="padding-left: 0;">
|
||||
<div class="ibox float-e-margins">
|
||||
<div class="ibox-title">
|
||||
<span style="float: left">{% trans 'Asset permission of ' %} <b>{{ user_group.name }}</b></span>
|
||||
<div class="ibox-tools">
|
||||
<a class="collapse-link">
|
||||
<i class="fa fa-chevron-up"></i>
|
||||
</a>
|
||||
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
|
||||
<i class="fa fa-wrench"></i>
|
||||
</a>
|
||||
<ul class="dropdown-menu dropdown-user">
|
||||
</ul>
|
||||
<a class="close-link">
|
||||
<i class="fa fa-times"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ibox-content">
|
||||
<table class="table table-hover " id="user_group_permissions_table" >
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="text-center">
|
||||
<input type="checkbox" id="check_all" class="ipt_check_all" >
|
||||
</th>
|
||||
<th>{% trans 'Name' %}</th>
|
||||
<th>{% trans 'Asset' %}</th>
|
||||
<th>{% trans 'Asset group' %}</th>
|
||||
<th>{% trans 'System user' %}</th>
|
||||
<th>{% trans 'Valid' %}</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-5" style="padding-left: 0;padding-right: 0">
|
||||
<div class="panel panel-primary">
|
||||
<div class="panel-heading">
|
||||
<i class="fa fa-info-circle"></i> {% trans 'Quick create permission for user group' %}
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<form method="post" action="{% url 'users:user-group-asset-permission-create' pk=user_group.id %}">
|
||||
<table class="table">
|
||||
<tbody>
|
||||
{% csrf_token %}
|
||||
<tr class="no-borders-tr">
|
||||
<td colspan="1" style="padding-top: 0">
|
||||
{% bootstrap_field form.name %}
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="no-borders-tr">
|
||||
<td colspan="1" style="padding-top: 0">
|
||||
{% bootstrap_field form.assets %}
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="no-borders-tr">
|
||||
<td colspan="1" style="padding-top: 0">
|
||||
{% bootstrap_field form.asset_groups %}
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="no-borders-tr">
|
||||
<td colspan="1" style="padding-top: 0">
|
||||
{% bootstrap_field form.system_users %}
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="no-borders-tr">
|
||||
<td>
|
||||
<button type="submit" class="btn btn-primary btn-sm">{% trans 'Submit' %}</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
{% block custom_foot_js %}
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
$('.select2').select2();
|
||||
var options = {
|
||||
ele: $('#user_group_permissions_table'),
|
||||
buttons: [],
|
||||
order: [],
|
||||
select: [],
|
||||
columnDefs: [
|
||||
{targets: 1, createdCell: function (td, cellData, rowData) {
|
||||
var detail_btn = '<a href="{% url "perms:asset-permission-detail" pk=DEFAULT_PK %}">' + cellData + '</a>';
|
||||
$(td).html(detail_btn.replace('{{ DEFAULT_PK }}', rowData.id));
|
||||
}},
|
||||
{targets: 2, createdCell: function (td, cellData, rowData) {
|
||||
var dataLength = cellData.length;
|
||||
$(td).html(dataLength);
|
||||
}},
|
||||
{targets: 3, createdCell: function (td, cellData, rowData) {
|
||||
var dataLength = cellData.length;
|
||||
$(td).html(dataLength);
|
||||
}},
|
||||
{targets: 4, createdCell: function (td, cellData, rowData) {
|
||||
var dataLength = cellData.length;
|
||||
$(td).html(dataLength);
|
||||
}},
|
||||
{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>')
|
||||
}
|
||||
}},
|
||||
{targets: 6, createdCell: function (td, cellData, rowData) {
|
||||
var btn = '<button class="btn btn-danger btn-xs btn_del_permission" id="{{ DEFAULT_PK }}" type="button" style="float: right;"><i class="fa fa-minus"></i></button>';
|
||||
btn = btn.replace('{{ DEFAULT_PK }}', cellData);
|
||||
$(td).html(btn)
|
||||
}}
|
||||
],
|
||||
ajax_url: '{% url "api-perms:asset-permission-list" %}?user_group={{ user_group.id }}',
|
||||
columns: [{data: function(){return ""}}, {data: "name" }, {data: "assets" }, {data: "asset_groups"},
|
||||
{data: "system_users"}, {data: "is_active"}, {data: "id"}]
|
||||
};
|
||||
jumpserver.initDataTable(options);
|
||||
}).on('click', '.btn_del_permission', function () {
|
||||
var $this = $(this);
|
||||
var body = {
|
||||
id: $this.attr('id'),
|
||||
user_group_id: {{ user_group.id }}
|
||||
};
|
||||
var the_url = "{% url 'api-perms:revoke-user-group-asset-permission' %}";
|
||||
var success = function () {
|
||||
$this.closest('tr').remove();
|
||||
};
|
||||
APIUpdateAttr({
|
||||
url: the_url,
|
||||
body: JSON.stringify(body),
|
||||
method: 'PUT',
|
||||
success_message: '{% trans "Revoke Successfully!" %}',
|
||||
success: success
|
||||
});
|
||||
}).on('click', 'buttons-excel', function () {
|
||||
console.log('click excel')
|
||||
})
|
||||
</script>
|
||||
{% endblock %}
|
|
@ -24,20 +24,21 @@
|
|||
<form method="post" class="form-horizontal" action="" >
|
||||
{% csrf_token %}
|
||||
{% bootstrap_field form.name layout="horizontal" %}
|
||||
<div class="form-group">
|
||||
<label for="users" class="col-sm-2 control-label">{% trans 'Users' %}</label>
|
||||
<div class="col-sm-9">
|
||||
<select name="users" id="id_users" data-placeholder="{% trans 'Select User' %}" class="select2 form-control m-b" multiple tabindex="2">
|
||||
{% for user in users %}
|
||||
{% if user.id in group_users %}
|
||||
<option value="{{ user.id }}" selected>{{ user.name }}</option>
|
||||
{% else %}
|
||||
<option value="{{ user.id }}">{{ user.name }}</option>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
{% bootstrap_field form.users layout="horizontal" %}
|
||||
{# <div class="form-group">#}
|
||||
{# <label for="users" class="col-sm-2 control-label">{% trans 'Users' %}</label>#}
|
||||
{# <div class="col-sm-9">#}
|
||||
{# <select name="users" id="id_users" data-placeholder="{% trans 'Select User' %}" class="select2 form-control m-b" multiple tabindex="2">#}
|
||||
{# {% for user in users %}#}
|
||||
{# {% if user.id in group_users %}#}
|
||||
{# <option value="{{ user.id }}" selected>{{ user.name }}</option>#}
|
||||
{# {% else %}#}
|
||||
{# <option value="{{ user.id }}">{{ user.name }}</option>#}
|
||||
{# {% endif %}#}
|
||||
{# {% endfor %}#}
|
||||
{# </select>#}
|
||||
{# </div>#}
|
||||
{# </div>#}
|
||||
{% bootstrap_field form.comment layout="horizontal" %}
|
||||
<div class="form-group">
|
||||
<div class="col-sm-4 col-sm-offset-2">
|
||||
|
|
|
@ -22,10 +22,7 @@
|
|||
<a href="{% url 'users:user-group-detail' pk=user_group.id %}" class="text-center"><i class="fa fa-laptop"></i> {% trans 'User group detail' %} </a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{% url 'users:user-group-asset-permission' pk=user_group.id %}" class="text-center"><i class="fa fa-bar-chart-o"></i> {% trans 'Asset permission' %}</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{% url 'users:user-group-granted-asset' pk=user.id %}" class="text-center"><i class="fa fa-cubes"></i> {% trans 'Asset granted' %}</a>
|
||||
<a href="{% url 'users:user-group-granted-asset' pk=user_group.id %}" class="text-center"><i class="fa fa-cubes"></i> {% trans 'Asset granted' %}</a>
|
||||
</li>
|
||||
<li class="pull-right">
|
||||
<a class="btn btn-outline btn-default" href="{% url 'users:user-group-update' pk=user_group.id %}"><i class="fa fa-edit"></i>Update</a>
|
||||
|
|
|
@ -17,16 +17,13 @@
|
|||
<li>
|
||||
<a href="{% url 'users:user-group-detail' pk=user_group.id %}" class="text-center"><i class="fa fa-laptop"></i> {% trans 'User detail' %} </a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{% url 'users:user-group-asset-permission' pk=user_group.id %}" class="text-center"><i class="fa fa-bar-chart-o"></i> {% trans 'Asset permission' %}</a>
|
||||
</li>
|
||||
<li class="active">
|
||||
<a href="{% url 'users:user-group-granted-asset' pk=user_group.id %}" class="text-center"><i class="fa fa-cubes"></i> {% trans 'Asset granted' %}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="tab-content">
|
||||
<div class="col-sm-8" style="padding-left: 0;">
|
||||
<div class="col-sm-7" style="padding-left: 0;">
|
||||
<div class="ibox float-e-margins">
|
||||
<div class="ibox-title">
|
||||
<span style="float: left">{% trans 'Assets granted of ' %} <b>{{ user_group.name }}</b></span>
|
||||
|
@ -62,7 +59,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-4" 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-title">
|
||||
<span style="float: left">{% trans 'Asset groups granted of ' %} <b>{{ user_group.name }}</b></span>
|
||||
|
|
|
@ -16,18 +16,7 @@
|
|||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
<div id="actions" class="hide">
|
||||
<div class="input-group">
|
||||
<select class="form-control m-b" style="width: auto" id="slct_bulk_update">
|
||||
<option value="delete">{% trans 'Delete selected' %}</option>
|
||||
</select>
|
||||
<div class="input-group-btn pull-left" style="padding-left: 5px;">
|
||||
<button id='btn_bulk_update' style="height: 32px;" class="btn btn-sm btn-primary">
|
||||
{% trans 'Submit' %}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block content_bottom_left %}{% endblock %}
|
||||
|
@ -57,11 +46,12 @@ $(document).ready(function() {
|
|||
} else {
|
||||
$(td).html(update_btn + del_btn)
|
||||
}
|
||||
}}],
|
||||
}}
|
||||
],
|
||||
ajax_url: '{% url "api-users:user-group-list" %}',
|
||||
columns: [{data: function(){return ""}}, {data: "name" }, {data: "user_amount"},
|
||||
{data: "comment"}, {data: "id" }],
|
||||
order: [4, 'asc'],
|
||||
order: [],
|
||||
op_html: $('#actions').html()
|
||||
};
|
||||
jumpserver.initDataTable(options);
|
||||
|
|
|
@ -52,24 +52,8 @@
|
|||
{% block custom_foot_js %}
|
||||
<script src="{% static 'js/jquery.form.min.js' %}"></script>
|
||||
<script>
|
||||
function changeField(obj, active) {
|
||||
var $this = $(obj);
|
||||
var field_id = $this.data('id');
|
||||
if (!active) {
|
||||
active = $this.attr('value');
|
||||
}
|
||||
if (active == '0') {
|
||||
$this.attr('value', '1').addClass('label-primary');
|
||||
var form_groups = $('#add_form .form-group:not(.abc)');
|
||||
form_groups.filter(':has(#' + field_id + ')').show().find('select,input').prop('disabled', false)
|
||||
} else {
|
||||
$this.attr('value', '0').removeClass('label-primary');
|
||||
var form_groups = $('#add_form .form-group:not(.abc)');
|
||||
form_groups.filter(':has(#' + field_id + ')').hide().find('select,input').prop('disabled', true)
|
||||
}
|
||||
}
|
||||
|
||||
function renderTable() {
|
||||
function initTable() {
|
||||
var options = {
|
||||
ele: $('#user_list_table'),
|
||||
columnDefs: [
|
||||
|
@ -90,24 +74,30 @@ function renderTable() {
|
|||
}},
|
||||
{targets: 6, createdCell: function (td, cellData, rowData) {
|
||||
var update_btn = '<a href="{% url "users:user-update" pk='00000000-0000-0000-0000-000000000000' %}" class="btn btn-xs btn-info">{% trans "Update" %}</a>'.replace('00000000-0000-0000-0000-000000000000', cellData);
|
||||
var del_btn = '<a class="btn btn-xs btn-danger m-l-xs btn_user_delete" data-uid="{{ DEFAULT_PK }}" data-name="99991938">{% trans "Delete" %}</a>'
|
||||
.replace('{{ DEFAULT_PK }}', cellData)
|
||||
.replace('99991938', rowData.name);
|
||||
if (rowData.id === 1 || rowData.username == "admin") {
|
||||
$(td).html(update_btn)
|
||||
|
||||
var del_btn = "";
|
||||
if (rowData.id === 1 || rowData.username === "admin" || rowData.username === "{{ user.username }}") {
|
||||
del_btn = '<a class="btn btn-xs btn-danger m-l-xs" disabled>{% trans "Delete" %}</a>'
|
||||
.replace('{{ DEFAULT_PK }}', cellData)
|
||||
.replace('99991938', rowData.name);
|
||||
} else {
|
||||
$(td).html(update_btn + del_btn)
|
||||
del_btn = '<a class="btn btn-xs btn-danger m-l-xs btn_user_delete" data-uid="{{ DEFAULT_PK }}" data-name="99991938">{% trans "Delete" %}</a>'
|
||||
.replace('{{ DEFAULT_PK }}', cellData)
|
||||
.replace('99991938', rowData.name);
|
||||
}
|
||||
$(td).html(update_btn + del_btn)
|
||||
}}],
|
||||
ajax_url: '{% url "api-users:user-list" %}',
|
||||
columns: [{data: "id"}, {data: "name" }, {data: "username" }, {data: "get_role_display" },
|
||||
{data: "groups_display" }, {data: "is_valid" }, {data: "id" }],
|
||||
op_html: $('#actions').html()
|
||||
};
|
||||
var table = jumpserver.initDataTable(options);
|
||||
table = jumpserver.initDataTable(options);
|
||||
return table
|
||||
}
|
||||
|
||||
$(document).ready(function(){
|
||||
renderTable();
|
||||
var table = initTable();
|
||||
var fields = $('#fm_user_bulk_update .form-group');
|
||||
$.each(fields, function (index, value) {
|
||||
console.log(value)
|
||||
|
@ -158,7 +148,7 @@ $(document).ready(function(){
|
|||
var id_list = [];
|
||||
var plain_id_list = [];
|
||||
$data_table.rows({selected: true}).every(function(){
|
||||
id_list.push({id: this.data().id});
|
||||
id_list.push({pk: this.data().id});
|
||||
plain_id_list.push(this.data().id);
|
||||
});
|
||||
if (id_list === []) {
|
||||
|
@ -169,6 +159,7 @@ $(document).ready(function(){
|
|||
var body = $.each(id_list, function(index, user_object) {
|
||||
user_object['is_active'] = false;
|
||||
});
|
||||
console.log(body);
|
||||
APIUpdateAttr({url: the_url, method: 'PATCH', body: JSON.stringify(body)});
|
||||
$data_table.ajax.reload();
|
||||
jumpserver.checked = false;
|
||||
|
|
|
@ -1,12 +1,8 @@
|
|||
{% extends 'users/_user.html' %}
|
||||
{% load i18n %}
|
||||
{% load bootstrap3 %}
|
||||
{% block user_template_title %}{% trans "Update user" %}{% endblock %}
|
||||
{% block password %}
|
||||
<h3>{% trans 'Password' %}</h3>
|
||||
<div class="form-group">
|
||||
<label for="password" class="col-sm-2 control-label">{% trans 'Password' %}</label>
|
||||
<div class="col-sm-9 controls" >
|
||||
<input id="password" name="password" type="password" class="form-control">
|
||||
</div>
|
||||
</div>
|
||||
<h3>{% trans 'Auth' %}</h3>
|
||||
{% bootstrap_field form.password layout="horizontal" %}
|
||||
{% endblock %}
|
||||
|
|
|
@ -30,8 +30,6 @@ urlpatterns = [
|
|||
url(r'^user/(?P<pk>[0-9a-zA-Z\-]{36})/update$', views.UserUpdateView.as_view(), name='user-update'),
|
||||
url(r'^user/update$', views.UserBulkUpdateView.as_view(), name='user-bulk-update'),
|
||||
url(r'^user/(?P<pk>[0-9a-zA-Z\-]{36})$', views.UserDetailView.as_view(), name='user-detail'),
|
||||
url(r'^user/(?P<pk>[0-9a-zA-Z\-]{36})/asset-permission$', views.UserAssetPermissionView.as_view(), name='user-asset-permission'),
|
||||
url(r'^user/(?P<pk>[0-9a-zA-Z\-]{36})/asset-permission/create$', views.UserAssetPermissionCreateView.as_view(), name='user-asset-permission-create'),
|
||||
url(r'^user/(?P<pk>[0-9a-zA-Z\-]{36})/assets', views.UserGrantedAssetView.as_view(), name='user-granted-asset'),
|
||||
url(r'^user/(?P<pk>[0-9a-zA-Z\-]{36})/login-history', views.UserDetailView.as_view(), name='user-login-history'),
|
||||
|
||||
|
@ -41,8 +39,6 @@ urlpatterns = [
|
|||
url(r'^user-group/(?P<pk>[0-9a-zA-Z\-]{36})$', views.UserGroupDetailView.as_view(), name='user-group-detail'),
|
||||
url(r'^user-group/create$', views.UserGroupCreateView.as_view(), name='user-group-create'),
|
||||
url(r'^user-group/(?P<pk>[0-9a-zA-Z\-]{36})/update$', views.UserGroupUpdateView.as_view(), name='user-group-update'),
|
||||
url(r'^user-group/(?P<pk>[0-9a-zA-Z\-]{36})/asset-permission$', views.UserGroupAssetPermissionView.as_view(), name='user-group-asset-permission'),
|
||||
url(r'^user-group/(?P<pk>[0-9a-zA-Z\-]{36})/asset-permission/create$', views.UserGroupAssetPermissionCreateView.as_view(), name='user-group-asset-permission-create'),
|
||||
url(r'^user-group/(?P<pk>[0-9a-zA-Z\-]{36})/assets', views.UserGroupGrantedAssetView.as_view(), name='user-group-granted-asset'),
|
||||
|
||||
# Login log
|
||||
|
|
|
@ -18,8 +18,7 @@ from ..utils import AdminUserRequiredMixin
|
|||
from .. import forms
|
||||
|
||||
__all__ = ['UserGroupListView', 'UserGroupCreateView', 'UserGroupDetailView',
|
||||
'UserGroupUpdateView', 'UserGroupAssetPermissionCreateView',
|
||||
'UserGroupAssetPermissionView', 'UserGroupGrantedAssetView']
|
||||
'UserGroupUpdateView', 'UserGroupGrantedAssetView']
|
||||
logger = get_logger(__name__)
|
||||
|
||||
|
||||
|
@ -27,9 +26,12 @@ class UserGroupListView(AdminUserRequiredMixin, TemplateView):
|
|||
template_name = 'users/user_group_list.html'
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(UserGroupListView, self).get_context_data(**kwargs)
|
||||
context.update({'app': _('Users'), 'action': _('User group list')})
|
||||
return context
|
||||
context = {
|
||||
'app': _('Users'),
|
||||
'action': _('User group list')
|
||||
}
|
||||
kwargs.update(context)
|
||||
return super().get_context_data(**kwargs)
|
||||
|
||||
|
||||
class UserGroupCreateView(AdminUserRequiredMixin, SuccessMessageMixin, CreateView):
|
||||
|
@ -40,26 +42,18 @@ class UserGroupCreateView(AdminUserRequiredMixin, SuccessMessageMixin, CreateVie
|
|||
success_message = '<a href={url}> {name} </a> was created successfully'
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(UserGroupCreateView, self).get_context_data(**kwargs)
|
||||
users = User.objects.all()
|
||||
context.update({'app': _('Users'), 'action': _('Create user group'),
|
||||
'users': users})
|
||||
return context
|
||||
|
||||
# 需要添加组下用户, 而user并不是group的多对多,所以需要手动建立关系
|
||||
def form_valid(self, form):
|
||||
user_group = form.save()
|
||||
users_id_list = self.request.POST.getlist('users', [])
|
||||
users = User.objects.filter(id__in=users_id_list)
|
||||
user_group.created_by = self.request.user.username or 'Admin'
|
||||
user_group.users.add(*users)
|
||||
user_group.save()
|
||||
return super(UserGroupCreateView, self).form_valid(form)
|
||||
context = {
|
||||
'app': _('Users'),
|
||||
'action': _('Create user group'),
|
||||
}
|
||||
kwargs.update(context)
|
||||
return super().get_context_data(**kwargs)
|
||||
|
||||
def get_success_message(self, cleaned_data):
|
||||
url = reverse_lazy('users:user-group-detail',
|
||||
kwargs={'pk': self.object.id}
|
||||
)
|
||||
url = reverse_lazy(
|
||||
'users:user-group-detail',
|
||||
kwargs={'pk': self.object.id}
|
||||
)
|
||||
return self.success_message.format(
|
||||
url=url, name=self.object.name
|
||||
)
|
||||
|
@ -72,26 +66,16 @@ class UserGroupUpdateView(AdminUserRequiredMixin, UpdateView):
|
|||
success_url = reverse_lazy('users:user-group-list')
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
# self.object = self.get_object()
|
||||
context = super(UserGroupUpdateView, self).get_context_data(**kwargs)
|
||||
users = User.objects.all()
|
||||
group_users = [user.id for user in self.object.users.all()]
|
||||
context.update({
|
||||
context = {
|
||||
'app': _('Users'),
|
||||
'action': _('Update user group'),
|
||||
'users': users,
|
||||
'group_users': group_users
|
||||
})
|
||||
return context
|
||||
|
||||
def form_valid(self, form):
|
||||
user_group = form.save()
|
||||
users_id_list = self.request.POST.getlist('users', [])
|
||||
users = User.objects.filter(id__in=users_id_list)
|
||||
user_group.users.clear()
|
||||
user_group.users.add(*users)
|
||||
user_group.save()
|
||||
return super(UserGroupUpdateView, self).form_valid(form)
|
||||
}
|
||||
kwargs.update(context)
|
||||
return super().get_context_data(**kwargs)
|
||||
|
||||
|
||||
class UserGroupDetailView(AdminUserRequiredMixin, DetailView):
|
||||
|
@ -107,58 +91,7 @@ class UserGroupDetailView(AdminUserRequiredMixin, DetailView):
|
|||
'users': users,
|
||||
}
|
||||
kwargs.update(context)
|
||||
return super(UserGroupDetailView, self).get_context_data(**kwargs)
|
||||
|
||||
|
||||
class UserGroupAssetPermissionView(AdminUserRequiredMixin, FormMixin,
|
||||
SingleObjectMixin, ListView):
|
||||
model = UserGroup
|
||||
template_name = 'users/user_group_asset_permission.html'
|
||||
context_object_name = 'user_group'
|
||||
form_class = forms.UserPrivateAssetPermissionForm
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
self.object = self.get_object(queryset=UserGroup.objects.all())
|
||||
return super(UserGroupAssetPermissionView, self)\
|
||||
.get(request, *args, **kwargs)
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = {
|
||||
'app': 'Users',
|
||||
'action': 'User group asset permissions',
|
||||
}
|
||||
kwargs.update(context)
|
||||
return super(UserGroupAssetPermissionView, self)\
|
||||
.get_context_data(**kwargs)
|
||||
|
||||
|
||||
class UserGroupAssetPermissionCreateView(AdminUserRequiredMixin, CreateView):
|
||||
form_class = forms.UserGroupPrivateAssetPermissionForm
|
||||
model = AssetPermission
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
user_group = self.get_object(queryset=UserGroup.objects.all())
|
||||
return redirect(reverse('users:user-group-asset-permission',
|
||||
kwargs={'pk': user_group.id}))
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
self.user_group = self.get_object(queryset=UserGroup.objects.all())
|
||||
return super(UserGroupAssetPermissionCreateView, self)\
|
||||
.post(request, *args, **kwargs)
|
||||
|
||||
def get_form(self, form_class=None):
|
||||
form = super(UserGroupAssetPermissionCreateView, self)\
|
||||
.get_form(form_class=form_class)
|
||||
form.user_group = self.user_group
|
||||
return form
|
||||
|
||||
def form_invalid(self, form):
|
||||
return redirect(reverse('users:user-group-asset-permission',
|
||||
kwargs={'pk': self.user_group.id}))
|
||||
|
||||
def get_success_url(self):
|
||||
return reverse('users:user-group-asset-permission',
|
||||
kwargs={'pk': self.user_group.id})
|
||||
return super().get_context_data(**kwargs)
|
||||
|
||||
|
||||
class UserGroupGrantedAssetView(AdminUserRequiredMixin, DetailView):
|
||||
|
@ -167,7 +100,8 @@ class UserGroupGrantedAssetView(AdminUserRequiredMixin, DetailView):
|
|||
context_object_name = 'user_group'
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
self.object = self.get_object(queryset=UserGroup.objects.all())
|
||||
print(kwargs.get('pk'))
|
||||
self.object = self.get_object(queryset=self.model.objects.all())
|
||||
return super().get(request, *args, **kwargs)
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
|
@ -176,4 +110,4 @@ class UserGroupGrantedAssetView(AdminUserRequiredMixin, DetailView):
|
|||
'action': 'User group granted asset',
|
||||
}
|
||||
kwargs.update(context)
|
||||
return super(UserGroupGrantedAssetView, self).get_context_data(**kwargs)
|
||||
return super().get_context_data(**kwargs)
|
||||
|
|
|
@ -8,6 +8,7 @@ import csv
|
|||
import codecs
|
||||
from io import StringIO
|
||||
|
||||
from django.contrib import messages
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
from django.contrib.messages.views import SuccessMessageMixin
|
||||
from django.core.cache import cache
|
||||
|
@ -29,16 +30,15 @@ from django.contrib.auth import logout as auth_logout
|
|||
|
||||
from .. import forms
|
||||
from ..models import User, UserGroup
|
||||
from ..utils import AdminUserRequiredMixin, send_user_created_mail
|
||||
from ..utils import AdminUserRequiredMixin
|
||||
from ..signals import on_user_created
|
||||
from common.mixins import JSONResponseMixin
|
||||
from common.utils import get_logger, get_object_or_none
|
||||
from perms.models import AssetPermission
|
||||
|
||||
__all__ = [
|
||||
'UserListView', 'UserCreateView', 'UserDetailView',
|
||||
'UserUpdateView', 'UserAssetPermissionCreateView',
|
||||
'UserAssetPermissionView', 'UserGrantedAssetView',
|
||||
'UserUpdateView',
|
||||
'UserGrantedAssetView',
|
||||
'UserExportView', 'UserBulkImportView', 'UserProfileView',
|
||||
'UserProfileUpdateView', 'UserPasswordUpdateView',
|
||||
'UserPublicKeyUpdateView', 'UserBulkUpdateView',
|
||||
|
@ -51,7 +51,7 @@ class UserListView(AdminUserRequiredMixin, TemplateView):
|
|||
template_name = 'users/user_list.html'
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(UserListView, self).get_context_data(**kwargs)
|
||||
context = super().get_context_data(**kwargs)
|
||||
context.update({
|
||||
'app': _('Users'),
|
||||
'action': _('User list'),
|
||||
|
@ -67,7 +67,7 @@ class UserCreateView(AdminUserRequiredMixin, SuccessMessageMixin, CreateView):
|
|||
success_message = _('Create user <a href="{url}">{name}</a> successfully.')
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(UserCreateView, self).get_context_data(**kwargs)
|
||||
context = super().get_context_data(**kwargs)
|
||||
context.update({'app': _('Users'), 'action': _('Create user')})
|
||||
return context
|
||||
|
||||
|
@ -76,7 +76,7 @@ class UserCreateView(AdminUserRequiredMixin, SuccessMessageMixin, CreateView):
|
|||
user.created_by = self.request.user.username or 'System'
|
||||
user.save()
|
||||
on_user_created.send(self.__class__, user=user)
|
||||
return super(UserCreateView, self).form_valid(form)
|
||||
return super().form_valid(form)
|
||||
|
||||
def get_success_message(self, cleaned_data):
|
||||
url = reverse_lazy('users:user-detail', kwargs={'pk': self.object.pk})
|
||||
|
@ -92,31 +92,34 @@ class UserUpdateView(AdminUserRequiredMixin, UpdateView):
|
|||
context_object_name = 'user_object'
|
||||
success_url = reverse_lazy('users:user-list')
|
||||
|
||||
def form_valid(self, form):
|
||||
username = self.object.username
|
||||
user = form.save(commit=False)
|
||||
user.username = username
|
||||
user.save()
|
||||
password = self.request.POST.get('password', '')
|
||||
if password:
|
||||
user.set_password(password)
|
||||
return super(UserUpdateView, self).form_valid(form)
|
||||
# def form_valid(self, form):
|
||||
# username = self.object.username
|
||||
# user = form.save(commit=False)
|
||||
# user.username = username
|
||||
# user.save()
|
||||
# password = self.request.POST.get('password', '')
|
||||
# if password:
|
||||
# user.set_password(password)
|
||||
# return super().form_valid(form)
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(UserUpdateView, self).get_context_data(**kwargs)
|
||||
context.update({'app': _('Users'), 'action': _('Update user')})
|
||||
return context
|
||||
context = {'app': _('Users'), 'action': _('Update user')}
|
||||
kwargs.update(context)
|
||||
return super().get_context_data(**kwargs)
|
||||
|
||||
|
||||
class UserBulkUpdateView(AdminUserRequiredMixin, ListView):
|
||||
class UserBulkUpdateView(AdminUserRequiredMixin, TemplateView):
|
||||
model = User
|
||||
form_class = forms.UserBulkUpdateForm
|
||||
template_name = 'users/user_bulk_update.html'
|
||||
success_url = reverse_lazy('users:user-list')
|
||||
success_message = _("Bulk update user success")
|
||||
form = None
|
||||
id_list = None
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
users_id = self.request.GET.get('users_id', '')
|
||||
self.id_list = [int(i) for i in users_id.split(',') if i.isdigit()]
|
||||
self.id_list = [i for i in users_id.split(',')]
|
||||
|
||||
if kwargs.get('form'):
|
||||
self.form = kwargs['form']
|
||||
|
@ -126,12 +129,13 @@ class UserBulkUpdateView(AdminUserRequiredMixin, ListView):
|
|||
)
|
||||
else:
|
||||
self.form = self.form_class()
|
||||
return super(UserBulkUpdateView, self).get(request, *args, **kwargs)
|
||||
return super().get(request, *args, **kwargs)
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
form = self.form_class(request.POST)
|
||||
if form.is_valid():
|
||||
form.save()
|
||||
messages.success(request, self.success_message)
|
||||
return redirect(self.success_url)
|
||||
else:
|
||||
return self.get(request, form=form, *args, **kwargs)
|
||||
|
@ -145,7 +149,7 @@ class UserBulkUpdateView(AdminUserRequiredMixin, ListView):
|
|||
'users': User.objects.all(),
|
||||
}
|
||||
kwargs.update(context)
|
||||
return super(UserBulkUpdateView, self).get_context_data(**kwargs)
|
||||
return super().get_context_data(**kwargs)
|
||||
|
||||
|
||||
class UserDetailView(AdminUserRequiredMixin, DetailView):
|
||||
|
@ -161,19 +165,7 @@ class UserDetailView(AdminUserRequiredMixin, DetailView):
|
|||
'groups': groups
|
||||
}
|
||||
kwargs.update(context)
|
||||
return super(UserDetailView, self).get_context_data(**kwargs)
|
||||
|
||||
|
||||
# USER_ATTR_MAPPING = (
|
||||
# ('name', 'Name'),
|
||||
# ('username', 'Username'),
|
||||
# ('email', 'Email'),
|
||||
# ('groups', 'User groups'),
|
||||
# ('role', 'Role'),
|
||||
# ('phone', 'Phone'),
|
||||
# ('wechat', 'Wechat'),
|
||||
# ('comment', 'Comment'),
|
||||
# )
|
||||
return super().get_context_data(**kwargs)
|
||||
|
||||
|
||||
@method_decorator(csrf_exempt, name='dispatch')
|
||||
|
@ -182,14 +174,15 @@ class UserExportView(View):
|
|||
fields = [
|
||||
User._meta.get_field(name)
|
||||
for name in [
|
||||
'id', 'name', 'username', 'email', 'role', 'wechat', 'phone',
|
||||
'enable_otp', 'is_active', 'comment',
|
||||
'id', 'name', 'username', 'email', 'role',
|
||||
'wechat', 'phone', 'is_active', 'comment',
|
||||
]
|
||||
]
|
||||
spm = request.GET.get('spm', '')
|
||||
users_id = cache.get(spm, ['1'])
|
||||
users_id = cache.get(spm, [])
|
||||
filename = 'users-{}.csv'.format(
|
||||
timezone.localtime(timezone.now()).strftime('%Y-%m-%d_%H-%M-%S'))
|
||||
timezone.localtime(timezone.now()).strftime('%Y-%m-%d_%H-%M-%S')
|
||||
)
|
||||
response = HttpResponse(content_type='text/csv')
|
||||
response['Content-Disposition'] = 'attachment; filename="%s"' % filename
|
||||
response.write(codecs.BOM_UTF8)
|
||||
|
@ -233,6 +226,7 @@ class UserBulkImportView(AdminUserRequiredMixin, JSONResponseMixin, FormView):
|
|||
}
|
||||
return self.render_json_response(data)
|
||||
|
||||
# todo: need be patch, method to long
|
||||
def form_valid(self, form):
|
||||
file = form.cleaned_data['file']
|
||||
data = file.read().decode('utf-8').strip(codecs.BOM_UTF8.decode('utf-8'))
|
||||
|
@ -243,8 +237,8 @@ class UserBulkImportView(AdminUserRequiredMixin, JSONResponseMixin, FormView):
|
|||
fields = [
|
||||
User._meta.get_field(name)
|
||||
for name in [
|
||||
'id', 'name', 'username', 'email', 'role', 'wechat', 'phone',
|
||||
'enable_otp', 'is_active', 'comment',
|
||||
'id', 'name', 'username', 'email', 'role',
|
||||
'wechat', 'phone', 'is_active', 'comment',
|
||||
]
|
||||
]
|
||||
mapping_reverse = {field.verbose_name: field.name for field in fields}
|
||||
|
@ -261,10 +255,11 @@ class UserBulkImportView(AdminUserRequiredMixin, JSONResponseMixin, FormView):
|
|||
if set(row) == {''}:
|
||||
continue
|
||||
user_dict = dict(zip(attr, row))
|
||||
print(user_dict)
|
||||
id_ = user_dict.pop('id', 0)
|
||||
user = get_object_or_none(User, id=id_)
|
||||
for k, v in user_dict.items():
|
||||
if k in ['enable_otp', 'is_active']:
|
||||
if k in ['is_active']:
|
||||
if v.lower() == 'false':
|
||||
v = False
|
||||
else:
|
||||
|
@ -312,63 +307,14 @@ class UserBulkImportView(AdminUserRequiredMixin, JSONResponseMixin, FormView):
|
|||
return self.render_json_response(data)
|
||||
|
||||
|
||||
class UserAssetPermissionView(AdminUserRequiredMixin, FormMixin,
|
||||
SingleObjectMixin, ListView):
|
||||
model = User
|
||||
template_name = 'users/user_asset_permission.html'
|
||||
context_object_name = 'user'
|
||||
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_context_data(self, **kwargs):
|
||||
context = {
|
||||
'app': 'Users',
|
||||
'action': 'User asset permissions',
|
||||
}
|
||||
kwargs.update(context)
|
||||
return super(UserAssetPermissionView, self).get_context_data(**kwargs)
|
||||
|
||||
|
||||
class UserAssetPermissionCreateView(AdminUserRequiredMixin, CreateView):
|
||||
form_class = forms.UserPrivateAssetPermissionForm
|
||||
model = AssetPermission
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
user = self.get_object(queryset=User.objects.all())
|
||||
return redirect(reverse('users:user-asset-permission',
|
||||
kwargs={'pk': user.id}))
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
self.user = self.get_object(queryset=User.objects.all())
|
||||
return super(UserAssetPermissionCreateView, self)\
|
||||
.post(request, *args, **kwargs)
|
||||
|
||||
def get_form(self, form_class=None):
|
||||
form = super(UserAssetPermissionCreateView, self)\
|
||||
.get_form(form_class=form_class)
|
||||
form.user = self.user
|
||||
return form
|
||||
|
||||
def form_invalid(self, form):
|
||||
return redirect(reverse('users:user-asset-permission',
|
||||
kwargs={'pk': self.user.id}))
|
||||
|
||||
def get_success_url(self):
|
||||
return reverse('users:user-asset-permission',
|
||||
kwargs={'pk': self.user.id})
|
||||
|
||||
|
||||
class UserGrantedAssetView(AdminUserRequiredMixin, DetailView):
|
||||
model = User
|
||||
template_name = 'users/user_granted_asset.html'
|
||||
context_object_name = 'user'
|
||||
object = None
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
self.object = self.get_object(queryset=User.objects.all())
|
||||
return super(UserGrantedAssetView, self).get(request, *args, **kwargs)
|
||||
return super().get(request, *args, **kwargs)
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = {
|
||||
|
@ -376,7 +322,7 @@ class UserGrantedAssetView(AdminUserRequiredMixin, DetailView):
|
|||
'action': 'User granted asset',
|
||||
}
|
||||
kwargs.update(context)
|
||||
return super(UserGrantedAssetView, self).get_context_data(**kwargs)
|
||||
return super().get_context_data(**kwargs)
|
||||
|
||||
|
||||
class UserProfileView(LoginRequiredMixin, TemplateView):
|
||||
|
@ -391,7 +337,7 @@ class UserProfileView(LoginRequiredMixin, TemplateView):
|
|||
'assets': assets,
|
||||
}
|
||||
kwargs.update(context)
|
||||
return super(UserProfileView, self).get_context_data(**kwargs)
|
||||
return super().get_context_data(**kwargs)
|
||||
|
||||
|
||||
class UserProfileUpdateView(LoginRequiredMixin, UpdateView):
|
||||
|
@ -416,7 +362,7 @@ class UserProfileUpdateView(LoginRequiredMixin, UpdateView):
|
|||
'action': 'Profile update',
|
||||
}
|
||||
kwargs.update(context)
|
||||
return super(UserProfileUpdateView, self).get_context_data(**kwargs)
|
||||
return super().get_context_data(**kwargs)
|
||||
|
||||
|
||||
class UserPasswordUpdateView(LoginRequiredMixin, UpdateView):
|
||||
|
@ -434,11 +380,11 @@ class UserPasswordUpdateView(LoginRequiredMixin, UpdateView):
|
|||
'action': 'Password update',
|
||||
}
|
||||
kwargs.update(context)
|
||||
return super(UserPasswordUpdateView, self).get_context_data(**kwargs)
|
||||
return super().get_context_data(**kwargs)
|
||||
|
||||
def get_success_url(self):
|
||||
auth_logout(self.request)
|
||||
return super(UserPasswordUpdateView, self).get_success_url()
|
||||
return super().get_success_url()
|
||||
|
||||
|
||||
class UserPublicKeyUpdateView(LoginRequiredMixin, UpdateView):
|
||||
|
@ -456,4 +402,4 @@ class UserPublicKeyUpdateView(LoginRequiredMixin, UpdateView):
|
|||
'action': 'Public key update',
|
||||
}
|
||||
kwargs.update(context)
|
||||
return super(UserPublicKeyUpdateView, self).get_context_data(**kwargs)
|
||||
return super().get_context_data(**kwargs)
|
||||
|
|
Loading…
Reference in New Issue