提交 61a481f4 编写于 作者: baltery's avatar baltery

[Fixture] 添加用户连接终端

上级 3fa5ce54
......@@ -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
\ No newline at end of file
from users.permissions import IsSuperUserOrAppUser, IsAppUser, \
IsSuperUserOrAppUserOrUserReadonly
from audits.models import ProxyLog
from users.utils import AdminUserRequiredMixin
\ No newline at end of file
......@@ -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(),
......
# ~*~ 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):
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册