Commit 08e17884 authored by ibuler's avatar ibuler

[Feature] 打算拆分下载和上传为独立模块,时间有限暂时放弃

parent 160b01ec
...@@ -9,6 +9,7 @@ from common.utils import validate_ssh_private_key, ssh_pubkey_gen, ssh_key_gen, ...@@ -9,6 +9,7 @@ from common.utils import validate_ssh_private_key, ssh_pubkey_gen, ssh_key_gen,
logger = get_logger(__file__) logger = get_logger(__file__)
from rest_framework import serializers
class AssetCreateForm(forms.ModelForm): class AssetCreateForm(forms.ModelForm):
...@@ -240,7 +241,7 @@ class SystemUserForm(forms.ModelForm): ...@@ -240,7 +241,7 @@ class SystemUserForm(forms.ModelForm):
fields = [ fields = [
'name', 'username', 'protocol', 'auto_generate_key', 'name', 'username', 'protocol', 'auto_generate_key',
'password', 'private_key_file', 'auto_push', 'sudo', 'password', 'private_key_file', 'auto_push', 'sudo',
'comment', 'shell', 'cluster' 'comment', 'shell', 'cluster', 'priority',
] ]
widgets = { widgets = {
'name': forms.TextInput(attrs={'placeholder': _('Name')}), 'name': forms.TextInput(attrs={'placeholder': _('Name')}),
...@@ -254,6 +255,7 @@ class SystemUserForm(forms.ModelForm): ...@@ -254,6 +255,7 @@ class SystemUserForm(forms.ModelForm):
'username': '* required', 'username': '* required',
'cluster': 'If auto push checked, system user will be create at cluster assets', 'cluster': 'If auto push checked, system user will be create at cluster assets',
'auto_push': 'Auto push system user to asset', 'auto_push': 'Auto push system user to asset',
'priority': 'High level will be using login asset as default, if user was granted more than 2 system user',
} }
...@@ -261,7 +263,7 @@ class SystemUserUpdateForm(forms.ModelForm): ...@@ -261,7 +263,7 @@ class SystemUserUpdateForm(forms.ModelForm):
class Meta: class Meta:
model = SystemUser model = SystemUser
fields = [ fields = [
'name', 'username', 'protocol', 'name', 'username', 'protocol', 'priority',
'sudo', 'comment', 'shell', 'cluster' 'sudo', 'comment', 'shell', 'cluster'
] ]
widgets = { widgets = {
...@@ -275,6 +277,7 @@ class SystemUserUpdateForm(forms.ModelForm): ...@@ -275,6 +277,7 @@ class SystemUserUpdateForm(forms.ModelForm):
'name': '* required', 'name': '* required',
'username': '* required', 'username': '* required',
'cluster': 'If auto push checked, then push system user to that cluster assets', 'cluster': 'If auto push checked, then push system user to that cluster assets',
'priority': 'High level will be using login asset as default, if user was granted more than 2 system user',
} }
......
...@@ -7,6 +7,7 @@ import logging ...@@ -7,6 +7,7 @@ import logging
import uuid import uuid
from hashlib import md5 from hashlib import md5
import sshpubkeys
from django.db import models from django.db import models
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.conf import settings from django.conf import settings
...@@ -27,7 +28,8 @@ class AssetUser(models.Model): ...@@ -27,7 +28,8 @@ class AssetUser(models.Model):
_private_key = models.TextField(max_length=4096, blank=True, null=True, verbose_name=_('SSH private key'), validators=[private_key_validator, ]) _private_key = models.TextField(max_length=4096, blank=True, null=True, verbose_name=_('SSH private key'), validators=[private_key_validator, ])
_public_key = models.TextField(max_length=4096, blank=True, verbose_name=_('SSH public key')) _public_key = models.TextField(max_length=4096, blank=True, verbose_name=_('SSH public key'))
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)
date_updated = models.DateTimeField(auto_now=True)
created_by = models.CharField(max_length=32, null=True, verbose_name=_('Created by')) created_by = models.CharField(max_length=32, null=True, verbose_name=_('Created by'))
@property @property
...@@ -45,16 +47,21 @@ class AssetUser(models.Model): ...@@ -45,16 +47,21 @@ class AssetUser(models.Model):
@property @property
def private_key(self): def private_key(self):
if self._private_key: if self._private_key:
key_str = signer.unsign(self._private_key) return signer.unsign(self._private_key)
return ssh_key_string_to_obj(key_str, password=self.password)
else:
return None
@private_key.setter @private_key.setter
def private_key(self, private_key_raw): def private_key(self, private_key_raw):
raise AttributeError("Using set_auth do that") raise AttributeError("Using set_auth do that")
# self._private_key = signer.sign(private_key_raw) # self._private_key = signer.sign(private_key_raw)
@property
def private_key_obj(self):
if self._private_key:
key_str = signer.unsign(self._private_key)
return ssh_key_string_to_obj(key_str, password=self.password)
else:
return None
@property @property
def private_key_file(self): def private_key_file(self):
if not self.private_key: if not self.private_key:
...@@ -74,6 +81,15 @@ class AssetUser(models.Model): ...@@ -74,6 +81,15 @@ class AssetUser(models.Model):
def public_key(self): def public_key(self):
return signer.unsign(self._public_key) return signer.unsign(self._public_key)
@property
def public_key_obj(self):
if self.public_key:
try:
return sshpubkeys.SSHKey(self.public_key)
except TabError:
pass
return None
def set_auth(self, password=None, private_key=None, public_key=None): def set_auth(self, password=None, private_key=None, public_key=None):
update_fields = [] update_fields = []
if password: if password:
...@@ -170,6 +186,7 @@ class SystemUser(AssetUser): ...@@ -170,6 +186,7 @@ class SystemUser(AssetUser):
('K', 'Public key'), ('K', 'Public key'),
) )
cluster = models.ManyToManyField('assets.Cluster', verbose_name=_("Cluster")) cluster = models.ManyToManyField('assets.Cluster', verbose_name=_("Cluster"))
priority = models.IntegerField(default=10, verbose_name=_("Priority")) # Todo: If user granted more priority user, default will be login as the hign
protocol = models.CharField(max_length=16, choices=PROTOCOL_CHOICES, default='ssh', verbose_name=_('Protocol')) protocol = models.CharField(max_length=16, choices=PROTOCOL_CHOICES, default='ssh', verbose_name=_('Protocol'))
auto_push = models.BooleanField(default=True, verbose_name=_('Auto push')) auto_push = models.BooleanField(default=True, verbose_name=_('Auto push'))
sudo = models.TextField(default='/sbin/ifconfig', verbose_name=_('Sudo')) sudo = models.TextField(default='/sbin/ifconfig', verbose_name=_('Sudo'))
...@@ -205,6 +222,7 @@ class SystemUser(AssetUser): ...@@ -205,6 +222,7 @@ class SystemUser(AssetUser):
'name': self.name, 'name': self.name,
'username': self.username, 'username': self.username,
'protocol': self.protocol, 'protocol': self.protocol,
'priority': self.priority,
'auto_push': self.auto_push, 'auto_push': self.auto_push,
} }
......
...@@ -115,7 +115,7 @@ class SystemUserSerializer(serializers.ModelSerializer): ...@@ -115,7 +115,7 @@ class SystemUserSerializer(serializers.ModelSerializer):
class AssetSystemUserSerializer(serializers.ModelSerializer): class AssetSystemUserSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = SystemUser model = SystemUser
fields = ('id', 'name', 'username', 'protocol', 'comment') fields = ('id', 'name', 'username', 'priority', 'protocol', 'comment',)
class SystemUserUpdateAssetsSerializer(serializers.ModelSerializer): class SystemUserUpdateAssetsSerializer(serializers.ModelSerializer):
......
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
<h3>{% trans 'Basic' %}</h3> <h3>{% trans 'Basic' %}</h3>
{% bootstrap_field form.name layout="horizontal" %} {% bootstrap_field form.name layout="horizontal" %}
{% bootstrap_field form.username layout="horizontal" %} {% bootstrap_field form.username layout="horizontal" %}
{% bootstrap_field form.priority layout="horizontal" %}
{% bootstrap_field form.protocol layout="horizontal" %} {% bootstrap_field form.protocol layout="horizontal" %}
{% bootstrap_field form.cluster layout="horizontal" %} {% bootstrap_field form.cluster layout="horizontal" %}
...@@ -49,7 +50,6 @@ ...@@ -49,7 +50,6 @@
{{ form.auto_generate_key}} {{ form.auto_generate_key}}
</div> </div>
</div> </div>
</div> </div>
<div class="auth-fields"> <div class="auth-fields">
{% bootstrap_field form.private_key_file layout="horizontal" %} {% bootstrap_field form.private_key_file layout="horizontal" %}
......
...@@ -64,7 +64,9 @@ ...@@ -64,7 +64,9 @@
{% block custom_foot_js %} {% block custom_foot_js %}
<script> <script>
$(document).ready(function () { $(document).ready(function () {
$('.select2').select2(); $('.select2').select2({
allowClear: true
});
$("#tags").select2({ $("#tags").select2({
tags: true, tags: true,
maximumSelectionLength: 8 //最多能够选择的个数 maximumSelectionLength: 8 //最多能够选择的个数
......
...@@ -123,7 +123,7 @@ class AdminUserAssetsView(AdminUserRequiredMixin, SingleObjectMixin, ListView): ...@@ -123,7 +123,7 @@ class AdminUserAssetsView(AdminUserRequiredMixin, SingleObjectMixin, ListView):
class AdminUserDeleteView(AdminUserRequiredMixin, DeleteView): class AdminUserDeleteView(AdminUserRequiredMixin, DeleteView):
model = AdminUser model = AdminUser
template_name = 'assets/delete_confirm.html' template_name = 'delete_confirm.html'
success_url = reverse_lazy('assets:admin-user-list') success_url = reverse_lazy('assets:admin-user-list')
...@@ -9,12 +9,13 @@ import chardet ...@@ -9,12 +9,13 @@ import chardet
from io import StringIO from io import StringIO
from django.conf import settings from django.conf import settings
from django.core.exceptions import ImproperlyConfigured, FieldDoesNotExist
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.views.generic import TemplateView, ListView, View from django.views.generic import TemplateView, ListView, View
from django.views.generic.edit import CreateView, DeleteView, FormView, UpdateView from django.views.generic.edit import CreateView, DeleteView, FormView, UpdateView
from django.urls import reverse_lazy from django.urls import reverse_lazy
from django.views.generic.detail import DetailView, SingleObjectMixin from django.views.generic.detail import DetailView, SingleObjectMixin
from django.http import HttpResponse, JsonResponse, HttpResponseRedirect from django.http import HttpResponse, JsonResponse, HttpResponseRedirect, Http404
from django.views.decorators.csrf import csrf_protect, csrf_exempt from django.views.decorators.csrf import csrf_protect, csrf_exempt
from django.utils.decorators import method_decorator from django.utils.decorators import method_decorator
from django.core.cache import cache from django.core.cache import cache
...@@ -22,8 +23,10 @@ from django.utils import timezone ...@@ -22,8 +23,10 @@ from django.utils import timezone
from django.contrib.auth.mixins import LoginRequiredMixin from django.contrib.auth.mixins import LoginRequiredMixin
from django.shortcuts import get_object_or_404, redirect, reverse from django.shortcuts import get_object_or_404, redirect, reverse
from common.mixins import JSONResponseMixin from common.mixins import JSONResponseMixin
from common.utils import get_object_or_none from common.utils import get_object_or_none
from common.imexp import ModelExportView
from .. import forms from .. import forms
from ..models import Asset, AssetGroup, AdminUser, Cluster, SystemUser from ..models import Asset, AssetGroup, AdminUser, Cluster, SystemUser
from ..hands import AdminUserRequiredMixin from ..hands import AdminUserRequiredMixin
...@@ -169,7 +172,7 @@ class AssetUpdateView(AdminUserRequiredMixin, UpdateView): ...@@ -169,7 +172,7 @@ class AssetUpdateView(AdminUserRequiredMixin, UpdateView):
class AssetDeleteView(AdminUserRequiredMixin, DeleteView): class AssetDeleteView(AdminUserRequiredMixin, DeleteView):
model = Asset model = Asset
template_name = 'assets/delete_confirm.html' template_name = 'delete_confirm.html'
success_url = reverse_lazy('assets:asset-list') success_url = reverse_lazy('assets:asset-list')
...@@ -193,46 +196,11 @@ class AssetDetailView(DetailView): ...@@ -193,46 +196,11 @@ class AssetDetailView(DetailView):
@method_decorator(csrf_exempt, name='dispatch') @method_decorator(csrf_exempt, name='dispatch')
class AssetExportView(View): class AssetExportView(ModelExportView):
def get(self, request): filename_prefix = 'jumpserver'
spm = request.GET.get('spm', '') redirect_url = reverse_lazy('assets:asset-export')
assets_id_default = [Asset.objects.first().id] if Asset.objects.first() else [1] model = Asset
assets_id = cache.get(spm, assets_id_default) fields = ('hostname', 'ip')
fields = [
field for field in Asset._meta.fields
if field.name not in [
'date_created'
]
]
filename = 'assets-{}.csv'.format(
timezone.localtime(timezone.now()).strftime('%Y-%m-%d_%H-%M-%S'))
response = HttpResponse(content_type='text/csv')
response['Content-Disposition'] = 'attachment; filename="%s"' % filename
response.write(codecs.BOM_UTF8)
assets = Asset.objects.filter(id__in=assets_id)
writer = csv.writer(response, dialect='excel',
quoting=csv.QUOTE_MINIMAL)
header = [field.verbose_name for field in fields]
header.append(_('Asset groups'))
writer.writerow(header)
for asset in assets:
groups = ','.join([group.name for group in asset.groups.all()])
data = [getattr(asset, field.name) for field in fields]
data.append(groups)
writer.writerow(data)
return response
def post(self, request, *args, **kwargs):
try:
assets_id = json.loads(request.body).get('assets_id', [])
except ValueError:
return HttpResponse('Json object not valid', status=400)
spm = uuid.uuid4().hex
cache.set(spm, assets_id, 300)
url = reverse_lazy('assets:asset-export') + '?spm=%s' % spm
return JsonResponse({'redirect': url})
class BulkImportAssetView(AdminUserRequiredMixin, JSONResponseMixin, FormView): class BulkImportAssetView(AdminUserRequiredMixin, JSONResponseMixin, FormView):
......
...@@ -97,5 +97,5 @@ class ClusterAssetsView(AdminUserRequiredMixin, DetailView): ...@@ -97,5 +97,5 @@ class ClusterAssetsView(AdminUserRequiredMixin, DetailView):
class ClusterDeleteView(AdminUserRequiredMixin, DeleteView): class ClusterDeleteView(AdminUserRequiredMixin, DeleteView):
model = Cluster model = Cluster
template_name = 'assets/delete_confirm.html' template_name = 'delete_confirm.html'
success_url = reverse_lazy('assets:cluster-list') success_url = reverse_lazy('assets:cluster-list')
...@@ -101,6 +101,6 @@ class AssetGroupUpdateView(AdminUserRequiredMixin, UpdateView): ...@@ -101,6 +101,6 @@ class AssetGroupUpdateView(AdminUserRequiredMixin, UpdateView):
class AssetGroupDeleteView(AdminUserRequiredMixin, DeleteView): class AssetGroupDeleteView(AdminUserRequiredMixin, DeleteView):
template_name = 'assets/delete_confirm.html' template_name = 'delete_confirm.html'
model = AssetGroup model = AssetGroup
success_url = reverse_lazy('assets:asset-group-list') success_url = reverse_lazy('assets:asset-group-list')
...@@ -99,7 +99,7 @@ class SystemUserDetailView(AdminUserRequiredMixin, DetailView): ...@@ -99,7 +99,7 @@ class SystemUserDetailView(AdminUserRequiredMixin, DetailView):
class SystemUserDeleteView(AdminUserRequiredMixin, DeleteView): class SystemUserDeleteView(AdminUserRequiredMixin, DeleteView):
model = SystemUser model = SystemUser
template_name = 'assets/delete_confirm.html' template_name = 'delete_confirm.html'
success_url = reverse_lazy('assets:system-user-list') success_url = reverse_lazy('assets:system-user-list')
......
This diff is collapsed.
...@@ -1067,13 +1067,13 @@ msgstr "配置" ...@@ -1067,13 +1067,13 @@ msgstr "配置"
msgid "Location" msgid "Location"
msgstr "位置" msgstr "位置"
#: assets/templates/assets/delete_confirm.html:6 #: assets/templates/delete_confirm.html:6
#: perms/templates/perms/delete_confirm.html:6 #: perms/templates/delete_confirm.html:6
#: users/templates/users/user_delete_confirm.html:6 #: users/templates/users/user_delete_confirm.html:6
msgid "Confirm delete" msgid "Confirm delete"
msgstr "确认删除" msgstr "确认删除"
#: assets/templates/assets/delete_confirm.html:11 #: assets/templates/delete_confirm.html:11
msgid "Are you sure delete" msgid "Are you sure delete"
msgstr "您确定删除吗?" msgstr "您确定删除吗?"
......
...@@ -19,7 +19,7 @@ from .hands import AdminUserRequiredMixin, User, UserGroup, SystemUser, \ ...@@ -19,7 +19,7 @@ from .hands import AdminUserRequiredMixin, User, UserGroup, SystemUser, \
Asset, AssetGroup Asset, AssetGroup
from .models import AssetPermission from .models import AssetPermission
from .forms import AssetPermissionForm from .forms import AssetPermissionForm
from .utils import associate_system_users_and_assets # from .utils import associate_system_users_and_assets
class AssetPermissionListView(AdminUserRequiredMixin, ListView): class AssetPermissionListView(AdminUserRequiredMixin, ListView):
...@@ -87,15 +87,15 @@ class AssetPermissionCreateView(AdminUserRequiredMixin, ...@@ -87,15 +87,15 @@ class AssetPermissionCreateView(AdminUserRequiredMixin,
'successfully.'.format(url=url, name=self.object.name)) 'successfully.'.format(url=url, name=self.object.name))
return success_message return success_message
def form_valid(self, form): # Todo: When create push system user
assets = form.cleaned_data['assets'] # def form_valid(self, form):
asset_groups = form.cleaned_data['asset_groups'] # assets = form.cleaned_data['assets']
system_users = form.cleaned_data['system_users'] # asset_groups = form.cleaned_data['asset_groups']
associate_system_users_and_assets(system_users, assets, asset_groups) # system_users = form.cleaned_data['system_users']
response = super(AssetPermissionCreateView, self).form_valid(form) # response = super(AssetPermissionCreateView, self).form_valid(form)
self.object.created_by = self.request.user.name # self.object.created_by = self.request.user.name
self.object.save() # self.object.save()
return response # return response
class AssetPermissionUpdateView(AdminUserRequiredMixin, UpdateView): class AssetPermissionUpdateView(AdminUserRequiredMixin, UpdateView):
...@@ -150,7 +150,7 @@ class AssetPermissionDetailView(AdminUserRequiredMixin, DetailView): ...@@ -150,7 +150,7 @@ class AssetPermissionDetailView(AdminUserRequiredMixin, DetailView):
class AssetPermissionDeleteView(AdminUserRequiredMixin, DeleteView): class AssetPermissionDeleteView(AdminUserRequiredMixin, DeleteView):
model = AssetPermission model = AssetPermission
template_name = 'perms/delete_confirm.html' template_name = 'delete_confirm.html'
success_url = reverse_lazy('perms:asset-permission-list') success_url = reverse_lazy('perms:asset-permission-list')
......
{% load i18n %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{% trans 'Confirm delete' %}</title>
</head>
<body>
<form action="" method="post">
{% csrf_token %}
<p>{% trans 'Are you sure delete' %} <b>{{ object.name }} </b> ?</p>
<input type="submit" value="Confirm" />
</form>
</body>
</html>
\ No newline at end of file
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
{% load i18n %} {% load i18n %}
{% load static %} {% load static %}
{% load common_tags %} {% load common_tags %}
{% block content_left_head %} {% block custom_head_css_js %}
<link href="{% static "css/plugins/footable/footable.core.css" %}" rel="stylesheet"> <link href="{% static "css/plugins/footable/footable.core.css" %}" rel="stylesheet">
<link href="{% static 'css/plugins/datepicker/datepicker3.css' %}" rel="stylesheet"> <link href="{% static 'css/plugins/datepicker/datepicker3.css' %}" rel="stylesheet">
<style> <style>
...@@ -12,6 +12,10 @@ ...@@ -12,6 +12,10 @@
</style> </style>
{% endblock %} {% endblock %}
{% block content_left_head %}
123
{% endblock %}
{% block table_search %} {% block table_search %}
<form id="search_form" method="get" action="" class="pull-right form-inline"> <form id="search_form" method="get" action="" class="pull-right form-inline">
<div class="form-group" id="date"> <div class="form-group" id="date">
...@@ -26,7 +30,7 @@ ...@@ -26,7 +30,7 @@
<select class="select2 form-control" name="username"> <select class="select2 form-control" name="username">
<option value="">{% trans 'User' %}</option> <option value="">{% trans 'User' %}</option>
{% for u in user_list %} {% for u in user_list %}
<option value="{{ u }}" {% if user == u %} selected {% endif %}>{{ u }}</option> <option value="{{ u }}" {% if u == username %} selected {% endif %}>{{ u }}</option>
{% endfor %} {% endfor %}
</select> </select>
</div> </div>
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
{% load i18n %} {% load i18n %}
{% load static %} {% load static %}
{% load terminal_tags %} {% load terminal_tags %}
{% block content_left_head %} {% block custom_head_css_js %}
<link href="{% static 'css/plugins/datepicker/datepicker3.css' %}" rel="stylesheet"> <link href="{% static 'css/plugins/datepicker/datepicker3.css' %}" rel="stylesheet">
<style> <style>
#search_btn { #search_btn {
...@@ -11,6 +11,9 @@ ...@@ -11,6 +11,9 @@
</style> </style>
{% endblock %} {% endblock %}
{% block content_left_head %}
{% endblock %}
{% block table_search %} {% block table_search %}
<form id="search_form" method="get" action="" class="pull-right form-inline"> <form id="search_form" method="get" action="" class="pull-right form-inline">
...@@ -26,7 +29,7 @@ ...@@ -26,7 +29,7 @@
<select class="select2 form-control" name="user"> <select class="select2 form-control" name="user">
<option value="">{% trans 'User' %}</option> <option value="">{% trans 'User' %}</option>
{% for u in user_list %} {% for u in user_list %}
<option value="{{ u }}" {% if u == user %} selected {% endif %}>{{ u }}</option> <option value="{{ u }}" {% if u == username %} selected {% endif %}>{{ u }}</option>
{% endfor %} {% endfor %}
</select> </select>
</div> </div>
...@@ -106,10 +109,17 @@ ...@@ -106,10 +109,17 @@
function success() { function success() {
window.setTimeout(function () { window.setTimeout(function () {
window.location.reload() window.location.reload()
}, 300) }, 1000)
} }
var success_message = '{% trans "Terminate task send, waiting ..." %}';
var the_url = "{% url 'api-terminal:tasks-list' %}"; var the_url = "{% url 'api-terminal:tasks-list' %}";
APIUpdateAttr({url: the_url, method: 'POST', body: JSON.stringify(data), success: success, success_message: 'Terminate success'}); APIUpdateAttr({
url: the_url,
method: 'POST',
body: JSON.stringify(data),
success: success,
success_message: success_message
});
} }
$(document).ready(function() { $(document).ready(function() {
$('table').DataTable({ $('table').DataTable({
...@@ -118,7 +128,9 @@ ...@@ -118,7 +128,9 @@
"bInfo" : false, "bInfo" : false,
"order": [] "order": []
}); });
$('.select2').select2(); $('.select2').select2({
dropdownAutoWidth: true
});
$('#date .input-daterange').datepicker({ $('#date .input-daterange').datepicker({
dateFormat: 'mm/dd/yy', dateFormat: 'mm/dd/yy',
keyboardNavigation: false, keyboardNavigation: false,
...@@ -135,12 +147,6 @@ ...@@ -135,12 +147,6 @@
terminal: terminal_id terminal: terminal_id
}; };
terminateSession(data) terminateSession(data)
}).on('click', '#btn_bulk_update', function () {
var data = [];
$('.cbx-term:checked').each(function () {
data.push({proxy_log_id: $(this).attr('value')})
});
terminateSession(data)
}) })
</script> </script>
{% endblock %} {% endblock %}
......
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
{% load i18n static %} {% load i18n static %}
{% block custom_head_css_js %} {% block custom_head_css_js %}
{{ block.super }} {{ block.super }}
<style> <style>
div.dataTables_wrapper div.dataTables_filter, div.dataTables_wrapper div.dataTables_filter,
.dataTables_length { .dataTables_length {
...@@ -15,9 +14,10 @@ ...@@ -15,9 +14,10 @@
#modal .modal-body { max-height: 200px; } #modal .modal-body { max-height: 200px; }
</style> </style>
{% endblock %} {% endblock %}
{% block table_search %}{% endblock %} {% block table_search %}{% endblock %}
{% block table_container %} {% block table_container %}
{#<div class="uc pull-left m-l-5 m-r-5"><a href="{% url "users:user-create" %}" class="btn btn-sm btn-primary"> {% trans "Create user" %} </a></div>#}
<table class="table table-striped table-bordered table-hover " id="terminal_list_table" > <table class="table table-striped table-bordered table-hover " id="terminal_list_table" >
<thead> <thead>
<tr> <tr>
...@@ -40,12 +40,11 @@ ...@@ -40,12 +40,11 @@
</tbody> </tbody>
</table> </table>
{% include 'terminal/terminal_modal_accept.html' %} {% include 'terminal/terminal_modal_accept.html' %}
{% endblock %} {% endblock %}
{% block custom_foot_js %} {% block custom_foot_js %}
<script src="{% static 'js/jquery.form.min.js' %}"></script> <script src="{% static 'js/jquery.form.min.js' %}"></script>
<script> <script>
$(document).ready(function(){ function initTable() {
var options = { var options = {
ele: $('#terminal_list_table'), ele: $('#terminal_list_table'),
buttons: [], buttons: [],
...@@ -100,19 +99,20 @@ $(document).ready(function(){ ...@@ -100,19 +99,20 @@ $(document).ready(function(){
op_html: $('#actions').html() op_html: $('#actions').html()
}; };
jumpserver.initDataTable(options); jumpserver.initDataTable(options);
}
$(document).ready(function(){
initTable();
$('#btn_terminal_accept').click(function () { }).on('click', '#btn-confirm',function () {
var $form = $('#form_terminal_accept'); var $form = $('#form_terminal_accept');
function success(data, textStatus, jqXHR) { function success(data, textStatus, jqXHR) {
if (data.success === true) { if (data.success === true) {
window.location.reload() window.location.reload()
} else { } else {
$('#modal-error').html(data.msg).css('display', 'block'); $('#modal-error').html(data.msg).css('display', 'block');
}
} }
$form.ajaxSubmit({success: success}); }
}) $form.ajaxSubmit({success: success});
}).on('click', '.btn-del', function(){ }).on('click', '.btn-del', function(){
var $this = $(this); var $this = $(this);
var id = $this.data('id'); var id = $this.data('id');
...@@ -124,8 +124,7 @@ $(document).ready(function(){ ...@@ -124,8 +124,7 @@ $(document).ready(function(){
var $this = $(this); var $this = $(this);
var terminal_id = $this.data('id'); var terminal_id = $this.data('id');
var the_url = "{% url 'api-terminal:terminal-detail' pk=DEFAULT_PK %}".replace('{{ DEFAULT_PK }}', terminal_id); var the_url = "{% url 'api-terminal:terminal-detail' pk=DEFAULT_PK %}".replace('{{ DEFAULT_PK }}', terminal_id);
var post_url = $('#form_terminal_accept').attr('action').replace('{{ DEFAULT_PK }}', terminal_id); var post_url = "{% url 'terminal:terminal-accept' pk=DEFAULT_PK %}".replace('{{ DEFAULT_PK }}', terminal_id);
console.log(post_url);
$.ajax({ $.ajax({
url: the_url, url: the_url,
method: 'GET', method: 'GET',
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
{% block modal_title%}{% trans "Accept terminal registration" %}{% endblock %} {% block modal_title%}{% trans "Accept terminal registration" %}{% endblock %}
{% block modal_body %} {% block modal_body %}
{% load bootstrap3 %} {% load bootstrap3 %}
<form action="{% url 'terminal:terminal-accept' pk="{{ DEFAULT_PK }}" %}" method="post" class="form-horizontal" id="form_terminal_accept" enctype="multipart/form-data"> <form action="" method="post" class="form-horizontal" id="form_terminal_accept" enctype="multipart/form-data">
{% csrf_token %} {% csrf_token %}
<p class="alert alert-danger" id="modal-error" style="display: none"></p> <p class="alert alert-danger" id="modal-error" style="display: none"></p>
{% bootstrap_field form.name layout="horizontal" %} {% bootstrap_field form.name layout="horizontal" %}
...@@ -16,4 +16,4 @@ ...@@ -16,4 +16,4 @@
</form> </form>
{% endblock %} {% endblock %}
{% block modal_confirm_id %}btn_terminal_accept{% endblock %} {% block modal_confirm_id %}btn-confirm{% endblock %}
\ No newline at end of file \ No newline at end of file
...@@ -10,8 +10,8 @@ from .. import api ...@@ -10,8 +10,8 @@ from .. import api
app_name = 'terminal' app_name = 'terminal'
router = routers.DefaultRouter() router = routers.DefaultRouter()
router.register(r'v1/terminal/(?P<terminal>[0-9]+)?/?status', api.StatusViewSet, 'terminal-status') router.register(r'v1/terminal/(?P<terminal>[a-zA-Z0-9\-]{36})?/?status', api.StatusViewSet, 'terminal-status')
router.register(r'v1/terminal/(?P<terminal>[0-9]+)?/?sessions', api.SessionViewSet, 'terminal-sessions') router.register(r'v1/terminal/(?P<terminal>a-zA-Z0-9\-]{36})?/?sessions', api.SessionViewSet, 'terminal-sessions')
router.register(r'v1/tasks', api.TaskViewSet, 'tasks') router.register(r'v1/tasks', api.TaskViewSet, 'tasks')
router.register(r'v1/terminal', api.TerminalViewSet, 'terminal') router.register(r'v1/terminal', api.TerminalViewSet, 'terminal')
router.register(r'v1/command', api.CommandViewSet, 'command') router.register(r'v1/command', api.CommandViewSet, 'command')
......
...@@ -70,7 +70,7 @@ class CommandListView(ListView): ...@@ -70,7 +70,7 @@ class CommandListView(ListView):
'command': self.command, 'command': self.command,
'date_from': self.date_from_s, 'date_from': self.date_from_s,
'date_to': self.date_to_s, 'date_to': self.date_to_s,
'user': self.user, 'username': self.user,
'asset': self.asset, 'asset': self.asset,
'system_user': self.system_user, 'system_user': self.system_user,
} }
......
...@@ -78,7 +78,7 @@ class SessionListView(AdminUserRequiredMixin, ListView): ...@@ -78,7 +78,7 @@ class SessionListView(AdminUserRequiredMixin, ListView):
'system_user_list': utils.get_system_user_list_from_cache(), 'system_user_list': utils.get_system_user_list_from_cache(),
'date_from': self.date_from_s, 'date_from': self.date_from_s,
'date_to': self.date_to_s, 'date_to': self.date_to_s,
'user': self.user, 'username': self.user,
'asset': self.asset, 'asset': self.asset,
'system_user': self.system_user, 'system_user': self.system_user,
} }
...@@ -122,6 +122,7 @@ class SessionOfflineListView(SessionListView): ...@@ -122,6 +122,7 @@ class SessionOfflineListView(SessionListView):
class SessionDetailView(SingleObjectMixin, ListView): class SessionDetailView(SingleObjectMixin, ListView):
template_name = 'terminal/session_detail.html' template_name = 'terminal/session_detail.html'
model = Session model = Session
object = None
def get_queryset(self): def get_queryset(self):
self.object = self.get_object() self.object = self.get_object()
......
...@@ -62,14 +62,14 @@ class TerminalDetailView(LoginRequiredMixin, DetailView): ...@@ -62,14 +62,14 @@ class TerminalDetailView(LoginRequiredMixin, DetailView):
class TerminalDeleteView(AdminUserRequiredMixin, DeleteView): class TerminalDeleteView(AdminUserRequiredMixin, DeleteView):
model = Terminal model = Terminal
template_name = 'assets/delete_confirm.html' template_name = 'delete_confirm.html'
success_url = reverse_lazy('terminal:terminal-list') success_url = reverse_lazy('terminal:terminal-list')
class TerminalAcceptView(AdminUserRequiredMixin, JSONResponseMixin, UpdateView): class TerminalAcceptView(AdminUserRequiredMixin, JSONResponseMixin, UpdateView):
model = Terminal model = Terminal
form_class = TerminalForm form_class = TerminalForm
template_name = 'Terminal/terminal_modal_test.html' template_name = 'terminal/terminal_modal_accept.html'
def form_valid(self, form): def form_valid(self, form):
terminal = form.save() terminal = form.save()
......
...@@ -49,5 +49,4 @@ class LoginLog(models.Model): ...@@ -49,5 +49,4 @@ class LoginLog(models.Model):
datetime = models.DateTimeField(auto_now_add=True, verbose_name=_('Date login')) datetime = models.DateTimeField(auto_now_add=True, verbose_name=_('Date login'))
class Meta: class Meta:
db_table = 'login_log'
ordering = ['-datetime', 'username'] ordering = ['-datetime', 'username']
...@@ -38,9 +38,9 @@ class User(AbstractUser): ...@@ -38,9 +38,9 @@ class User(AbstractUser):
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'))
secret_key_otp = models.CharField(max_length=16, blank=True) secret_key_otp = models.CharField(max_length=16, blank=True)
# Todo: private_key may be not used # Todo: Auto generate key, let user download
_private_key = models.CharField(max_length=5000, blank=True, verbose_name=_('ssh private key')) _private_key = models.CharField(max_length=5000, blank=True, verbose_name=_('Private key'))
_public_key = models.CharField(max_length=5000, blank=True, verbose_name=_('ssh public key')) _public_key = models.CharField(max_length=5000, blank=True, verbose_name=_('Public key'))
comment = models.TextField(max_length=200, blank=True, verbose_name=_('Comment')) comment = models.TextField(max_length=200, blank=True, verbose_name=_('Comment'))
is_first_login = models.BooleanField(default=False) is_first_login = models.BooleanField(default=False)
date_expired = models.DateTimeField(default=date_expired_default, blank=True, null=True, verbose_name=_('Date expired')) date_expired = models.DateTimeField(default=date_expired_default, blank=True, null=True, verbose_name=_('Date expired'))
......
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