Commit 4e7b665e authored by ibuler's avatar ibuler

[Change] 添加翻译,并添加用户登陆页面

parent a4ad9b49
...@@ -11,7 +11,7 @@ from django.shortcuts import get_object_or_404 ...@@ -11,7 +11,7 @@ from django.shortcuts import get_object_or_404
from common.mixins import IDInFilterMixin from common.mixins import IDInFilterMixin
from common.utils import get_object_or_none, signer from common.utils import get_object_or_none, signer
from .hands import IsSuperUser, IsAppUser from .hands import IsSuperUser, IsAppUser, IsValidUser, get_user_granted_assets
from .models import AssetGroup, Asset, IDC, SystemUser, AdminUser from .models import AssetGroup, Asset, IDC, SystemUser, AdminUser
from . import serializers from . import serializers
...@@ -20,10 +20,13 @@ class AssetViewSet(IDInFilterMixin, BulkModelViewSet): ...@@ -20,10 +20,13 @@ class AssetViewSet(IDInFilterMixin, BulkModelViewSet):
"""API endpoint that allows Asset to be viewed or edited.""" """API endpoint that allows Asset to be viewed or edited."""
queryset = Asset.objects.all() queryset = Asset.objects.all()
serializer_class = serializers.AssetSerializer serializer_class = serializers.AssetSerializer
permission_classes = (IsSuperUser,) permission_classes = (IsValidUser,)
def get_queryset(self): def get_queryset(self):
queryset = super(AssetViewSet, self).get_queryset() if self.request.user.is_superuser:
queryset = super(AssetViewSet, self).get_queryset()
else:
queryset = get_user_granted_assets(self.request.user)
idc_id = self.request.query_params.get('idc_id', '') idc_id = self.request.query_params.get('idc_id', '')
system_users_id = self.request.query_params.get('system_user_id', '') system_users_id = self.request.query_params.get('system_user_id', '')
asset_group_id = self.request.query_params.get('asset_group_id', '') asset_group_id = self.request.query_params.get('asset_group_id', '')
......
...@@ -12,5 +12,6 @@ ...@@ -12,5 +12,6 @@
from users.utils import AdminUserRequiredMixin from users.utils import AdminUserRequiredMixin
from users.permissions import IsAppUser, IsSuperUser from users.permissions import IsAppUser, IsSuperUser, IsValidUser
from users.models import User, UserGroup from users.models import User, UserGroup
from perms.utils import get_user_granted_assets
\ No newline at end of file
...@@ -99,7 +99,12 @@ class Asset(models.Model): ...@@ -99,7 +99,12 @@ class Asset(models.Model):
return False, warning return False, warning
def to_json(self): def to_json(self):
pass return {
'id': self.id,
'hostname': self.hostname,
'ip': self.ip,
'port': self.port,
}
def _to_secret_json(self): def _to_secret_json(self):
"""Ansible use it create inventory""" """Ansible use it create inventory"""
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
<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="" class="text-center"><i class="fa fa-laptop"></i> {% trans 'Asset detail' %} </a> <a href="{% url 'assets:asset-detail' %}" class="text-center"><i class="fa fa-laptop"></i> {% trans 'Asset detail' %} </a>
</li> </li>
<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>
......
{% extends '_base_list.html' %}
{% load i18n %}
{% load static %}
{% block custom_head_css_js %}
<link href="{% static 'css/plugins/select2/select2.min.css' %}" rel="stylesheet">
<script src="{% static 'js/plugins/select2/select2.full.min.js' %}"></script>
<style>
.custom{
margin-right:5px;
}
#modal .modal-body { max-height: 200px; }
</style>
{% endblock %}
{% block content_left_head %}{% endblock %}
{% block table_search %}
{# <div class="html5buttons">#}
{# <div class="dt-buttons btn-group">#}
{# <a class="btn btn-default btn_export" tabindex="0">#}
{# <span>{% trans "Export" %}</span>#}
{# </a>#}
{# </div>#}
{# </div>#}
{% endblock %}
{% block table_container %}
<table class="table table-striped table-bordered table-hover " id="asset_list_table" >
<thead>
<tr>
<th class="text-center"><input type="checkbox" class="ipt_check_all"></th>
<th class="text-center">{% trans 'Hostname' %}</th>
<th class="text-center">{% trans 'IP' %}</th>
<th class="text-center">{% trans 'Port' %}</th>
<th class="text-center">{% trans 'Type' %}</th>
<th class="text-center">{% trans 'Env' %}</th>
<th class="text-center">{% trans 'Hardware' %}</th>
<th class="text-center">{% trans 'Valid' %}</th>
<th class="text-center">{% trans 'Alive' %}</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
{% include 'assets/_asset_import_modal.html' %}
{% include 'assets/_asset_bulk_update_modal.html' %}
{% endblock %}
{% block custom_foot_js %}
<script src="{% static 'js/jquery.form.min.js' %}"></script>
<script type="text/javascript">
$(document).ready(function(){
var options = {
ele: $('#asset_list_table'),
columnDefs: [
{targets: 1, createdCell: function (td, cellData, rowData) {
var detail_btn = '<a href="{% url "assets:asset-detail" pk=99991937 %}">' + cellData + '</a>';
$(td).html(detail_btn.replace('99991937', rowData.id));
}},
{targets: 7, createdCell: function (td, cellData) {
if (!cellData) {
$(td).html('<i class="fa fa-times text-danger"></i>')
} else {
$(td).html('<i class="fa fa-check text-navy"></i>')
}
}},
{targets: 8, createdCell: function (td, cellData) {
if (!cellData) {
$(td).html('<i class="fa fa-circle text-danger"></i>')
} else {
$(td).html('<i class="fa fa-circle text-navy"></i>')
}
}}
],
ajax_url: '{% url "api-assets:asset-list" %}',
columns: [{data: "id"}, {data: "hostname" }, {data: "ip" }, {data: "port" },
{data: "get_type_display" }, {data: "get_env_display"}, {data: "hardware"},
{data: "is_active" }, {data: "is_active"}],
};
var table = jumpserver.initDataTable(options);
$('.btn_export').click(function () {
var assets = [];
var rows = table.rows('.selected').data();
$.each(rows, function (index, obj) {
assets.push(obj.id)
});
console.log(assets);
$.ajax({
url: "{% url "assets:asset-export" %}",
method: 'POST',
data: JSON.stringify({assets_id: assets}),
dataType: "json",
success: function (data, textStatus) {
window.open(data.redirect)
},
error: function () {
toastr.error('Export failed');
}
})
});
$('#btn_asset_import').click(function() {
var $form = $('#fm_asset_import');
$form.find('.help-block').remove();
function success (data) {
if (data.valid === false) {
$('<span />', {class: 'help-block text-danger'}).html(data.msg).insertAfter($('#id_assets'));
} else {
$('#id_created').html(data.created_info);
$('#id_created_detail').html(data.created.join(', '));
$('#id_updated').html(data.updated_info);
$('#id_updated_detail').html(data.updated.join(', '));
$('#id_failed').html(data.failed_info);
$('#id_failed_detail').html(data.failed.join(', '));
var $data_table = $('#asset_list_table').DataTable();
$data_table.ajax.reload();
}
}
$form.ajaxSubmit({success: success});
})
})
.on('click', '.btn_asset_delete', function () {
var $this = $(this);
var name = $(this).closest("tr").find(":nth-child(2)").children('a').html();
var uid = $this.data('uid');
var the_url = '{% url "api-assets:asset-detail" pk=99991937 %}'.replace('99991937', uid);
objectDelete($this, name, the_url);
})
.on('click', '#btn_bulk_update', function () {
var action = $('#slct_bulk_update').val();
var $data_table = $('#asset_list_table').DataTable();
var id_list = [];
var plain_id_list = [];
$data_table.rows({selected: true}).every(function(){
id_list.push({id: this.data().id});
plain_id_list.push(this.data().id);
});
if (plain_id_list.length == 0) {
return false;
}
var the_url = "{% url 'api-assets:asset-list' %}";
function doDeactive() {
var body = $.each(id_list, function(index, asset_object) {
asset_object['is_active'] = false;
});
APIUpdateAttr({url: the_url, method: 'PATCH', body: JSON.stringify(body)});
$data_table.ajax.reload();
jumpserver.checked = false;
}
function doActive() {
var body = $.each(id_list, function(index, asset_object) {
asset_object['is_active'] = true;
});
APIUpdateAttr({url: the_url, method: 'PATCH', body: JSON.stringify(body)});
$data_table.ajax.reload();
jumpserver.checked = false;
}
function doDelete() {
swal({
title: "{% trans 'Are you sure?' %}",
text: "{% trans 'This will delete the selected assets !!!' %}",
type: "warning",
showCancelButton: true,
confirmButtonColor: "#DD6B55",
confirmButtonText: "{% trans 'Confirm' %}",
closeOnConfirm: false
}, function() {
var success = function() {
var msg = "{% trans 'Asset Deleted.' %}";
swal("{% trans 'Asset Delete' %}", msg, "success");
$('#asset_list_table').DataTable().ajax.reload();
};
var fail = function() {
var msg = "{% trans 'Asset Deleting failed.' %}";
swal("{% trans 'Asset Delete' %}", msg, "error");
};
var url_delete = the_url + '?id__in=' + JSON.stringify(plain_id_list);
APIUpdateAttr({url: url_delete, method: 'DELETE', success: success, error: fail});
$data_table.ajax.reload();
jumpserver.checked = false;
});
}
function doUpdate() {
$('#asset_bulk_update_modal').modal('show');
}
switch(action) {
case 'deactive':
doDeactive();
break;
case 'delete':
doDelete();
break;
case 'update':
doUpdate();
break;
case 'active':
doActive();
break;
default:
break;
}
})
.on('click', '#btn_asset_bulk_update', function () {
var json_data = $("#fm_asset_bulk_update").serializeObject();
var body = {};
body.enable_otp = (json_data.enable_otp === 'on')? true: false;
if (json_data.type != '') {
body.type = json_data.type;
}
if (json_data.groups != undefined) {
body.groups = json_data.groups;
}
if (typeof body.groups === 'string') {
body.groups = [parseInt(body.groups)]
} else if(typeof body.groups === 'array') {
var new_groups = body.groups.map(Number);
body.groups = new_groups;
}
if (json_data.system_users != undefined) {
body.system_users = json_data.system_users;
}
if (typeof body.system_users === 'string') {
body.system_users = [parseInt(body.system_users)]
} else if(typeof body.system_users === 'array') {
var new_users = body.system_users.map(Number);
body.system_users = new_users;
}
if (json_data.tags != undefined) {
body.tags = json_data.tags;
}
if (typeof body.tags == 'string') {
body.tags = [parseInt(body.tags)];
} else if (typeof body.tags === 'array') {
var new_tags = body.tags.map(Number);
body.tags = new_tags;
}
var $data_table = $('#asset_list_table').DataTable();
var post_list = [];
$data_table.rows({selected: true}).every(function(){
var content = Object.assign({id: this.data().id}, body);
post_list.push(content);
});
if (post_list === []) {
return false
}
var the_url = "{% url 'api-assets:asset-list' %}";
var success = function() {
var msg = "{% trans 'The selected assets has been updated successfully.' %}";
swal("{% trans 'Asset Updated' %}", msg, "success");
$('#asset_list_table').DataTable().ajax.reload();
jumpserver.checked = false;
};
console.log(JSON.stringify(post_list));
console.log(the_url);
{# APIUpdateAttr({url: the_url, method: 'PATCH', body: JSON.stringify(post_list), success: success});#}
$('#asset_bulk_update_modal').modal('hide');
});
</script>
{% endblock %}
...@@ -17,6 +17,9 @@ urlpatterns = [ ...@@ -17,6 +17,9 @@ urlpatterns = [
url(r'^asset-modal$', views.AssetModalListView.as_view(), name='asset-modal-list'), url(r'^asset-modal$', views.AssetModalListView.as_view(), name='asset-modal-list'),
url(r'^asset-modal-update$', views.AssetModalCreateView.as_view(), name='asset-modal-update'), url(r'^asset-modal-update$', views.AssetModalCreateView.as_view(), name='asset-modal-update'),
# User asset view
url(r'^user-asset/$', views.UserAssetListView.as_view(), name='user-asset-list'),
# Resource asset group url # Resource asset group url
url(r'^asset-group/$', views.AssetGroupListView.as_view(), name='asset-group-list'), url(r'^asset-group/$', views.AssetGroupListView.as_view(), name='asset-group-list'),
url(r'^asset-group/create/$', views.AssetGroupCreateView.as_view(), name='asset-group-create'), url(r'^asset-group/create/$', views.AssetGroupCreateView.as_view(), name='asset-group-create'),
......
...@@ -44,6 +44,19 @@ class AssetListView(AdminUserRequiredMixin, TemplateView): ...@@ -44,6 +44,19 @@ class AssetListView(AdminUserRequiredMixin, TemplateView):
return super(AssetListView, self).get_context_data(**kwargs) return super(AssetListView, self).get_context_data(**kwargs)
class UserAssetListView(TemplateView):
template_name = 'assets/user_asset_list.html'
def get_context_data(self, **kwargs):
context = {
'app': 'Assets',
'action': 'asset list',
'system_users': SystemUser.objects.all(),
}
kwargs.update(context)
return super(UserAssetListView, self).get_context_data(**kwargs)
class AssetCreateView(AdminUserRequiredMixin, CreateView): class AssetCreateView(AdminUserRequiredMixin, CreateView):
model = Asset model = Asset
form_class = forms.AssetCreateForm form_class = forms.AssetCreateForm
......
...@@ -2391,45 +2391,33 @@ msgid "Create by" ...@@ -2391,45 +2391,33 @@ msgid "Create by"
msgstr "创建者" msgstr "创建者"
#: users/templates/users/user_group_detail.html:89 #: users/templates/users/user_group_detail.html:89
#, fuzzy
#| msgid "User"
msgid "Add user" msgid "Add user"
msgstr "用户" msgstr "创建用户"
#: users/templates/users/user_group_list.html:5 #: users/templates/users/user_group_list.html:5
#, fuzzy
#| msgid "Asset group"
msgid "Add User Group" msgid "Add User Group"
msgstr "资产组" msgstr "创建用户组"
#: users/templates/users/user_group_list.html:13 #: users/templates/users/user_group_list.html:13
#, fuzzy
#| msgid "User group"
msgid "User Amount" msgid "User Amount"
msgstr "用户" msgstr "用户数量"
#: users/templates/users/user_group_list.html:95 #: users/templates/users/user_group_list.html:95
#, fuzzy
#| msgid "User group list"
msgid "UserGroups Deleted." msgid "UserGroups Deleted."
msgstr "用户组列表" msgstr "用户组删除"
#: users/templates/users/user_group_list.html:96 #: users/templates/users/user_group_list.html:96
#: users/templates/users/user_group_list.html:101 #: users/templates/users/user_group_list.html:101
#, fuzzy
#| msgid "User group list"
msgid "UserGroups Delete" msgid "UserGroups Delete"
msgstr "用户组列表" msgstr "用户组删除"
#: users/templates/users/user_group_list.html:100 #: users/templates/users/user_group_list.html:100
msgid "UserGroup Deleting failed." msgid "UserGroup Deleting failed."
msgstr "" msgstr "用户组删除失败"
#: users/templates/users/user_list.html:42 #: users/templates/users/user_list.html:42
#, fuzzy
#| msgid "Deactive selected"
msgid "Active selected" msgid "Active selected"
msgstr "禁用所选" msgstr "激活所选"
#: users/templates/users/user_list.html:167 #: users/templates/users/user_list.html:167
msgid "This will delete the selected users !!!" msgid "This will delete the selected users !!!"
...@@ -2438,51 +2426,37 @@ msgstr "" ...@@ -2438,51 +2426,37 @@ msgstr ""
# msgid "Deleted!" # msgid "Deleted!"
# msgstr "删除" # msgstr "删除"
#: users/templates/users/user_list.html:175 #: users/templates/users/user_list.html:175
#, fuzzy
#| msgid "has been deleted."
msgid "User Deleted." msgid "User Deleted."
msgstr "已被删除" msgstr "已被删除"
#: users/templates/users/user_list.html:176 #: users/templates/users/user_list.html:176
#: users/templates/users/user_list.html:181 #: users/templates/users/user_list.html:181
#, fuzzy
#| msgid "Delete"
msgid "User Delete" msgid "User Delete"
msgstr "删除" msgstr "删除"
#: users/templates/users/user_list.html:180 #: users/templates/users/user_list.html:180
#, fuzzy
#| msgid "User detail"
msgid "User Deleting failed." msgid "User Deleting failed."
msgstr "用户详情" msgstr "用户删除失败"
#: users/templates/users/user_list.html:240 #: users/templates/users/user_list.html:240
msgid "The selected users has been updated successfully." msgid "The selected users has been updated successfully."
msgstr "" msgstr ""
#: users/templates/users/user_list.html:241 #: users/templates/users/user_list.html:241
#, fuzzy
#| msgid "Update"
msgid "User Updated" msgid "User Updated"
msgstr "更新" msgstr "更新"
#: users/templates/users/user_profile.html:98 #: users/templates/users/user_profile.html:98
#, fuzzy
#| msgid "SSH private key"
msgid "Update Public Key" msgid "Update Public Key"
msgstr "ssh密钥" msgstr "更新公钥"
#: users/templates/users/user_profile.html:109 #: users/templates/users/user_profile.html:109
#, fuzzy
#| msgid "SSH private key"
msgid "Paste your SSH Public Key here" msgid "Paste your SSH Public Key here"
msgstr "ssh密钥" msgstr "复制公钥到这里"
#: users/templates/users/user_profile.html:131 #: users/templates/users/user_profile.html:131
#, fuzzy
#| msgid "SSH private key"
msgid "Failed to update SSH public key." msgid "Failed to update SSH public key."
msgstr "ssh密钥" msgstr "更新公钥失败"
#: users/templates/users/user_update.html:3 users/views/user.py:102 #: users/templates/users/user_update.html:3 users/views/user.py:102
msgid "Update user" msgid "Update user"
......
...@@ -194,6 +194,32 @@ class MyGrantedAssetsGroupsApi(APIView): ...@@ -194,6 +194,32 @@ class MyGrantedAssetsGroupsApi(APIView):
class MyAssetGroupAssetsApi(ListAPIView): class MyAssetGroupAssetsApi(ListAPIView):
permission_classes = (IsValidUser,)
def get(self, request, *args, **kwargs):
asset_groups = {}
# asset_group = {1: {'id': 1, 'name': 'hello', 'assets': set(),
# 'assets_id': set()}, 2: {}}
user = request.user
if user:
assets = get_user_granted_assets(user)
for asset in assets:
for asset_group in asset.groups.all():
if asset_group.id in asset_groups:
asset_groups[asset_group.id]['assets'].add(asset.to_json())
else:
asset_groups[asset_group.id] = {
'id': asset_group.id,
'name': asset_group.name,
'comment': asset_group.comment,
'assets': {asset.to_json()},
}
asset_groups_json = asset_groups.values()
return Response(asset_groups_json, status=200)
class MyAssetGroupOfAssetsApi(ListAPIView):
"""授权用户资产组下的资产列表, 非该资产组的所有资产,而是被授权的""" """授权用户资产组下的资产列表, 非该资产组的所有资产,而是被授权的"""
permission_classes = (IsValidUser,) permission_classes = (IsValidUser,)
serializer_class = AssetGrantedSerializer serializer_class = AssetGrantedSerializer
......
...@@ -20,8 +20,11 @@ urlpatterns = [ ...@@ -20,8 +20,11 @@ urlpatterns = [
api.MyGrantedAssetsGroupsApi.as_view(), api.MyGrantedAssetsGroupsApi.as_view(),
name='my-asset-groups'), name='my-asset-groups'),
url(r'^v1/user/my/asset-group/(?P<pk>[0-9]+)/assets/$', url(r'^v1/user/my/asset-group/(?P<pk>[0-9]+)/assets/$',
api.MyAssetGroupOfAssetsApi.as_view(),
name='my-asset-group-of-assets'),
url(r'^v1/user/my/asset-group-assets/$',
api.MyAssetGroupAssetsApi.as_view(), api.MyAssetGroupAssetsApi.as_view(),
name='user-my-asset-group-assets'), name='my-asset-group-assets'),
# 查询某个用户授权的资产和资产组 # 查询某个用户授权的资产和资产组
url(r'^v1/user/(?P<pk>[0-9]+)/assets/$', url(r'^v1/user/(?P<pk>[0-9]+)/assets/$',
......
{% load i18n %}
<li id="index"> <li id="index">
<a href=""> <a href="">
<i class="fa fa-dashboard"></i> <span class="nav-label">仪表盘</span><span class="label label-info pull-right"></span> <i class="fa fa-dashboard"></i><span class="nav-label">{% trans 'Dashboard' %}</span><span class="label label-info pull-right"></span>
</a> </a>
</li> </li>
<li id=""> <li id="assets">
<a href=""> <a href="{% url 'assets:user-asset-list' %}">
<i class="fa fa-files-o"></i><span class="nav-label">我的资产</span><span class="label label-info pull-right"></span> <i class="fa fa-files-o"></i><span class="nav-label">{% trans 'My assets' %}</span><span class="label label-info pull-right"></span>
</a> </a>
</li> </li>
<li id=""> <li id="users">
<a href="#"> <a href="{% url 'users:user-profile' %}">
<i class="fa fa-download"></i> <span class="nav-label">上传下载</span><span class="fa arrow"></span> <i class="fa fa-user" ></i> <span class="nav-label">{% trans 'Profile' %}</span><span class="label label-info pull-right"></span>
</a> </a>
<ul class="nav nav-second-level">
<li class="upload"><a href="">文件上传</a></li>
<li class="download"><a href="">文件下载</a></li>
</ul>
</li> </li>
<li id=""> <li id="applications">
<a href=""> <a href="{% url 'users:user-profile' %}">
<i class="fa fa-gears"></i> <span class="nav-label">用户信息</span><span class="label label-info pull-right"></span> <i class="fa fa-user" ></i> <span class="nav-label">{% trans 'Terminal' %}</span><span class="label label-info pull-right"></span>
</a> </a>
</li> </li>
<li class="special_link"> <li class="special_link">
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
</a> </a>
<ul class="dropdown-menu animated fadeInRight m-t-xs"> <ul class="dropdown-menu animated fadeInRight m-t-xs">
<li><a value="">{% trans 'Profile' %}</a></li> <li><a value="">{% trans 'Profile' %}</a></li>
<li><a value="">{% trans 'Profile settings' %}</a></li>
<li class="divider"></li> <li class="divider"></li>
<li><a href="">{% trans 'Logout' %}</a></li> <li><a href="">{% trans 'Logout' %}</a></li>
</ul> </ul>
......
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