mirror of https://github.com/jumpserver/jumpserver
[Fixture] 添加用户连接终端
parent
3fa5ce5404
commit
61a481f427
|
@ -6,7 +6,7 @@ from django.core.cache import cache
|
|||
from django.conf import settings
|
||||
from django.utils import timezone
|
||||
import copy
|
||||
from rest_framework.generics import ListCreateAPIView, RetrieveUpdateDestroyAPIView
|
||||
from rest_framework.generics import ListCreateAPIView
|
||||
from rest_framework import viewsets
|
||||
from rest_framework.views import APIView, Response
|
||||
from rest_framework.permissions import AllowAny
|
||||
|
@ -15,7 +15,8 @@ from rest_framework.decorators import api_view
|
|||
|
||||
from .models import Terminal, TerminalHeatbeat
|
||||
from .serializers import TerminalSerializer, TerminalHeatbeatSerializer
|
||||
from .hands import IsSuperUserOrAppUser, IsAppUser, User, ProxyLog
|
||||
from .hands import IsSuperUserOrAppUser, IsAppUser, ProxyLog, \
|
||||
IsSuperUserOrAppUserOrUserReadonly
|
||||
from common.utils import get_object_or_none
|
||||
|
||||
|
||||
|
@ -55,7 +56,7 @@ class TerminalRegisterView(ListCreateAPIView):
|
|||
class TerminalViewSet(viewsets.ModelViewSet):
|
||||
queryset = Terminal.objects.all()
|
||||
serializer_class = TerminalSerializer
|
||||
permission_classes = (IsSuperUserOrAppUser,)
|
||||
permission_classes = (IsSuperUserOrAppUserOrUserReadonly,)
|
||||
|
||||
def create(self, request, *args, **kwargs):
|
||||
return Response({'msg': 'Use register view except that'}, status=404)
|
||||
|
@ -102,5 +103,4 @@ class TerminateConnectionView(APIView):
|
|||
tasks[terminal_id] = [{'name': 'kill_proxy',
|
||||
'proxy_log_id': proxy_log_id}]
|
||||
|
||||
print(tasks)
|
||||
return Response({'msg': 'get it'})
|
||||
|
|
|
@ -2,5 +2,7 @@
|
|||
#
|
||||
|
||||
from users.models import User
|
||||
from users.permissions import IsSuperUserOrAppUser, IsAppUser
|
||||
from audits.models import ProxyLog
|
||||
from users.permissions import IsSuperUserOrAppUser, IsAppUser, \
|
||||
IsSuperUserOrAppUserOrUserReadonly
|
||||
from audits.models import ProxyLog
|
||||
from users.utils import AdminUserRequiredMixin
|
|
@ -68,19 +68,20 @@ $(document).ready(function(){
|
|||
}
|
||||
}},
|
||||
{targets: 7, createdCell: function (td, cellData, rowData) {
|
||||
console.log(rowData.name);
|
||||
var update_btn = '<a href="{% url "applications:terminal-update" pk=99991937 %}" class="btn btn-xs btn-info">{% trans "Update" %}</a>'
|
||||
.replace('99991937', cellData);
|
||||
var delete_btn = '<a class="btn btn-xs btn-danger m-l-xs btn_delete" data-uid="99991937" data-name="99991938">{% trans "Delete" %}</a>'
|
||||
var delete_btn = '<a class="btn btn-xs btn-danger m-l-xs btn-del" data-id="99991937" data-name="99991938">{% trans "Delete" %}</a>'
|
||||
.replace('99991937', cellData)
|
||||
.replace('99991938', rowData.name);
|
||||
var accept_btn = '<a class="btn btn-xs btn-primary btn-accept" data-id="99991937">{% trans "Accept" %}</a> '
|
||||
.replace('99991937', cellData);
|
||||
var reject_btn = '<a class="btn btn-xs btn-danger m-l-xs btn_delete" data-uid="99991937" data-name="99991938">{% trans "Reject" %}</a>'
|
||||
var reject_btn = '<a class="btn btn-xs btn-danger m-l-xs btn-del" data-id="99991937" data-name="99991938">{% trans "Reject" %}</a>'
|
||||
.replace('99991937', cellData)
|
||||
.replace('99991938', rowData.name);
|
||||
var connect_btn = '<a href="{% url "applications:terminal-connect" pk=99991937 %}"" class="btn btn-xs btn-warning btn-connect" >{% trans "Connect" %}</a> '
|
||||
.replace('99991937', cellData);
|
||||
if (rowData.is_accepted) {
|
||||
$(td).html(update_btn + delete_btn)
|
||||
$(td).html(connect_btn + update_btn + delete_btn)
|
||||
} else {
|
||||
$(td).html(accept_btn + reject_btn)
|
||||
}
|
||||
|
@ -105,11 +106,11 @@ $(document).ready(function(){
|
|||
$form.ajaxSubmit({success: success});
|
||||
})
|
||||
|
||||
}).on('click', '.btn_delete', function(){
|
||||
}).on('click', '.btn-del', function(){
|
||||
var $this = $(this);
|
||||
var uid = $this.data('uid');
|
||||
var id = $this.data('id');
|
||||
var name = $(this).data('name');
|
||||
var the_url = '{% url "api-applications:terminal-detail" pk=99991937 %}'.replace('99991937', uid);
|
||||
var the_url = '{% url "api-applications:terminal-detail" pk=99991937 %}'.replace('99991937', id);
|
||||
objectDelete($this, name, the_url)
|
||||
|
||||
}).on('click', '.btn-accept', function () {
|
||||
|
@ -133,6 +134,10 @@ $(document).ready(function(){
|
|||
$('#modal_terminal_accept').modal({
|
||||
show: true
|
||||
});
|
||||
}).on('click', '.btn-connect', function () {
|
||||
var $this = $(this);
|
||||
var id = $this.data('id');
|
||||
console.log(id)
|
||||
})
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
|
|
@ -9,9 +9,11 @@ from .. import views
|
|||
app_name = 'applications'
|
||||
|
||||
urlpatterns = [
|
||||
url(r'^terminal$', views.TerminalListView.as_view(), name='terminal-list'),
|
||||
url(r'^terminal/$', views.TerminalListView.as_view(), name='terminal-list'),
|
||||
url(r'^terminal/(?P<pk>\d+)/$', views.TerminalDetailView.as_view(),
|
||||
name='terminal-detail'),
|
||||
url(r'^terminal/(?P<pk>\d+)/connect/$', views.TerminalConnectView.as_view(),
|
||||
name='terminal-connect'),
|
||||
url(r'^terminal/(?P<pk>\d+)/update$', views.TerminalUpdateView.as_view(),
|
||||
name='terminal-update'),
|
||||
url(r'^terminal/(?P<pk>\d+)/modal/accept$', views.TerminalModelAccept.as_view(),
|
||||
|
|
|
@ -1,18 +1,19 @@
|
|||
# ~*~ coding: utf-8 ~*~
|
||||
#
|
||||
|
||||
from django.views.generic import ListView, UpdateView, DeleteView, DetailView
|
||||
from django.views.generic.edit import BaseUpdateView
|
||||
from django.views.generic import ListView, UpdateView, DeleteView, \
|
||||
DetailView, TemplateView
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.urls import reverse_lazy
|
||||
from django.urls import reverse_lazy, reverse
|
||||
|
||||
from .models import Terminal
|
||||
from users.utils import AdminUserRequiredMixin
|
||||
from common.mixins import JSONResponseMixin
|
||||
from .models import Terminal
|
||||
from .forms import TerminalForm
|
||||
from .hands import AdminUserRequiredMixin
|
||||
|
||||
|
||||
class TerminalListView(ListView):
|
||||
class TerminalListView(LoginRequiredMixin, ListView):
|
||||
model = Terminal
|
||||
template_name = 'applications/terminal_list.html'
|
||||
form_class = TerminalForm
|
||||
|
@ -27,11 +28,11 @@ class TerminalListView(ListView):
|
|||
return context
|
||||
|
||||
|
||||
class TerminalUpdateView(UpdateView):
|
||||
class TerminalUpdateView(AdminUserRequiredMixin, UpdateView):
|
||||
model = Terminal
|
||||
form_class = TerminalForm
|
||||
template_name = 'applications/terminal_update.html'
|
||||
success_url = reverse_lazy('applications:applications-list')
|
||||
success_url = reverse_lazy('applications:terminal-list')
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(TerminalUpdateView, self).get_context_data(**kwargs)
|
||||
|
@ -39,7 +40,7 @@ class TerminalUpdateView(UpdateView):
|
|||
return context
|
||||
|
||||
|
||||
class TerminalDetailView(DetailView):
|
||||
class TerminalDetailView(LoginRequiredMixin, DetailView):
|
||||
model = Terminal
|
||||
template_name = 'applications/terminal_detail.html'
|
||||
context_object_name = 'terminal'
|
||||
|
@ -53,7 +54,7 @@ class TerminalDetailView(DetailView):
|
|||
return context
|
||||
|
||||
|
||||
class TerminalDeleteView(DeleteView):
|
||||
class TerminalDeleteView(AdminUserRequiredMixin, DeleteView):
|
||||
model = Terminal
|
||||
template_name = 'assets/delete_confirm.html'
|
||||
success_url = reverse_lazy('applications:applications-list')
|
||||
|
@ -88,3 +89,26 @@ class TerminalModelAccept(AdminUserRequiredMixin, JSONResponseMixin, UpdateView)
|
|||
return self.render_json_response(data)
|
||||
|
||||
|
||||
class TerminalConnectView(LoginRequiredMixin, DetailView):
|
||||
template_name = 'flash_message_standalone.html'
|
||||
model = Terminal
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
if self.object.type == 'Web':
|
||||
context = {
|
||||
'title': _('Redirect to web terminal'),
|
||||
'messages': _('Redirect to web terminal: {}'.format(self.object.url)),
|
||||
'auto_redirect': True,
|
||||
'interval': 3,
|
||||
'redirect_url': self.object.url
|
||||
}
|
||||
else:
|
||||
context = {
|
||||
'title': _('Connect ssh terminal'),
|
||||
'messages': _('You should use your ssh client tools '
|
||||
'connect terminal: {} <br /> <br />'
|
||||
'{}'.format(self.object.name, self.object.url)),
|
||||
}
|
||||
|
||||
kwargs.update(context)
|
||||
return super(TerminalConnectView, self).get_context_data(**kwargs)
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
Other module of this app shouldn't connect with other app.
|
||||
|
||||
:copyright: (c) 2014-2016 by Jumpserver Team.
|
||||
:copyright: (c) 2014-2017 by Jumpserver Team.
|
||||
:license: GPL v2, see LICENSE for more details.
|
||||
"""
|
||||
|
||||
|
|
|
@ -16,11 +16,13 @@
|
|||
<div class="panel-options">
|
||||
<ul class="nav nav-tabs">
|
||||
<li class="active">
|
||||
<a href="{% url 'assets:asset-detail' %}" class="text-center"><i class="fa fa-laptop"></i> {% trans 'Asset detail' %} </a>
|
||||
<a href="{% url 'assets:asset-detail' pk=asset.id %}" class="text-center"><i class="fa fa-laptop"></i> {% trans 'Asset detail' %} </a>
|
||||
</li>
|
||||
{% if user.is_superuser %}
|
||||
<li class="pull-right">
|
||||
<a class="btn btn-outline btn-default" href="{% url 'assets:asset-update' pk=asset.id %}"><i class="fa fa-edit"></i>Update</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
<div class="tab-content">
|
||||
|
@ -134,6 +136,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% if user.is_superuser %}
|
||||
<div class="col-sm-5" style="padding-left: 0;padding-right: 0">
|
||||
<div class="panel panel-primary">
|
||||
<div class="panel-heading">
|
||||
|
@ -222,6 +225,7 @@
|
|||
</table>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -125,7 +125,7 @@ class AssetUpdateView(AdminUserRequiredMixin, UpdateView):
|
|||
return super(AssetUpdateView, self).form_invalid(form)
|
||||
|
||||
|
||||
class AssetDeleteView(DeleteView):
|
||||
class AssetDeleteView(AdminUserRequiredMixin, DeleteView):
|
||||
model = Asset
|
||||
template_name = 'assets/delete_confirm.html'
|
||||
success_url = reverse_lazy('assets:asset-list')
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
</a>
|
||||
</li>
|
||||
<li id="applications">
|
||||
<a href="{% url 'users:user-profile' %}">
|
||||
<a href="{% url 'applications:terminal-list' %}">
|
||||
<i class="fa fa-terminal" ></i> <span class="nav-label">{% trans 'Terminal' %}</span><span class="label label-info pull-right"></span>
|
||||
</a>
|
||||
</li>
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
{% if messages %}
|
||||
<p>
|
||||
<div class="alert alert-success" id="messages">
|
||||
{{ messages }}
|
||||
{{ messages|safe }}
|
||||
</div>
|
||||
</p>
|
||||
{% endif %}
|
||||
|
@ -52,16 +52,21 @@
|
|||
Copyright Jumpserver.org
|
||||
</div>
|
||||
<div class="col-md-6 text-right">
|
||||
<small>2014-2016</small>
|
||||
<small>2014-2017</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
<script>
|
||||
var time=5;
|
||||
var time = '{{ interval }}';
|
||||
if (!time){
|
||||
time = 5;
|
||||
} else {
|
||||
time = parseInt(time);
|
||||
}
|
||||
function redirect_page() {
|
||||
if (time >= 0) {
|
||||
var messages = '{{ messages }}, <b>' + time +'</b> ...';
|
||||
var messages = '{{ messages|safe }}, <b>' + time +'</b> ...';
|
||||
$('#messages').html(messages);
|
||||
time--;
|
||||
setTimeout(redirect_page, 1000);
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
Other module of this app shouldn't connect with other app.
|
||||
|
||||
:copyright: (c) 2014-2016 by Jumpserver Team.
|
||||
:copyright: (c) 2014-2017 by Jumpserver Team.
|
||||
:license: GPL v2, see LICENSE for more details.
|
||||
"""
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ class User(AbstractUser):
|
|||
email = models.EmailField(max_length=30, unique=True, verbose_name=_('Email'))
|
||||
groups = models.ManyToManyField(UserGroup, related_name='users', blank=True, verbose_name=_('User group'))
|
||||
role = models.CharField(choices=ROLE_CHOICES, default='User', max_length=10, blank=True, verbose_name=_('Role'))
|
||||
avatar = models.ImageField(upload_to="avatar", verbose_name=_('Avatar'))
|
||||
avatar = models.ImageField(upload_to="avatar", null=True, verbose_name=_('Avatar'))
|
||||
wechat = models.CharField(max_length=30, blank=True, verbose_name=_('Wechat'))
|
||||
phone = models.CharField(max_length=20, blank=True, null=True, verbose_name=_('Phone'))
|
||||
enable_otp = models.BooleanField(default=False, verbose_name=_('Enable OTP'))
|
||||
|
|
|
@ -12,7 +12,7 @@ class IsValidUser(permissions.IsAuthenticated, permissions.BasePermission):
|
|||
and request.user.is_valid
|
||||
|
||||
|
||||
class IsAppUser(IsValidUser, permissions.BasePermission):
|
||||
class IsAppUser(IsValidUser):
|
||||
"""Allows access only to app user """
|
||||
|
||||
def has_permission(self, request, view):
|
||||
|
@ -20,7 +20,7 @@ class IsAppUser(IsValidUser, permissions.BasePermission):
|
|||
and request.user.is_app
|
||||
|
||||
|
||||
class IsSuperUser(IsValidUser, permissions.BasePermission):
|
||||
class IsSuperUser(IsValidUser):
|
||||
"""Allows access only to superuser"""
|
||||
|
||||
def has_permission(self, request, view):
|
||||
|
@ -28,7 +28,7 @@ class IsSuperUser(IsValidUser, permissions.BasePermission):
|
|||
and request.user.is_superuser
|
||||
|
||||
|
||||
class IsSuperUserOrAppUser(IsValidUser, permissions.BasePermission):
|
||||
class IsSuperUserOrAppUser(IsValidUser):
|
||||
"""Allows access between superuser and app user"""
|
||||
|
||||
def has_permission(self, request, view):
|
||||
|
@ -36,8 +36,16 @@ class IsSuperUserOrAppUser(IsValidUser, permissions.BasePermission):
|
|||
and (request.user.is_superuser or request.user.is_app)
|
||||
|
||||
|
||||
class IsCurrentUserOrReadOnly(permissions.BasePermission):
|
||||
class IsSuperUserOrAppUserOrUserReadonly(IsSuperUserOrAppUser):
|
||||
def has_permission(self, request, view):
|
||||
if IsValidUser.has_permission(self, request, view) \
|
||||
and request.method in permissions.SAFE_METHODS:
|
||||
return True
|
||||
else:
|
||||
return IsSuperUserOrAppUser.has_permission(self, request, view)
|
||||
|
||||
|
||||
class IsCurrentUserOrReadOnly(permissions.BasePermission):
|
||||
def has_object_permission(self, request, view, obj):
|
||||
if request.method in permissions.SAFE_METHODS:
|
||||
return True
|
||||
|
|
|
@ -55,7 +55,7 @@
|
|||
Copyright Jumpserver.org
|
||||
</div>
|
||||
<div class="col-md-6 text-right">
|
||||
<small>© 2014-2016</small>
|
||||
<small>© 2014-2017</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -78,7 +78,7 @@
|
|||
Copyright Jumpserver.org
|
||||
</div>
|
||||
<div class="col-md-6 text-right">
|
||||
<small>© 2014-2016</small>
|
||||
<small>© 2014-2017</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -74,7 +74,7 @@
|
|||
Copyright Jumpserver.org
|
||||
</div>
|
||||
<div class="col-md-6 text-right">
|
||||
<small>© 2014-2016</small>
|
||||
<small>© 2014-2017</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -3,18 +3,15 @@
|
|||
from __future__ import unicode_literals
|
||||
import base64
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
import uuid
|
||||
|
||||
from paramiko.rsakey import RSAKey
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.mixins import UserPassesTestMixin
|
||||
from django.urls import reverse_lazy
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.core.cache import cache
|
||||
|
||||
from paramiko.rsakey import RSAKey
|
||||
|
||||
from common.tasks import send_mail_async
|
||||
from common.utils import reverse, get_object_or_none
|
||||
from .models import User
|
||||
|
@ -30,10 +27,13 @@ logger = logging.getLogger('jumpserver')
|
|||
|
||||
|
||||
class AdminUserRequiredMixin(UserPassesTestMixin):
|
||||
login_url = reverse_lazy('users:login')
|
||||
|
||||
def test_func(self):
|
||||
return self.request.user.is_superuser
|
||||
if not self.request.user.is_authenticated:
|
||||
return False
|
||||
elif not self.request.user.is_superuser:
|
||||
self.raise_exception = True
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def user_add_success_next(user):
|
||||
|
|
Loading…
Reference in New Issue