Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
J
jumpserver
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
ops
jumpserver
Commits
43fe9851
Commit
43fe9851
authored
Oct 06, 2015
by
Administrator
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
添加组授权
parent
699046da
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
372 additions
and
68 deletions
+372
-68
perm_api.py
jperm/perm_api.py
+60
-51
urls.py
jperm/urls.py
+2
-0
views.py
jperm/views.py
+0
-0
mytags.py
jumpserver/templatetags/mytags.py
+51
-2
models.py
juser/models.py
+2
-0
user_perm.yaml
playbook/user_perm.yaml
+13
-11
perm_group_edit.html
templates/jperm/perm_group_edit.html
+156
-0
perm_group_list.html
templates/jperm/perm_group_list.html
+82
-0
perm_user_list.html
templates/jperm/perm_user_list.html
+5
-3
nav.html
templates/nav.html
+1
-1
No files found.
jperm/perm_api.py
View file @
43fe9851
...
...
@@ -11,6 +11,7 @@ from jumpserver.models import Setting
def
get_object_list
(
model
,
id_list
):
"""根据id列表获取对象列表"""
object_list
=
[]
for
object_id
in
id_list
:
if
object_id
:
...
...
@@ -19,51 +20,69 @@ def get_object_list(model, id_list):
return
object_list
def
perm_user_handle
(
user
,
asset_new
,
asset_del
,
group_new
,
group_del
):
username
=
user
.
name
asset_group_new
=
get_object_list
(
AssetGroup
,
group_new
)
asset_group_del
=
get_object_list
(
AssetGroup
,
group_del
)
for
asset_group
in
asset_group_new
:
asset_new
.
extend
([
asset
.
ip
for
asset
in
asset_group
.
asset_set
.
all
()])
for
asset_group
in
asset_group_del
:
asset_del
.
extend
(
asset
.
ip
for
asset
in
asset_group
.
asset_set
.
all
())
def
get_rand_file_path
(
base_dir
=
os
.
path
.
join
(
BASE_DIR
,
'tmp'
)):
"""获取随机文件路径"""
filename
=
uuid
.
uuid1
()
.
hex
return
os
.
path
.
join
(
base_dir
,
filename
)
def
get_inventory
(
host_group
):
"""生成资产表库存清单"""
path
=
get_rand_file_path
()
f
=
open
(
path
,
'w'
)
for
group
,
host_list
in
host_group
.
items
():
f
.
write
(
'[
%
s]
\n
'
%
group
)
for
ip
in
host_list
:
asset
=
get_object
(
Asset
,
ip
=
ip
)
if
asset
.
use_default
_auth
:
f
.
write
(
'
%
s
ansbile_ssh_port=
%
s
\n
'
%
(
ip
,
asset
.
port
)
)
if
asset
.
use_default
:
f
.
write
(
'
%
s
\n
'
%
ip
)
else
:
f
.
write
(
'
%
s ansible_ssh_port=
%
s ansible_ssh_user=
%
s ans
bile_ssh_pass=
%
s
\n
'
%
(
ip
,
asset
.
port
,
asset
.
username
,
CRYPTOR
.
decrypt
(
asset
.
password
)))
f
.
write
(
'
%
s ansible_ssh_port=
%
s ansible_ssh_user=
%
s ans
ible_ssh_pass=
%
s
\n
'
%
(
ip
,
asset
.
port
,
asset
.
username
,
CRYPTOR
.
decrypt
(
asset
.
password
)))
f
.
close
()
return
path
def
get_playbook
(
tempate
,
var
):
str_playbook
=
open
(
tempate
)
.
read
()
def
get_playbook
(
template
,
var
):
"""根据playbook模板,生成playbook"""
str_playbook
=
open
(
template
)
.
read
()
for
k
,
v
in
var
.
items
():
str_playbook
=
re
.
sub
(
r'
%
s'
%
k
,
v
,
str_playbook
)
str_playbook
=
re
.
sub
(
r'
%
s'
%
k
,
v
,
str_playbook
)
# 正则来替换传入的字符
path
=
get_rand_file_path
()
f
=
open
(
path
,
'w'
)
f
.
write
(
str_playbook
)
return
path
def
perm_user_api
(
user
,
asset_new
,
asset_del
,
asset_group_new
,
asset_group_del
):
asset_new_ip
=
[]
asset_del_ip
=
[]
def
playbook_run
(
inventory
,
playbook
,
default_user
=
None
,
default_port
=
None
,
default_pri_key_path
=
None
):
stats
=
callbacks
.
AggregateStats
()
playbook_cb
=
callbacks
.
PlaybookCallbacks
(
verbose
=
utils
.
VERBOSITY
)
runner_cb
=
callbacks
.
PlaybookRunnerCallbacks
(
stats
,
verbose
=
utils
.
VERBOSITY
)
# run the playbook
results
=
PlayBook
(
host_list
=
inventory
,
playbook
=
playbook
,
forks
=
5
,
remote_user
=
default_user
,
remote_port
=
default_port
,
private_key_file
=
default_pri_key_path
,
callbacks
=
playbook_cb
,
runner_callbacks
=
runner_cb
,
stats
=
stats
,
become
=
True
,
become_user
=
'root'
)
.
run
()
for
hostname
,
result
in
results
.
items
():
if
result
.
get
(
'failures'
,
2
):
print
"
%
s >>> Failed"
%
hostname
else
:
print
"
%
s >>> Success"
%
hostname
return
results
def
perm_user_api
(
asset_new
,
asset_del
,
asset_group_new
,
asset_group_del
,
user
=
None
,
user_group
=
None
):
"""用户授权api,通过调用ansible API完成用户新建等"""
asset_new_ip
=
[]
# 新授权的ip列表
asset_del_ip
=
[]
# 回收授权的ip列表
if
''
in
asset_group_new
:
asset_group_new
.
remove
(
''
)
...
...
@@ -71,48 +90,38 @@ def perm_user_api(user, asset_new, asset_del, asset_group_new, asset_group_del):
if
''
in
asset_group_del
:
asset_group_del
.
remove
(
''
)
asset_new_ip
.
extend
([
asset
.
ip
for
asset
in
get_object_list
(
Asset
,
asset_new
)])
asset_new_ip
.
extend
([
asset
.
ip
for
asset
in
get_object_list
(
Asset
,
asset_new
)])
# 查库,获取新授权ip
for
asset_group_id
in
asset_group_new
:
asset_new_ip
.
extend
([
asset
.
ip
for
asset
in
get_object
(
AssetGroup
,
id
=
asset_group_id
)
.
asset_set
.
all
()])
asset_del_ip
.
extend
([
asset
.
ip
for
asset
in
get_object_list
(
Asset
,
asset_del
)])
asset_new_ip
.
extend
([
asset
.
ip
for
asset
in
get_object
(
AssetGroup
,
id
=
asset_group_id
)
.
asset_set
.
all
()])
# 同理
asset_del_ip
.
extend
([
asset
.
ip
for
asset
in
get_object_list
(
Asset
,
asset_del
)])
# 查库,获取回收授权的ip
for
asset_group_id
in
asset_group_del
:
asset_del_ip
.
extend
([
asset
.
ip
for
asset
in
get_object
(
AssetGroup
,
id
=
asset_group_id
)
.
asset_set
.
all
()])
asset_del_ip
.
extend
([
asset
.
ip
for
asset
in
get_object
(
AssetGroup
,
id
=
asset_group_id
)
.
asset_set
.
all
()])
# 同理
print
asset_new_ip
print
asset_del_ip
stats
=
callbacks
.
AggregateStats
()
playbook_cb
=
callbacks
.
PlaybookCallbacks
(
verbose
=
utils
.
VERBOSITY
)
runner_cb
=
callbacks
.
PlaybookRunnerCallbacks
(
stats
,
verbose
=
utils
.
VERBOSITY
)
if
asset_new_ip
or
asset_del_ip
:
host_group
=
{
'new'
:
asset_new_ip
,
'del'
:
asset_del_ip
}
host_list
=
get_inventory
(
host_group
)
inventory
=
get_inventory
(
host_group
)
if
user
:
the_items
=
user
.
username
,
elif
user_group
:
users
=
user_group
.
user_set
.
all
()
the_items
=
','
.
join
([
user
.
username
for
user
in
users
])
else
:
return
HttpResponse
(
'Argument error.'
)
playbook
=
get_playbook
(
os
.
path
.
join
(
BASE_DIR
,
'playbook'
,
'user_perm.yaml'
),
{
'the_new_group'
:
'new'
,
'the_del_group'
:
'del'
,
'the_user'
:
user
.
username
,
'the_pub_key'
:
'/tmp/id_rsa.pub'
})
'the_items'
:
the_items
,
'the_pub_key'
:
'/tmp/id_rsa.pub'
})
settings
=
get_object
(
Setting
,
id
=
1
)
if
settings
:
default_user
=
settings
.
default_user
default_port
=
settings
.
default_port
default_pri_key_path
=
settings
.
default_pri_key_path
else
:
default_user
=
default_pri_key_path
=
''
results
=
PlayBook
(
host_list
=
host_list
,
playbook
=
playbook
,
forks
=
5
,
remote_user
=
default_user
,
private_key_file
=
default_pri_key_path
,
callbacks
=
playbook_cb
,
runner_callbacks
=
runner_cb
,
stats
=
stats
,
become
=
True
,
become_user
=
'root'
)
.
run
()
for
hostname
,
result
in
results
.
items
():
if
result
.
get
(
'failures'
,
2
):
print
"
%
s >>> Failed"
%
hostname
else
:
print
"
%
s >>> Success"
%
hostname
default_user
=
default_port
=
default_pri_key_path
=
''
results
=
playbook_run
(
inventory
,
playbook
,
default_user
,
default_port
,
default_pri_key_path
)
return
results
jperm/urls.py
View file @
43fe9851
...
...
@@ -5,6 +5,8 @@ urlpatterns = patterns('jperm.views',
# Examples:
(
r'^user/$'
,
perm_user_list
),
(
r'^perm_user_edit/$'
,
perm_user_edit
),
(
r'^group/$'
,
perm_group_list
),
(
r'^perm_group_edit/$'
,
perm_group_edit
),
# (r'^dept_perm_edit/$', 'dept_perm_edit'),
# (r'^perm_list/$', view_splitter, {'su': perm_list, 'adm': perm_list_adm}),
# (r'^dept_perm_list/$', 'dept_perm_list'),
...
...
jperm/views.py
View file @
43fe9851
This diff is collapsed.
Click to expand it.
jumpserver/templatetags/mytags.py
View file @
43fe9851
...
...
@@ -54,8 +54,8 @@ def get_role(user_id):
# return "%s ..." % ' '.join(groups[0:2])
#
@register.filter
(
name
=
'group
_str2
'
)
def
groups
_str2
(
group_list
):
@register.filter
(
name
=
'group
s2str
'
)
def
groups
2str
(
group_list
):
"""
将用户组列表转换为str
"""
...
...
@@ -64,6 +64,55 @@ def groups_str2(group_list):
else
:
return
'
%
s ...'
%
' '
.
join
([
group
.
name
for
group
in
group_list
[
0
:
2
]])
@register.filter
(
name
=
'user_asset_count'
)
def
user_asset_count
(
user
):
"""
返回用户权限主机的数量
"""
assets_id
=
user
.
assets
.
split
(
','
)
asset_groups
=
user
.
asset_groups
.
split
(
','
)
for
asset_group_id
in
asset_groups
:
asset_group
=
get_object
(
AssetGroup
,
id
=
asset_group_id
)
if
asset_group
:
assets_id
.
extend
(
asset
.
id
for
asset
in
asset_group
.
asset_set
.
all
())
assets_id
=
set
(
map
(
str
,
assets_id
))
return
len
(
assets_id
)
@register.filter
(
name
=
'user_asset_group_count'
)
def
user_asset_group_count
(
user
):
"""
返回用户权限主机组的数量
"""
return
len
(
filter
(
lambda
x
:
x
,
user
.
asset_groups
.
split
(
','
)))
#
# @register.filter(name='user_group_asset_count')
# def user_group_asset_count(user_group):
# """
# 返回用户组权限主机的数量
# """
# assets_id = user_group.assets.split(',')
# asset_groups = user_group.asset_groups.split(',')
#
# for asset_group_id in asset_groups:
# asset_group = get_object(AssetGroup, id=asset_group_id)
# if asset_group:
# assets_id.extend(asset.id for asset in asset_group.asset_set.all())
#
# assets_id = set(map(str, assets_id))
# return len(assets_id)
#
#
# @register.filter(name='user_group_asset_count')
# def user_group_asset_group_count(user_group):
# """
# 返回用户组权限主机组的数量
# """
# return len(user_group.asset_groups.split(','))
#
# @register.filter(name='group_str2_all')
# def group_str2_all(group_list):
...
...
juser/models.py
View file @
43fe9851
...
...
@@ -5,6 +5,8 @@ from django.db import models
class
UserGroup
(
models
.
Model
):
name
=
models
.
CharField
(
max_length
=
80
,
unique
=
True
)
assets
=
models
.
TextField
(
max_length
=
1000
,
verbose_name
=
"Assets"
,
default
=
''
)
asset_groups
=
models
.
CharField
(
max_length
=
1000
,
verbose_name
=
"Asset Groups"
,
default
=
''
)
comment
=
models
.
CharField
(
max_length
=
160
,
blank
=
True
,
null
=
True
)
def
__unicode__
(
self
):
...
...
playbook/user_perm.yaml
View file @
43fe9851
-
hosts
:
the_del_group
tasks
:
-
name
:
del user
user
:
name={{ item }} state=absent remove=yes
with_items
:
[
the_items
]
-
hosts
:
the_new_group
vars
:
user
:
the_user
tasks
:
-
name
:
add user
user
:
name={{ user }} state=present
user
:
name={{ item }} state=present
with_items
:
[
the_items
]
-
name
:
.ssh direcotory
file
:
name=/home/{{ user }}/.ssh mode=700 owner={{ user }} group={{ user }} state=directory
file
:
name=/home/{{ item }}/.ssh mode=700 owner={{ item }} group={{ item }} state=directory
with_items
:
[
the_items
]
-
name
:
set authorizied_file
copy
:
src=the_pub_key dest=/home/{{ user }}/.ssh/authorizied_keys owner={{ user }} group={{ user }} mode=600
copy
:
src=the_pub_key dest=/home/{{ item }}/.ssh/authorizied_keys owner={{ item }} group={{ item }} mode=600
with_items
:
[
the_items
]
-
hosts
:
the_del_group
vars
:
user
:
the_user
tasks
:
-
name
:
del user
user
:
name={{ user }} state=absent remove=yes
templates/jperm/perm_group_edit.html
0 → 100644
View file @
43fe9851
{% 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-lg-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=
"selectAllOption('userForm')"
>
确认保存
</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 %}
\ No newline at end of file
templates/jperm/perm_group_list.html
0 → 100644
View file @
43fe9851
{% 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-lg-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 %}
\ No newline at end of file
templates/jperm/perm_user_list.html
View file @
43fe9851
...
...
@@ -51,9 +51,11 @@
{% for user in users.object_list %}
<tr
class=
"gradeX"
>
<td
class=
"text-center"
>
{{ user.name }}
</td>
<td
class=
"text-center"
>
<a
href=
"/juser/user_list/?gid={{ user.id }}"
>
{{ user.id }}
</a>
</td>
<td
class=
"text-center"
>
<a
href=
"/jasset/host_list/?gid={{ user.id }}"
>
{{ user.id }}
</a>
</td>
<td
class=
"text-center"
>
{{ user.comment }}
</td>
<td
class=
"text-center"
>
<a
href=
"/juser/user_list/?gid={{ user.id }}"
>
{{ user.group.all | groups2str }}
</a>
</td>
<td
class=
"text-center"
>
<a
href=
"/jasset/asset_list/?gid={{ user.id }}"
>
{{ user | user_asset_count }}
</a>
</td>
<td
class=
"text-center"
>
<a
href=
"/jasset/group_list/?gid={{ user.id }}"
>
{{ user | user_asset_group_count }}
</a></td>
<td
class=
"text-center"
>
<a
href=
"../perm_user_detail/?id={{ user.id }}"
class=
"btn btn-xs btn-primary"
>
详情
</a>
<a
href=
"../perm_user_edit/?id={{ user.id }}"
class=
"btn btn-xs btn-danger"
>
编辑
</a>
...
...
templates/nav.html
View file @
43fe9851
...
...
@@ -32,7 +32,7 @@
</li>
<li
class=
"perm_list perm_edit perm_detail"
>
<a
href=
"/jperm/
perm_list
/"
>
用户组授权
</a>
<a
href=
"/jperm/
group
/"
>
用户组授权
</a>
</li>
<li
class=
"sudo_list sudo_edit sudo_add cmd_list cmd_edit cmd_add sudo_detail"
>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment