pull/26/head
yumaojun 2015-12-14 20:28:39 +08:00
commit 05f80f743b
65 changed files with 522 additions and 1264 deletions

View File

@ -21,7 +21,7 @@ import uuid
os.environ['DJANGO_SETTINGS_MODULE'] = 'jumpserver.settings'
if django.get_version() != '1.6':
django.setup()
setup = django.setup()
from django.contrib.sessions.models import Session
from jumpserver.api import ServerError, User, Asset, PermRole, AssetGroup, get_object, mkdir, get_asset_info
from jumpserver.api import logger, Log, TtyLog, get_role_key, CRYPTOR, bash, get_tmp_dir
@ -526,7 +526,7 @@ class Nav(object):
user_asset_search = user_asset_all
self.search_result = dict(zip(range(len(user_asset_search)), user_asset_search))
color_print('[%-3s] %-12s %-15s %-5s %-10s %s' % ('ID', u'主机名', 'IP', u'端口', u'角色', u'备注'), 'title')
color_print('[%-3s] %-12s %-15s %-5s %-10s %s' % ('ID', u'主机名', 'IP', u'端口', u'系统用户', u'备注'), 'title')
for index, asset in self.search_result.items():
# 获取该资产信息
asset_info = get_asset_info(asset)
@ -556,13 +556,13 @@ class Nav(object):
roles = self.user_perm.get('role').keys()
if len(roles) > 1: # 授权角色数大于1
color_print('[%-2s] %-15s' % ('ID', '角色'), 'info')
color_print('[%-2s] %-15s' % ('ID', '系统用户'), 'info')
role_check = dict(zip(range(len(roles)), roles))
for i, r in role_check.items():
print '[%-2s] %-15s' % (i, r.name)
print
print "请输入运行命令角色的ID, q退出"
print "请输入运行命令所关联系统用户的ID, q退出"
try:
role_id = raw_input("\033[1;32mRole>:\033[0m ").strip()
@ -575,7 +575,7 @@ class Nav(object):
elif len(roles) == 1: # 授权角色数为1
role = roles[0]
assets = list(self.user_perm.get('role', {}).get(role).get('asset')) # 获取该用户,角色授权主机
print "该角色有权限的所有主机"
print "授权包含该系统用户的所有主机"
for asset in assets:
print ' %s' % asset.hostname
print
@ -766,11 +766,11 @@ def main():
roles = nav.user_perm.get('asset').get(asset).get('role')
if len(roles) > 1:
role_check = dict(zip(range(len(roles)), roles))
print "\033[32m[ID] 角色\033[0m"
print "\033[32m[ID] 系统用户\033[0m"
for index, role in role_check.items():
print "[%-2s] %s" % (index, role.name)
print
print "授权角色超过1个请输入角色ID, q退出"
print "授权系统用户超过1个请输入ID, q退出"
try:
role_index = raw_input("\033[1;32mID>:\033[0m ").strip()
if role_index == 'q':

View File

@ -30,7 +30,7 @@ connect.py逻辑说明
匹配到0了就显示没有权限或者主机
匹配到1个则继续
查询该服务器是否支持ldap 如果是获得ldap用户密码登陆
如果否,查询授权表,查看该服务器授权的角色,并返回对应账号密码,登陆
如果否,查询授权表,查看该服务器授权的系统用户,并返回对应账号密码,登陆
connect函数是登陆函数采用paramiko 使用channel登陆posix_shell 来完成交互,并记录日志
signal模块来完成窗口改变导致的tty大小随之改变
PyCrypt是对称加密类

View File

@ -40,14 +40,14 @@ class AssetGroup(models.Model):
class IDC(models.Model):
name = models.CharField(max_length=32, verbose_name=u'机房名称')
bandwidth = models.CharField(max_length=32, blank=True, null=True, verbose_name=u'机房带宽')
linkman = models.CharField(max_length=16, blank=True, null=True, verbose_name=u'联系人')
phone = models.CharField(max_length=32, blank=True, null=True, verbose_name=u'联系电话')
address = models.CharField(max_length=128, blank=True, null=True, verbose_name=u"机房地址")
network = models.TextField(blank=True, null=True, verbose_name=u"IP地址段")
date_added = models.DateField(auto_now=True, null=True)
operator = models.CharField(max_length=32, blank=True, null=True, verbose_name=u"运营商")
comment = models.CharField(max_length=128, blank=True, null=True, verbose_name=u"备注")
bandwidth = models.CharField(max_length=32, blank=True, null=True, default='', verbose_name=u'机房带宽')
linkman = models.CharField(max_length=16, blank=True, null=True, default='', verbose_name=u'联系人')
phone = models.CharField(max_length=32, blank=True, null=True, default='', verbose_name=u'联系电话')
address = models.CharField(max_length=128, blank=True, null=True, default='', verbose_name=u"机房地址")
network = models.TextField(blank=True, null=True, default='', verbose_name=u"IP地址段")
date_added = models.DateField(auto_now=True, default='', null=True)
operator = models.CharField(max_length=32, blank=True, default='', null=True, verbose_name=u"运营商")
comment = models.CharField(max_length=128, blank=True, default='', null=True, verbose_name=u"备注")
def __unicode__(self):
return self.name

View File

@ -3,23 +3,22 @@ from django.conf.urls import patterns, include, url
from jasset.views import *
urlpatterns = patterns('',
url(r'^asset_add/$', asset_add),
url(r"^asset_add_batch/$", asset_add_batch),
url(r'^group_del/$', group_del),
url(r'^asset_list/$', asset_list),
url(r'^asset_del/$', asset_del),
url(r"^asset_detail/$", asset_detail),
url(r'^asset_edit/$', asset_edit),
url(r'^asset_update/$', asset_update),
url(r'^asset_update_batch/$', asset_update_batch),
url(r'^group_add/$', group_add),
url(r'^group_list/$', group_list),
url(r'^group_edit/$', group_edit),
url(r'^group_list/$', group_list),
url(r'^asset_edit_batch/$', asset_edit_batch),
url(r'^idc_add/$', idc_add),
url(r'^idc_list/$', idc_list),
url(r'^idc_edit/$', idc_edit),
url(r'^idc_del/$', idc_del),
url(r'^upload/$', asset_upload),
url(r'^asset/add/$', asset_add, name='asset_add'),
url(r"^asset/add_batch/$", asset_add_batch, name='asset_add_batch'),
url(r'^asset/list/$', asset_list, name='asset_list'),
url(r'^asset/del/$', asset_del, name='asset_del'),
url(r"^asset/detail/$", asset_detail, name='asset_detail'),
url(r'^asset/edit/$', asset_edit, name='asset_edit'),
url(r'^asset/edit_batch/$', asset_edit_batch, name='asset_edit_batch'),
url(r'^asset/update/$', asset_update, name='asset_update'),
url(r'^asset/update_batch/$', asset_update_batch, name='asset_update_batch'),
url(r'^asset/upload/$', asset_upload, name='asset_upload'),
url(r'^group/del/$', group_del, name='asset_group_del'),
url(r'^group/add/$', group_add, name='asset_group_add'),
url(r'^group/list/$', group_list, name='asset_group_list'),
url(r'^group/edit/$', group_edit, name='asset_group_edit'),
url(r'^idc/add/$', idc_add, name='idc_add'),
url(r'^idc/list/$', idc_list, name='idc_list'),
url(r'^idc/edit/$', idc_edit, name='idc_edit'),
url(r'^idc/del/$', idc_del, name='idc_del'),
)

View File

@ -81,7 +81,7 @@ def group_edit(request):
db_update_group(id=group_id, name=name, comment=comment, asset_select=asset_select)
smg = u"主机组 %s 添加成功" % name
return HttpResponseRedirect('/jasset/group_list')
return HttpResponseRedirect(reverse('asset_group_list'))
return my_render('jasset/group_edit.html', locals(), request)
@ -246,7 +246,7 @@ def asset_edit(request):
else:
emg = u'主机 %s 修改失败' % ip
return my_render('jasset/error.html', locals(), request)
return HttpResponseRedirect('/jasset/asset_detail/?id=%s' % asset_id)
return HttpResponseRedirect(reverse('asset_detail')+'?id=%s' % asset_id)
return my_render('jasset/asset_edit.html', locals(), request)
@ -263,7 +263,6 @@ def asset_list(request):
asset_group_all = AssetGroup.objects.all()
asset_types = ASSET_TYPE
asset_status = ASSET_STATUS
asset_id = request.GET.get('id')
idc_name = request.GET.get('idc', '')
group_name = request.GET.get('group', '')
asset_type = request.GET.get('asset_type', '')
@ -273,6 +272,7 @@ def asset_list(request):
group_id = request.GET.get("group_id", '')
idc_id = request.GET.get("idc_id", '')
asset_id_all = request.GET.getlist("id", '')
if group_id:
group = get_object(AssetGroup, id=group_id)
if group:
@ -302,9 +302,6 @@ def asset_list(request):
if status:
asset_find = asset_find.filter(status__contains=status)
if asset_id:
asset_find = asset_find.filter(id=asset_id)
if keyword:
asset_find = asset_find.filter(
Q(hostname__contains=keyword) |
@ -451,10 +448,10 @@ def asset_update(request):
asset = get_object(Asset, id=asset_id)
name = request.user.username
if not asset:
return HttpResponseRedirect('/jasset/asset_detail/?id=%s' % asset_id)
return HttpResponseRedirect(reverse('asset_detail')+'?id=%s' % asset_id)
else:
asset_ansible_update([asset], name)
return HttpResponseRedirect('/jasset/asset_detail/?id=%s' % asset_id)
return HttpResponseRedirect(reverse('asset_detail')+'/?id=%s' % asset_id)
@require_role('admin')
@ -494,7 +491,7 @@ def idc_add(request):
else:
idc_form.save()
smg = u'IDC: %s添加成功' % idc_name
return HttpResponseRedirect("/jasset/idc_list/")
return HttpResponseRedirect(reverse('idc_list'))
else:
idc_form = IdcForm()
return my_render('jasset/idc_add.html', locals(), request)
@ -528,7 +525,7 @@ def idc_edit(request):
idc_form = IdcForm(request.POST, instance=idc)
if idc_form.is_valid():
idc_form.save()
return HttpResponseRedirect("/jasset/idc_list/")
return HttpResponseRedirect(reverse('idc_list'))
else:
idc_form = IdcForm(instance=idc)
return my_render('jasset/idc_edit.html', locals(), request)
@ -545,7 +542,7 @@ def idc_del(request):
for idc_id in idc_id_list:
IDC.objects.filter(id=idc_id).delete()
return HttpResponseRedirect('/jasset/idc_list/')
return HttpResponseRedirect(reverse('idc_list'))
@require_role('admin')

View File

@ -3,11 +3,9 @@ from django.conf.urls import patterns, include, url
from jlog.views import *
urlpatterns = patterns('',
(r'^$', log_list),
(r'^log_list/(\w+)/$', log_list),
(r'^log_detail/(\w+)/$', log_detail),
(r'^history/$', log_history),
(r'^log_kill/', log_kill),
(r'^record/$', log_record),
(r'^web_terminal/$', web_terminal),
url(r'^list/(\w+)/$', log_list, name='log_list'),
url(r'^detail/(\w+)/$', log_detail, name='log_detail'),
url(r'^history/$', log_history, name='log_history'),
url(r'^log_kill/', log_kill, name='log_kill'),
url(r'^record/$', log_record, name='log_record'),
)

View File

@ -127,21 +127,16 @@ def log_record(request):
return HttpResponse('无日志记录!')
@require_role('user')
def web_terminal(request):
asset_id = request.GET.get('id')
role_name = request.GET.get('role')
web_terminal_uri = 'ws://%s/terminal?id=%s&role=%s' % (WEB_SOCKET_HOST, asset_id, role_name)
return render_to_response('jlog/web_terminal.html', locals())
@require_role('admin')
def log_detail(request, offset):
log_id = request.GET.get('id')
if offset == 'exec':
log = get_object(ExecLog, id=log_id)
assets_hostname = log.host.split(' ')
result = eval(str(log.result))
try:
result = eval(str(log.result))
except (SyntaxError, NameError):
result = {}
return my_render('jlog/exec_detail.html', locals(), request)
elif offset == 'file':
log = get_object(FileLog, id=log_id)

View File

@ -1,27 +1,28 @@
# -*- coding: utf-8 -*-
from ansible.inventory.group import Group
from ansible.inventory.host import Host
from ansible.inventory import Inventory
from ansible.runner import Runner
from ansible.playbook import PlayBook
from ansible import callbacks
from ansible import utils
from passlib.hash import sha512_crypt
from utils import get_rand_pass
from jumpserver.api import logger
from tempfile import NamedTemporaryFile
import os.path
from ansible.inventory.group import Group
from ansible.inventory.host import Host
from ansible.inventory import Inventory
from ansible.runner import Runner
from ansible.playbook import PlayBook
from ansible import callbacks
from ansible import utils
import ansible.constants as C
from passlib.hash import sha512_crypt
from django.template.loader import get_template
from django.template import Context
import os.path
from utils import get_rand_pass
from jumpserver.api import logger
API_DIR = os.path.dirname(os.path.abspath(__file__))
ANSIBLE_DIR = os.path.join(API_DIR, 'playbooks')
C.HOST_KEY_CHECKING = False
class AnsibleError(StandardError):

View File

@ -175,13 +175,17 @@ def gen_resource(ob, perm=None):
for asset in assets:
asset_info = get_asset_info(asset)
role_key = get_role_key(user, role)
info = {'hostname': asset.hostname,
'ip': asset.ip,
'port': asset_info.get('port', 22),
'username': role.name,
'password': CRYPTOR.decrypt(role.password),
'ssh_key': get_role_key(user, role)
}
'password': CRYPTOR.decrypt(role.password)
}
if os.path.isfile(role_key):
info['ssh_key'] = role_key
res.append(info)
else:
for asset, asset_info in perm.get('asset').items():
@ -192,13 +196,17 @@ def gen_resource(ob, perm=None):
role = sorted(list(perm.get('asset').get(asset).get('role')))[0]
except IndexError:
continue
role_key = get_role_key(user, role)
info = {'hostname': asset.hostname,
'ip': asset.ip,
'port': asset_info.get('port', 22),
'username': role.name,
'password': CRYPTOR.decrypt(role.password),
'ssh_key': get_role_key(user, role)
}
if os.path.isfile(role_key):
info['ssh_key'] = role_key
res.append(info)
elif isinstance(ob, User):
@ -214,8 +222,12 @@ def gen_resource(ob, perm=None):
continue
info['username'] = role.name
info['password'] = CRYPTOR.decrypt(role.password)
info['ssh_key'] = get_role_key(ob, role)
role_key = get_role_key(ob, role)
if os.path.isfile(role_key):
info['ssh_key'] = role_key
res.append(info)
elif isinstance(ob, (list, QuerySet)):
for asset in ob:
info = get_asset_info(asset)

View File

@ -2,21 +2,21 @@ from django.conf.urls import patterns, include, url
from jperm.views import *
urlpatterns = patterns('jperm.views',
(r'^rule/$', perm_rule_list),
(r'^perm_rule_add/$', perm_rule_add),
(r'^perm_rule_detail/$', perm_rule_detail),
(r'^perm_rule_edit/$', perm_rule_edit),
(r'^perm_rule_delete/$', perm_rule_delete),
(r'^role/$', perm_role_list),
(r'^role/perm_role_add/$', perm_role_add),
(r'^role/perm_role_delete/$', perm_role_delete),
(r'^role/perm_role_detail/$', perm_role_detail),
(r'^role/perm_role_edit/$', perm_role_edit),
(r'^role/push/$', perm_role_push),
(r'^role/recycle/$', perm_role_recycle),
(r'^role/get/$', perm_role_get),
(r'^sudo/$', perm_sudo_list),
(r'^sudo/perm_sudo_add/$', perm_sudo_add),
(r'^sudo/perm_sudo_delete/$', perm_sudo_delete),
(r'^sudo/perm_sudo_edit/$', perm_sudo_edit),
url(r'^rule/list/$', perm_rule_list, name='rule_list'),
url(r'^rule/add/$', perm_rule_add, name='rule_add'),
url(r'^rule/detail/$', perm_rule_detail, name='rule_detail'),
url(r'^rule/edit/$', perm_rule_edit, name='rule_edit'),
url(r'^rule/del/$', perm_rule_delete, name='rule_del'),
url(r'^role/list/$', perm_role_list, name='role_list'),
url(r'^role/add/$', perm_role_add, name='role_add'),
url(r'^role/del/$', perm_role_delete, name='role_del'),
url(r'^role/detail/$', perm_role_detail, name='role_detail'),
url(r'^role/edit/$', perm_role_edit, name='role_edit'),
url(r'^role/push/$', perm_role_push, name='role_push'),
url(r'^role/recycle/$', perm_role_recycle, name='role_recycle'),
url(r'^role/get/$', perm_role_get, name='role_get'),
url(r'^sudo/list/$', perm_sudo_list, name='sudo_list'),
url(r'^sudo/add/$', perm_sudo_add, name='sudo_add'),
url(r'^sudo/del/$', perm_sudo_delete, name='sudo_del'),
url(r'^sudo/edit/$', perm_sudo_edit, name='sudo_edit'),
)

View File

@ -110,7 +110,7 @@ def perm_rule_add(request):
raise ServerError(u'授权规则 %s 已存在' % rule_name)
if not rule_name or not roles_select:
raise ServerError(u'角色名称和授权角色不能为空')
raise ServerError(u'系统用户名称和规则名称不能为空')
# 获取需要授权的主机列表
assets_obj = [Asset.objects.get(id=asset_id) for asset_id in assets_select]
@ -132,7 +132,7 @@ def perm_rule_add(request):
asset_no_push = get_role_push_host(role=role)[1] # 获取某角色已经推送的资产
need_push_asset.update(set(calc_assets) & set(asset_no_push))
if need_push_asset:
raise ServerError(u'没有推送角色 %s 的主机 %s'
raise ServerError(u'没有推送系统用户 %s 的主机 %s'
% (role.name, ','.join([asset.hostname for asset in need_push_asset])))
# 仅授权成功的,写回数据库(授权规则,用户,用户组,资产,资产组,用户角色)
@ -146,7 +146,7 @@ def perm_rule_add(request):
rule.save()
msg = u"添加授权规则:%s" % rule.name
return HttpResponseRedirect('/jperm/rule/')
return HttpResponseRedirect(reverse('rule_list'))
except ServerError, e:
error = e
return my_render('jperm/perm_rule_add.html', locals(), request)
@ -181,10 +181,10 @@ def perm_rule_edit(request):
assets_select = request.POST.getlist('asset', [])
asset_groups_select = request.POST.getlist('asset_group', [])
roles_select = request.POST.getlist('role', [])
print rule_name, roles_select
try:
if not rule_name or not roles_select:
raise ServerError(u'角色名称和授权角色不能为空')
raise ServerError(u'系统用户和关联系统用户不能为空')
assets_obj = [Asset.objects.get(id=asset_id) for asset_id in assets_select]
asset_groups_obj = [AssetGroup.objects.get(id=group_id) for group_id in asset_groups_select]
@ -204,7 +204,7 @@ def perm_rule_edit(request):
asset_no_push = get_role_push_host(role=role)[1] # 获取某角色已经推送的资产
need_push_asset.update(set(calc_assets) & set(asset_no_push))
if need_push_asset:
raise ServerError(u'没有推送角色 %s 的主机 %s'
raise ServerError(u'没有推送系统用户 %s 的主机 %s'
% (role.name, ','.join([asset.hostname for asset in need_push_asset])))
# 仅授权成功的,写回数据库(授权规则,用户,用户组,资产,资产组,用户角色)
@ -214,7 +214,7 @@ def perm_rule_edit(request):
rule.asset_group = asset_groups_obj
rule.role = roles_obj
rule.name = rule_name
rule.comment = rule.comment
rule.comment = rule_comment
rule.save()
msg = u"更新授权规则:%s成功" % rule.name
@ -247,7 +247,7 @@ def perm_role_list(request):
list role page
"""
# 渲染数据
header_title, path1, path2 = "系统角色", "角色管理", "查看角色"
header_title, path1, path2 = "系统用户", "系统用户管理", "查看系统用户"
# 获取所有系统角色
roles_list = PermRole.objects.all()
@ -271,7 +271,7 @@ def perm_role_add(request):
add role page
"""
# 渲染数据
header_title, path1, path2 = "系统角色", "角色管理", "添加角色"
header_title, path1, path2 = "系统用户", "系统用户管理", "添加系统用户"
sudos = PermSudo.objects.all()
if request.method == "POST":
@ -301,8 +301,8 @@ def perm_role_add(request):
role = PermRole(name=name, comment=comment, password=encrypt_pass, key_path=key_path)
role.save()
role.sudo = sudos_obj
msg = u"添加角色: %s" % name
return HttpResponseRedirect('/jperm/role/')
msg = u"添加系统用户: %s" % name
return HttpResponseRedirect(reverse('role_list'))
except ServerError, e:
error = e
@ -336,7 +336,7 @@ def perm_role_delete(request):
logger.info(u"delete role %s - delete role key directory: %s" % (role.name, role_key))
# 数据库里删除记录 TODO: 判断返回结果,处理异常
role.delete()
return HttpResponse(u"删除角色: %s" % role.name)
return HttpResponse(u"删除系统用户: %s" % role.name)
else:
return HttpResponse(u"不支持该操作")
@ -353,7 +353,7 @@ def perm_role_detail(request):
'': [<User: user1>]}
"""
# 渲染数据
header_title, path1, path2 = "系统角色", "角色管理", "角色详情"
header_title, path1, path2 = "系统用户", "系统用户管理", "系统用户详情"
try:
if request.method == "GET":
@ -382,7 +382,7 @@ def perm_role_edit(request):
edit role page
"""
# 渲染数据
header_title, path1, path2 = "系统角色", "角色管理", "角色编辑"
header_title, path1, path2 = "系统用户", "系统用户管理", "系统用户编辑"
# 渲染数据
role_id = request.GET.get("id")
@ -405,7 +405,7 @@ def perm_role_edit(request):
try:
if not role:
raise ServerError('角色用户不能存在')
raise ServerError('该系统用户不能存在')
if role_password:
encrypt_pass = CRYPTOR.encrypt(role_password)
@ -423,8 +423,8 @@ def perm_role_edit(request):
role.sudo = role_sudos
role.save()
msg = u"更新系统角色 %s" % role.name
return HttpResponseRedirect('/jperm/role/')
msg = u"更新系统用户 %s" % role.name
return HttpResponseRedirect(reverse('role_list'))
except ServerError, e:
error = e
@ -437,7 +437,7 @@ def perm_role_push(request):
the role push page
"""
# 渲染数据
header_title, path1, path2 = "系统角色", "角色管理", "角色推送"
header_title, path1, path2 = "系统用户", "系统用户管理", "系统用户推送"
role_id = request.GET.get('id')
asset_ids = request.GET.get('asset_id')
role = get_object(PermRole, id=role_id)
@ -521,9 +521,9 @@ def perm_role_push(request):
func(is_password=password_push, is_public_key=key_push, role=role, asset=asset, success=True)
if not failed_asset:
msg = u'角色 %s 推送成功[ %s ]' % (role.name, ','.join(success_asset.keys()))
msg = u'系统用户 %s 推送成功[ %s ]' % (role.name, ','.join(success_asset.keys()))
else:
error = u'角色 %s 推送失败 [ %s ], 推送成功 [ %s ]' % (role.name,
error = u'系统用户 %s 推送失败 [ %s ], 推送成功 [ %s ]' % (role.name,
','.join(failed_asset.keys()),
','.join(success_asset.keys()))
return my_render('jperm/perm_role_push.html', locals(), request)
@ -628,7 +628,7 @@ def perm_sudo_delete(request):
sudo = PermSudo.objects.get(id=sudo_id)
# 数据库里删除记录
sudo.delete()
return HttpResponse(u"删除角色: %s" % sudo.name)
return HttpResponse(u"删除系统用户: %s" % sudo.name)
else:
return HttpResponse(u"不支持该操作")

File diff suppressed because one or more lines are too long

View File

@ -1,9 +1,9 @@
#coding: utf8
[base]
url = http://127.0.0.1
key = 88aaaf7ffe3c6c04
log = debug
url = http://yourIP
key = 16位字母数字
log = debug | warning
[db]
host = 127.0.0.1
@ -13,12 +13,12 @@ password = mysql234
database = jumpserver
[websocket]
web_socket_host = j:3000
web_socket_host = yourIP|yourDomainName:3000
[mail]
mail_enable = 1
email_host = smtp.exmail.qq.com
email_port = 25
email_host_user = noreply@jumpserver.org
email_host_password = jumpserver1234
email_host = yourSMTPHost
email_port = yourSMTPHost|25
email_host_user = yourEmail
email_host_password = yourEmailPassword
email_use_tls = True

View File

@ -25,6 +25,7 @@ from jumpserver.models import Setting
from django.http import HttpResponseRedirect
from django.shortcuts import render_to_response
from django.core.mail import send_mail
from django.core.urlresolvers import reverse
def set_log(level, filename='jumpserver.log'):
@ -69,7 +70,8 @@ def get_asset_info(asset):
info['password'] = CRYPTOR.decrypt(default.field3)
except ServerError:
pass
info['ssh_key'] = default.field4
if os.path.isfile(default.field4):
info['ssh_key'] = default.field4
else:
info['port'] = int(asset.port)
info['username'] = asset.username
@ -92,7 +94,7 @@ def get_role_key(user, role):
with open(os.path.join(role.key_path, 'id_rsa')) as fk:
with open(user_role_key_path, 'w') as fu:
fu.write(fk.read())
logger.debug(u"创建新的用户角色key %s, Owner: %s" % (user_role_key_path, user.username))
logger.debug(u"创建新的系统用户key %s, Owner: %s" % (user_role_key_path, user.username))
chown(user_role_key_path, user.username)
os.chmod(user_role_key_path, 0600)
return user_role_key_path
@ -265,15 +267,15 @@ def require_role(role='user'):
def __deco(request, *args, **kwargs):
request.session['pre_url'] = request.path
if not request.user.is_authenticated():
return HttpResponseRedirect('/login/')
return HttpResponseRedirect(reverse('login'))
if role == 'admin':
# if request.session.get('role_id', 0) < 1:
if request.user.role == 'CU':
return HttpResponseRedirect('/')
return HttpResponseRedirect(reverse('index'))
elif role == 'super':
# if request.session.get('role_id', 0) < 2:
if request.user.role in ['CU', 'GA']:
return HttpResponseRedirect('/')
return HttpResponseRedirect(reverse('index'))
return func(request, *args, **kwargs)
return __deco
@ -350,7 +352,7 @@ def view_splitter(request, su=None, adm=None):
elif is_role_request(request, 'admin'):
return adm(request)
else:
return HttpResponseRedirect('/login/')
return HttpResponseRedirect(reverse('login'))
def validate(request, user_group=None, user=None, asset_group=None, asset=None, edept=None):

View File

@ -1,19 +1,20 @@
from django.conf.urls import patterns, include, url
urlpatterns = patterns('',
urlpatterns = patterns('jumpserver.views',
# Examples:
(r'^$', 'jumpserver.views.index'),
(r'^api/user/$', 'jumpserver.api.api_user'),
(r'^skin_config/$', 'jumpserver.views.skin_config'),
(r'^login/$', 'jumpserver.views.Login'),
(r'^logout/$', 'jumpserver.views.Logout'),
(r'^exec_cmd/$', 'jumpserver.views.exec_cmd'),
(r'^file/upload/$', 'jumpserver.views.upload'),
(r'^file/download/$', 'jumpserver.views.download'),
(r'^setting', 'jumpserver.views.setting'),
(r'^juser/', include('juser.urls')),
(r'^jasset/', include('jasset.urls')),
(r'^jlog/', include('jlog.urls')),
(r'^jperm/', include('jperm.urls')),
url(r'^$', 'index', name='index'),
# url(r'^api/user/$', 'api_user'),
url(r'^skin_config/$', 'skin_config', name='skin_config'),
url(r'^login/$', 'Login', name='login'),
url(r'^logout/$', 'Logout', name='logout'),
url(r'^exec_cmd/$', 'exec_cmd', name='exec_cmd'),
url(r'^file/upload/$', 'upload', name='file_upload'),
url(r'^file/download/$', 'download', name='file_download'),
url(r'^setting', 'setting', name='setting'),
url(r'^terminal/$', 'web_terminal', name='terminal'),
url(r'^juser/', include('juser.urls')),
url(r'^jasset/', include('jasset.urls')),
url(r'^jlog/', include('jlog.urls')),
url(r'^jperm/', include('jperm.urls')),
)

View File

@ -79,7 +79,7 @@ def get_count_by_date(date_li, item):
@require_role(role='user')
def index_cu(request):
username = request.user.username
return HttpResponseRedirect('/juser/user_detail/')
return HttpResponseRedirect(reverse('user_detail'))
@require_role(role='user')
@ -169,7 +169,7 @@ def Login(request):
"""登录界面"""
error = ''
if request.user.is_authenticated():
return HttpResponseRedirect('/')
return HttpResponseRedirect(reverse('index'))
if request.method == 'GET':
return render_to_response('login.html')
else:
@ -211,7 +211,7 @@ def Login(request):
@require_role('user')
def Logout(request):
logout(request)
return HttpResponseRedirect('/login/')
return HttpResponseRedirect(reverse('index'))
@require_role('admin')
@ -230,7 +230,10 @@ def setting(request):
if '' in [username, port]:
return HttpResponse('所填内容不能为空, 且密码和私钥填一个')
else:
private_key_path = os.path.join(BASE_DIR, 'keys/role_keys', 'default', 'default_private_key.pem')
private_key_dir = os.path.join(BASE_DIR, 'keys', 'default')
private_key_path = os.path.join(private_key_dir, 'admin_user.pem')
mkdir(private_key_dir)
if private_key:
with open(private_key_path, 'w') as f:
f.write(private_key)
@ -343,3 +346,11 @@ def exec_cmd(request):
check_assets = request.GET.get('check_assets', '')
web_terminal_uri = 'ws://%s/exec?role=%s' % (WEB_SOCKET_HOST, role)
return my_render('exec_cmd.html', locals(), request)
@require_role('user')
def web_terminal(request):
asset_id = request.GET.get('id')
role_name = request.GET.get('role')
web_terminal_uri = 'ws://%s/terminal?id=%s&role=%s' % (WEB_SOCKET_HOST, asset_id, role_name)
return render_to_response('jlog/web_terminal.html', locals())

View File

@ -6,25 +6,20 @@ urlpatterns = patterns('juser.views',
# Examples:
# url(r'^$', 'jumpserver.views.home', name='home'),
# url(r'^blog/', include('blog.urls')),
(r'^group_add/$', group_add),
(r'^group_list/$', group_list),
(r'^group_del/$', group_del),
(r'^group_edit/$', group_edit),
(r'^user_add/$', user_add),
(r'^user_del/$', 'user_del'),
(r'^user_list/$', user_list),
(r'^user_edit/$', user_edit),
(r'^user_detail/$', 'user_detail'),
(r'^profile/$', 'profile'),
(r'^send_mail_retry/$', send_mail_retry),
(r'^reset_password/$', reset_password),
(r'^forget_password/$', forget_password),
(r'^change_info/$', 'change_info'),
(r'^regen_ssh_key/$', 'regen_ssh_key'),
(r'^down_key/$', 'down_key'),
url(r'^group/add/$', 'group_add', name='user_group_add'),
url(r'^group/list/$', 'group_list', name='user_group_list'),
url(r'^group/del/$', 'group_del', name='user_group_del'),
url(r'^group/edit/$', 'group_edit', name='user_group_edit'),
url(r'^user/add/$', 'user_add', name='user_add'),
url(r'^user/del/$', 'user_del', name='user_del'),
url(r'^user/list/$', 'user_list', name='user_list'),
url(r'^user/edit/$', 'user_edit', name='user_edit'),
url(r'^user/detail/$', 'user_detail', name='user_detail'),
url(r'^user/profile/$', 'profile', name='user_profile'),
url(r'^user/update/$', 'change_info', name='user_update'),
url(r'^mail/retry/$', 'send_mail_retry', name='mail_retry'),
url(r'^password/reset/$', 'reset_password', name='password_reset'),
url(r'^password/forget/$', 'forget_password', name='password_forget'),
url(r'^key/gen/$', 'regen_ssh_key', name='key_gen'),
url(r'^key/down/$', 'down_key', name='key_down'),
)

View File

@ -130,7 +130,7 @@ def gen_ssh_key(username, password='',
"""
logger.debug('生成ssh key 并设置authorized_keys')
private_key_file = os.path.join(key_dir, username+'.pem')
mkdir(key_dir, mode=0700)
mkdir(key_dir, mode=0777)
if os.path.isfile(private_key_file):
os.unlink(private_key_file)
ret = bash('echo -e "y\n"|ssh-keygen -t rsa -f %s -b %s -P "%s"' % (private_key_file, length, password))
@ -169,7 +169,7 @@ def user_add_mail(user, kwargs):
您的权限 %s
您的web登录密码 %s
您的ssh密钥文件密码 %s
密钥下载地址 %s/juser/down_key/?uuid=%s
密钥下载地址 %s/juser/key/down/?uuid=%s
说明 请登陆后再下载密钥
""" % (user.name, user.username, user_role.get(user.role, u'普通用户'),
kwargs.get('password'), kwargs.get('ssh_key_pwd'), URL, user.uuid)
@ -195,7 +195,7 @@ def get_display_msg(user, password, ssh_key_pwd, ssh_key_login_need, send_mail_n
用户名%s
密码%s
密钥密码%s
密钥下载url: %s/juser/down_key/?uuid=%s
密钥下载url: %s/juser/key/down/?uuid=%s
该账号密码可以登陆web和跳板机
""" % (URL, user.username, password, ssh_key_pwd, URL, user.uuid)
else:

View File

@ -58,10 +58,14 @@ def group_list(request):
header_title, path1, path2 = '查看用户组', '用户管理', '查看用户组'
keyword = request.GET.get('search', '')
user_group_list = UserGroup.objects.all().order_by('name')
group_id = request.GET.get('id', '')
if keyword:
user_group_list = user_group_list.filter(Q(name__icontains=keyword) | Q(comment__icontains=keyword))
if group_id:
user_group_list = user_group_list.filter(id=int(group_id))
user_group_list, p, user_groups, page_range, current_page, show_first, show_end = pages(user_group_list, request)
return my_render('juser/group_list.html', locals(), request)
@ -124,7 +128,7 @@ def group_edit(request):
except ServerError, e:
error = e
if not error:
return HttpResponseRedirect('/juser/group_list/')
return HttpResponseRedirect(reverse('user_group_list'))
else:
users_all = User.objects.all()
users_selected = User.objects.filter(group=user_group)
@ -229,7 +233,7 @@ def user_detail(request):
user = get_object(User, id=user_id)
if not user:
return HttpResponseRedirect('/juser/user_list/')
return HttpResponseRedirect(reverse('user_list'))
user_perm_info = get_group_user_perm(user)
role_assets = user_perm_info.get('role')
@ -339,7 +343,7 @@ def user_edit(request):
if request.method == 'GET':
user_id = request.GET.get('id', '')
if not user_id:
return HttpResponseRedirect('/')
return HttpResponseRedirect(reverse('index'))
user_role = {'SU': u'超级管理员', 'CU': u'普通用户'}
user = get_object(User, id=user_id)
@ -364,7 +368,7 @@ def user_edit(request):
if user_id:
user = get_object(User, id=user_id)
else:
return HttpResponseRedirect('/juser/user_list/')
return HttpResponseRedirect(reverse('user_list'))
if password != '':
password_decode = password
@ -387,12 +391,12 @@ def user_edit(request):
地址%s
用户名 %s
密码%s (如果密码为None代表密码为原密码)
角色%s
权限%s
""" % (user.name, URL, user.username, password_decode, user_role.get(role_post, u''))
send_mail('您的信息已修改', msg, MAIL_FROM, [email], fail_silently=False)
return HttpResponseRedirect('/juser/user_list/')
return HttpResponseRedirect(reverse('user_list'))
return my_render('juser/user_edit.html', locals(), request)
@ -400,7 +404,7 @@ def user_edit(request):
def profile(request):
user_id = request.user.id
if not user_id:
return HttpResponseRedirect('/')
return HttpResponseRedirect(reverse('index'))
user = User.objects.get(id=user_id)
return my_render('juser/profile.html', locals(), request)
@ -411,7 +415,7 @@ def change_info(request):
user = User.objects.get(id=user_id)
error = ''
if not user:
return HttpResponseRedirect('/')
return HttpResponseRedirect(reverse('index'))
if request.method == 'POST':
name = request.POST.get('name', '')

View File

@ -116,25 +116,6 @@ def file_monitor(path='.', client=None):
break
class Application(tornado.web.Application):
def __init__(self):
handlers = [
(r'/monitor', MonitorHandler),
(r'/terminal', WebTerminalHandler),
(r'/kill', WebTerminalKillHandler),
(r'/exec', ExecHandler),
]
setting = {
'cookie_secret': 'DFksdfsasdfkasdfFKwlwfsdfsa1204mx',
'template_path': os.path.join(os.path.dirname(__file__), 'templates'),
'static_path': os.path.join(os.path.dirname(__file__), 'static'),
'debug': True,
}
tornado.web.Application.__init__(self, handlers, **setting)
class MonitorHandler(tornado.websocket.WebSocketHandler):
clients = []
threads = []
@ -231,7 +212,7 @@ class ExecHandler(tornado.websocket.WebSocketHandler):
logger.debug('Websocket: Open exec request')
role_name = self.get_argument('role', 'sb')
self.remote_ip = self.request.remote_ip
logger.debug('Web执行命令: 请求角色 %s' % role_name)
logger.debug('Web执行命令: 请求系统用户 %s' % role_name)
self.role = get_object(PermRole, name=role_name)
self.perm = get_group_user_perm(self.user)
roles = self.perm.get('role').keys()
@ -270,8 +251,11 @@ class ExecHandler(tornado.websocket.WebSocketHandler):
def run_cmd(self, command, pattern):
self.runner.run('shell', command, pattern=pattern)
newline_pattern = re.compile(r'\n')
for k, v in self.runner.results.items():
for host, output in v.items():
output = newline_pattern.sub('<br />', output)
logger.debug(output)
if k == 'ok':
header = "<span style='color: green'>[ %s => %s]</span>\n" % (host, 'Ok')
else:
@ -312,7 +296,7 @@ class WebTerminalHandler(tornado.websocket.WebSocketHandler):
if asset:
roles = user_have_perm(self.user, asset)
logger.debug(roles)
logger.debug('角色: %s' % role_name)
logger.debug('系统用户: %s' % role_name)
login_role = ''
for role in roles:
if role.name == role_name:
@ -412,12 +396,32 @@ class WebTerminalHandler(tornado.websocket.WebSocketHandler):
except IndexError:
pass
class Application(tornado.web.Application):
def __init__(self):
handlers = [
(r'/monitor', MonitorHandler),
(r'/terminal', WebTerminalHandler),
(r'/kill', WebTerminalKillHandler),
(r'/exec', ExecHandler),
]
setting = {
'cookie_secret': 'DFksdfsasdfkasdfFKwlwfsdfsa1204mx',
'template_path': os.path.join(os.path.dirname(__file__), 'templates'),
'static_path': os.path.join(os.path.dirname(__file__), 'static'),
'debug': False,
}
tornado.web.Application.__init__(self, handlers, **setting)
if __name__ == '__main__':
tornado.options.parse_command_line()
app = Application()
server = tornado.httpserver.HTTPServer(app)
server.bind(options.port, options.host)
# server.listen(options.port)
server.start(num_processes=1)
#server.listen(options.port)
server.start(num_processes=10)
print "Run server on %s:%s" % (options.host, options.port)
tornado.ioloop.IOLoop.instance().start()

View File

@ -15,7 +15,7 @@
<div id="footer">
<div class="content">
<input type="text" id="pattern" value="{{ check_assets }}" placeholder="Ansible Pattern">
<input type="text" id="command" placeholder="Command to execute">
<input type="text" id="command" placeholder="Command to execute" onkeypress="if(event.keyCode==13){sendMessage()}">
<input type="button" id="send_btn" value="Send" onclick="sendMessage()">
</div>
</div>
@ -92,7 +92,7 @@
{# background-color: #ecf0f1;#}
{# border: #000 solid 5px;#}
background: #000;
width: 800px;
width: 720px;
box-shadow: rgba(0, 0, 0, 0.8) 2px 2px 20px;
color: #fff;
}
@ -109,7 +109,7 @@
position: fixed;
bottom: 0;
height: 50px;
width: 800px;
width: 720px;
{# border: #000 solid -10px;#}
background-color: #2980b9;
}
@ -130,7 +130,7 @@
}
.content {
width: 800px;
width: 720px;
margin-left: 5px;
}
@ -169,11 +169,11 @@
}
@media(max-width: 1000px) {
.content { width: 90%; }
.content { width: 100%; }
}
@media(max-width: 780px) {
#footer { height: 91px; }
#footer { height: 51px; }
#chat_box { padding-bottom: 91px; }
#user { width: 100%; }
@ -192,6 +192,7 @@
}
}
</style>
</body>
<div></div>
<div></div>

View File

@ -28,14 +28,13 @@
<script src="/static/js/dropzone/dropzone.js"></script>
<!-- active menu -->
<script>
var str = document.location.pathname.split("/")[1];
var str1 = document.location.pathname.split("/")[2];
$("#"+str).addClass('active');
if($("."+str1).length>0) {
$("."+str1).addClass('active');
}
if(str.length==0){
$("#index").addClass('active');
var url_array = document.location.pathname.split("/");
s1 = url_array[1];
s2 = url_array[2];
if (s1 == ''){
$('#index').addClass('active')
} else {
$("#"+s1).addClass('active');
$('#'+s1+' .'+s2).addClass('active');
}
</script>

View File

@ -13,7 +13,7 @@
<h5>用户总数</h5>
</div>
<div class="ibox-content">
<h1 class="no-margins"><a href="/juser/user_list/">{{ users.count}}</a></h1>
<h1 class="no-margins"><a href="{% url 'user_list' %}">{{ users.count}}</a></h1>
<small>All user</small>
</div>
</div>
@ -25,7 +25,7 @@
<h5>主机总数</h5>
</div>
<div class="ibox-content">
<h1 class="no-margins"><a href="/jasset/host_list/">{{ hosts.count }}</a></h1>
<h1 class="no-margins"><a href="{% url 'asset_list' %}">{{ hosts.count }}</a></h1>
<small>All host</small>
</div>
</div>
@ -38,7 +38,7 @@
<h5>在线用户</h5>
</div>
<div class="ibox-content">
<h1 class="no-margins"><a href="/jlog/log_list/online/"> <span id="online_users">{{ online_user | length }}</span></a></h1>
<h1 class="no-margins"><a href="{% url 'log_list' 'online' %}"> <span id="online_users">{{ online_user | length }}</span></a></h1>
{# <div class="stat-percent font-bold text-navy">{{ percent_online_user }} <i class="fa fa-level-up"></i></div>#}
<small>Online user</small>
</div>
@ -52,7 +52,7 @@
<h5>已连接服务器</h5>
</div>
<div class="ibox-content">
<h1 class="no-margins"><a href="/jlog/log_list/online/"> <span id="online_hosts">{{ online_host | length }}</span></a></h1>
<h1 class="no-margins"><a href="{% url 'log_list' 'online' %}"> <span id="online_hosts">{{ online_host | length }}</span></a></h1>
<small>Connected host</small>
</div>
</div>

View File

@ -25,7 +25,7 @@
<div class="ibox-content" style="line-height: 26px">
<span style="font-size: large"></span>迎使用<span class="text-navy"><b>Jumpserver</b></span>跳板机系统,
首先需要 <b><a href="/juser/down_key/?id={{ user.id }}">下载</a></b> 登录跳板机的SSH密钥文件然后导入到工具或者ssh命令指定密钥文件(确保密钥文件权限600),输入收到的密钥密码,登录跳板机。
首先需要 <b><a href="{% url 'key_down' %}?id={{ user.id }}">下载</a></b> 登录跳板机的SSH密钥文件然后导入到工具或者ssh命令指定密钥文件(确保密钥文件权限600),输入收到的密钥密码,登录跳板机。
登录后根据提示进行操作。跳板机web界面支持修改密码、个人信息和上传下载文件等功能可以向管理员申请权限。
</div>
</div>
@ -124,7 +124,7 @@
<td>{{ user.name }}</td>
</tr>
<tr>
<td class="text-navy">角色</td>
<td class="text-navy">系统用户</td>
<td>{{ user.role }}</td>
</tr>
<tr>

View File

@ -26,8 +26,8 @@
<div class="panel blank-panel">
<div class="panel-options">
<ul class="nav nav-tabs">
<li class="active"><a href="/jasset/asset_add/" class="text-center"><i class="fa fa-laptop"></i> 单台添加 </a></li>
<li><a href="/jasset/asset_add_batch" class="text-center"><i class="fa fa-bar-chart-o"></i> 批量添加 </a></li>
<li class="active"><a href="{% url 'asset_add' %}" class="text-center"><i class="fa fa-laptop"></i> 单台添加 </a></li>
<li><a href="{% url 'asset_add_batch' %}" class="text-center"><i class="fa fa-bar-chart-o"></i> 批量添加 </a></li>
</ul>
</div>
<div class="panel-body">

View File

@ -31,8 +31,8 @@
<div class="panel blank-panel">
<div class="panel-options">
<ul class="nav nav-tabs">
<li><a href="/jasset/asset_add/" class="text-center"><i class="fa fa-laptop"></i> 单台添加 </a></li>
<li class="active"><a href="/jasset/asset_add_batch/" class="text-center"><i class="fa fa-bar-chart-o"></i> 批量添加 </a></li>
<li><a href="{% url 'asset_add' %}" class="text-center"><i class="fa fa-laptop"></i> 单台添加 </a></li>
<li class="active"><a href="{% url 'asset_add_batch' %}" class="text-center"><i class="fa fa-bar-chart-o"></i> 批量添加 </a></li>
</ul>
</div>
<div class="panel-body">
@ -44,14 +44,13 @@
<div class="alert alert-success text-center">{{ smg }}</div>
{% endif %}
<p>请下载Excel文件, 按照格式填写主机信息, 上传导入. <a href="/static/files/excels/asset.xlsx">点击下载模板</a></p>
<form action="/jasset/upload/" method="POST" enctype="multipart/form-data">
<form action="{% url 'asset_upload' %}" method="POST" enctype="multipart/form-data">
<div class="file-box">
<input id='textfield' />
<input type="button" class="btn btn-info btn-sm" name="file_name" value="点击选择文件">
<input type="file" name="file_name" class="file" id="fileField" size="28" onchange="document.getElementById('textfield').value=this.value" />
<button class="btn btn-primary btn-sm" type="submit">上传文件</button>
</div>
</form>
</div>
</div>

View File

@ -29,10 +29,10 @@
<input type="text" class="form-control m-b input-sm" id="search_input" name="keyword" value="{{ keyword }}" placeholder="Search">
<input type="text" style="display: none">
<div class="input-group-btn">
<button id='search_btn' href="/jasset/asset_list/?search=true" type="button" class="btn btn-sm btn-primary search-btn" onclick="change_info()">
<button id='search_btn' href="{% url 'asset_list' %}?search=true" type="button" class="btn btn-sm btn-primary search-btn" onclick="change_info()">
- 搜索 -
</button>
<button type="button" href="/jasset/asset_list/?export=true" name="export" class="btn btn-sm btn-success search-btn-excel" onclick="return false">
<button type="button" href="{% url 'asset_list' %}?export=true" name="export" class="btn btn-sm btn-success search-btn-excel" onclick="return false">
- 导出 -
</button>
</div>
@ -63,7 +63,7 @@
<td class="text-center" name="id" value="{{ asset.id }}" data-editable='false'>
<input name="id" value="{{ asset.id }}" type="checkbox" class="i-checks">
</td>
<td class="text-center hostname"> <a href="/jasset/asset_detail/?id={{ asset.id }}">{{ asset.hostname|default_if_none:"" }}</a></td>
<td class="text-center hostname"> <a href="{% url 'asset_detail' %}?id={{ asset.id }}">{{ asset.hostname|default_if_none:"" }}</a></td>
<td class="text-center"> {{ asset.ip|default_if_none:"" }} </td>
<td class="text-center"> {{ asset.idc.name|default_if_none:"" }} </td>
<td class="text-center">{{ asset.group.all|group_str2 }}</td>
@ -110,8 +110,8 @@
});
$('#exec_cmd').click(function(){
var url = '/jperm/role/get/';
var new_url = '/exec_cmd/?role=';
var url = '{% url "role_get" %} ';
var new_url = '{% url "exec_cmd" %}?role=';
var check_array = [];
$(".gradeX input:checked").closest('tr').find('.hostname a').each(function() {
check_array.push($(this).text())
@ -130,12 +130,12 @@
title: title,
maxmin: true,
shade: false,
area: ['800px', '600px'],
area: ['725px', '600px'],
content: new_url+data+'&check_assets='+check_assets
});
//window.open(new_url + data, '', 'location=no, resizeable=no, height=410, width=625, top=89px, left=99px,toolbar=no,menubar=no,scrollbars=auto,status=no');
} else if (dataArray.length == '1' && data == 'error'){
layer.alert('没有授权角色')
layer.alert('没有授权系统用户')
} else {
aUrl = '';
$.each(dataArray, function(index, value){
@ -143,7 +143,7 @@
});
layer.alert(aUrl, {
skin: 'layui-layer-molv',
title: '多个角色,请选择一个连接',
title: '授权多个系统用户,请选择一个连接',
shade: false,
closeBtn: 0
})
@ -155,18 +155,29 @@
});
$('.conn').click(function(){
var url='/jperm/role/get/?id=' + $(this).attr('value');
var url='{% url "role_get" %}?id=' + $(this).attr('value');
var href = $(this).attr('href');
var new_url = '/jlog/web_terminal/?id=' + $(this).attr('value') + '&role=';
var new_url = '{% url "terminal" %}?id=' + $(this).attr('value') + '&role=';
var hostname = $(this).closest('tr').find('.hostname a')[0].innerHTML;
var title = 'Jumpserver Web Terminal' + '<span class="text-info"> '+ hostname +'</span>';
$.ajax({
type: 'GET',
url: url,
data: {},
success: function(data){
var dataArray = data.split(',');
if (dataArray.length == 1 && data != 'error'){
var title = 'Jumpserver Web Terminal' + '<span class="text-info"> '+ hostname +'</span>';
if (data == 'error' || data == '' || data == null || data == undefined){
layer.alert('没有授权系统用户')
} else if (dataArray.length == 1 && data != 'error' && navigator.platform == 'Win32') {
layer.open({
type: 2,
title: title,
maxmin: true,
shade: false,
area: ['628px', '420px'],
content: new_url + data
});
} else if (dataArray.length == 1 && data != 'error'){
layer.open({
type: 2,
title: title,
@ -176,17 +187,14 @@
content: new_url+data
});
//window.open(new_url + data, '', 'location=no, resizeable=no, height=410, width=625, top=89px, left=99px,toolbar=no,menubar=no,scrollbars=auto,status=no');
} else if (dataArray.length == '1' && data == 'error'){
layer.alert('没有授权角色')
} else {
aUrl = '';
$.each(dataArray, function(index, value){
aUrl += '<a onclick="windowOpen(this); return false" class="btn btn-xs btn-primary newa" href=' + new_url + value + ' value=' + hostname + '>' + value + '</a> '
});
console.log(aUrl);
layer.alert(aUrl, {
skin: 'layui-layer-molv',
title: '多个角色,请选择一个连接',
title: '授权多个系统用户,请选择一个连接',
shade: false,
closeBtn: 0
})
@ -263,50 +271,6 @@
});
$('#asset_del').click(function () {
var asset_id_all = getIDall();
if (asset_id_all == ''){
alert("请至少选择一行!");
return false;
}
if (confirm("确定删除?")) {
$.ajax({
type: "post",
data: {asset_id_all: asset_id_all},
url: "/jasset/asset_del/?arg=batch",
success: function () {
parent.location.reload();
}
});
}
});
$('#asset_update').click(function () {
var asset_id_all = getIDall();
if (asset_id_all == ''){
if (confirm("更新全部资产信息?")) {
layer.msg('玩命更新中...', {time: 200000});
$.ajax({
type: "post",
url: "/jasset/asset_update_batch/?arg=all",
success: function () {
parent.location.reload();
}
});
}
}
else {
layer.msg('玩命更新中...', {time: 200000});
$.ajax({
type: "post",
data: {asset_id_all: asset_id_all},
url: "/jasset/asset_update_batch/",
success: function () {
parent.location.reload();
}
});
}
});
{# $('#asset_update_all').click(function () {#}
{# layer.msg('玩命更新中...', {time: 200000});#}
@ -319,10 +283,6 @@
{# });#}
{# });#}
function change_info(){
var args = $("#asset_form").serialize();
window.location = "/jasset/asset_list/?" + args
}
$("#search_input").keydown(function(e){
if(e.keyCode==13){

View File

@ -11,7 +11,7 @@
<div class="ibox-title">
<span class="text text-primary"><b>{{ asset.ip }}</b></span>
<div class="ibox-tools">
<a class="" href="/jasset/asset_update/?id={{ asset.id }}">
<a class="" href="{% url 'asset_update' %}?id={{ asset.id }}">
<i class="fa fa-refresh"></i>
</a>
<a class="collapse-link">
@ -197,16 +197,16 @@
<table class="table">
<p>授权用户信息</p>
<td class="text-navy">授权用户</td>
<td class="text-navy">系统角色</td>
<td class="text-navy">关联用户</td>
{% for perm in user_perm %}
<tr>
<td class="text-navy"><a href="/juser/user_detail/?id={{ perm.0.id }}">{{ perm.0 }}</a></td>
<td class="text-navy"><a href="{% url 'user_detail' %}?id={{ perm.0.id }}">{{ perm.0 }}</a></td>
<td>
<table class="table">
{% if perm.1 %}
{% for role in perm.1 %}
<tr>
<td class="text-navy"><a href="/jperm/role/perm_role_detail/?id={{ role.id }}">{{ role }}</a></td>
<td class="text-navy"><a href="{% url 'role_detail' %}?id={{ role.id }}">{{ role }}</a></td>
</tr>
{% endfor %}
{% endif %}
@ -224,7 +224,7 @@
{% for user_group in user_group_perm %}
<tr>
<td class="text-navy">{{ user_group }}</td>
<td class="text-navy"><a href="/juser/user_list/?gid={{ user_group.id }}">详情</a></td>
<td class="text-navy"><a href="{% url 'user_group_list' %}?gid={{ user_group.id }}">详情</a></td>
</tr>
{% endfor %}
</table>
@ -238,7 +238,7 @@
{% for rule in user_rule_perm %}
<tr>
<td class="text-navy">{{ rule }}</td>
<td class="text-navy"><a href="/jperm/perm_rule_detail/?id={{ rule.id }}">详情</a></td>
<td class="text-navy"><a href="{% url 'rule_detail' %}/?id={{ rule.id }}">详情</a></td>
</tr>
{% endfor %}
</table>
@ -251,7 +251,7 @@
</div>
<div class="ibox-title">
<h5>主机修改记录</h5>
<a href="/jasset/asset_edit/?id={{ asset.id }}" data-toggle="tooltip" class="text-success pull-center" data-placement="bottom" title="修改">&nbsp&nbsp&nbsp&nbsp点击修改</a>
<a href="{% url 'asset_edit' %}?id={{ asset.id }}" data-toggle="tooltip" class="text-success pull-center" data-placement="bottom" title="修改">&nbsp&nbsp&nbsp&nbsp点击修改</a>
<div class="ibox-tools">
<a class="collapse-link">
<i class="fa fa-chevron-up"></i>

View File

@ -25,7 +25,7 @@
<div class="ibox-content">
<form id="asset_form">
<div class="col-sm-1" style="padding-left: 0">
<a target="_blank" href="/jasset/asset_add/" class="btn btn-sm btn-primary "> 添加资产 </a>
<a href="{% url 'asset_add' %}" class="btn btn-sm btn-primary "> 添加资产 </a>
</div>
<div class="col-sm-7" style="padding-left: 0px">
@ -34,9 +34,9 @@
<option value="">机房</option>
{% for idc in idc_all %}
{% ifequal idc.name idc_name %}
<option value="{{idc.name}}" selected> {{ idc.name }}</option>
<option value="{{idc.name}}" selected> {{ idc.name|slice:":20" }}</option>
{% else %}
<option value="{{idc.name}}"> {{ idc.name }}</option>
<option value="{{idc.name}}"> {{ idc.name|slice:":20" }}</option>
{% endifequal %}
{% endfor %}
</select>
@ -47,9 +47,9 @@
<option value="">主机组</option>
{% for asset_group in asset_group_all %}
{% ifequal asset_group.name group_name %}
<option value="{{ asset_group.name }}" selected> {{ asset_group.name }} </option>
<option value="{{ asset_group.name }}" selected> {{ asset_group.name|slice:":20" }} </option>
{% else %}
<option value="{{ asset_group.name }}"> {{ asset_group.name }} </option>
<option value="{{ asset_group.name }}"> {{ asset_group.name|slice:":20" }} </option>
{% endifequal %}
{% endfor %}
</select>
@ -87,10 +87,10 @@
<input type="text" class="form-control m-b input-sm" id="search_input" name="keyword" value="{{ keyword }}" placeholder="Search">
<input type="text" style="display: none">
<div class="input-group-btn">
<button id='search_btn' href="/jasset/asset_list/?search=true" type="button" class="btn btn-sm btn-primary search-btn" onclick="change_info()">
<button id='search_btn' href="{% url 'asset_list' %}?search=true" type="button" class="btn btn-sm btn-primary search-btn" onclick="change_info()">
- 搜索 -
</button>
<button type="button" href="/jasset/asset_list/?export=true" name="export" class="btn btn-sm btn-success search-btn-excel" onclick="return false">
<button type="button" href="{% url 'asset_list' %}?export=true" name="export" class="btn btn-sm btn-success search-btn-excel" onclick="return false">
- 导出 -
</button>
</div>
@ -121,7 +121,7 @@
<td class="text-center" name="id" value="{{ asset.id }}" data-editable='false'>
<input name="id" value="{{ asset.id }}" type="checkbox" class="i-checks">
</td>
<td class="text-center hostname"> <a href="/jasset/asset_detail/?id={{ asset.id }}">{{ asset.hostname|default_if_none:"" }}</a></td>
<td class="text-center hostname"> <a href="{% url 'asset_detail' %}?id={{ asset.id }}">{{ asset.hostname|default_if_none:"" }}</a></td>
<td class="text-center"> {{ asset.ip|default_if_none:"" }} </td>
<td class="text-center"> {{ asset.idc.name|default_if_none:"" }} </td>
<td class="text-center">{{ asset.group.all|group_str2 }}</td>
@ -131,9 +131,9 @@
<td class="text-center"> {{ asset.memory|default_if_none:"" }}{% if asset.memory %}G{% endif %}</td>
<td class="text-center"> {{ asset.disk|get_disk_info }}{% if asset.memory %}G{% endif %}</td>
<td class="text-center" data-editable='false'>
<a href="/jasset/asset_edit/?id={{ asset.id }}" class="btn btn-xs btn-info">编辑</a>
<a href="{% url 'asset_edit' %}?id={{ asset.id }}" class="btn btn-xs btn-info">编辑</a>
<a value="{{ asset.id }}" class="conn btn btn-xs btn-warning">连接</a>
<a value="/jasset/asset_del/?id={{ asset.id }}" class="btn btn-xs btn-danger asset_del">删除</a>
<a value="{% url 'asset_del' %}?id={{ asset.id }}" class="btn btn-xs btn-danger asset_del">删除</a>
</td>
</tr>
{% endfor %}
@ -142,7 +142,7 @@
<div class="row">
<div class="col-sm-6">
<input type="button" id="asset_del" class="btn btn-danger btn-sm" name="del_button" value="删除"/>
<a value="/jasset/asset_edit_batch/" type="button" class="btn btn-sm btn-warning iframe">修改</a>
<a value="{% url 'asset_edit_batch' %}" type="button" class="btn btn-sm btn-warning iframe">修改</a>
<input type="button" id="asset_update" class="btn btn-info btn-sm" name="update_button" value="更新"/>
{# <input type="button" id="asset_update_all" class="btn btn-primary btn-sm" name="update_button" value="更新全部"/>#}
<input type="button" id="exec_cmd" class="btn btn-sm btn-primary" name="exec_cmd" value="执行命令"/>
@ -174,8 +174,8 @@
});
$('#exec_cmd').click(function(){
var url = '/jperm/role/get/';
var new_url = '/exec_cmd/?role=';
var url = '{% url "role_get" %}';
var new_url = '{% url "exec_cmd" %}?role=';
var check_array = [];
$(".gradeX input:checked").closest('tr').find('.hostname a').each(function() {
check_array.push($(this).text())
@ -194,12 +194,12 @@
title: title,
maxmin: true,
shade: false,
area: ['800px', '600px'],
area: ['725px', '600px'],
content: new_url+data+'&check_assets='+check_assets
});
//window.open(new_url + data, '', 'location=no, resizeable=no, height=410, width=625, top=89px, left=99px,toolbar=no,menubar=no,scrollbars=auto,status=no');
} else if (dataArray.length == '1' && data == 'error'){
layer.alert('没有授权角色')
layer.alert('没有授权系统用户')
} else {
aUrl = '';
$.each(dataArray, function(index, value){
@ -207,7 +207,7 @@
});
layer.alert(aUrl, {
skin: 'layui-layer-molv',
title: '多个角色,请选择一个连接',
title: '授权多个系统用户,请选择一个连接',
shade: false,
closeBtn: 0
})
@ -219,9 +219,9 @@
});
$('.conn').click(function(){
var url='/jperm/role/get/?id=' + $(this).attr('value'); // 获取用户有权限的角色
var url='{% url "role_get" %}?id=' + $(this).attr('value'); // 获取用户有权限的角色
var href = $(this).attr('href');
var new_url = '/jlog/web_terminal/?id=' + $(this).attr('value') + '&role='; // webterminal socket url
var new_url = '{% url "terminal" %}?id=' + $(this).attr('value') + '&role='; // webterminal socket url
var hostname = $(this).closest('tr').find('.hostname a')[0].innerHTML;
$.ajax({
type: 'GET',
@ -230,12 +230,20 @@
success: function(data){
var dataArray = data.split(',');
if (data == 'error' || data == '' || data == null || data == undefined){
layer.alert('没有授权角色')
layer.alert('没有授权系统用户')
}
else if (dataArray.length == 1 && data != 'error'){
else if (dataArray.length == 1 && data != 'error' && navigator.platform == 'Win32'){
var title = 'Jumpserver Web Terminal' + '<span class="text-info"> '+ hostname +'</span>';
console.log(new_url+data);
layer.open({
type: 2,
title: title,
maxmin: true,
shade: false,
area: ['628px', '420px'],
content: new_url+data
});
} else if (dataArray.length == 1 && data != 'error'){
layer.open({
type: 2,
title: title,
maxmin: true,
@ -243,7 +251,8 @@
area: ['628px', '452px'],
content: new_url+data
});
} else {
}
else {
aUrl = '';
$.each(dataArray, function(index, value){
aUrl += '<a onclick="windowOpen(this); return false" class="btn btn-xs btn-primary newa" href=' + new_url + value + ' value=' + hostname + '>' + value + '</a> '
@ -251,7 +260,7 @@
console.log(aUrl);
layer.alert(aUrl, {
skin: 'layui-layer-molv',
title: '多个角色,请选择一个连接',
title: '授权多个系统用户,请选择一个连接',
shade: false,
closeBtn: 0
})
@ -338,7 +347,7 @@
$.ajax({
type: "post",
data: {asset_id_all: asset_id_all},
url: "/jasset/asset_del/?arg=batch",
url: "{% url 'asset_del' %}?arg=batch",
success: function () {
parent.location.reload();
}
@ -353,7 +362,7 @@
layer.msg('玩命更新中...', {time: 200000});
$.ajax({
type: "post",
url: "/jasset/asset_update_batch/?arg=all",
url: "{% url 'asset_update_batch' %}?arg=all",
success: function () {
parent.location.reload();
}
@ -365,7 +374,7 @@
$.ajax({
type: "post",
data: {asset_id_all: asset_id_all},
url: "/jasset/asset_update_batch/",
url: "{% url 'asset_update_batch' %}",
success: function () {
parent.location.reload();
}
@ -386,7 +395,7 @@
function change_info(){
var args = $("#asset_form").serialize();
window.location = "/jasset/asset_list/?" + args
window.location = "{% url 'asset_list' %}?" + args
}
$("#search_input").keydown(function(e){

View File

@ -23,8 +23,8 @@
</div>
<div class="ibox-content">
<div class="">
<a target="_blank" href="/jasset/group_add/" class="btn btn-sm btn-primary "> 添加主机组 </a>
<a target="_blank" class="btn btn-sm btn-danger" id="del_check"> 删除所选 </a>
<a href="{% url 'asset_group_add' %}" class="btn btn-sm btn-primary "> 添加主机组 </a>
<a class="btn btn-sm btn-danger" id="del_check"> 删除所选 </a>
<form id="search_form" method="get" action="" class="pull-right mail-search">
<div class="input-group">
<input type="text" class="form-control input-sm" id="search_input" name="keyword" placeholder="Search">
@ -58,12 +58,12 @@
<input name="id" value="{{ asset_group.id }}" type="checkbox" class="i-checks">
</td>
<td class="text-center"> {{ asset_group.name }} </td>
<td class="text-center"> <a href="/jasset/asset_list/?group_id={{ asset_group.id }}">{{ asset_group.asset_set.count }}</a> </td>
<td class="text-center"> <a href="{% url 'asset_list' %}?group_id={{ asset_group.id }}">{{ asset_group.asset_set.count }}</a> </td>
<td class="text-center"> {{ asset_group.comment }} </td>
<td class="text-center">
<a href="/jasset/asset_list/?group_id={{ asset_group.id }}" class="btn btn-xs btn-info">详情</a>
<a href="/jasset/group_edit/?id={{ asset_group.id }}" class="btn btn-xs btn-info">编辑</a>
<a value="/jasset/group_del/?id={{ asset_group.id }}" class="btn btn-xs btn-danger group_del">删除</a>
<a href="{% url 'asset_list' %}?group_id={{ asset_group.id }}" class="btn btn-xs btn-info">详情</a>
<a href="{% url 'asset_group_edit' %}?id={{ asset_group.id }}" class="btn btn-xs btn-info">编辑</a>
<a value="{% url 'asset_group_del' %}?id={{ asset_group.id }}" class="btn btn-xs btn-danger group_del">删除</a>
</td>
</tr>
{% endfor %}
@ -108,7 +108,7 @@
check_array.push($(this).attr('value'))
});
$.get(
'/jasset/group_del/',
'{% url "asset_group_del" %}',
{id: check_array.join(',')},
function(data){
$('tr.gradeX input:checked').closest('tr').remove();

View File

@ -17,10 +17,6 @@
<i class="fa fa-wrench"></i>
</a>
<ul class="dropdown-menu dropdown-user">
<li><a href="#">未启用 1</a>
</li>
<li><a href="#">未启用 2</a>
</li>
</ul>
<a class="close-link">
<i class="fa fa-times"></i>
@ -29,7 +25,7 @@
</div>
<div class="ibox-content">
<div class="">
<a target="_blank" href="/jasset/idc_add" class="btn btn-sm btn-primary "> 添加机房 </a>
<a href="{% url 'idc_add' %}" class="btn btn-sm btn-primary "> 添加机房 </a>
<input type="button" id="del_check" class="btn btn-danger btn-sm" name="del_button" value="删除所选"/>
<form id="search_form" method="get" action="" class="pull-right mail-search">
<div class="input-group">
@ -63,15 +59,15 @@
{% for post in contacts.object_list %}
<tr class="gradeX">
<td class="text-center" name="j_id" value="{{ post.id }}" data-editable='false'><input name="id" value="{{ post.id }}" type="checkbox" class="i-checks"></td>
<td class="text-center"> {{ post.name }} </td>
<td class="text-center"> <a href="/jasset/asset_list/?idc_id={{ post.id }}">{{ post.asset_set.count }}</a> </td>
<td class="text-center"> <a href="{% url 'asset_list' %}?idc_id={{ post.id }}">{{ post.name }}</a> </td>
<td class="text-center"> <a href="{% url 'asset_list' %}?idc_id={{ post.id }}">{{ post.asset_set.count }}</a> </td>
<td class="text-center"> {{ post.linkman }} </td>
<td class="text-center"> {{ post.phone }} </td>
<td class="text-center"> {{ post.comment }} </td>
<td class="text-center">
<a href="/jasset/asset_list/?idc_id={{ post.id }}" class="iframe btn btn-xs btn-primary">详情</a>
<a href="/jasset/idc_edit/?id={{ post.id }}" class="btn btn-xs btn-info">编辑</a>
<a href="/jasset/idc_del/?id={{ post.id }}" class="btn btn-xs btn-danger idc_del">删除</a>
<a href="{% url 'idc_edit' %}?id={{ post.id }}" class="btn btn-xs btn-info">编辑</a>
<a href="{% url 'idc_del' %}?id={{ post.id }}" class="btn btn-xs btn-danger idc_del">删除</a>
</td>
</tr>
{% endfor %}
@ -91,7 +87,9 @@
</div>
</div>
</div>
{% endblock %}
{% block self_footer_js %}
<script>
$(document).ready(function(){
$('.idc_del').click(function(){
@ -103,7 +101,8 @@
function (data) {
row.remove();
}
)
);
return false
}
});
@ -114,16 +113,15 @@
check_array.push($(this).attr('value'))
});
$.get(
'/jasset/idc_del/',
'{% url "idc_del" %}',
{id: check_array.join(',')},
function(data){
$('tr.gradeX input:checked').closest('tr').remove();
}
)
);
return false;
}
})
});
</script>
{% endblock %}

View File

@ -1,10 +0,0 @@
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>资产管理</title>
</head>
<body>
<h1>welocome!</h1>
</body>
</html>

View File

@ -1,106 +0,0 @@
{% load mytags %}
<html>
<head>
{% include 'link_css.html' %}
{% include 'head_script.html' %}
<style type="text/css">
body
{
background: #FFFFFF;
}
</style>
</head>
<body>
<div class="row">
<div class="contact-box">
<h3 class="text-center">{{ offset }}主机详情</h3>
<table class="table table-striped table-bordered table-hover " id="editable" >
<thead>
<tr>
<th> IP地址 </th>
<th> 端口号 </th>
<th> 登录方式 </th>
<th> 所属IDC </th>
<th> 所属业务组 </th>
<th> 添加时间 </th>
<th> 备注 </th>
</tr>
</thead>
<tbody>
<tr class="gradeX">
<td> <a id="ip" class="iframe" href="/jasset/{{ post.ip }}/">{{ post.ip }}</a></td>
<td> {{ post.port }} </td>
<td> {{ post.login_type|get_login_type }} </td>
<td class="text-center"> {{ post.idc.name }} </td>
<td class="text-center">{% for group in post.bis_group.all %} {{ group }} {% endfor %}</td>
<td class="text-center"> {{ post.date_added|date:"Y-m-d H:i:s" }} </td>
<td class="text-center"> {{ post.comment }} </td>
</tr>
</tbody>
</table>
<h3 class="text-center">{{ offset }}主机用户权限详情</h3>
<table class="table table-striped table-bordered table-hover " id="editable" >
<thead>
<tr>
<th> 用户名 </th>
</tr>
</thead>
<tbody>
<tr class="gradeX">
<td>
{% for user in user_permed_list %}
<a class="btn"> {{ user.name }} </a>
{% endfor %}
</td>
</tr>
</tbody>
</table>
<!--<a> 是否 激活: {{ post.is_active }}</a>-->
<h3 class="text-center">最近一周登录详情</h3>
<table class="table table-striped table-bordered table-hover ">
<thead>
<tr>
<th class="text-center"> 用户名 </th>
<th class="text-center"> 登录时间 </th>
<th class="text-center"> 退出时间 </th>
<th class="text-center"> 详情 </th>
</tr>
</thead>
<tbody>
{% for l in log %}
<tr class="gradeX">
<td class="text-center" id="username"> {{ l.user }} </td>
<td class="text-center" id="start_time">{{ l.start_time|date:"Y-m-d H:i:s" }}</td>
<td class="text-center" id="end_time"> {{ l.end_time|date:"Y-m-d H:i:s" }} </td>
<td class="text-center">
<a class="log_command text-success" href="/jlog/history/?id={{ l.id }}">命令统计</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</body>
<script src="/static/js/bootstrap-dialog.js"></script>
<script>
$('.log_command').on('click',function(){
var url = $(this).attr('href');
var username = $('#username')[0].innerText;
var ip = $('#ip')[0].innerText;
var start_time = $('#start_time')[0].innerText;
var end_time = $('#end_time')[0].innerText;
var div_username = ' 登录用户名: '+'<span class="text-info">'+username+'' + '</span>';
var div_ip = ' 登录主机: '+'<span class="text-info">' + ip + '</span>';
var div_time = ' 开始时间: ' + '<span class="text-info">'+start_time +'</span>' + ' 结束时间: ' +'<span class="text-info">' + end_time + '</span>'
var title = div_username + div_ip + div_time
$.ajax({url:url,success:function(data){
BootstrapDialog.show({title: title, message:data});
}});
return false;
})
</script>
</html>

View File

@ -29,10 +29,10 @@
<div class="ibox-content">
<div class="panel-options">
<ul class="nav nav-tabs">
<li><a href="/jlog/log_list/online/" class="text-center"><i class="fa fa-laptop"></i> 在线 </a></li>
<li><a href="/jlog/log_list/offline/" class="text-center"><i class="fa fa-bar-chart-o"></i> 历史记录 </a></li>
<li class="active"><a href="/jlog/log_list/exec/" class="text-center"><i class="fa fa-bar-chart-o"></i> 命令记录 </a></li>
<li><a href="/jlog/log_list/file/" class="text-center"><i class="fa fa-bar-chart-o"></i> 上传下载 </a></li>
<li><a href="{% url 'log_list' 'online' %}" class="text-center"><i class="fa fa-laptop"></i> 在线 </a></li>
<li><a href="{% url 'log_list' 'offline' %}" class="text-center"><i class="fa fa-bar-chart-o"></i> 历史记录 </a></li>
<li class="active"><a href="{% url 'log_list' 'exec' %}" class="text-center"><i class="fa fa-bar-chart-o"></i> 命令记录 </a></li>
<li><a href="{% url 'log_list' 'file' %}" class="text-center"><i class="fa fa-bar-chart-o"></i> 上传下载 </a></li>
<div class="" style="float: right">
<form id="search_form" method="get" action="" class="pull-right mail-search">
<div class="input-group">
@ -72,7 +72,7 @@
<td class="text-center remote_ip"> {{ post.remote_ip }} </td>
<td class="text-center start_time"> {{ post.datetime|date:"Y-m-d H:i:s"}} </td>
<td class="text-center">
<a href="/jlog/log_detail/exec/?id={{ post.id }}" class="btn btn-xs btn-primary">详情</a>
<a href="{% url 'log_detail' 'exec' %}?id={{ post.id }}" class="btn btn-xs btn-primary">详情</a>
</td>
</tr>
{% endfor %}

View File

@ -29,10 +29,10 @@
<div class="ibox-content">
<div class="panel-options">
<ul class="nav nav-tabs">
<li><a href="/jlog/log_list/online/" class="text-center"><i class="fa fa-laptop"></i> 在线 </a></li>
<li><a href="/jlog/log_list/offline/" class="text-center"><i class="fa fa-bar-chart-o"></i> 历史记录 </a></li>
<li><a href="/jlog/log_list/exec/" class="text-center"><i class="fa fa-bar-chart-o"></i> 命令记录 </a></li>
<li class="active"><a href="/jlog/log_list/file/" class="text-center"><i class="fa fa-bar-chart-o"></i> 上传下载 </a></li>
<li><a href="{% url 'log_list' 'online' %}" class="text-center"><i class="fa fa-laptop"></i> 在线 </a></li>
<li><a href="{% url 'log_list' 'offline' %}" class="text-center"><i class="fa fa-bar-chart-o"></i> 历史记录 </a></li>
<li><a href="{% url 'log_list' 'exec' %}" class="text-center"><i class="fa fa-bar-chart-o"></i> 命令记录 </a></li>
<li class="active"><a href="{% url 'log_list' 'file' %}" class="text-center"><i class="fa fa-bar-chart-o"></i> 上传下载 </a></li>
<div class="" style="float: right">
<form id="search_form" method="get" action="" class="pull-right mail-search">
<div class="input-group">
@ -74,7 +74,7 @@
<td class="text-center"> {{ post.remote_ip }} </td>
<td class="text-center"> {{ post.datetime|date:"Y-m-d H:i:s"}} </td>
<td class="text-center">
<a href="/jlog/log_detail/file/?id={{ post.id }}" class="btn btn-xs btn-primary">详情</a>
<a href="{% url 'log_detail' 'file' %}?id={{ post.id }}" class="btn btn-xs btn-primary">详情</a>
</td>
</tr>
{% endfor %}

View File

@ -1,139 +0,0 @@
{% extends 'base.html' %}
{% block self_head_css_js %}
<link href="/static/css/plugins/datepicker/datepicker3.css" rel="stylesheet">
<link href="/static/css/plugins/chosen/chosen.css" rel="stylesheet">
<script src="/static/js/plugins/chosen/chosen.jquery.js"></script>
{% endblock %}
{% block content %}
{% include 'nav_cat_bar.html' %}
<div class="wrapper wrapper-content animated fadeInRight">
<div class="row">
<div class="col-sm-12">
<div class="ibox float-e-margins">
<div id="ibox-content" class="ibox-title">
<h5> 用户日志详细信息列表 </h5>
<div class="ibox-tools">
<a class="collapse-link">
<i class="fa fa-chevron-up"></i>
</a>
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
<i class="fa fa-wrench"></i>
</a>
<a class="close-link">
<i class="fa fa-times"></i>
</a>
</div>
</div>
<div class="ibox-content">
<div class="panel-options">
<ul class="nav nav-tabs">
<li><a href="/jlog/log_list/online/" class="text-center"><i class="fa fa-laptop"></i> 在线 </a></li>
<li><a href="/jlog/log_list/offline/" class="text-center"><i class="fa fa-bar-chart-o"></i> 历史记录 </a></li>
<li class="active"><a href="/jlog/search/" class="text-center"><i class="fa fa-bar-chart-o"></i> 详细搜索 </a></li>
</ul>
</div>
<br/>
<div class="tab-content">
<form method="get" action="" role="form" class="form-inline">
<p>
选择相应条件进行搜索
</p>
<div class="form-group" id="data_5">
<div class="input-daterange input-group" id="datepicker">
<input type="text" class="input-sm form-control" style="width: 100px;" name="start" value="{{ date_seven_day }}">
<span class="input-group-addon">to</span>
<input type="text" class="input-sm form-control" style="width: 100px;" name="end" value="{{ date_now_str }}">
</div>
</div>
<div class="form-group">
<div class="input-group">
<select name="single" data-placeholder="用户名" class="chosen-select" multiple style="width:300px;" tabindex="2">
<option value="用户">用户名</option>
<option value="Bolivia, Plurinational State of">hongweiguang</option>
<option value="Bonaire, Sint Eustatius and Saba">wangyong</option>
<option value="Bosnia and Herzegovina">hehe</option>
<option value="Botswana">wangyong</option>
<option value="Bouvet Island">wangyongd</option>
<option value="Romania">Romania</option>
<option value="Zambia">Zambia</option>
<option value="Zimbabwe">Zimbabwe</option>
</select>
</div>
</div>
<div class="form-group">
<div class="input-group">
<select name="multi" data-placeholder="主机" class="chosen-select" multiple style="width:200px;" tabindex="4">
<option value="主机">主机</option>
<option value="United States">172.16.1.1</option>
<option value="Afghanistan">172.16.1.1</option>
<option value="Aland Islands">172.16.1.1</option>
<option value="Albania">172.16.1.1</option>
<option value="Algeria">172.16.1.1</option>
<option value="American Samoa">172.16.1.1</option>
<option value="Andorra">172.16.1.1</option>
<option value="Angola">172.16.1.1</option>
<option value="Anguilla">172.16.1.1</option>
<option value="Antarctica">172.16.1.1</option>
</select>
</div>
</div>
<div class="form-group">
<input id="cmd" name="cmd" placeholder="命令" type="text" class="form-control" style="width: 200px;">
</div>
<div class="form-group">
<button id="submit_button" class="btn btn-primary" type="submit">搜索</button>
</div>
</form>
<div class="row">
<div class="col-sm-6">
</div>
{% include 'paginator.html' %}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
function log_search(){
$.ajax({
type: "GET",
url: "/jlog/search/?env=offline",
data: $("#search_form").serialize(),
success: function (data) {
$(".tab-content").html(data);
}
});
}
$(document).ready(function(){
$('#data_5 .input-daterange').datepicker({
dateFormat: 'yy-mm-dd',
keyboardNavigation: false,
forceParse: false,
autoclose: true
});
});
var config = {
'.chosen-select' : {},
'.chosen-select-deselect' : {allow_single_deselect:true},
'.chosen-select-no-single' : {disable_search_threshold:10},
'.chosen-select-no-results': {no_results_text:'Oops, nothing found!'},
'.chosen-select-width' : {width:"95%"}
};
for (var selector in config) {
$(selector).chosen(config[selector]);
}
</script>
{% endblock %}
{% block self_footer_js %}
<script src="/static/js/cropper/cropper.min.js"></script>
<script src="/static/js/datapicker/bootstrap-datepicker.js"></script>
<script src="/static/js/plugins/chosen/chosen.jquery.js"></script>
{% endblock %}

View File

@ -52,10 +52,10 @@
<div class="ibox-content">
<div class="panel-options">
<ul class="nav nav-tabs">
<li><a href="/jlog/log_list/online/" class="text-center"><i class="fa fa-laptop"></i> 在线 </a></li>
<li class="active"><a href="/jlog/log_list/offline/" class="text-center"><i class="fa fa-bar-chart-o"></i> 历史记录 </a></li>
<li><a href="/jlog/log_list/exec/" class="text-center"><i class="fa fa-bar-chart-o"></i> 命令记录 </a></li>
<li><a href="/jlog/log_list/file/" class="text-center"><i class="fa fa-bar-chart-o"></i> 上传下载 </a></li>
<li><a href="{% url 'log_list' 'online' %}" class="text-center"><i class="fa fa-laptop"></i> 在线 </a></li>
<li class="active"><a href="{% url 'log_list' 'offline' %}" class="text-center"><i class="fa fa-bar-chart-o"></i> 历史记录 </a></li>
<li><a href="{% url 'log_list' 'exec' %}" class="text-center"><i class="fa fa-bar-chart-o"></i> 命令记录 </a></li>
<li><a href="{% url 'log_list' 'file' %}" class="text-center"><i class="fa fa-bar-chart-o"></i> 上传下载 </a></li>
</ul>
</div>
<form class="form-inline" action="" method="get">
@ -119,9 +119,9 @@
<td class="text-center remote_ip"> {{ post.remote_ip }} </td>
<td class="text-center"> {{ post.login_type }} </td>
{% ifnotequal session_role_id 0 %}
<td class="text-center"><a href="/jlog/history/?id={{ post.id }}" class="log_command"> 统计 </a></td>
<td class="text-center"><a href="{% url 'log_history' %}?id={{ post.id }}" class="log_command"> 统计 </a></td>
{% endifnotequal %}
<td class="text-center"><a value="/jlog/record/?id={{ post.id }}" class="log_record"> 回放 </a></td>
<td class="text-center"><a value="{% url 'log_record' %}?id={{ post.id }}" class="log_record"> 回放 </a></td>
<td class="text-center start_time"> {{ post.start_time|date:"Y-m-d H:i:s"}} </td>
<td class="text-center end_time"> {{ post.end_time|date:"Y-m-d H:i:s" }} </td>
</tr>

View File

@ -67,10 +67,10 @@
<div class="ibox-content">
<div class="panel-options">
<ul class="nav nav-tabs">
<li class="active"><a href="/jlog/log_list/online/" class="text-center"><i class="fa fa-laptop"></i> 在线 </a></li>
<li><a href="/jlog/log_list/offline/" class="text-center"><i class="fa fa-bar-chart-o"></i> 历史记录 </a></li>
<li><a href="/jlog/log_list/exec/" class="text-center"><i class="fa fa-bar-chart-o"></i> 命令记录 </a></li>
<li><a href="/jlog/log_list/file/" class="text-center"><i class="fa fa-bar-chart-o"></i> 上传下载 </a></li>
<li class="active"><a href="{% url 'log_list' 'online' %}" class="text-center"><i class="fa fa-laptop"></i> 在线 </a></li>
<li><a href="{% url 'log_list' 'offline' %}" class="text-center"><i class="fa fa-bar-chart-o"></i> 历史记录 </a></li>
<li><a href="{% url 'log_list' 'exec' %}" class="text-center"><i class="fa fa-bar-chart-o"></i> 命令记录 </a></li>
<li><a href="{% url 'log_list' 'file' %}" class="text-center"><i class="fa fa-bar-chart-o"></i> 上传下载 </a></li>
<div class="" style="float: right">
<form id="search_form" method="get" action="" class="pull-right mail-search">
<div class="input-group">
@ -108,7 +108,7 @@
<td id="ip" class="text-center"> {{ post.host }} </td>
<td id="remote_ip" class="text-center"> {{ post.remote_ip }} </td>
<td class="text-center"> {{ post.login_type }} </td>
<td class="text-center"><a href="/jlog/history/?id={{ post.id }}" class="log_command"> 统计 </a></td>
<td class="text-center"><a href="{% url 'log_history' %}?id={{ post.id }}" class="log_command"> 统计 </a></td>
<td class="text-center"><a class="monitor" file_path="{{ post.log_path }}"> 监控 </a></td>
<td class="text-center"><input type="button" id="cut" class="btn btn-danger btn-xs" name="cut" value="阻断" onclick='cut("{{ post.pid }}", "{{ post.login_type }}")' /></td>
<td class="text-center" id="start_time"> {{ post.start_time|date:"Y-m-d H:i:s" }} </td>
@ -207,13 +207,13 @@
if (login_type=='web'){
var g_url = '{{ web_kill_uri }}' + '?id=' + num;
} else {
var g_url = "/jlog/log_kill/?id=" + num;
var g_url = "{% url 'log_kill' %} }?id=" + num;
}
$.ajax({
type: "GET",
url: g_url+"&sessionid={{ session_id }}",
success: window.open("/jlog/log_list/online/", "_self")
success: window.open("{% url 'log_list' 'online' %}", "_self")
});
}

View File

@ -19,7 +19,7 @@
<td class="text-center" id="dept_name"> {{ post.dept_name }} </td>
<td class="text-center" id="host"> {{ post.host }} </td>
<td class="text-center" id="remote_ip"> {{ post.remote_ip }} </td>
<td class="text-center"><a href="/jlog/history/?id={{ post.id }}" class="log_command"> 命令统计 </td>
<td class="text-center"><a href="{% url 'log_history' %}?id={{ post.id }}" class="log_command"> 命令统计 </td>
<td class="text-center" id="start_time"> {{ post.start_time|date:"Y-m-d H:i:s"}} </td>
<td class="text-center" id="end_time"> {{ post.end_time|date:"Y-m-d H:i:s" }} </td>
</tr>

View File

@ -1,155 +0,0 @@
{% extends 'base.html' %}
{% load mytags %}
{% block content %}
{% include 'nav_cat_bar.html' %}
<div class="wrapper wrapper-content animated fadeInRight">
<div class="row">
<div class="col-sm-10">
<div class="ibox float-e-margins">
<div class="ibox-title">
<h5> {{ user_group.name }}授权修改</h5>
<div class="ibox-tools">
<a class="collapse-link">
<i class="fa fa-chevron-up"></i>
</a>
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
<i class="fa fa-wrench"></i>
</a>
<a class="close-link">
<i class="fa fa-times"></i>
</a>
</div>
</div>
<div class="ibox-content">
<form id="userPerm" method="post" class="form-horizontal" action="../perm_group_edit/?id={{ user_group.id }}">
{% if error %}
<div class="alert alert-warning text-center">{{ error }}</div>
{% endif %}
{% if msg %}
<div class="alert alert-success text-center">{{ msg }}</div>
{% endif %}
<div class="row">
<div class="form-group">
<label for="" class="col-sm-2 control-label">用户组<span class="red-fonts">*</span></label>
<div class="col-sm-4">
<input id="user_group_name" name="user_group_name" type="text" class="form-control" value="{{ user_group.name }}" readonly>
</div>
</div>
<div class="hr-line-dashed"></div>
<div class="form-group">
<label for="" class="col-sm-2 control-label">资产<span class="red-fonts">*</span></label>
<div class="col-sm-4">
<div>
<select id="assets" name="assets" class="form-control m-b" size="12" multiple>
{% for asset in assets %}
<option value="{{ asset.id }}">{{ asset.ip }}</option>
{% endfor %}
</select>
</div>
</div>
<div class="col-sm-1">
<div class="btn-group" style="margin-top: 42px;">
<button type="button" class="btn btn-white" onclick="move('assets', 'asset_select')"><i class="fa fa-chevron-right"></i></button>
<button type="button" class="btn btn-white" onclick="move('asset_select', 'assets')"><i class="fa fa-chevron-left"></i> </button>
</div>
</div>
<div class="col-sm-3">
<div>
<select id="asset_select" name="asset_select" class="form-control m-b" size="12" multiple>
{% for asset in asset_permed %}
<option value="{{ asset.id }}">{{ asset.ip }}</option>
{% endfor %}
</select>
</div>
</div>
</div>
<div class="hr-line-dashed"></div>
<div class="form-group">
<label for="" class="col-sm-2 control-label">资产组<span class="red-fonts">*</span></label>
<div class="col-sm-4">
<div>
<select id="asset_groups" name="asset_groups" class="form-control m-b" size="12" multiple>
{% for asset_group in asset_groups %}
<option value="{{ asset_group.id }}">{{ asset_group.name }}</option>
{% endfor %}
</select>
</div>
</div>
<div class="col-sm-1">
<div class="btn-group" style="margin-top: 42px;">
<button type="button" class="btn btn-white" onclick="move('asset_groups', 'asset_groups_select')"><i class="fa fa-chevron-right"></i></button>
<button type="button" class="btn btn-white" onclick="move('asset_groups_select', 'asset_groups')"><i class="fa fa-chevron-left"></i> </button>
</div>
</div>
<div class="col-sm-3">
<div>
<select id="asset_groups_select" name="asset_groups_select" class="form-control m-b" size="12" multiple>
{% for asset_group in asset_group_permed %}
<option value="{{ asset_group.id }}">{{ asset_group.name }}</option>
{% endfor %}
</select>
</div>
</div>
</div>
</div>
<div class="row">
<div class="form-group">
<div class="col-sm-4 col-sm-offset-2">
<button class="btn btn-white" type="reset">取消</button>
<button id="submit_button" class="btn btn-primary" type="submit" onclick="selectAll()">确认保存</button>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<script>
$('#sudoPerm').validator({
timely: 2,
theme: "yellow_right_effect",
fields: {
"name": {
rule: "required",
tip: "输入授权名",
ok: "",
msg: {required: "必须填写!"}
}
},
valid: function(form) {
form.submit();
}
});
$(document).ready(function(){
$("#submit_button").click(function(){
$('#user_groups_select option').each(function(){
$(this).prop('selected', true)
})
$('#asset_groups_select option').each(function(){
$(this).prop('selected', true)
})
})
})
</script>
{% endblock %}

View File

@ -1,81 +0,0 @@
{% extends 'base.html' %}
{% load mytags %}
{% block content %}
{% include 'nav_cat_bar.html' %}
<div class="wrapper wrapper-content animated fadeInRight">
<div class="row">
<div class="col-sm-10">
<div class="ibox float-e-margins">
<div class="ibox-title">
<h5> 查看小组</h5>
<div class="ibox-tools">
<a class="collapse-link">
<i class="fa fa-chevron-up"></i>
</a>
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
<i class="fa fa-wrench"></i>
</a>
<a class="close-link">
<i class="fa fa-times"></i>
</a>
</div>
</div>
<div class="ibox-content">
<div class="">
<a target="_blank" href="/juser/group_add/" class="btn btn-sm btn-primary "> 添加用户组 </a>
<form id="search_form" method="get" action="" class="pull-right mail-search">
<div class="input-group">
<input type="text" class="form-control input-sm" id="search_input" name="search" placeholder="Search">
<div class="input-group-btn">
<button id='search_btn' type="submit" class="btn btn-sm btn-primary">
- 搜索 -
</button>
</div>
</div>
</form>
</div>
<table class="table table-striped table-bordered table-hover " id="editable" >
<thead>
<tr>
<th class="text-center">用户组</th>
<th class="text-center">成员</th>
<th class="text-center">授权资产</th>
<th class="text-center">授权资产组</th>
<th class="text-center">操作</th>
</tr>
</thead>
<tbody>
{% for user_group in user_groups.object_list %}
<tr class="gradeX">
<td class="text-center"> {{ user_group.name }} </td>
<td class="text-center">
<a href="/juser/user_list/?gid={{ user_group.id }}">{{ user_group.user_set.all | length }} </a>
</td>
<td class="text-center"> <a href="/jasset/asset_list/?gid={{ user_group.id }}">{{ user_group | user_asset_count }} </a> </td>
<td class="text-center"> <a href="/jasset/group_list/?gid={{ user_group.id }}">{{ user_group | user_asset_group_count }}</a></td>
<td class="text-center">
<a href="../perm_user_detail/?id={{ user_group.id }}" class="btn btn-xs btn-primary">详情</a>
<a href="../perm_group_edit/?id={{ user_group.id }}" class="btn btn-xs btn-danger">编辑</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<div class="row">
<div class="col-sm-6">
<div class="dataTables_info" id="editable_info" role="status" aria-live="polite">
Showing {{ users.start_index }} to {{ users.end_index }} of {{ p.count }} entries
</div>
</div>
{% include 'paginator.html' %}
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -34,29 +34,29 @@
<div class="alert alert-success text-center">{{ msg }}</div>
{% endif %}
<div class="form-group">
<label for="role_name" class="col-sm-2 control-label">角色名称<span class="red-fonts">*</span></label>
<label for="role_name" class="col-sm-2 control-label">用户名称<span class="red-fonts">*</span></label>
<div class="col-sm-8">
<input id="role_name" name="role_name" placeholder="Role Name" type="text" class="form-control">
</div>
</div>
<div class="hr-line-dashed"></div>
<div class="form-group">
<label for="role_password" class="col-sm-2 control-label">角色密码</label>
<label for="role_password" class="col-sm-2 control-label">用户密码</label>
<div class="col-sm-8">
<input id="role_password" name="role_password" placeholder="Role Password" type="password" class="form-control">
<span class="help-block m-b-none">如果不添加密码,会自动生成</span>
</div>
</div>
<div class="form-group">
<label for="role_key" class="col-sm-2 control-label">角色密钥</label>
<label for="role_key" class="col-sm-2 control-label">用户密钥</label>
<div class="col-sm-8">
<textarea class="form-control" name="role_key" placeholder="请复制粘贴私钥" rows="10" style="font-size: 9px;"></textarea>
<span class="help-block m-b-none">如果不添加密钥,会自动生成, 密码密钥必填一项</span>
<span class="help-block m-b-none">如果不添加密钥,会自动生成 </span>
</div>
</div>
<div class="hr-line-dashed"></div>
<div class="form-group">
<label for="sudo" class="col-sm-2 control-label">角色Sudo命令</label>
<label for="sudo" class="col-sm-2 control-label">关联Sudo</label>
<div class="col-sm-8" id="sudo_name">
<select name="sudo_name" data-placeholder="请选择Sudo别名" class="chosen-select form-control m-b" multiple tabindex="2">
{% for sudo in sudos %}
@ -101,9 +101,9 @@ $('#roleForm').validator({
fields: {
"role_name": {
rule: "required;check_name",
tip: "输入角色名称",
tip: "输入系统用户名称",
ok: "",
msg: {required: "角色名称必填"}
msg: {required: "系统用户名称必填"}
},
{# "role_key": {#}
{# rule: "required(either)",#}

View File

@ -36,7 +36,7 @@
{% for rule in rules %}
<tr class="gradeX">
<td class="text-left"> {{ rule.date_added | date:"Y-m-d H:i:s"}} </td>
<td class="text-right"> <a href="/jperm/perm_rule_detail/?id={{ rule.id }}">{{ rule.name }}</a> </td>
<td class="text-right"> <a href="{% url 'rule_detail' %}?id={{ rule.id }}">{{ rule.name }}</a> </td>
</tr>
{% endfor %}
</table>
@ -77,7 +77,7 @@
<table class="table progress-striped text-left">
{% for user in users %}
<tr class="gradeX">
<td> <a href="/jasset/asset_detail/?id={{ user.id }}">{{ user.name }}</a> </td>
<td> <a href="{% url 'user_detail' %}?id={{ user.id }}">{{ user.name }}</a> </td>
</tr>
{% endfor %}
</table>
@ -86,7 +86,7 @@
<table class="table progress-striped text-right">
{% for group in user_groups %}
<tr class="gradeX-">
<td> <a href="/jasset/asset_list/?group_id={{ group.id }}">{{ group.name }}</a> </td>
<td> <a href="{% url 'user_group_list' %}?id={{ group.id }}">{{ group.name }}</a> </td>
</tr>
{% endfor %}
</table>
@ -121,36 +121,35 @@
</div>
</div>
<div class="ibox-content">
<div class="text-center">
<table class="table" id="agedit" >
<td class="text-navy text-left">主机</td>
<td class="text-navy text-right">主机组</td>
<tr>
<td>
<table class="table progress-striped text-left">
{% for asset in assets %}
<tr class="gradeX">
<td> <a href="/jasset/asset_detail/?id={{ asset.id }}">{{ asset.ip }}</a> </td>
</tr>
{% endfor %}
</table>
</td>
<td>
<table class="table progress-striped text-right">
{% for group in asset_groups %}
<tr class="gradeX-">
<td> <a href="/jasset/asset_list/?group_id={{ group.id }}">{{ group.name }}</a> </td>
</tr>
{% endfor %}
</table>
</td>
</tr>
</table>
</div>
</div>
</div>
<div class="text-center">
<table class="table" id="agedit" >
<td class="text-navy text-left">主机</td>
<td class="text-navy text-right">主机组</td>
<tr>
<td>
<table class="table progress-striped text-left">
{% for asset in assets %}
<tr class="gradeX">
<td> <a href="{% url 'asset_detail' %}?id={{ asset.id }}">{{ asset.ip }}</a> </td>
</tr>
{% endfor %}
</table>
</td>
<td>
<table class="table progress-striped text-right">
{% for group in asset_groups %}
<tr class="gradeX-">
<td> <a href="{% url 'asset_list' %}?group_id={{ group.id }}">{{ group.name }}</a> </td>
</tr>
{% endfor %}
</table>
</td>
</tr>
</table>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-6">
@ -207,7 +206,7 @@
{% else %}
<td class="text-center" style="color: #ec4758;cursor: help" title="{{ info.result }}" >{{ info.success | yesno:"成功,失败,未知" }} </td>
{% endif %}
<td class="text-center" ><a class="fa fa-times del" href="/jperm/role/recycle/?role_id={{ role.id }}&asset_id={{ asset.id }}" style="color: #ec4758;"></a></td>
<td class="text-center" ><a class="fa fa-times del" href="{% url 'role_recycle' %}?role_id={{ role.id }}&asset_id={{ asset.id }}" style="color: #ec4758;"></a></td>
</tr>
{% endfor %}
</tbody>

View File

@ -34,14 +34,14 @@
<div class="alert alert-success text-center">{{ msg }}</div>
{% endif %}
<div class="form-group">
<label for="role_name" class="col-sm-2 control-label">规则名称<span class="red-fonts">*</span></label>
<label for="role_name" class="col-sm-2 control-label">用户名称<span class="red-fonts">*</span></label>
<div class="col-sm-8">
<input id="role_name" name="role_name" placeholder="Role Name" type="text" class="form-control" value="{{ role.name }}">
</div>
</div>
<div class="hr-line-dashed"></div>
<div class="form-group">
<label for="role_password" class="col-sm-2 control-label">角色密码</label>
<label for="role_password" class="col-sm-2 control-label">用户密码</label>
<div class="col-sm-8">
<input id="role_password" name="role_password" type="password" class="form-control">
<span class="help-block m-b-none">不修改请留空</span>
@ -49,7 +49,7 @@
</div>
<div class="hr-line-dashed"></div>
<div class="form-group">
<label for="role_key" class="col-sm-2 control-label">角色密钥</label>
<label for="role_key" class="col-sm-2 control-label">用户密钥</label>
<div class="col-sm-8">
<textarea class="form-control" name="role_key" placeholder="请复制粘贴私钥" rows="10" style="font-size: 9px;"></textarea>
<span class="help-block m-b-none">不修改请留空</span>
@ -57,9 +57,9 @@
</div>
<div class="hr-line-dashed"></div>
<div class="form-group">
<label for="sudo" class="col-sm-2 control-label">角色Sudo命令<span class="red-fonts">*</span></label>
<label for="sudo" class="col-sm-2 control-label">关联sudo<span class="red-fonts">*</span></label>
<div class="col-sm-8">
<select name="sudo_name" data-placeholder="请选择Sudo别名" class="chosen-select form-control m-b" multiple tabindex="2">
<select name="sudo_name" data-placeholder="请选择Sudo" class="chosen-select form-control m-b" multiple tabindex="2">
{% for sudo in sudo_all %}
<option value="{{ sudo.id }}" {% if sudo in role_sudos %} selected {% endif %}>{{ sudo.name }}</option>
{% endfor %}
@ -100,9 +100,9 @@ $('#roleForm').validator({
fields: {
"role_name": {
rule: "required;check_name",
tip: "输入角色名称",
tip: "输入系统用户名称",
ok: "",
msg: {required: "角色名称必填"}
msg: {required: "系统用户名称必填"}
}
},
valid: function(form) {

View File

@ -16,7 +16,7 @@
{% endif %}
</div>
<div class="ibox-title">
<h5> 所有系统角色</h5>
<h5> 所有系统用户</h5>
<div class="ibox-tools">
<a class="collapse-link">
<i class="fa fa-chevron-up"></i>
@ -31,8 +31,7 @@
</div>
<div class="ibox-content">
<div class="">
<a href="/jperm/role/perm_role_add/" class="btn btn-sm btn-primary "> 添加角色 </a>
{# <a href="/jperm/role/perm_role_push/" class="btn btn-sm btn-danger "> 推送角色 </a>#}
<a href="{% url 'role_add' %}" class="btn btn-sm btn-primary "> 添加系统用户 </a>
<form id="search_form" method="get" action="" class="pull-right mail-search">
<div class="input-group">
<input type="text" class="form-control input-sm" id="search_input" name="search" placeholder="Search">
@ -56,12 +55,12 @@
<tbody id="edittbody">
{% for role in roles %}
<tr class="gradeX" id={{ role.id }}>
<td class="text-center"><a href="/jperm/role/perm_role_detail/?id={{ role.id }}">{{ role.name }} </a></td>
<td class="text-center"><a href="{% url 'role_detail' %}?id={{ role.id }}">{{ role.name }} </a></td>
<td class="text-center"> {{ role | role_contain_which_sudos }} </td>
<td class="text-center"> {{ role.date_added | date:"Y-m-d H:i:s"}} </td>
<td class="text-center">
<a href="/jperm/role/perm_role_edit/?id={{ role.id }}" class="btn btn-xs btn-info">编辑</a>
<a href="/jperm/role/push/?id={{ role.id }}" class="btn btn-xs btn-warning">推送</a>
<a href="{% url 'role_edit' %}?id={{ role.id }}" class="btn btn-xs btn-info">编辑</a>
<a href="{% url 'role_push' %}?id={{ role.id }}" class="btn btn-xs btn-warning">推送</a>
<button onclick="remove_role({{ role.id }})" class="btn btn-xs btn-danger">删除</button>
</td>
</tr>
@ -88,7 +87,7 @@ function remove_role(role_id){
if (confirm("确认删除")) {
$.ajax({
type: "POST",
url: "/jperm/role/perm_role_delete/",
url: "{% url 'role_del' %}",
data: "id=" + role_id,
success: function(msg){
alert( "成功: " + msg );

View File

@ -34,7 +34,7 @@
<div class="alert alert-success text-center">{{ msg }}</div>
{% endif %}
<div class="form-group">
<label for="role" class="col-sm-2 control-label">角色</label>
<label for="role" class="col-sm-2 control-label">系统用户</label>
<div class="col-sm-8">
<input name="id" type="text" class="form-control" disabled value="{{ role.name }}">
</div>
@ -125,8 +125,8 @@ $('#pushForm').validator({
},
"roles": {
rule: "required",
tip: "请选择角色",
msg: {required: "必须选择角色"}
tip: "请选择系统用户",
msg: {required: "必须选择系统用户"}
}
},
valid: function(form) {

View File

@ -36,14 +36,14 @@
<div class="form-group">
<label for="name" class="col-sm-2 control-label">授权名称<span class="red-fonts">*</span></label>
<div class="col-sm-8">
<input id="name" name="name" placeholder="Rule Name" type="text" class="form-control">
<input id="name" name="name" type="text" class="form-control">
</div>
</div>
<div class="hr-line-dashed"></div>
<div class="form-group">
<label for="user" class="col-sm-2 control-label">用户</label>
<div class="col-sm-8">
<select name="user" id="user" data-placeholder="用户" class="chosen-select form-control m-b" multiple tabindex="2">
<select name="user" id="user" data-placeholder="请选择用户" class="chosen-select form-control m-b" multiple tabindex="2">
{% for user in users %}
<option value="{{ user.id }}">{{ user.name }}</option>
{% endfor %}
@ -85,9 +85,9 @@
</div>
<div class="hr-line-dashed"></div>
<div class="form-group">
<label for="role" class="col-sm-2 control-label">角色<span class="red-fonts">*</span></label>
<label for="role" class="col-sm-2 control-label">系统用户<span class="red-fonts">*</span></label>
<div class="col-sm-8" id="role_name">
<select name="role" data-placeholder="请选择角色" class="chosen-select form-control m-b" multiple tabindex="2">
<select name="role" data-placeholder="请选择需要关联的系统用户" class="chosen-select form-control m-b" multiple tabindex="2">
{% for role in roles %}
<option value="{{ role.id }}">{{ role.name }}</option>
{% endfor %}
@ -99,7 +99,7 @@
<div class="form-group">
<label for="comment" class="col-sm-2 control-label">备注</label>
<div class="col-sm-8">
<input id="comment" name="comment" placeholder="Rule Comment" type="text" class="form-control" {% if error %}value="{{ username }}" {% endif %}>
<input id="comment" name="comment" type="text" class="form-control" {% if error %}value="{{ username }}" {% endif %}>
</div>
</div>
<div class="hr-line-dashed"></div>
@ -133,7 +133,7 @@ $('#ruleForm').validator({
fields: {
"name": {
rule: "required;check_name",
rule: "required",
tip: "输入规则名称",
msg: {required: "规则名称必填"}
},
@ -149,8 +149,8 @@ $('#ruleForm').validator({
},
"role": {
rule: "required",
tip: "请选择角色",
msg: {required: "必须选择角色"}
tip: "请选择系统用户",
msg: {required: "必须选择系统用户"}
}
},
valid: function(form) {

View File

@ -46,7 +46,7 @@
<td>{{ rule.date_added | date:"Y-m-d H:i:s"}}</td>
</tr>
<tr>
<td class="text-navy">角色</td>
<td class="text-navy">关联用户</td>
<td>{{ roles_name }}</td>
</tr>
@ -83,36 +83,35 @@
</div>
</div>
<div class="ibox-content">
<div class="text-center">
<table class="table" id="agedit" >
<td class="text-navy text-left">用户</td>
<td class="text-navy text-right">用户组</td>
<tr>
<td>
<table class="table progress-striped text-left">
{% for user in users %}
<tr class="gradeX">
<td> <a href="/jasset/asset_detail/?id={{ user.id }}">{{ user.name }}</a> </td>
</tr>
{% endfor %}
</table>
</td>
<td>
<table class="table progress-striped text-right">
{% for group in user_groups %}
<tr class="gradeX-">
<td> <a href="/jasset/asset_list/?group_id={{ group.id }}">{{ group.name }}</a> </td>
</tr>
{% endfor %}
</table>
</td>
</tr>
</table>
</div>
</div>
</div>
<div class="text-center">
<table class="table" id="agedit" >
<td class="text-navy text-left">用户</td>
<td class="text-navy text-right">用户组</td>
<tr>
<td>
<table class="table progress-striped text-left">
{% for user in users %}
<tr class="gradeX">
<td> <a href="{% url 'user_detail' %}?id={{ user.id }}">{{ user.name }}</a> </td>
</tr>
{% endfor %}
</table>
</td>
<td>
<table class="table progress-striped text-right">
{% for group in user_groups %}
<tr class="gradeX-">
<td> <a href="{% url 'user_group_list' %}?group_id={{ group.id }}">{{ group.name }}</a> </td>
</tr>
{% endfor %}
</table>
</td>
</tr>
</table>
</div>
</div>
</div>
</div>
<div class="col-sm-4">
<div class="ibox float-e-margins">
<div class="ibox-title">
@ -145,7 +144,7 @@
<table class="table progress-striped text-left">
{% for asset in assets %}
<tr class="gradeX">
<td> <a href="/jasset/asset_detail/?id={{ asset.id }}">{{ asset.ip }}</a> </td>
<td> <a href="{% url 'asset_detail' %}?id={{ asset.id }}">{{ asset.ip }}</a> </td>
</tr>
{% endfor %}
</table>
@ -154,7 +153,7 @@
<table class="table progress-striped text-right">
{% for group in asset_groups %}
<tr class="gradeX-">
<td> <a href="/jasset/asset_list/?group_id={{ group.id }}">{{ group.name }}</a> </td>
<td> <a href="{% url 'asset_list' %}?group_id={{ group.id }}">{{ group.name }}</a> </td>
</tr>
{% endfor %}
</table>

View File

@ -85,9 +85,9 @@
</div>
<div class="hr-line-dashed"></div>
<div class="form-group">
<label for="role" class="col-sm-2 control-label">角色<span class="red-fonts">*</span></label>
<label for="role" class="col-sm-2 control-label">系统用户<span class="red-fonts">*</span></label>
<div class="col-sm-8">
<select name="role" data-placeholder="请选择角色" class="chosen-select form-control m-b" multiple tabindex="2">
<select name="role" data-placeholder="请选择系统用户" class="chosen-select form-control m-b" multiple tabindex="2">
{% for role in roles %}
<option value="{{ role.id }}"{% if role in rule.role.all %} selected {% endif %}>{{ role.name }}</option>
{% endfor %}
@ -99,7 +99,7 @@
<div class="form-group">
<label for="comment" class="col-sm-2 control-label">备注</label>
<div class="col-sm-8">
<input id="comment" name="rule_comment" placeholder="Rule Comment" type="text" class="form-control" value="{{ rule.comment }}">
<input id="comment" name="comment" placeholder="Rule Comment" type="text" class="form-control" value="{{ rule.comment }}">
</div>
</div>
<div class="hr-line-dashed"></div>
@ -150,8 +150,8 @@ $('#ruleForm').validator({
},
"role": {
rule: "required",
tip: "请选择角色",
msg: {required: "必须选择角色"}
tip: "请选择系统用户",
msg: {required: "必须选择系统用户"}
}
},
valid: function(form) {

View File

@ -34,7 +34,7 @@
<div class="ibox-content">
<div class="">
<a href="/jperm/perm_rule_add/" class="btn btn-sm btn-primary "> 添加规则 </a>
<a href="{% url 'rule_add' %}" class="btn btn-sm btn-primary "> 添加规则 </a>
<form id="search_form" method="get" action="" class="pull-right mail-search">
<div class="input-group">
<input type="text" class="form-control input-sm" id="search_input" name="search" placeholder="Search">
@ -55,14 +55,14 @@
<th class="text-center">用户组</th>
<th class="text-center">资产</th>
<th class="text-center">资产组</th>
<th class="text-center">角色</th>
<th class="text-center">系统用户</th>
<th class="text-center">操作</th>
</tr>
</thead>
<tbody id="edittbody">
{% for rule in rules %}
<tr class="gradeX" id={{ rule.id }}>
<td class="text-center"> <a href="/jperm/perm_rule_detail/?id={{ rule.id }}" >{{ rule.name }}</a> </td>
<td class="text-center"> <a href="{% url 'rule_detail' %}?id={{ rule.id }}" >{{ rule.name }}</a> </td>
<td class="text-center">
{{ rule | rule_member_count:"user" }}
</td>
@ -79,7 +79,7 @@
{{ rule | rule_member_count:"role" }}
</td>
<td class="text-center">
<a href="/jperm/perm_rule_edit/?id={{ rule.id }}" class="btn btn-xs btn-info">编辑</a>
<a href="{% url 'rule_edit' %}?id={{ rule.id }}" class="btn btn-xs btn-info">编辑</a>
<button onclick="remove_rule({{ rule.id }})" class="btn btn-xs btn-danger">删除</button>
</td>
</tr>

View File

@ -32,7 +32,7 @@
<div class="ibox-content">
<div class="">
<a href="/jperm/sudo/perm_sudo_add/" class="btn btn-sm btn-primary "> 添加别名 </a>
<a href="{% url 'sudo_add' %}" class="btn btn-sm btn-primary "> 添加别名 </a>
<form id="search_form" method="get" action="" class="pull-right mail-search">
<div class="input-group">
<input type="text" class="form-control input-sm" id="search_input" name="search" placeholder="Search">
@ -62,7 +62,7 @@
<td class="text-center"> {{ sudo.date_added | date:"Y-m-d H:i:s"}} </td>
<td class="text-center">
{# <a href="/jperm/sudo/perm_sudo_detail/?id={{ sudo.id }}" class="btn btn-xs btn-primary">详情</a>#}
<a href="/jperm/sudo/perm_sudo_edit/?id={{ sudo.id }}" class="btn btn-xs btn-info">编辑</a>
<a href="{% url 'sudo_edit' %}?id={{ sudo.id }}" class="btn btn-xs btn-info">编辑</a>
<button onclick="remove_sudo({{ sudo.id }})" class="btn btn-xs btn-danger">删除</button>
</td>
</tr>

View File

@ -1,130 +0,0 @@
{% extends 'base.html' %}
{% load mytags %}
{% block content %}
{% include 'nav_cat_bar.html' %}
<div class="wrapper wrapper-content animated fadeInRight">
<div class="row">
<div class="col-sm-10">
<div class="ibox float-e-margins">
<div class="panel blank-panel">
<div class="panel-heading">
<div class="panel-options">
<ul class="nav nav-tabs">
<li id="tab1" class=""><a href="/jperm/sys_user_list/" >查看系统用户</a></li>
<li id="tab2" class="active"><a href="/jperm/sys_user_add/">添加系统用户</a></li>
</ul>
</div>
</div>
<div class="panel-body">
<div class="tab-content">
<div id="tab-default" class="tab-pane active">
<form method="post" id="userForm" class="form-horizontal" action="">
{% if error %}
<div class="alert alert-warning text-center">{{ error }}</div>
{% endif %}
{% if msg %}
<div class="alert alert-success text-center">{{ msg }}</div>
{% endif %}
<div class="form-group">
<label for="username" class="col-sm-2 control-label">用户名<span class="red-fonts">*</span></label>
<div class="col-sm-8">
<input id="username" name="username" placeholder="Username" type="text" class="form-control" {% if error %}value="{{ username }}" {% endif %}>
</div>
</div>
<div class="hr-line-dashed"></div>
<div class="form-group">
<label for="password" class="col-sm-2 control-label">密码<span class="red-fonts">*</span></label>
<div class="col-sm-8">
<input id="password" name="password" placeholder="Password" type="password" class="form-control" {% if error %}value="{{ password }}" {% endif %} >
<span class="help-block m-b-none">通常在其它硬件上使用服务器会使用自动生成的key</span>
</div>
</div>
<div class="hr-line-dashed"></div>
<div class="form-group">
<label for="" class="col-sm-2 control-label">推送资产组<span class="red-fonts">*</span></label>
<div class="col-sm-4">
<div>
<select id="asset_groups" name="asset_groups" class="form-control" size="12" multiple>
{% for asset_group in asset_group_all %}
<option value="{{ asset_group.id }}">{{ asset_group.name }}</option>
{% endfor %}
</select>
<span class="help-block m-b-none">将在以上资产组服务器新建系统用户</span>
</div>
</div>
<div class="col-sm-1">
<div class="btn-group" style="margin-top: 42px;">
<button type="button" class="btn btn-white" onclick="move('asset_groups', 'asset_groups_select')"><i class="fa fa-chevron-right"></i></button>
<button type="button" class="btn btn-white" onclick="move('asset_groups_select', 'asset_groups')"><i class="fa fa-chevron-left"></i> </button>
</div>
</div>
<div class="col-sm-3">
<div>
<select id="asset_groups_select" name="asset_groups_select" class="form-control m-b" size="12" multiple>
</select>
</div>
</div>
</div>
<div class="hr-line-dashed"></div>
<div class="form-group">
<label for="comment" class="col-sm-2 control-label">备注<span class="red-fonts">*</span></label>
<div class="col-sm-8">
<input id="comment" name="comment" placeholder="Comment" type="text" class="form-control" {% if error %}value="{{ comment }}" {% endif %} >
</div>
</div>
<div class="hr-line-dashed"></div>
<div class="form-group">
<div class="col-sm-4 col-sm-offset-2">
<button class="btn btn-white" type="reset">取消</button>
<button id="submit_button" class="btn btn-primary" type="submit">确认保存</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% block self_footer_js %}
<script>
$('#userForm').validator({
timely: 2,
theme: "yellow_right_effect",
rules: {
check_username: [/^\w{3,20}$/, '大小写字母数字和下划线'],
type_m: function(element){
return $("#M").is(":checked");
}
},
fields: {
"username": {
rule: "required;check_username",
tip: "输入用户名",
ok: "",
msg: {required: "必须填写!"}
},
"password": {
rule: "required;length[6~50]",
tip: "输入密码",
ok: "",
msg: {required: "必须填写!"}
}
},
valid: function(form) {
form.submit();
}
});
</script>
{% endblock %}

View File

@ -1,102 +0,0 @@
{% extends 'base.html' %}
{% load mytags %}
{% block content %}
{% include 'nav_cat_bar.html' %}
<div class="wrapper wrapper-content animated fadeInRight">
<div class="row">
<div class="col-sm-12">
<div class="ibox float-e-margins">
<div class="panel blank-panel">
<div class="panel-heading">
<div class="panel-options">
<ul class="nav nav-tabs">
<li id="tab1" class="active"><a href="/jperm/sys_user_list/" >查看系统用户</a></li>
<li id="tab2" class=""><a href="/jperm/sys_user_add/">添加系统用户</a></li>
</ul>
</div>
</div>
<div class="panel-body">
<div class="tab-content">
<div id="tab-default" class="tab-pane active">
<div class="ibox-content">
<table class="table table-striped table-bordered table-hover " id="editable" >
<thead>
<tr>
<th class="text-center">
<input type="checkbox" name="select_all" onclick="selectAll()">
</th>
<th class="text-center">用户名</th>
<th class="text-center">操作</th>
</tr>
</thead>
<tbody>
{% for user in users.object_list %}
<tr class="gradeX">
<td class="text-center">
<input type="checkbox" name="selected" value="{{ user.id }}">
</td>
<td class="text-center"> {{ user.username }} </td>
<td class="text-center">
<a href="../user_detail/?id={{ user.id }}" class="btn btn-xs btn-primary">详情</a>
<a href="../user_edit/?id={{ user.id }}" class="btn btn-xs btn-info">编辑</a>
<a value="../user_del/?id={{ user.id }}" class="btn btn-xs btn-danger del {% if user.username == 'admin' %} disabled {% endif %}">删除</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<div class="row">
<div class="col-sm-6">
<div class="dataTables_info" id="editable_info" role="status" aria-live="polite">
Showing {{ users.start_index }} to {{ users.end_index }} of {{ p.count }} entries
</div>
</div>
{% include 'paginator.html' %}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% block self_head_css_js %}
<script>
$(document).ready(function(){
$('.del').click(function(){
var row = $(this).closest('tr');
$.get(
$(this).attr('value'),
{},
function(data){
row.remove();
alert(data);
}
)
});
$('#del_btn').click(function(){
var check_array = [];
if (confirm("确定删除")) {
$(".gradeX input:checked").each(function() {
check_array.push($(this).attr("value"))
});
$.post("/juser/user_del/",
{id: check_array.join(",")},
function(data){
$(".gradeX input:checked").closest("tr").remove();
alert(data);
}
)
}
});
});
</script>
{% endblock %}

View File

@ -53,7 +53,7 @@
<div class="form-group">
<label for="ssh_key_pwd" class="col-sm-2 control-label">SSH密钥</label>
<div class="col-sm-8">
<a value="/juser/regen_ssh_key/?uuid={{ user.uuid }}" id="regen_ssh_key" class="form-control"> 重新生成</a>
<a value="{% url 'key_gen' %}?uuid={{ user.uuid }}" id="regen_ssh_key" class="form-control"> 重新生成</a>
<span class="help-block m-b-none">
重新生成密钥,需要重新下载并导入
</span>

View File

@ -22,7 +22,7 @@
<tr>
<th class="text-center">用户名</th>
<th class="text-center">姓名</th>
<th class="text-center">角色</th>
<th class="text-center">系统用户</th>
</tr>
</thead>
<tbody>

View File

@ -25,7 +25,7 @@
<div class="ibox-content">
<div class="">
<a target="_blank" href="/juser/group_add/" class="btn btn-sm btn-primary "> 添加用户组 </a>
<a href="{% url 'user_group_add' %}" class="btn btn-sm btn-primary "> 添加用户组 </a>
<a id="del_btn" class="btn btn-sm btn-danger "> 删除所选 </a>
<form id="search_form" method="get" action="" class="pull-right mail-search">
<div class="input-group">
@ -59,12 +59,12 @@
</td>
<td class="text-center"> {{ group.name }} </td>
<td class="text-center">
<a href="/juser/user_list/?gid={{ group.id }}"> {{ group.id | members_count }}</a>
<a href="{% url 'user_list' %}?gid={{ group.id }}"> {{ group.id | members_count }}</a>
</td>
<td class="text-center"> {{ group.comment }} </td>
<td class="text-center">
<a href="../group_edit/?id={{ group.id }}" class="btn btn-xs btn-info">编辑</a>
<a value="../group_del/?id={{ group.id }}" class="btn btn-xs btn-danger del">删除</a>
<a href="{% url 'user_group_edit' %}?id={{ group.id }}" class="btn btn-xs btn-info">编辑</a>
<a value="{% url 'user_group_del' %}?id={{ group.id }}" class="btn btn-xs btn-danger del">删除</a>
</td>
</tr>
{% endfor %}
@ -112,7 +112,7 @@
$(".gradeX input:checked").each(function() {
check_array.push($(this).attr("value"))
});
$.get("/juser/group_del/",
$.get("{% url 'user_group_del' %}",
{id: check_array.join(",")},
function(result){
alert(result);

View File

@ -23,7 +23,7 @@
<td class="text-center" width="120">ID</td>
<td class="text-center">用户名</td>
<td class="text-center">姓名</td>
<td class="text-center">角色</td>
<td class="text-center">关联用户</td>
<td class="text-center">Email</td>
<td class="text-center">激活</td>
</tr>

View File

@ -51,9 +51,9 @@
<tr>
<td class="text-navy">key</td>
{% if user.username|key_exist %}
<td><a href="/juser/down_key/?id={{ user.id }}" >下载</a></td>
<td><a href="{% url 'key_down' %}?id={{ user.id }}" >下载</a></td>
{% else %}
<td><span style="color: #586b7d">下载</span></td>
<td><span style="color: #586b7d">NoKey</span></td>
{% endif %}
</tr>
<tr>
@ -78,7 +78,7 @@
<table class="table">
{% for group in user.group.all %}
<tr>
<td><a href="/jperm/perm_edit/?id={{ group.id }}">{{ group.name }}</a></td>
<td><a href="{% url 'user_group_list' %}?id={{ group.id }}">{{ group.name }}</a></td>
</tr>
{% endfor %}
</table>
@ -96,7 +96,7 @@
<table class="table">
{% for group in user_perm_info.asset_group.keys%}
<tr>
<td><a href="/jasset/group_list/?id={{ group.id }}">{{ group.name }}</a></td>
<td><a href="{% url 'user_group_list' %}?id={{ group.id }}">{{ group.name }}</a></td>
</tr>
{% endfor %}
</table>
@ -108,7 +108,7 @@
<table class="table">
{% for rule in user_perm_info.rule%}
<tr>
<td><a href="/jperm/role/?id={{ rule.id }}">{{ rule.name }}</a></td>
<td><a href="{% url 'role_list' %}?id={{ rule.id }}">{{ rule.name }}</a></td>
</tr>
{% endfor %}
</table>
@ -140,7 +140,7 @@
</div>
<div class="ibox-content ibox-heading">
<h3>用户的所有授权主机</h3>
<small><i class="fa fa-map-marker"></i> 这里包含了用户授权角色和角色下的主机.</small>
<small><i class="fa fa-map-marker"></i> 这里包含了用户授权的主机和其映射的系统用户.</small>
</div>
<div class="ibox-content inspinia-timeline">
{% for role, assets in role_assets.items %}
@ -149,19 +149,19 @@
<div class="col-xs-3 date">
<i class="fa fa-info"></i>
<b>
<a href="/jperm/role/&id={{ role.id }}">{{ role.name }}</a></b>
<a href="{% url 'role_list' %}?id={{ role.id }}">{{ role.name }}</a></b>
<br>
<small class="text-navy">共: {{ assets.asset | length }}台</small>
</div>
<div class="col-xs-7 content no-top-border">
<p class="m-b-xs">
<strong>{{ role.comment }}</strong></p>
<strong>{{ role.comment }}</strong>
</p>
<p>
{% for asset in assets.asset %}
<a href="/jasset/asset_list/?id={{ asset.id }}">{{ asset.hostname }}</a><br>
<a href="{% url 'asset_list' %}?id={{ asset.id }}">{{ asset.hostname }}</a><br>
{% endfor %}
</p>
<p></p>
</div>
</div>
</div>

View File

@ -23,7 +23,7 @@
</div>
</div>
<div class="ibox-content">
<form method="post" id="userForm" class="form-horizontal" action="/juser/user_edit/?id={{ user.id }}">
<form method="post" id="userForm" class="form-horizontal" action="{% url 'user_edit' %}?id={{ user.id }}">
{% if error %}
<div class="alert alert-warning text-center">{{ error }}</div>
{% endif %}
@ -70,7 +70,7 @@
</div>
<div class="hr-line-dashed"></div>
<div class="form-group">
<label for="role" class="col-sm-2 control-label">角色<span class="red-fonts">*</span></label>
<label for="role" class="col-sm-2 control-label">权限<span class="red-fonts">*</span></label>
<div class="col-sm-8">
{% for r, role_name in user_role.items %}
<div class="col-sm-3">

View File

@ -24,7 +24,7 @@
<div class="ibox-content">
<div class="">
<a target="_blank" href="/juser/user_add/" class="btn btn-sm btn-primary "> 添加用户 </a>
<a href="{% url 'user_add' %}" class="btn btn-sm btn-primary "> 添加用户 </a>
<a id="del_btn" class="btn btn-sm btn-danger "> 删除所选 </a>
<form id="search_form" method="get" action="" class="pull-right mail-search">
<div class="input-group">
@ -60,7 +60,7 @@
<td class="text-center">
<input type="checkbox" name="checked" value="{{ user.id }}">
</td>
<td class="text-center"><a href="../user_detail/?id={{ user.id }}">{{ user.username }}</a></td>
<td class="text-center"><a href="{% url 'user_detail' %}?id={{ user.id }}">{{ user.username }}</a></td>
<td class="text-center"> {{ user.name }} </td>
<td class="text-center" title="{% for user_group in user.group.all %} {{ user_group.name }} {% endfor %}"> {{ user.group.all | groups2str }} </td>
<td class="text-center"> {{ user.id | get_role }}</td>
@ -68,15 +68,15 @@
<td class="text-center">{{ user.is_active | bool2str }}</td>
<td class="text-center">
{% if user.username|key_exist %}
<a href="/juser/down_key/?uuid={{ user.uuid }}" >下载</a>
<a href="{% url 'key_down' %}?uuid={{ user.uuid }}" >下载</a>
{% else %}
<span style="color: #586b7d">下载</span>
<span style="color: #586b7d">NoKey</span>
{% endif %}
</td>
<td class="text-center">
<a href="../user_edit/?id={{ user.id }}" class="btn btn-xs btn-info">编辑</a>
<a href="{% url 'user_edit' %}?id={{ user.id }}" class="btn btn-xs btn-info">编辑</a>
<a value="{{ user.uuid }}" class="btn btn-xs btn-warning email">Email</a>
<a value="../user_del/?id={{ user.id }}" class="btn btn-xs btn-danger del {% if user.username == 'admin' %} disabled {% endif %}">删除</a>
<a value="{% url 'user_del' %}?id={{ user.id }}" class="btn btn-xs btn-danger del {% if user.username == 'admin' %} disabled {% endif %}">删除</a>
</td>
</tr>
{% endfor %}
@ -124,7 +124,7 @@
check_array.push($(this).attr("value"))
});
console.log(check_array.join(","));
$.post("/juser/user_del/",
$.post("{% url 'user_del' %}",
{id: check_array.join(",")},
function(data){
$(".gradeX input:checked").closest("tr").remove();
@ -136,7 +136,7 @@
});
$('.email').click(function(){
$.get('/juser/send_mail_retry/?uuid=' + $(this).attr('value'),
$.get('{% url "mail_retry" %}?uuid=' + $(this).attr('value'),
{},
function(data){
alert(data)

View File

@ -31,7 +31,7 @@
</div>
<button type="submit" class="btn btn-primary block full-width m-b">Login</button>
<a href="/juser/forget_password/"><small>Forgot password? </small></a>
<a href="{% url 'password_forget' %}"><small>Forgot password? </small></a>
</form>
<p class="m-t"> <small><b>Copyright</b> Jumpserver.org Organization © 2014-2015</small> </p>
</div>

View File

@ -4,49 +4,49 @@
<ul class="nav" id="side-menu">
{% include 'nav_li_profile.html' %}
<li id="index">
<a href="/"><i class="fa fa-dashboard"></i> <span class="nav-label">仪表盘</span><span class="label label-info pull-right"></span></a>
<a href="{% url 'index' %}"><i class="fa fa-dashboard"></i> <span class="nav-label">仪表盘</span><span class="label label-info pull-right"></span></a>
</li>
<li id="juser">
<a href="#"><i class="fa fa-group"></i> <span class="nav-label">用户管理</span><span class="fa arrow"></span></a>
<ul class="nav nav-second-level">
<li class="group_list group_edit group_add"><a href="/juser/group_list/">查看用户组</a></li>
<li class="user_list user_edit user_detail user_add"><a href="/juser/user_list/">查看用户<span class="label {% ifequal user_active_num user_total_num %}label-primary {% else %}label-warning {% endifequal %}pull-right">{{ user_active_num }}/{{ user_total_num }}</span></a></li>
<li class="group"><a href="{% url 'user_group_list' %}">查看用户组</a></li>
<li class="user"><a href="{% url 'user_list' %}">查看用户<span class="label {% ifequal user_active_num user_total_num %}label-primary {% else %}label-warning {% endifequal %}pull-right">{{ user_active_num }}/{{ user_total_num }}</span></a></li>
</ul>
</li>
<li id="jasset">
<a><i class="fa fa-inbox"></i> <span class="nav-label">资产管理</span><span class="fa arrow"></span></a>
<ul class="nav nav-second-level">
<li class="group_list group_detail group_edit"><a href="/jasset/group_list/">查看资产组</a></li>
<li class="asset_list asset_detail asset_edit asset_add asset_add_batch"><a href="/jasset/asset_list/">查看资产<span class="label label-info pull-right">{{ host_active_num }}/{{ host_total_num}}</span></a></li>
<li class="idc_list idc_detail idc_edit"><a href="/jasset/idc_list/">查看机房</a></li>
<li class="group"><a href="{% url 'asset_group_list' %}">查看资产组</a></li>
<li class="asset"> <a href="{% url 'asset_list' %}">查看资产<span class="label label-info pull-right">{{ host_active_num }}/{{ host_total_num}}</span></a></li>
<li class="idc"> <a href="{% url 'idc_list' %}">查看机房</a></li>
</ul>
</li>
<li id="jperm">
<a href="#"><i class="fa fa-edit"></i> <span class="nav-label">授权管理</span><span class="fa arrow"></span></a>
<ul class="nav nav-second-level">
<li class="rule perm_rule_add perm_rule_detail perm_rule_edit">
<a href="/jperm/rule/">授权规则</a>
<li class="sudo">
<a class="sudo" href="{% url 'sudo_list' %}">Sudo</a>
</li>
<li class="role">
<a href="/jperm/role/">系统角色</a>
<a href="{% url 'role_list' %}">系统用户</a>
</li>
<li class="sudo">
<a href="/jperm/sudo/">Sudo命令</a>
<li class="rule">
<a href="{% url 'rule_list' %}">授权规则</a>
</li>
</ul>
</li>
<li id="jlog">
<a href="/jlog/log_list/online/"><i class="fa fa-files-o"></i> <span class="nav-label">日志审计</span><span class="label label-info pull-right"></span></a>
<a href="{% url 'log_list' 'online' %}"><i class="fa fa-files-o"></i> <span class="nav-label">日志审计</span><span class="label label-info pull-right"></span></a>
</li>
<li id="file">
<a href="#"><i class="fa fa-download"></i> <span class="nav-label">上传下载</span><span class="fa arrow"></span></a>
<ul class="nav nav-second-level">
<li class="upload"><a href="/file/upload/">文件上传</a></li>
<li class="download"><a href="/file/download/">文件下载</a></li>
<li class="upload"><a href="{% url 'file_upload' %}">文件上传</a></li>
<li class="download"><a href="{% url 'file_download' %}">文件下载</a></li>
</ul>
</li>
<li id="setting">
<a href="/setting/"><i class="fa fa-gears"></i> <span class="nav-label">设置</span><span class="label label-info pull-right"></span></a>
<a href="{% url 'setting' %}"><i class="fa fa-gears"></i> <span class="nav-label">设置</span><span class="label label-info pull-right"></span></a>
</li>
<li class="special_link">
<a href="http://www.jumpserver.org" target="_blank"><i class="fa fa-database"></i> <span class="nav-label">访问官网</span></a>
@ -63,16 +63,16 @@
<ul class="nav" id="side-menu">
{% include 'nav_li_profile.html' %}
<li id="juser">
<a href="/juser/user_detail/"><i class="fa fa-dashboard"></i> <span class="nav-label">仪表盘</span><span class="label label-info pull-right"></span></a>
<a href="{% url 'user_detail' %}"><i class="fa fa-dashboard"></i> <span class="nav-label">仪表盘</span><span class="label label-info pull-right"></span></a>
</li>
<li id="jasset">
<a href="/jasset/asset_list/"><i class="fa fa-inbox"></i> <span class="nav-label">查看主机</span><span class="label label-info pull-right"></span></a>
<a href="{% url 'asset_list' %}"><i class="fa fa-inbox"></i> <span class="nav-label">查看主机</span><span class="label label-info pull-right"></span></a>
</li>
<li id="file">
<a href="#"><i class="fa fa-download"></i> <span class="nav-label">上传下载</span><span class="fa arrow"></span></a>
<ul class="nav nav-second-level">
<li class="upload"><a href="/file/upload/">文件上传</a></li>
<li class="download"><a href="/file/download/">文件下载</a></li>
<li class="upload"><a href="{% url 'file_upload' %}">文件上传</a></li>
<li class="download"><a href="{% url 'file_download' %}">文件下载</a></li>
</ul>
</li>

View File

@ -22,7 +22,7 @@
{% for apply in apply_info %}
<li>
<div class="dropdown-messages-box">
<a href="/jperm/apply_show/online/" class="pull-left">
<a href="" class="pull-left">
<img alt="image" class="img-circle" src="/static/img/a4.jpg">
</a>
<div class="media-body">
@ -38,7 +38,7 @@
{% endfor %}
<li>
<div class="text-center link-block">
<a href="/jperm/apply_show/online/">
<a href="">
<i class="fa fa-envelope"></i> <strong>Read All Messages</strong>
</a>
</div>
@ -71,7 +71,7 @@
{# </ul>#}
{# </li>#}
<li>
<a href="/logout/">
<a href="{% url 'logout' %}">
<i class="fa fa-sign-out"></i> Log out
</a>
</li>

View File

@ -3,7 +3,7 @@
<h2>{{ header_title }}</h2>
<ol class="breadcrumb">
<li>
<a href="/">仪表盘</a>
<a href="{% url 'index' %}">仪表盘</a>
</li>
<li>
{% if path1 %}

View File

@ -15,8 +15,8 @@
</span>
</a>
<ul class="dropdown-menu animated fadeInRight m-t-xs">
<li><a value="/juser/profile/?id={{ session_user_id }}" class="iframe_user">个人信息</a></li>
<li><a href="/juser/change_info/">修改信息</a></li>
<li><a value="{% url 'user_profile' %}?id={{ session_user_id }}" class="iframe_user">个人信息</a></li>
<li><a href="{% url 'user_update' %}">修改信息</a></li>
{# {% if not user.role == 'CU' %}#}
{# {% if request.session.role_id == 0 %}#}
{# <li><a href="/juser/change_role/">系统后台</a></li>#}
@ -25,7 +25,7 @@
{# {% endif %}#}
{# {% endif %}#}
<li class="divider"></li>
<li><a href="/logout/">注销</a></li>
<li><a href="{% url 'logout' %}">注销</a></li>
</ul>
</div>