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

[Fixture] 添加用户连接终端

上级 3fa5ce54
...@@ -6,7 +6,7 @@ from django.core.cache import cache ...@@ -6,7 +6,7 @@ from django.core.cache import cache
from django.conf import settings from django.conf import settings
from django.utils import timezone from django.utils import timezone
import copy import copy
from rest_framework.generics import ListCreateAPIView, RetrieveUpdateDestroyAPIView from rest_framework.generics import ListCreateAPIView
from rest_framework import viewsets from rest_framework import viewsets
from rest_framework.views import APIView, Response from rest_framework.views import APIView, Response
from rest_framework.permissions import AllowAny from rest_framework.permissions import AllowAny
...@@ -15,7 +15,8 @@ from rest_framework.decorators import api_view ...@@ -15,7 +15,8 @@ from rest_framework.decorators import api_view
from .models import Terminal, TerminalHeatbeat from .models import Terminal, TerminalHeatbeat
from .serializers import TerminalSerializer, TerminalHeatbeatSerializer 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 from common.utils import get_object_or_none
...@@ -55,7 +56,7 @@ class TerminalRegisterView(ListCreateAPIView): ...@@ -55,7 +56,7 @@ class TerminalRegisterView(ListCreateAPIView):
class TerminalViewSet(viewsets.ModelViewSet): class TerminalViewSet(viewsets.ModelViewSet):
queryset = Terminal.objects.all() queryset = Terminal.objects.all()
serializer_class = TerminalSerializer serializer_class = TerminalSerializer
permission_classes = (IsSuperUserOrAppUser,) permission_classes = (IsSuperUserOrAppUserOrUserReadonly,)
def create(self, request, *args, **kwargs): def create(self, request, *args, **kwargs):
return Response({'msg': 'Use register view except that'}, status=404) return Response({'msg': 'Use register view except that'}, status=404)
...@@ -102,5 +103,4 @@ class TerminateConnectionView(APIView): ...@@ -102,5 +103,4 @@ class TerminateConnectionView(APIView):
tasks[terminal_id] = [{'name': 'kill_proxy', tasks[terminal_id] = [{'name': 'kill_proxy',
'proxy_log_id': proxy_log_id}] 'proxy_log_id': proxy_log_id}]
print(tasks)
return Response({'msg': 'get it'}) return Response({'msg': 'get it'})
...@@ -2,5 +2,7 @@ ...@@ -2,5 +2,7 @@
# #
from users.models import User from users.models import User
from users.permissions import IsSuperUserOrAppUser, IsAppUser from users.permissions import IsSuperUserOrAppUser, IsAppUser, \
from audits.models import ProxyLog IsSuperUserOrAppUserOrUserReadonly
\ No newline at end of file from audits.models import ProxyLog
from users.utils import AdminUserRequiredMixin
\ No newline at end of file
...@@ -68,19 +68,20 @@ $(document).ready(function(){ ...@@ -68,19 +68,20 @@ $(document).ready(function(){
} }
}}, }},
{targets: 7, createdCell: function (td, cellData, rowData) { {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>' var update_btn = '<a href="{% url "applications:terminal-update" pk=99991937 %}" class="btn btn-xs btn-info">{% trans "Update" %}</a>'
.replace('99991937', cellData); .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('99991937', cellData)
.replace('99991938', rowData.name); .replace('99991938', rowData.name);
var accept_btn = '<a class="btn btn-xs btn-primary btn-accept" data-id="99991937">{% trans "Accept" %}</a> ' var accept_btn = '<a class="btn btn-xs btn-primary btn-accept" data-id="99991937">{% trans "Accept" %}</a> '
.replace('99991937', cellData); .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('99991937', cellData)
.replace('99991938', rowData.name); .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) { if (rowData.is_accepted) {
$(td).html(update_btn + delete_btn) $(td).html(connect_btn + update_btn + delete_btn)
} else { } else {
$(td).html(accept_btn + reject_btn) $(td).html(accept_btn + reject_btn)
} }
...@@ -105,11 +106,11 @@ $(document).ready(function(){ ...@@ -105,11 +106,11 @@ $(document).ready(function(){
$form.ajaxSubmit({success: success}); $form.ajaxSubmit({success: success});
}) })
}).on('click', '.btn_delete', function(){ }).on('click', '.btn-del', function(){
var $this = $(this); var $this = $(this);
var uid = $this.data('uid'); var id = $this.data('id');
var name = $(this).data('name'); 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) objectDelete($this, name, the_url)
}).on('click', '.btn-accept', function () { }).on('click', '.btn-accept', function () {
...@@ -133,6 +134,10 @@ $(document).ready(function(){ ...@@ -133,6 +134,10 @@ $(document).ready(function(){
$('#modal_terminal_accept').modal({ $('#modal_terminal_accept').modal({
show: true show: true
}); });
}).on('click', '.btn-connect', function () {
var $this = $(this);
var id = $this.data('id');
console.log(id)
}) })
</script> </script>
{% endblock %} {% endblock %}
...@@ -9,9 +9,11 @@ from .. import views ...@@ -9,9 +9,11 @@ from .. import views
app_name = 'applications' app_name = 'applications'
urlpatterns = [ 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(), url(r'^terminal/(?P<pk>\d+)/$', views.TerminalDetailView.as_view(),
name='terminal-detail'), 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(), url(r'^terminal/(?P<pk>\d+)/update$', views.TerminalUpdateView.as_view(),
name='terminal-update'), name='terminal-update'),
url(r'^terminal/(?P<pk>\d+)/modal/accept$', views.TerminalModelAccept.as_view(), url(r'^terminal/(?P<pk>\d+)/modal/accept$', views.TerminalModelAccept.as_view(),
......
# ~*~ coding: utf-8 ~*~ # ~*~ coding: utf-8 ~*~
# #
from django.views.generic import ListView, UpdateView, DeleteView, DetailView from django.views.generic import ListView, UpdateView, DeleteView, \
from django.views.generic.edit import BaseUpdateView DetailView, TemplateView
from django.contrib.auth.mixins import LoginRequiredMixin
from django.utils.translation import ugettext as _ 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 common.mixins import JSONResponseMixin
from .models import Terminal
from .forms import TerminalForm from .forms import TerminalForm
from .hands import AdminUserRequiredMixin
class TerminalListView(ListView): class TerminalListView(LoginRequiredMixin, ListView):
model = Terminal model = Terminal
template_name = 'applications/terminal_list.html' template_name = 'applications/terminal_list.html'
form_class = TerminalForm form_class = TerminalForm
...@@ -27,11 +28,11 @@ class TerminalListView(ListView): ...@@ -27,11 +28,11 @@ class TerminalListView(ListView):
return context return context
class TerminalUpdateView(UpdateView): class TerminalUpdateView(AdminUserRequiredMixin, UpdateView):
model = Terminal model = Terminal
form_class = TerminalForm form_class = TerminalForm
template_name = 'applications/terminal_update.html' 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): def get_context_data(self, **kwargs):
context = super(TerminalUpdateView, self).get_context_data(**kwargs) context = super(TerminalUpdateView, self).get_context_data(**kwargs)
...@@ -39,7 +40,7 @@ class TerminalUpdateView(UpdateView): ...@@ -39,7 +40,7 @@ class TerminalUpdateView(UpdateView):
return context return context
class TerminalDetailView(DetailView): class TerminalDetailView(LoginRequiredMixin, DetailView):
model = Terminal model = Terminal
template_name = 'applications/terminal_detail.html' template_name = 'applications/terminal_detail.html'
context_object_name = 'terminal' context_object_name = 'terminal'
...@@ -53,7 +54,7 @@ class TerminalDetailView(DetailView): ...@@ -53,7 +54,7 @@ class TerminalDetailView(DetailView):
return context return context
class TerminalDeleteView(DeleteView): class TerminalDeleteView(AdminUserRequiredMixin, DeleteView):
model = Terminal model = Terminal
template_name = 'assets/delete_confirm.html' template_name = 'assets/delete_confirm.html'
success_url = reverse_lazy('applications:applications-list') success_url = reverse_lazy('applications:applications-list')
...@@ -88,3 +89,26 @@ class TerminalModelAccept(AdminUserRequiredMixin, JSONResponseMixin, UpdateView) ...@@ -88,3 +89,26 @@ class TerminalModelAccept(AdminUserRequiredMixin, JSONResponseMixin, UpdateView)
return self.render_json_response(data) 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 @@ ...@@ -6,7 +6,7 @@
Other module of this app shouldn't connect with other app. 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. :license: GPL v2, see LICENSE for more details.
""" """
......
...@@ -16,11 +16,13 @@ ...@@ -16,11 +16,13 @@
<div class="panel-options"> <div class="panel-options">
<ul class="nav nav-tabs"> <ul class="nav nav-tabs">
<li class="active"> <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> </li>
{% if user.is_superuser %}
<li class="pull-right"> <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> <a class="btn btn-outline btn-default" href="{% url 'assets:asset-update' pk=asset.id %}"><i class="fa fa-edit"></i>Update</a>
</li> </li>
{% endif %}
</ul> </ul>
</div> </div>
<div class="tab-content"> <div class="tab-content">
...@@ -134,6 +136,7 @@ ...@@ -134,6 +136,7 @@
</div> </div>
</div> </div>
</div> </div>
{% if user.is_superuser %}
<div class="col-sm-5" style="padding-left: 0;padding-right: 0"> <div class="col-sm-5" style="padding-left: 0;padding-right: 0">
<div class="panel panel-primary"> <div class="panel panel-primary">
<div class="panel-heading"> <div class="panel-heading">
...@@ -222,6 +225,7 @@ ...@@ -222,6 +225,7 @@
</table> </table>
</div> </div>
</div> </div>
{% endif %}
</div> </div>
</div> </div>
</div> </div>
......
...@@ -125,7 +125,7 @@ class AssetUpdateView(AdminUserRequiredMixin, UpdateView): ...@@ -125,7 +125,7 @@ class AssetUpdateView(AdminUserRequiredMixin, UpdateView):
return super(AssetUpdateView, self).form_invalid(form) return super(AssetUpdateView, self).form_invalid(form)
class AssetDeleteView(DeleteView): class AssetDeleteView(AdminUserRequiredMixin, DeleteView):
model = Asset model = Asset
template_name = 'assets/delete_confirm.html' template_name = 'assets/delete_confirm.html'
success_url = reverse_lazy('assets:asset-list') success_url = reverse_lazy('assets:asset-list')
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
</a> </a>
</li> </li>
<li id="applications"> <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> <i class="fa fa-terminal" ></i> <span class="nav-label">{% trans 'Terminal' %}</span><span class="label label-info pull-right"></span>
</a> </a>
</li> </li>
......
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
{% if messages %} {% if messages %}
<p> <p>
<div class="alert alert-success" id="messages"> <div class="alert alert-success" id="messages">
{{ messages }} {{ messages|safe }}
</div> </div>
</p> </p>
{% endif %} {% endif %}
...@@ -52,16 +52,21 @@ ...@@ -52,16 +52,21 @@
Copyright Jumpserver.org Copyright Jumpserver.org
</div> </div>
<div class="col-md-6 text-right"> <div class="col-md-6 text-right">
<small>2014-2016</small> <small>2014-2017</small>
</div> </div>
</div> </div>
</div> </div>
</body> </body>
<script> <script>
var time=5; var time = '{{ interval }}';
if (!time){
time = 5;
} else {
time = parseInt(time);
}
function redirect_page() { function redirect_page() {
if (time >= 0) { if (time >= 0) {
var messages = '{{ messages }}, <b>' + time +'</b> ...'; var messages = '{{ messages|safe }}, <b>' + time +'</b> ...';
$('#messages').html(messages); $('#messages').html(messages);
time--; time--;
setTimeout(redirect_page, 1000); setTimeout(redirect_page, 1000);
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
Other module of this app shouldn't connect with other app. 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. :license: GPL v2, see LICENSE for more details.
""" """
......
...@@ -33,7 +33,7 @@ class User(AbstractUser): ...@@ -33,7 +33,7 @@ class User(AbstractUser):
email = models.EmailField(max_length=30, unique=True, verbose_name=_('Email')) email = models.EmailField(max_length=30, unique=True, verbose_name=_('Email'))
groups = models.ManyToManyField(UserGroup, related_name='users', blank=True, verbose_name=_('User group')) 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')) 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')) wechat = models.CharField(max_length=30, blank=True, verbose_name=_('Wechat'))
phone = models.CharField(max_length=20, blank=True, null=True, verbose_name=_('Phone')) phone = models.CharField(max_length=20, blank=True, null=True, verbose_name=_('Phone'))
enable_otp = models.BooleanField(default=False, verbose_name=_('Enable OTP')) enable_otp = models.BooleanField(default=False, verbose_name=_('Enable OTP'))
......
...@@ -12,7 +12,7 @@ class IsValidUser(permissions.IsAuthenticated, permissions.BasePermission): ...@@ -12,7 +12,7 @@ class IsValidUser(permissions.IsAuthenticated, permissions.BasePermission):
and request.user.is_valid and request.user.is_valid
class IsAppUser(IsValidUser, permissions.BasePermission): class IsAppUser(IsValidUser):
"""Allows access only to app user """ """Allows access only to app user """
def has_permission(self, request, view): def has_permission(self, request, view):
...@@ -20,7 +20,7 @@ class IsAppUser(IsValidUser, permissions.BasePermission): ...@@ -20,7 +20,7 @@ class IsAppUser(IsValidUser, permissions.BasePermission):
and request.user.is_app and request.user.is_app
class IsSuperUser(IsValidUser, permissions.BasePermission): class IsSuperUser(IsValidUser):
"""Allows access only to superuser""" """Allows access only to superuser"""
def has_permission(self, request, view): def has_permission(self, request, view):
...@@ -28,7 +28,7 @@ class IsSuperUser(IsValidUser, permissions.BasePermission): ...@@ -28,7 +28,7 @@ class IsSuperUser(IsValidUser, permissions.BasePermission):
and request.user.is_superuser and request.user.is_superuser
class IsSuperUserOrAppUser(IsValidUser, permissions.BasePermission): class IsSuperUserOrAppUser(IsValidUser):
"""Allows access between superuser and app user""" """Allows access between superuser and app user"""
def has_permission(self, request, view): def has_permission(self, request, view):
...@@ -36,8 +36,16 @@ class IsSuperUserOrAppUser(IsValidUser, permissions.BasePermission): ...@@ -36,8 +36,16 @@ class IsSuperUserOrAppUser(IsValidUser, permissions.BasePermission):
and (request.user.is_superuser or request.user.is_app) 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): def has_object_permission(self, request, view, obj):
if request.method in permissions.SAFE_METHODS: if request.method in permissions.SAFE_METHODS:
return True return True
......
...@@ -55,7 +55,7 @@ ...@@ -55,7 +55,7 @@
Copyright Jumpserver.org Copyright Jumpserver.org
</div> </div>
<div class="col-md-6 text-right"> <div class="col-md-6 text-right">
<small>© 2014-2016</small> <small>© 2014-2017</small>
</div> </div>
</div> </div>
</div> </div>
......
...@@ -78,7 +78,7 @@ ...@@ -78,7 +78,7 @@
Copyright Jumpserver.org Copyright Jumpserver.org
</div> </div>
<div class="col-md-6 text-right"> <div class="col-md-6 text-right">
<small>© 2014-2016</small> <small>© 2014-2017</small>
</div> </div>
</div> </div>
</div> </div>
......
...@@ -74,7 +74,7 @@ ...@@ -74,7 +74,7 @@
Copyright Jumpserver.org Copyright Jumpserver.org
</div> </div>
<div class="col-md-6 text-right"> <div class="col-md-6 text-right">
<small>© 2014-2016</small> <small>© 2014-2017</small>
</div> </div>
</div> </div>
</div> </div>
......
...@@ -3,18 +3,15 @@ ...@@ -3,18 +3,15 @@
from __future__ import unicode_literals from __future__ import unicode_literals
import base64 import base64
import logging import logging
import os
import re
import uuid import uuid
from paramiko.rsakey import RSAKey
from django.conf import settings from django.conf import settings
from django.contrib.auth.mixins import UserPassesTestMixin from django.contrib.auth.mixins import UserPassesTestMixin
from django.urls import reverse_lazy from django.urls import reverse_lazy
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from django.core.cache import cache from django.core.cache import cache
from paramiko.rsakey import RSAKey
from common.tasks import send_mail_async from common.tasks import send_mail_async
from common.utils import reverse, get_object_or_none from common.utils import reverse, get_object_or_none
from .models import User from .models import User
...@@ -30,10 +27,13 @@ logger = logging.getLogger('jumpserver') ...@@ -30,10 +27,13 @@ logger = logging.getLogger('jumpserver')
class AdminUserRequiredMixin(UserPassesTestMixin): class AdminUserRequiredMixin(UserPassesTestMixin):
login_url = reverse_lazy('users:login')
def test_func(self): 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): def user_add_success_next(user):
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册