Commit de2416b1 authored by BaiJiangJie's avatar BaiJiangJie

Merge branch 'dev' of github.com:jumpserver/jumpserver into github_dev

parents 486793dd c529061e
...@@ -40,7 +40,7 @@ class SystemUserViewSet(BulkModelViewSet): ...@@ -40,7 +40,7 @@ class SystemUserViewSet(BulkModelViewSet):
permission_classes = (IsSuperUserOrAppUser,) permission_classes = (IsSuperUserOrAppUser,)
class SystemUserAuthInfoApi(generics.RetrieveUpdateAPIView): class SystemUserAuthInfoApi(generics.RetrieveUpdateDestroyAPIView):
""" """
Get system user auth info Get system user auth info
""" """
...@@ -48,6 +48,11 @@ class SystemUserAuthInfoApi(generics.RetrieveUpdateAPIView): ...@@ -48,6 +48,11 @@ class SystemUserAuthInfoApi(generics.RetrieveUpdateAPIView):
permission_classes = (IsSuperUserOrAppUser,) permission_classes = (IsSuperUserOrAppUser,)
serializer_class = serializers.SystemUserAuthSerializer serializer_class = serializers.SystemUserAuthSerializer
def destroy(self, request, *args, **kwargs):
instance = self.get_object()
instance.clear_auth()
return Response(status=204)
class SystemUserPushApi(generics.RetrieveAPIView): class SystemUserPushApi(generics.RetrieveAPIView):
""" """
......
...@@ -107,6 +107,7 @@ class AssetUser(models.Model): ...@@ -107,6 +107,7 @@ class AssetUser(models.Model):
def clear_auth(self): def clear_auth(self):
self._password = '' self._password = ''
self._private_key = '' self._private_key = ''
self._public_key = ''
self.save() self.save()
def auto_gen_auth(self): def auto_gen_auth(self):
......
...@@ -61,10 +61,14 @@ class Node(models.Model): ...@@ -61,10 +61,14 @@ class Node(models.Model):
return child return child
def get_children(self): def get_children(self):
return self.__class__.objects.filter(key__regex=r'^{}:[0-9]+$'.format(self.key)) return self.__class__.objects.filter(
key__regex=r'^{}:[0-9]+$'.format(self.key)
)
def get_all_children(self): def get_all_children(self):
return self.__class__.objects.filter(key__startswith='{}:'.format(self.key)) return self.__class__.objects.filter(
key__startswith='{}:'.format(self.key)
)
def get_family(self): def get_family(self):
children = list(self.get_all_children()) children = list(self.get_all_children())
......
...@@ -107,14 +107,14 @@ ...@@ -107,14 +107,14 @@
</div> </div>
<div class="col-sm-4" style="padding-left: 0;padding-right: 0"> <div class="col-sm-4" style="padding-left: 0;padding-right: 0">
<div class="panel panel-primary only-ssh"> <div class="panel panel-primary ">
<div class="panel-heading"> <div class="panel-heading">
<i class="fa fa-info-circle"></i> {% trans 'Quick update' %} <i class="fa fa-info-circle"></i> {% trans 'Quick update' %}
</div> </div>
<div class="panel-body"> <div class="panel-body">
<table class="table"> <table class="table">
<tbody> <tbody>
<tr class="no-borders-tr"> <tr class="only-ssh">
<td width="50%">{% trans 'Auto push' %}:</td> <td width="50%">{% trans 'Auto push' %}:</td>
<td> <td>
<span class="pull-right"> <span class="pull-right">
...@@ -130,8 +130,8 @@ ...@@ -130,8 +130,8 @@
</span> </span>
</td> </td>
</tr> </tr>
<tr class="no-borders-tr">
{% if system_user.auto_push %} {% if system_user.auto_push %}
<tr class="only-ssh">
<td width="50%">{% trans 'Push system user now' %}:</td> <td width="50%">{% trans 'Push system user now' %}:</td>
<td> <td>
<span style="float: right"> <span style="float: right">
...@@ -139,8 +139,8 @@ ...@@ -139,8 +139,8 @@
</span> </span>
</td> </td>
</tr> </tr>
<tr>
{% endif %} {% endif %}
<tr class="only-ssh">
<td width="50%">{% trans 'Test assets connective' %}:</td> <td width="50%">{% trans 'Test assets connective' %}:</td>
<td> <td>
<span style="float: right"> <span style="float: right">
...@@ -149,6 +149,15 @@ ...@@ -149,6 +149,15 @@
</td> </td>
</tr> </tr>
<tr>
<td width="50%">{% trans 'Clear auth' %}:</td>
<td>
<span style="float: right">
<button type="button" class="btn btn-primary btn-xs btn-clear-auth" style="width: 54px">{% trans 'Clear' %}</button>
</span>
</td>
</tr>
{# <tr>#} {# <tr>#}
{# <td width="50%">{% trans 'Change auth period' %}:</td>#} {# <td width="50%">{% trans 'Change auth period' %}:</td>#}
{# <td>#} {# <td>#}
...@@ -239,6 +248,7 @@ $(document).ready(function () { ...@@ -239,6 +248,7 @@ $(document).ready(function () {
if($('#id_protocol_type').text() === 'rdp'){ if($('#id_protocol_type').text() === 'rdp'){
$('.only-ssh').addClass('hidden') $('.only-ssh').addClass('hidden')
} }
$(".panel-body .table tr:visible:first").addClass('no-borders-tr');
$('.select2').select2() $('.select2').select2()
.on('select2:select', function(evt) { .on('select2:select', function(evt) {
var data = evt.params.data; var data = evt.params.data;
...@@ -321,6 +331,13 @@ $(document).ready(function () { ...@@ -321,6 +331,13 @@ $(document).ready(function () {
success: success, success: success,
flash_message: false flash_message: false
}); });
}).on('click', '.btn-clear-auth', function () {
var the_url = '{% url "api-assets:system-user-auth-info" pk=system_user.id %}';
APIUpdateAttr({
url: the_url,
method: 'DELETE',
success_message: "{% trans 'Clear auth' %}" + " {% trans 'success' %}"
});
}) })
</script> </script>
{% endblock %} {% endblock %}
...@@ -8,7 +8,7 @@ msgid "" ...@@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Jumpserver 0.3.3\n" "Project-Id-Version: Jumpserver 0.3.3\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-05-08 17:24+0800\n" "POT-Creation-Date: 2018-05-17 11:32+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: ibuler <ibuler@qq.com>\n" "Last-Translator: ibuler <ibuler@qq.com>\n"
"Language-Team: Jumpserver team<ibuler@qq.com>\n" "Language-Team: Jumpserver team<ibuler@qq.com>\n"
...@@ -17,22 +17,22 @@ msgstr "" ...@@ -17,22 +17,22 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
#: assets/api/node.py:96 #: assets/api/node.py:106
msgid "New node {}" msgid "New node {}"
msgstr "新节点 {}" msgstr "新节点 {}"
#: assets/api/node.py:225 #: assets/api/node.py:242
msgid "更新节点资产硬件信息: {}" msgid "更新节点资产硬件信息: {}"
msgstr "" msgstr ""
#: assets/api/node.py:238 #: assets/api/node.py:255
msgid "测试节点下资产是否可连接: {}" msgid "测试节点下资产是否可连接: {}"
msgstr "" msgstr ""
#: assets/forms/asset.py:24 assets/models/asset.py:66 assets/models/user.py:103 #: assets/forms/asset.py:24 assets/models/asset.py:66 assets/models/user.py:103
#: assets/templates/assets/asset_detail.html:183 #: assets/templates/assets/asset_detail.html:183
#: assets/templates/assets/asset_detail.html:191 #: assets/templates/assets/asset_detail.html:191
#: assets/templates/assets/system_user_detail.html:166 perms/models.py:33 #: assets/templates/assets/system_user_detail.html:175 perms/models.py:33
msgid "Nodes" msgid "Nodes"
msgstr "节点管理" msgstr "节点管理"
...@@ -438,7 +438,7 @@ msgstr "默认资产组" ...@@ -438,7 +438,7 @@ msgstr "默认资产组"
msgid "User" msgid "User"
msgstr "用户" msgstr "用户"
#: assets/models/label.py:18 assets/models/node.py:15 #: assets/models/label.py:18 assets/models/node.py:18
#: assets/templates/assets/label_list.html:15 common/models.py:27 #: assets/templates/assets/label_list.html:15 common/models.py:27
msgid "Value" msgid "Value"
msgstr "值" msgstr "值"
...@@ -535,7 +535,7 @@ msgstr "测试系统用户可连接性: {}" ...@@ -535,7 +535,7 @@ msgstr "测试系统用户可连接性: {}"
msgid "定期测试系统用户可连接性: {}" msgid "定期测试系统用户可连接性: {}"
msgstr "" msgstr ""
#: assets/tasks.py:401 #: assets/tasks.py:402
msgid "推送系统用户到入资产: {}" msgid "推送系统用户到入资产: {}"
msgstr "" msgstr ""
...@@ -660,7 +660,7 @@ msgstr "重置" ...@@ -660,7 +660,7 @@ msgstr "重置"
#: common/templates/common/ldap_setting.html:60 #: common/templates/common/ldap_setting.html:60
#: common/templates/common/terminal_setting.html:103 #: common/templates/common/terminal_setting.html:103
#: perms/templates/perms/asset_permission_create_update.html:70 #: perms/templates/perms/asset_permission_create_update.html:70
#: terminal/templates/terminal/session_list.html:120 #: terminal/templates/terminal/session_list.html:124
#: terminal/templates/terminal/terminal_update.html:48 #: terminal/templates/terminal/terminal_update.html:48
#: users/templates/users/_user.html:47 #: users/templates/users/_user.html:47
#: users/templates/users/forgot_password.html:44 #: users/templates/users/forgot_password.html:44
...@@ -782,8 +782,8 @@ msgstr "选择节点" ...@@ -782,8 +782,8 @@ msgstr "选择节点"
#: assets/templates/assets/admin_user_detail.html:100 #: assets/templates/assets/admin_user_detail.html:100
#: assets/templates/assets/asset_detail.html:200 #: assets/templates/assets/asset_detail.html:200
#: assets/templates/assets/asset_list.html:634 #: assets/templates/assets/asset_list.html:636
#: assets/templates/assets/system_user_detail.html:183 #: assets/templates/assets/system_user_detail.html:192
#: assets/templates/assets/system_user_list.html:138 templates/_modal.html:22 #: assets/templates/assets/system_user_list.html:138 templates/_modal.html:22
#: terminal/templates/terminal/session_detail.html:108 #: terminal/templates/terminal/session_detail.html:108
#: users/templates/users/user_detail.html:362 #: users/templates/users/user_detail.html:362
...@@ -963,19 +963,19 @@ msgstr "仅显示当前节点资产" ...@@ -963,19 +963,19 @@ msgstr "仅显示当前节点资产"
msgid "Displays all child node assets" msgid "Displays all child node assets"
msgstr "显示所有子节点资产" msgstr "显示所有子节点资产"
#: assets/templates/assets/asset_list.html:215 #: assets/templates/assets/asset_list.html:217
msgid "Create node failed" msgid "Create node failed"
msgstr "创建节点失败" msgstr "创建节点失败"
#: assets/templates/assets/asset_list.html:227 #: assets/templates/assets/asset_list.html:229
msgid "Have child node, cancel" msgid "Have child node, cancel"
msgstr "存在子节点,不能删除" msgstr "存在子节点,不能删除"
#: assets/templates/assets/asset_list.html:229 #: assets/templates/assets/asset_list.html:231
msgid "Have assets, cancel" msgid "Have assets, cancel"
msgstr "存在资产,不能删除" msgstr "存在资产,不能删除"
#: assets/templates/assets/asset_list.html:629 #: assets/templates/assets/asset_list.html:631
#: assets/templates/assets/system_user_list.html:133 #: assets/templates/assets/system_user_list.html:133
#: users/templates/users/user_detail.html:357 #: users/templates/users/user_detail.html:357
#: users/templates/users/user_detail.html:382 #: users/templates/users/user_detail.html:382
...@@ -984,20 +984,20 @@ msgstr "存在资产,不能删除" ...@@ -984,20 +984,20 @@ msgstr "存在资产,不能删除"
msgid "Are you sure?" msgid "Are you sure?"
msgstr "你确认吗?" msgstr "你确认吗?"
#: assets/templates/assets/asset_list.html:630 #: assets/templates/assets/asset_list.html:632
msgid "This will delete the selected assets !!!" msgid "This will delete the selected assets !!!"
msgstr "删除选择资产" msgstr "删除选择资产"
#: assets/templates/assets/asset_list.html:638 #: assets/templates/assets/asset_list.html:640
msgid "Asset Deleted." msgid "Asset Deleted."
msgstr "已被删除" msgstr "已被删除"
#: assets/templates/assets/asset_list.html:639 #: assets/templates/assets/asset_list.html:641
#: assets/templates/assets/asset_list.html:644 #: assets/templates/assets/asset_list.html:646
msgid "Asset Delete" msgid "Asset Delete"
msgstr "删除" msgstr "删除"
#: assets/templates/assets/asset_list.html:643 #: assets/templates/assets/asset_list.html:645
msgid "Asset Deleting failed." msgid "Asset Deleting failed."
msgstr "删除失败" msgstr "删除失败"
...@@ -1032,6 +1032,7 @@ msgid "Create gateway" ...@@ -1032,6 +1032,7 @@ msgid "Create gateway"
msgstr "创建网关" msgstr "创建网关"
#: assets/templates/assets/domain_gateway_list.html:87 #: assets/templates/assets/domain_gateway_list.html:87
#: assets/templates/assets/domain_gateway_list.html:89
#: common/templates/common/email_setting.html:58 #: common/templates/common/email_setting.html:58
#: common/templates/common/ldap_setting.html:58 #: common/templates/common/ldap_setting.html:58
msgid "Test connection" msgid "Test connection"
...@@ -1080,10 +1081,23 @@ msgstr "家目录" ...@@ -1080,10 +1081,23 @@ msgstr "家目录"
msgid "Uid" msgid "Uid"
msgstr "Uid" msgstr "Uid"
#: assets/templates/assets/system_user_detail.html:174 #: assets/templates/assets/system_user_detail.html:153
#: assets/templates/assets/system_user_detail.html:339
msgid "Clear auth"
msgstr "清除认证信息"
#: assets/templates/assets/system_user_detail.html:156
msgid "Clear"
msgstr "清除"
#: assets/templates/assets/system_user_detail.html:183
msgid "Add to node" msgid "Add to node"
msgstr "添加到节点" msgstr "添加到节点"
#: assets/templates/assets/system_user_detail.html:339
msgid "success"
msgstr "成功"
#: assets/templates/assets/system_user_list.html:18 #: assets/templates/assets/system_user_list.html:18
#: assets/views/system_user.py:45 #: assets/views/system_user.py:45
msgid "Create system user" msgid "Create system user"
...@@ -2113,15 +2127,16 @@ msgstr "时长" ...@@ -2113,15 +2127,16 @@ msgstr "时长"
msgid "Monitor" msgid "Monitor"
msgstr "监控" msgstr "监控"
#: terminal/templates/terminal/session_list.html:105 #: terminal/templates/terminal/session_list.html:106
#: terminal/templates/terminal/session_list.html:108
msgid "Terminate" msgid "Terminate"
msgstr "终断" msgstr "终断"
#: terminal/templates/terminal/session_list.html:116 #: terminal/templates/terminal/session_list.html:120
msgid "Terminate selected" msgid "Terminate selected"
msgstr "终断所选" msgstr "终断所选"
#: terminal/templates/terminal/session_list.html:136 #: terminal/templates/terminal/session_list.html:140
msgid "Terminate task send, waiting ..." msgid "Terminate task send, waiting ..."
msgstr "终断任务已发送,请等待" msgstr "终断任务已发送,请等待"
......
...@@ -6,7 +6,7 @@ from rest_framework.views import APIView, Response ...@@ -6,7 +6,7 @@ from rest_framework.views import APIView, Response
from rest_framework.generics import ListAPIView, get_object_or_404, RetrieveUpdateAPIView from rest_framework.generics import ListAPIView, get_object_or_404, RetrieveUpdateAPIView
from rest_framework import viewsets from rest_framework import viewsets
from common.utils import set_or_append_attr_bulk from common.utils import set_or_append_attr_bulk, get_object_or_none
from users.permissions import IsValidUser, IsSuperUser, IsSuperUserOrAppUser from users.permissions import IsValidUser, IsSuperUser, IsSuperUserOrAppUser
from .utils import AssetPermissionUtil from .utils import AssetPermissionUtil
from .models import AssetPermission from .models import AssetPermission
...@@ -147,8 +147,13 @@ class UserGrantedNodeAssetsApi(ListAPIView): ...@@ -147,8 +147,13 @@ class UserGrantedNodeAssetsApi(ListAPIView):
user = get_object_or_404(User, id=user_id) user = get_object_or_404(User, id=user_id)
else: else:
user = self.request.user user = self.request.user
node = get_object_or_404(Node, id=node_id)
nodes = AssetPermissionUtil.get_user_nodes_with_assets(user) nodes = AssetPermissionUtil.get_user_nodes_with_assets(user)
node = get_object_or_none(Node, id=node_id)
if not node:
unnode = [node for node in nodes if node.name == 'Unnode']
node = unnode[0] if unnode else None
assets = nodes.get(node, []) assets = nodes.get(node, [])
for asset, system_users in assets.items(): for asset, system_users in assets.items():
asset.system_users_granted = system_users asset.system_users_granted = system_users
......
...@@ -13,7 +13,6 @@ logger = get_logger(__file__) ...@@ -13,7 +13,6 @@ logger = get_logger(__file__)
class AssetPermissionUtil: class AssetPermissionUtil:
@staticmethod @staticmethod
def get_user_permissions(user): def get_user_permissions(user):
return AssetPermission.objects.all().valid().filter(users=user) return AssetPermission.objects.all().valid().filter(users=user)
...@@ -122,6 +121,24 @@ class AssetPermissionUtil: ...@@ -122,6 +121,24 @@ class AssetPermissionUtil:
nodes[node].update(set(_system_users)) nodes[node].update(set(_system_users))
return nodes return nodes
@classmethod
def get_user_nodes_inherit_group(cls, user):
nodes = defaultdict(set)
groups = user.groups.all()
for group in groups:
_nodes = cls.get_user_group_nodes(group)
for node, system_users in _nodes.items():
nodes[node].update(set(system_users))
return nodes
@classmethod
def get_user_nodes(cls, user):
nodes = cls.get_user_nodes_direct(user)
nodes_inherit = cls.get_user_nodes_inherit_group(user)
for node, system_users in nodes_inherit.items():
nodes[node].update(set(system_users))
return nodes
@classmethod @classmethod
def get_user_nodes_assets_direct(cls, user): def get_user_nodes_assets_direct(cls, user):
assets = defaultdict(set) assets = defaultdict(set)
...@@ -164,15 +181,24 @@ class AssetPermissionUtil: ...@@ -164,15 +181,24 @@ class AssetPermissionUtil:
:param user: :param user:
:return: {node: {asset: set(su1, su2)}} :return: {node: {asset: set(su1, su2)}}
""" """
from assets.models import Node
unnode = Node(value='Unnode')
nodes = defaultdict(dict) nodes = defaultdict(dict)
for _node in cls.get_user_nodes(user):
children = _node.get_family()
for node in children:
nodes[node] = defaultdict(set)
nodes[unnode] = defaultdict(set)
_assets = cls.get_user_assets(user) _assets = cls.get_user_assets(user)
for asset, _system_users in _assets.items(): for asset, _system_users in _assets.items():
_nodes = asset.get_nodes() _nodes = asset.get_nodes()
in_node = False
for node in _nodes: for node in _nodes:
if asset in nodes[node]: if node in nodes:
in_node = True
nodes[node][asset].update(_system_users) nodes[node][asset].update(_system_users)
else: if not in_node:
nodes[node][asset] = _system_users nodes[unnode][asset].update(_system_users)
return nodes return nodes
@classmethod @classmethod
......
...@@ -9,6 +9,7 @@ from django.core.cache import cache ...@@ -9,6 +9,7 @@ from django.core.cache import cache
from django.shortcuts import get_object_or_404, redirect from django.shortcuts import get_object_or_404, redirect
from django.utils import timezone from django.utils import timezone
from django.core.files.storage import default_storage from django.core.files.storage import default_storage
from django.http.response import HttpResponseRedirectBase
from django.http import HttpResponseNotFound from django.http import HttpResponseNotFound
from django.conf import settings from django.conf import settings
...@@ -25,7 +26,7 @@ from .serializers import TerminalSerializer, StatusSerializer, \ ...@@ -25,7 +26,7 @@ from .serializers import TerminalSerializer, StatusSerializer, \
SessionSerializer, TaskSerializer, ReplaySerializer SessionSerializer, TaskSerializer, ReplaySerializer
from .hands import IsSuperUserOrAppUser, IsAppUser, \ from .hands import IsSuperUserOrAppUser, IsAppUser, \
IsSuperUserOrAppUserOrUserReadonly IsSuperUserOrAppUserOrUserReadonly
from .backends import get_command_store, get_multi_command_store, \ from .backends import get_command_storage, get_multi_command_storage, \
SessionCommandSerializer SessionCommandSerializer
logger = logging.getLogger(__file__) logger = logging.getLogger(__file__)
...@@ -227,8 +228,8 @@ class CommandViewSet(viewsets.ViewSet): ...@@ -227,8 +228,8 @@ class CommandViewSet(viewsets.ViewSet):
} }
""" """
command_store = get_command_store() command_store = get_command_storage()
multi_command_storage = get_multi_command_store() multi_command_storage = get_multi_command_storage()
serializer_class = SessionCommandSerializer serializer_class = SessionCommandSerializer
permission_classes = (IsSuperUserOrAppUser,) permission_classes = (IsSuperUserOrAppUser,)
...@@ -291,19 +292,20 @@ class SessionReplayViewSet(viewsets.ViewSet): ...@@ -291,19 +292,20 @@ class SessionReplayViewSet(viewsets.ViewSet):
url = default_storage.url(path) url = default_storage.url(path)
return redirect(url) return redirect(url)
else: else:
configs = settings.TERMINAL_REPLAY_STORAGE.items() configs = settings.TERMINAL_REPLAY_STORAGE
configs = [cfg for cfg in configs if cfg['TYPE'] != 'server']
if not configs: if not configs:
return HttpResponseNotFound() return HttpResponseNotFound()
for name, config in configs: date = self.session.date_start.strftime('%Y-%m-%d')
client = jms_storage.init(config) file_path = os.path.join(date, str(self.session.id) + '.replay.gz')
date = self.session.date_start.strftime('%Y-%m-%d') target_path = default_storage.base_location + '/' + path
file_path = os.path.join(date, str(self.session.id) + '.replay.gz') storage = jms_storage.get_multi_object_storage(configs)
target_path = default_storage.base_location + '/' + path ok, err = storage.download(file_path, target_path)
if ok:
if client and client.has_file(file_path) and \ return redirect(default_storage.url(path))
client.download_file(file_path, target_path): else:
return redirect(default_storage.url(path)) logger.error("Failed download replay file: {}".format(err))
return HttpResponseNotFound() return HttpResponseNotFound()
...@@ -313,34 +315,14 @@ class SessionReplayV2ViewSet(SessionReplayViewSet): ...@@ -313,34 +315,14 @@ class SessionReplayV2ViewSet(SessionReplayViewSet):
session = None session = None
def retrieve(self, request, *args, **kwargs): def retrieve(self, request, *args, **kwargs):
session_id = kwargs.get('pk') response = super().retrieve(request, *args, **kwargs)
self.session = get_object_or_404(Session, id=session_id)
path = self.gen_session_path()
data = { data = {
'type': 'guacamole' if self.session.protocol == 'rdp' else 'json', 'type': 'guacamole' if self.session.protocol == 'rdp' else 'json',
'src': '', 'src': '',
} }
if isinstance(response, HttpResponseRedirectBase):
if default_storage.exists(path): data['src'] = response.url
url = default_storage.url(path)
data['src'] = url
return Response(data) return Response(data)
else:
configs = settings.TERMINAL_REPLAY_STORAGE.items()
if not configs:
return HttpResponseNotFound()
for name, config in configs:
client = jms_storage.init(config)
date = self.session.date_start.strftime('%Y-%m-%d')
file_path = os.path.join(date, str(self.session.id) + '.replay.gz')
target_path = default_storage.base_location + '/' + path
if client and client.has_file(file_path) and \
client.download_file(file_path, target_path):
url = default_storage.url(path)
data['src'] = url
return Response(data)
return HttpResponseNotFound() return HttpResponseNotFound()
......
...@@ -7,19 +7,19 @@ TYPE_ENGINE_MAPPING = { ...@@ -7,19 +7,19 @@ TYPE_ENGINE_MAPPING = {
} }
def get_command_store(): def get_command_storage():
params = settings.COMMAND_STORAGE config = settings.COMMAND_STORAGE
engine_class = import_module(params['ENGINE']) engine_class = import_module(config['ENGINE'])
storage = engine_class.CommandStore(params) storage = engine_class.CommandStore(config)
return storage return storage
def get_terminal_command_store(): def get_terminal_command_storages():
storage_list = {} storage_list = {}
for name, params in settings.TERMINAL_COMMAND_STORAGE.items(): for name, params in settings.TERMINAL_COMMAND_STORAGE.items():
tp = params['TYPE'] tp = params['TYPE']
if tp == 'server': if tp == 'server':
storage = get_command_store() storage = get_command_storage()
else: else:
if not TYPE_ENGINE_MAPPING.get(tp): if not TYPE_ENGINE_MAPPING.get(tp):
continue continue
...@@ -29,9 +29,9 @@ def get_terminal_command_store(): ...@@ -29,9 +29,9 @@ def get_terminal_command_store():
return storage_list return storage_list
def get_multi_command_store(): def get_multi_command_storage():
from .command.multi import CommandStore from .command.multi import CommandStore
storage_list = get_terminal_command_store().values() storage_list = get_terminal_command_storages().values()
storage = CommandStore(storage_list) storage = CommandStore(storage_list)
return storage return storage
......
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# #
from jms_es_sdk import ESStore from jms_storage.es import ESStorage
from .base import CommandBase from .base import CommandBase
from .models import AbstractSessionCommand from .models import AbstractSessionCommand
class CommandStore(CommandBase, ESStore): class CommandStore(ESStorage, CommandBase):
def __init__(self, params): def __init__(self, params):
hosts = params.get('HOSTS', ['http://localhost']) super().__init__(params)
ESStore.__init__(self, hosts=hosts)
def save(self, command):
return ESStore.save(self, command)
def bulk_save(self, commands):
return ESStore.bulk_save(self, commands)
def filter(self, date_from=None, date_to=None, def filter(self, date_from=None, date_to=None,
user=None, asset=None, system_user=None, user=None, asset=None, system_user=None,
input=None, session=None): input=None, session=None):
data = ESStore.filter( data = super().filter(date_from=date_from, date_to=date_to,
self, date_from=date_from, date_to=date_to, user=user, asset=asset, system_user=system_user,
user=user, asset=asset, system_user=system_user, input=input, session=session)
input=input, session=session
)
return AbstractSessionCommand.from_multi_dict( return AbstractSessionCommand.from_multi_dict(
[item["_source"] for item in data["hits"] if item] [item["_source"] for item in data["hits"] if item]
) )
def count(self, date_from=None, date_to=None,
user=None, asset=None, system_user=None,
input=None, session=None):
amount = ESStore.count(
self, date_from=date_from, date_to=date_to,
user=user, asset=asset, system_user=system_user,
input=input, session=session
)
return amount
...@@ -9,7 +9,7 @@ from rest_framework_bulk.serializers import BulkListSerializer ...@@ -9,7 +9,7 @@ from rest_framework_bulk.serializers import BulkListSerializer
from common.mixins import BulkSerializerMixin from common.mixins import BulkSerializerMixin
from common.utils import get_object_or_none from common.utils import get_object_or_none
from .models import Terminal, Status, Session, Task from .models import Terminal, Status, Session, Task
from .backends import get_multi_command_store from .backends import get_multi_command_storage
class TerminalSerializer(serializers.ModelSerializer): class TerminalSerializer(serializers.ModelSerializer):
...@@ -47,7 +47,7 @@ class TerminalSerializer(serializers.ModelSerializer): ...@@ -47,7 +47,7 @@ class TerminalSerializer(serializers.ModelSerializer):
class SessionSerializer(serializers.ModelSerializer): class SessionSerializer(serializers.ModelSerializer):
command_amount = serializers.SerializerMethodField() command_amount = serializers.SerializerMethodField()
command_store = get_multi_command_store() command_store = get_multi_command_storage()
class Meta: class Meta:
model = Session model = Session
......
# ~*~ coding: utf-8 ~*~ # ~*~ coding: utf-8 ~*~
from django import template from django import template
from ..backends import get_multi_command_store from ..backends import get_multi_command_storage
register = template.Library() register = template.Library()
command_store = get_multi_command_store() command_store = get_multi_command_storage()
@register.filter @register.filter
......
...@@ -9,10 +9,10 @@ from django.utils.translation import ugettext as _ ...@@ -9,10 +9,10 @@ from django.utils.translation import ugettext as _
from common.mixins import DatetimeSearchMixin, AdminUserRequiredMixin from common.mixins import DatetimeSearchMixin, AdminUserRequiredMixin
from ..models import Command from ..models import Command
from .. import utils from .. import utils
from ..backends import get_multi_command_store from ..backends import get_multi_command_storage
__all__ = ['CommandListView'] __all__ = ['CommandListView']
common_storage = get_multi_command_store() common_storage = get_multi_command_storage()
class CommandListView(DatetimeSearchMixin, AdminUserRequiredMixin, ListView): class CommandListView(DatetimeSearchMixin, AdminUserRequiredMixin, ListView):
......
...@@ -10,7 +10,7 @@ from django.conf import settings ...@@ -10,7 +10,7 @@ from django.conf import settings
from users.utils import AdminUserRequiredMixin from users.utils import AdminUserRequiredMixin
from common.mixins import DatetimeSearchMixin from common.mixins import DatetimeSearchMixin
from ..models import Session, Command, Terminal from ..models import Session, Command, Terminal
from ..backends import get_multi_command_store from ..backends import get_multi_command_storage
from .. import utils from .. import utils
...@@ -19,7 +19,7 @@ __all__ = [ ...@@ -19,7 +19,7 @@ __all__ = [
'SessionDetailView', 'SessionDetailView',
] ]
command_store = get_multi_command_store() command_store = get_multi_command_storage()
class SessionListView(AdminUserRequiredMixin, DatetimeSearchMixin, ListView): class SessionListView(AdminUserRequiredMixin, DatetimeSearchMixin, ListView):
......
...@@ -11,7 +11,7 @@ __all__ = ['UserGroup'] ...@@ -11,7 +11,7 @@ __all__ = ['UserGroup']
class UserGroup(NoDeleteModelMixin): class UserGroup(NoDeleteModelMixin):
id = models.UUIDField(default=uuid.uuid4, primary_key=True) id = models.UUIDField(default=uuid.uuid4, primary_key=True)
name = models.CharField(max_length=128, verbose_name=_('Name')) name = models.CharField(max_length=128, unique=True, verbose_name=_('Name'))
comment = models.TextField(blank=True, verbose_name=_('Comment')) comment = models.TextField(blank=True, verbose_name=_('Comment'))
date_created = models.DateTimeField(auto_now_add=True, null=True, date_created = models.DateTimeField(auto_now_add=True, null=True,
verbose_name=_('Date created')) verbose_name=_('Date created'))
......
...@@ -40,7 +40,6 @@ itsdangerous==0.24 ...@@ -40,7 +40,6 @@ itsdangerous==0.24
itypes==1.1.0 itypes==1.1.0
Jinja2==2.10 Jinja2==2.10
jmespath==0.9.3 jmespath==0.9.3
jms-es-sdk
kombu==4.0.2 kombu==4.0.2
ldap3==2.4 ldap3==2.4
MarkupSafe==1.0 MarkupSafe==1.0
...@@ -62,7 +61,7 @@ pytz==2017.3 ...@@ -62,7 +61,7 @@ pytz==2017.3
PyYAML==3.12 PyYAML==3.12
redis==2.10.6 redis==2.10.6
requests==2.18.4 requests==2.18.4
jms-storage==0.0.13 jms-storage==0.0.17
s3transfer==0.1.13 s3transfer==0.1.13
simplejson==3.13.2 simplejson==3.13.2
six==1.11.0 six==1.11.0
......
#!/usr/bin/python
#
import os
import sys
from collections import Counter
import django
from django.db.models import Count
if os.path.exists('../apps'):
sys.path.insert(0, '../apps')
elif os.path.exists('./apps'):
sys.path.insert(0, './apps')
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "jumpserver.settings")
django.setup()
from users.models import UserGroup
def clean_group(interactive=True):
groups = UserGroup.objects.all()
groups_name_list = groups.values_list('name', flat=True)
groups_with_info = groups.annotate(Count('users'))\
.annotate(Count('asset_permissions'))
counter = Counter(groups_name_list)
for name, count in counter.items():
if count == 0:
continue
groups_duplicate = groups_with_info.filter(name=name)
need_clean_count = groups_duplicate.count()
for group in groups_duplicate:
need_clean = True
if group.users__count > 0:
need_clean = False
elif group.asset_permissions__count > 0:
need_clean = False
elif need_clean_count == 1:
need_clean = False
if need_clean:
confirm = True
if interactive:
confirm = False
while True:
confirm = input(
"Delete user group <{}>, create at {}? ([y]/n)".format(
name, group.date_created)
)
if confirm.lower() == "y":
confirm = True
break
elif confirm.lower() == "n":
confirm = False
break
else:
print("No valid input")
continue
if confirm:
group.delete()
print("Delete success: {}".format(name))
need_clean_count -= 1
else:
continue
if __name__ == '__main__':
clean_group()
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment