mirror of https://github.com/jumpserver/jumpserver
[Feture] 添加session 列表,并支持kill session
parent
bf8fa95597
commit
01558c985a
|
@ -16,8 +16,8 @@ from django.conf import settings
|
|||
|
||||
from common.utils import get_object_or_none
|
||||
from .models import Terminal, Status, Session, Task
|
||||
from .serializers import TerminalSerializer, TerminalStatusSerializer, \
|
||||
TerminalSessionSerializer, TerminalTaskSerializer
|
||||
from .serializers import TerminalSerializer, StatusSerializer, \
|
||||
SessionSerializer, TaskSerializer
|
||||
from .hands import IsSuperUserOrAppUser, IsAppUser, ProxyLog, \
|
||||
IsSuperUserOrAppUserOrUserReadonly
|
||||
from .backends import get_command_store, get_replay_store, SessionCommandSerializer
|
||||
|
@ -64,48 +64,58 @@ class TerminalViewSet(viewsets.ModelViewSet):
|
|||
return super().get_permissions()
|
||||
|
||||
|
||||
class TerminalStatusViewSet(viewsets.ModelViewSet):
|
||||
class StatusViewSet(viewsets.ModelViewSet):
|
||||
queryset = Status.objects.all()
|
||||
serializer_class = TerminalStatusSerializer
|
||||
serializer_class = StatusSerializer
|
||||
permission_classes = (IsSuperUserOrAppUser,)
|
||||
session_serializer_class = TerminalSessionSerializer
|
||||
session_serializer_class = SessionSerializer
|
||||
task_serializer_class = TaskSerializer
|
||||
|
||||
def create(self, request, *args, **kwargs):
|
||||
self.handle_sessions()
|
||||
return super().create(request, *args, **kwargs)
|
||||
super().create(request, *args, **kwargs)
|
||||
tasks = self.request.user.terminal.task_set.filter(is_finished=False)
|
||||
serializer = self.task_serializer_class(tasks, many=True)
|
||||
return Response(serializer.data, status=201)
|
||||
|
||||
def handle_sessions(self):
|
||||
sessions_active = []
|
||||
|
||||
for session_data in self.request.data.get("sessions", []):
|
||||
session_data["terminal"] = self.request.user.terminal.id
|
||||
_uuid = session_data["uuid"]
|
||||
session = get_object_or_none(Session, uuid=_uuid)
|
||||
if session:
|
||||
serializer = TerminalSessionSerializer(
|
||||
data=session_data, instance=session
|
||||
)
|
||||
else:
|
||||
serializer = TerminalSessionSerializer(data=session_data)
|
||||
|
||||
if serializer.is_valid():
|
||||
serializer.save()
|
||||
else:
|
||||
msg = "session data is not valid {}".format(serializer.errors)
|
||||
logger.error(msg)
|
||||
|
||||
self.create_or_update_session(session_data)
|
||||
if not session_data["is_finished"]:
|
||||
sessions_active.append(session_data["id"])
|
||||
sessions_active.append(session_data["uuid"])
|
||||
|
||||
sessions_in_db_active = Session.objects.filter(
|
||||
is_finished=False, terminal=self.request.user.terminal.id
|
||||
is_finished=False,
|
||||
terminal=self.request.user.terminal.id
|
||||
)
|
||||
|
||||
for session in sessions_in_db_active:
|
||||
if str(session.id) not in sessions_active:
|
||||
if str(session.uuid) not in sessions_active:
|
||||
session.is_finished = True
|
||||
session.date_end = timezone.now()
|
||||
session.save()
|
||||
|
||||
def create_or_update_session(self, session_data):
|
||||
session_data["terminal"] = self.request.user.terminal.id
|
||||
_uuid = session_data["uuid"]
|
||||
session = get_object_or_none(Session, uuid=_uuid)
|
||||
if session:
|
||||
serializer = SessionSerializer(
|
||||
data=session_data, instance=session
|
||||
)
|
||||
else:
|
||||
serializer = SessionSerializer(data=session_data)
|
||||
|
||||
if serializer.is_valid():
|
||||
session = serializer.save()
|
||||
return session
|
||||
else:
|
||||
msg = "session data is not valid {}".format(serializer.errors)
|
||||
logger.error(msg)
|
||||
return None
|
||||
|
||||
def get_queryset(self):
|
||||
terminal_id = self.kwargs.get("terminal", None)
|
||||
if terminal_id:
|
||||
|
@ -123,9 +133,9 @@ class TerminalStatusViewSet(viewsets.ModelViewSet):
|
|||
return super().get_permissions()
|
||||
|
||||
|
||||
class TerminalSessionViewSet(viewsets.ModelViewSet):
|
||||
class SessionViewSet(viewsets.ModelViewSet):
|
||||
queryset = Session.objects.all()
|
||||
serializers_class = TerminalSessionSerializer
|
||||
serializers_class = SessionSerializer
|
||||
permission_classes = (IsSuperUserOrAppUser,)
|
||||
|
||||
def get_queryset(self):
|
||||
|
@ -136,21 +146,21 @@ class TerminalSessionViewSet(viewsets.ModelViewSet):
|
|||
return self.queryset
|
||||
|
||||
|
||||
class TerminalTaskViewSet(viewsets.ModelViewSet):
|
||||
class TaskViewSet(viewsets.ModelViewSet):
|
||||
queryset = Task.objects.all()
|
||||
serializer_class = TerminalTaskSerializer
|
||||
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.terminalstatus_set.all()
|
||||
return self.queryset
|
||||
# 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):
|
||||
|
@ -182,7 +192,7 @@ class SessionReplayAPI(APIView):
|
|||
return Response({"session_id": session.id}, status=201)
|
||||
|
||||
|
||||
class SessionCommandViewSet(viewsets.ViewSet):
|
||||
class CommandViewSet(viewsets.ViewSet):
|
||||
"""接受app发送来的command log, 格式如下
|
||||
{
|
||||
"user": "admin",
|
||||
|
|
|
@ -94,7 +94,7 @@ class Session(models.Model):
|
|||
is_finished = models.BooleanField(default=False)
|
||||
has_replay = models.BooleanField(default=False, verbose_name=_("Replay"))
|
||||
has_command = models.BooleanField(default=False, verbose_name=_("Command"))
|
||||
terminal = models.UUIDField(null=True, verbose_name=_("Terminal"))
|
||||
terminal = models.ForeignKey(Terminal, null=True, on_delete=models.CASCADE)
|
||||
date_start = models.DateTimeField(verbose_name=_("Date Start"))
|
||||
date_end = models.DateTimeField(verbose_name=_("Date End"), null=True)
|
||||
|
||||
|
@ -106,8 +106,12 @@ class Session(models.Model):
|
|||
|
||||
|
||||
class Task(models.Model):
|
||||
NAME_CHOICES = (
|
||||
("kill_session", "Kill Session"),
|
||||
)
|
||||
|
||||
id = models.UUIDField(default=uuid.uuid4, primary_key=True)
|
||||
name = models.CharField(max_length=128, verbose_name=_("Name"))
|
||||
name = models.CharField(max_length=128, choices=NAME_CHOICES, verbose_name=_("Name"))
|
||||
args = models.CharField(max_length=1024, verbose_name=_("Task Args"))
|
||||
terminal = models.ForeignKey(Terminal, null=True, on_delete=models.CASCADE)
|
||||
is_finished = models.BooleanField(default=False)
|
||||
|
|
|
@ -35,21 +35,21 @@ class TerminalSerializer(serializers.ModelSerializer):
|
|||
return False
|
||||
|
||||
|
||||
class TerminalSessionSerializer(serializers.ModelSerializer):
|
||||
class SessionSerializer(serializers.ModelSerializer):
|
||||
|
||||
class Meta:
|
||||
model = Session
|
||||
fields = '__all__'
|
||||
|
||||
|
||||
class TerminalStatusSerializer(serializers.ModelSerializer):
|
||||
class StatusSerializer(serializers.ModelSerializer):
|
||||
|
||||
class Meta:
|
||||
fields = '__all__'
|
||||
model = Status
|
||||
|
||||
|
||||
class TerminalTaskSerializer(serializers.ModelSerializer):
|
||||
class TaskSerializer(serializers.ModelSerializer):
|
||||
|
||||
class Meta:
|
||||
fields = '__all__'
|
||||
|
|
|
@ -66,9 +66,8 @@
|
|||
<th class="text-center">{% trans 'System user' %}</th>
|
||||
<th class="text-center">{% trans 'Terminal' %}</th>
|
||||
<th class="text-center">{% trans 'Command' %}</th>
|
||||
<th class="text-center">{% trans 'Success' %}</th>
|
||||
<th class="text-center">{% trans 'Finished' %}</th>
|
||||
<th class="text-center">{% trans 'Monitor' %}</th>
|
||||
<th class="text-center">{% trans 'Terminate' %}</th>
|
||||
<th class="text-center">{% trans 'Date start' %}</th>
|
||||
<th class="text-center">{% trans 'Time' %}</th>
|
||||
{% endblock %}
|
||||
|
@ -85,13 +84,6 @@
|
|||
<td class="text-center">{{ session.system_user }}</td>
|
||||
<td class="text-center">{{ session.terminal.name }}</td>
|
||||
<td class="text-center">{{ session.commands.all|length}}</td>
|
||||
<td class="text-center">
|
||||
{% if session.is_failed %}
|
||||
<i class="fa fa-times text-danger"></i>
|
||||
{% else %}
|
||||
<i class="fa fa-check text-navy"></i>
|
||||
{% endif %}
|
||||
</td>
|
||||
{% if session.is_finished %}
|
||||
<td class="text-center">
|
||||
<i class="fa fa-check text-navy"></i>
|
||||
|
@ -101,10 +93,10 @@
|
|||
</td>
|
||||
{% else %}
|
||||
<td class="text-center">
|
||||
<a class="btn-term" value="{{ session.id }}"><i class="fa fa-times text-danger"></i></a>
|
||||
<a><span class="text-danger"><i class="fa fa-eye"></i></span></a>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<a><span class="text-danger"><i class="fa fa-eye"></i></span></a>
|
||||
<a class="btn-term" value="{{ session.uuid }}" terminal="{{ session.terminal.id }}"><i class="fa fa-times text-danger"></i></a>
|
||||
</td>
|
||||
{% endif %}
|
||||
<td class="text-center">{{ session.date_start }}</td>
|
||||
|
@ -131,13 +123,13 @@
|
|||
{% block custom_foot_js %}
|
||||
<script src="{% static 'js/plugins/datepicker/bootstrap-datepicker.js' %}"></script>
|
||||
<script>
|
||||
function terminateConnection(data) {
|
||||
function terminateSession(data) {
|
||||
function success() {
|
||||
window.setTimeout(function () {
|
||||
window.location.reload()
|
||||
}, 300)
|
||||
}
|
||||
var the_url = "";
|
||||
var the_url = "{% url 'api-terminal:tasks-list' %}";
|
||||
APIUpdateAttr({url: the_url, method: 'POST', body: JSON.stringify(data), success: success, success_message: 'Terminate success'});
|
||||
}
|
||||
$(document).ready(function() {
|
||||
|
@ -156,17 +148,20 @@
|
|||
});
|
||||
}).on('click', '.btn-term', function () {
|
||||
var $this = $(this);
|
||||
var proxy_log_id = $this.attr('value');
|
||||
var session_id = $this.attr('value');
|
||||
var terminal_id = $this.attr('terminal');
|
||||
var data = {
|
||||
proxy_log_id: proxy_log_id
|
||||
name: "kill_session",
|
||||
args: session_id,
|
||||
terminal: terminal_id
|
||||
};
|
||||
terminateConnection(data)
|
||||
terminateSession(data)
|
||||
}).on('click', '#btn_bulk_update', function () {
|
||||
var data = [];
|
||||
$('.cbx-term:checked').each(function () {
|
||||
data.push({proxy_log_id: $(this).attr('value')})
|
||||
});
|
||||
terminateConnection(data)
|
||||
terminateSession(data)
|
||||
})
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
|
|
@ -10,10 +10,11 @@ from .. import api
|
|||
app_name = 'terminal'
|
||||
|
||||
router = routers.DefaultRouter()
|
||||
router.register(r'v1/terminal/(?P<terminal>[0-9]+)?/?status', api.TerminalStatusViewSet, 'terminal-status')
|
||||
router.register(r'v1/terminal/(?P<terminal>[0-9]+)?/?sessions', api.TerminalSessionViewSet, 'terminal-sessions')
|
||||
router.register(r'v1/terminal/(?P<terminal>[0-9]+)?/?status', api.StatusViewSet, 'terminal-status')
|
||||
router.register(r'v1/terminal/(?P<terminal>[0-9]+)?/?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.SessionCommandViewSet, 'command')
|
||||
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'),
|
||||
|
|
Loading…
Reference in New Issue