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
d7de3edc
Commit
d7de3edc
authored
Feb 09, 2015
by
guanghongwei
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
sudoȨ
parent
b9e2c9aa
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
235 additions
and
129 deletions
+235
-129
connect.py
connect.py
+1
-30
models.py
jperm/models.py
+3
-2
views.py
jperm/views.py
+43
-4
views.py
jumpserver/views.py
+51
-2
views.py
juser/views.py
+22
-16
sudo_add.html
templates/jperm/sudo_add.html
+98
-73
nav.html
templates/nav.html
+17
-2
No files found.
connect.py
View file @
d7de3edc
...
...
@@ -16,8 +16,6 @@ import getpass
import
fnmatch
import
readline
from
multiprocessing
import
Pool
from
Crypto.Cipher
import
AES
from
binascii
import
b2a_hex
,
a2b_hex
from
ConfigParser
import
ConfigParser
from
django.core.exceptions
import
ObjectDoesNotExist
...
...
@@ -27,6 +25,7 @@ from juser.models import User
from
jasset.models
import
Asset
from
jlog.models
import
Log
from
jperm.views
import
perm_user_asset
from
jumpserver.views
import
PyCrypt
try
:
import
termios
...
...
@@ -75,34 +74,6 @@ class ServerError(Exception):
pass
class
PyCrypt
(
object
):
"""This class used to encrypt and decrypt password."""
def
__init__
(
self
,
key
):
self
.
key
=
key
self
.
mode
=
AES
.
MODE_CBC
def
encrypt
(
self
,
text
):
cryptor
=
AES
.
new
(
self
.
key
,
self
.
mode
,
b
'0000000000000000'
)
length
=
16
try
:
count
=
len
(
text
)
except
TypeError
:
raise
ServerError
(
'Encrypt password error, TYpe error.'
)
add
=
(
length
-
(
count
%
length
))
text
+=
(
'
\0
'
*
add
)
ciphertext
=
cryptor
.
encrypt
(
text
)
return
b2a_hex
(
ciphertext
)
def
decrypt
(
self
,
text
):
cryptor
=
AES
.
new
(
self
.
key
,
self
.
mode
,
b
'0000000000000000'
)
try
:
plain_text
=
cryptor
.
decrypt
(
a2b_hex
(
text
))
except
TypeError
:
raise
ServerError
(
'Decrypt password error, TYpe error.'
)
return
plain_text
.
rstrip
(
'
\0
'
)
def
get_win_size
():
"""This function use to get the size of the windows!"""
if
'TIOCGWINSZ'
in
dir
(
termios
):
...
...
jperm/models.py
View file @
d7de3edc
...
...
@@ -18,7 +18,8 @@ class CmdGroup(models.Model):
class
SudoPerm
(
models
.
Model
):
name
=
models
.
CharField
(
max_length
=
20
)
user_group
=
models
.
ManyToManyField
(
UserGroup
)
asset_group
=
models
.
ManyToManyField
(
BisGroup
)
cmd_group
=
models
.
ManyToManyField
(
CmdGroup
)
comment
=
models
.
CharField
(
max_length
=
30
)
\ No newline at end of file
comment
=
models
.
CharField
(
max_length
=
30
,
null
=
True
,
blank
=
True
)
\ No newline at end of file
jperm/views.py
View file @
d7de3edc
...
...
@@ -7,6 +7,14 @@ from jasset.models import Asset, BisGroup
from
jperm.models
import
Perm
,
SudoPerm
,
CmdGroup
from
django.core.paginator
import
Paginator
,
EmptyPage
,
InvalidPage
from
django.db.models
import
Q
from
jumpserver.views
import
LDAP_ENABLE
,
ldap_conn
,
CONF
if
LDAP_ENABLE
:
LDAP_HOST_URL
=
CONF
.
get
(
'ldap'
,
'host_url'
)
LDAP_BASE_DN
=
CONF
.
get
(
'ldap'
,
'base_dn'
)
LDAP_ROOT_DN
=
CONF
.
get
(
'ldap'
,
'root_dn'
)
LDAP_ROOT_PW
=
CONF
.
get
(
'ldap'
,
'root_pw'
)
def
perm_group_update
(
user_group_name
=
''
,
user_group_id
=
''
,
asset_groups_name
=
''
,
asset_groups_id
=
''
):
...
...
@@ -138,7 +146,6 @@ def perm_asset_detail(request):
return
render_to_response
(
'jperm/perm_asset_detail.html'
,
locals
())
def
user_asset_cmd_groups_get
(
user_groups_select
,
asset_groups_select
,
cmd_groups_select
):
user_groups_select_list
=
[]
asset_groups_select_list
=
[]
...
...
@@ -167,10 +174,41 @@ def sudo_db_add(user_groups_select, asset_groups_select, cmd_groups_select, comm
sudo_perm
.
cmd_group
=
cmd_groups_select_list
def
sudo_ldap_add
(
user_groups_select
,
asset_groups_select
,
cmd_groups_select
):
def
unicode2str
(
unicode_list
):
return
[
str
(
i
)
for
i
in
unicode_list
]
def
sudo_ldap_add
(
name
,
users_runas
,
user_groups_select
,
asset_groups_select
,
cmd_groups_select
):
user_groups_select_list
,
asset_groups_select_list
,
cmd_groups_select_list
=
\
user_asset_cmd_groups_get
(
user_groups_select
,
asset_groups_select
,
cmd_groups_select
)
users
=
[]
assets
=
[]
cmds
=
[]
for
user_group
in
user_groups_select_list
:
users
.
extend
(
user_group
.
user_set
.
all
())
for
asset_group
in
asset_groups_select_list
:
assets
.
extend
(
asset_group
.
asset_set
.
all
())
for
cmd_group
in
cmd_groups_select_list
:
cmds
.
extend
(
cmd_group
.
cmd
.
split
(
','
))
users_name
=
[
user
.
name
for
user
in
users
]
assets_ip
=
[
asset
.
ip
for
asset
in
assets
]
sudo_dn
=
'cn=
%
s,ou=Sudoers,
%
s'
%
(
name
,
LDAP_BASE_DN
)
sudo_attr
=
{
'objectClass'
:
[
'top'
,
'sudoRole'
],
'cn'
:
[
'
%
s'
%
str
(
name
)],
'sudoCommand'
:
unicode2str
(
cmds
),
'sudoHost'
:
unicode2str
(
assets_ip
),
'sudoOption'
:
[
'!authenticate'
],
'sudoRunAsUser'
:
unicode2str
(
users_runas
),
'sudoUser'
:
unicode2str
(
users_name
)}
ldap_conn
.
add
(
sudo_dn
,
sudo_attr
)
def
sudo_add
(
request
):
header_title
,
path1
,
path2
=
u'Sudo授权 | Perm Sudo Add.'
,
u'jperm'
,
u'sudo_add'
...
...
@@ -179,16 +217,17 @@ def sudo_add(request):
cmd_groups
=
CmdGroup
.
objects
.
all
()
if
request
.
method
==
'POST'
:
name
=
request
.
POST
.
get
(
'name'
)
users_runas
=
request
.
POST
.
get
(
'runas'
,
'root'
)
.
split
(
','
)
user_groups_select
=
request
.
POST
.
getlist
(
'user_groups_select'
)
asset_groups_select
=
request
.
POST
.
getlist
(
'asset_groups_select'
)
cmd_groups_select
=
request
.
POST
.
getlist
(
'cmd_groups_select'
)
comment
=
request
.
POST
.
get
(
'comment'
,
''
)
sudo_db_add
(
user_groups_select
,
asset_groups_select
,
cmd_groups_select
,
comment
)
sudo_ldap_add
(
name
,
users_runas
,
user_groups_select
,
asset_groups_select
,
cmd_groups_select
)
msg
=
'添加成功'
return
render_to_response
(
'jperm/sudo_add.html'
,
locals
())
...
...
jumpserver/views.py
View file @
d7de3edc
...
...
@@ -3,15 +3,29 @@
import
hashlib
import
ldap
from
ldap
import
modlist
from
Crypto.Cipher
import
AES
from
binascii
import
b2a_hex
,
a2b_hex
from
ConfigParser
import
ConfigParser
import
os
from
django.http
import
HttpResponse
from
django.shortcuts
import
render_to_response
from
django.http
import
HttpResponseRedirect
from
juser.models
import
User
from
connect
import
PyCrypt
,
KEY
from
jasset.models
import
Asset
,
BisGroup
,
IDC
BASE_DIR
=
os
.
path
.
abspath
(
os
.
path
.
dirname
(
os
.
path
.
dirname
(
__file__
)))
CONF
=
ConfigParser
()
CONF
.
read
(
os
.
path
.
join
(
BASE_DIR
,
'jumpserver.conf'
))
LDAP_ENABLE
=
CONF
.
getint
(
'ldap'
,
'ldap_enable'
)
if
LDAP_ENABLE
:
LDAP_HOST_URL
=
CONF
.
get
(
'ldap'
,
'host_url'
)
LDAP_BASE_DN
=
CONF
.
get
(
'ldap'
,
'base_dn'
)
LDAP_ROOT_DN
=
CONF
.
get
(
'ldap'
,
'root_dn'
)
LDAP_ROOT_PW
=
CONF
.
get
(
'ldap'
,
'root_pw'
)
def
md5_crypt
(
string
):
return
hashlib
.
new
(
"md5"
,
string
)
.
hexdigest
()
...
...
@@ -30,7 +44,7 @@ def jasset_group_add(name, comment, type):
emg
=
u'该业务组已存在!'
else
:
BisGroup
.
objects
.
create
(
name
=
name
,
comment
=
comment
,
type
=
type
)
smg
=
u'业务组
%
s添加成功'
%
name
smg
=
u'业务组
%
s添加成功'
%
name
def
jasset_host_edit
(
j_id
,
j_ip
,
j_idc
,
j_port
,
j_type
,
j_group
,
j_active
,
j_comment
):
...
...
@@ -151,3 +165,38 @@ class LDAPMgmt():
print
e
class
PyCrypt
(
object
):
"""This class used to encrypt and decrypt password."""
def
__init__
(
self
,
key
):
self
.
key
=
key
self
.
mode
=
AES
.
MODE_CBC
def
encrypt
(
self
,
text
):
cryptor
=
AES
.
new
(
self
.
key
,
self
.
mode
,
b
'0000000000000000'
)
length
=
16
try
:
count
=
len
(
text
)
except
TypeError
:
raise
ServerError
(
'Encrypt password error, TYpe error.'
)
add
=
(
length
-
(
count
%
length
))
text
+=
(
'
\0
'
*
add
)
ciphertext
=
cryptor
.
encrypt
(
text
)
return
b2a_hex
(
ciphertext
)
def
decrypt
(
self
,
text
):
cryptor
=
AES
.
new
(
self
.
key
,
self
.
mode
,
b
'0000000000000000'
)
try
:
plain_text
=
cryptor
.
decrypt
(
a2b_hex
(
text
))
except
TypeError
:
raise
ServerError
(
'Decrypt password error, TYpe error.'
)
return
plain_text
.
rstrip
(
'
\0
'
)
if
LDAP_ENABLE
:
ldap_conn
=
LDAPMgmt
(
LDAP_HOST_URL
,
LDAP_BASE_DN
,
LDAP_ROOT_DN
,
LDAP_ROOT_PW
)
else
:
ldap_conn
=
None
juser/views.py
View file @
d7de3edc
...
...
@@ -20,17 +20,16 @@ from juser.models import UserGroup, User
from
connect
import
PyCrypt
,
KEY
from
connect
import
BASE_DIR
from
connect
import
CONF
from
jumpserver.views
import
md5_crypt
,
LDAPMgmt
from
jumpserver.views
import
md5_crypt
,
LDAPMgmt
,
LDAP_ENABLE
,
ldap_conn
CRYPTOR
=
PyCrypt
(
KEY
)
LDAP_ENABLE
=
CONF
.
getint
(
'ldap'
,
'ldap_enable'
)
if
LDAP_ENABLE
:
LDAP_HOST_URL
=
CONF
.
get
(
'ldap'
,
'host_url'
)
LDAP_BASE_DN
=
CONF
.
get
(
'ldap'
,
'base_dn'
)
LDAP_ROOT_DN
=
CONF
.
get
(
'ldap'
,
'root_dn'
)
LDAP_ROOT_PW
=
CONF
.
get
(
'ldap'
,
'root_pw'
)
CRYPTOR
=
PyCrypt
(
KEY
)
def
gen_rand_pwd
(
num
):
"""生成随机密码"""
...
...
@@ -176,20 +175,18 @@ def ldap_add_user(username, ldap_pwd):
'userPassword'
:
[
'{crypt}x'
],
'gidNumber'
:
[
str
(
user
.
id
)]}
sudo_dn
=
'cn=
%
s,ou=Sudoers,
%
s'
%
(
username
,
LDAP_BASE_DN
)
sudo_attr
=
{
'objectClass'
:
[
'top'
,
'sudoRole'
],
'cn'
:
[
'
%
s'
%
str
(
username
)],
'sudoCommand'
:
[
'/bin/pwd'
],
'sudoHost'
:
[
'192.168.1.1'
],
'sudoOption'
:
[
'!authenticate'
],
'sudoRunAsUser'
:
[
'root'
],
'sudoUser'
:
[
'
%
s'
%
str
(
username
)]}
ldap_conn
=
LDAPMgmt
(
LDAP_HOST_URL
,
LDAP_BASE_DN
,
LDAP_ROOT_DN
,
LDAP_ROOT_PW
)
# sudo_dn = 'cn=%s,ou=Sudoers,%s' % (username, LDAP_BASE_DN)
# sudo_attr = {'objectClass': ['top', 'sudoRole'],
# 'cn': ['%s' % str(username)],
# 'sudoCommand': ['/bin/pwd'],
# 'sudoHost': ['192.168.1.1'],
# 'sudoOption': ['!authenticate'],
# 'sudoRunAsUser': ['root'],
# 'sudoUser': ['%s' % str(username)]}
ldap_conn
.
add
(
user_dn
,
user_attr
)
ldap_conn
.
add
(
group_dn
,
group_attr
)
ldap_conn
.
add
(
sudo_dn
,
sudo_attr
)
#
ldap_conn.add(sudo_dn, sudo_attr)
def
ldap_del_user
(
username
):
...
...
@@ -197,12 +194,21 @@ def ldap_del_user(username):
group_dn
=
"cn=
%
s,ou=Group,
%
s"
%
(
username
,
LDAP_BASE_DN
)
sudo_dn
=
'cn=
%
s,ou=Sudoers,
%
s'
%
(
username
,
LDAP_BASE_DN
)
ldap_conn
=
LDAPMgmt
(
LDAP_HOST_URL
,
LDAP_BASE_DN
,
LDAP_ROOT_DN
,
LDAP_ROOT_PW
)
ldap_conn
.
delete
(
user_dn
)
ldap_conn
.
delete
(
group_dn
)
ldap_conn
.
delete
(
sudo_dn
)
# def ldap_group_add(group_name, username_list, gid):
# group_dn = "cn=%s,ou=Group,%s" % (group_name, LDAP_BASE_DN)
# group_attr = {'objectClass': ['posixGroup', 'top'],
# 'cn': [str(group_name)],
# 'userPassword': ['{crypt}x'],
# 'gidNumber': [gid],
# 'memberUid': username_list}
# ldap_conn.add(group_dn, group_attr)
def
group_add
(
request
,
group_type_select
=
'A'
):
error
=
''
msg
=
''
...
...
templates/jperm/sudo_add.html
View file @
d7de3edc
...
...
@@ -37,107 +37,132 @@
<div
class=
"alert alert-success text-center"
>
{{ msg }}
</div>
{% endif %}
<div
class=
"row"
>
<div
class=
"col-sm-5"
><h4>
用户组
</h4>
<div>
<select
id=
"user_groups"
name=
"user_groups"
class=
"form-control"
size=
"5"
multiple
>
{% for user_group in user_groups %}
<option
value=
"{{ user_group.id }}"
>
{{ user_group.name }}
</option>
{% endfor %}
</select>
<div
class=
"form-group"
>
<label
for=
"name"
class=
"col-sm-2 control-label"
>
授权名
</label>
<div
class=
"col-sm-8"
>
<input
id=
"name"
name=
"name"
placeholder=
"OnlyForEnglish"
type=
"text"
class=
"form-control"
>
<span
class=
"help-block m-b-none"
>
取个名字方便辨识,只支持英文
</span>
</div>
</div>
<div
class=
"hr-line-dashed"
></div>
<div
class=
"col-sm-1"
>
<div
class=
"btn-group"
style=
"margin-top: 50px;"
>
<button
type=
"button"
class=
"btn btn-white"
onclick=
"move('user_groups', 'user_groups_select')"
><i
class=
"fa fa-chevron-right"
></i></button>
<button
type=
"button"
class=
"btn btn-white"
onclick=
"move('user_groups_select', 'user_groups')"
><i
class=
"fa fa-chevron-left"
></i>
</button>
<div
class=
"form-group"
>
<label
for=
"runas"
class=
"col-sm-2 control-label"
>
RunAsUser
</label>
<div
class=
"col-sm-8"
>
<input
id=
"runas"
name=
"runas"
placeholder=
"RunAsUser"
type=
"text"
class=
"form-control"
>
<span
class=
"help-block m-b-none"
>
允许以哪个用户允许sudo,逗号分隔,默认root
</span>
</div>
</div>
<div
class=
"hr-line-dashed"
></div>
<div
class=
"col-sm-5"
><h4>
授权用户组
</h4>
<div>
<select
id=
"user_groups_select"
name=
"user_groups_select"
class=
"form-control m-b"
size=
"5"
multiple
>
</select>
<div
class=
"form-group"
>
<label
for=
""
class=
"col-sm-2 control-label"
>
用户组
</label>
<div
class=
"col-sm-4"
>
<div>
<select
id=
"user_groups"
name=
"user_groups"
class=
"form-control"
size=
"5"
multiple
>
{% for user_group in user_groups %}
<option
value=
"{{ user_group.id }}"
>
{{ user_group.name }}
</option>
{% endfor %}
</select>
</div>
</div>
</div>
</div>
<div
class=
"hr-line-dashed"
></div>
<div
class=
"row"
>
<div
class=
"col-sm-5"
><h4>
主机组
</h4>
<div>
<select
id=
"asset_groups"
name=
"asset_groups"
class=
"form-control m-b"
size=
"5"
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: 12px;"
>
<button
type=
"button"
class=
"btn btn-white"
onclick=
"move('user_groups', 'user_groups_select')"
><i
class=
"fa fa-chevron-right"
></i></button>
<button
type=
"button"
class=
"btn btn-white"
onclick=
"move('user_groups_select', 'user_groups')"
><i
class=
"fa fa-chevron-left"
></i>
</button>
</div>
</div>
<div
class=
"col-sm-1"
>
<div
class=
"btn-group"
style=
"margin-top: 50px;"
>
<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
class=
"col-sm-3"
>
<div>
<select
id=
"user_groups_select"
name=
"user_groups_select"
class=
"form-control m-b"
size=
"5"
multiple
>
</select>
</div>
</div>
</div>
</div>
<div
class=
"col-sm-5"
><h4>
授权主机组
</h4>
<div>
<select
id=
"asset_groups_select"
name=
"asset_groups_select"
class=
"form-control m-b"
size=
"5"
multiple
>
</select>
</div>
</div>
</div>
<div
class=
"hr-line-dashed"
></div>
<div
class=
"hr-line-dashed"
></div>
<div
class=
"form-group"
>
<label
for=
""
class=
"col-sm-2 control-label"
>
主机组
</label>
<div
class=
"col-sm-4"
>
<div>
<select
id=
"asset_groups"
name=
"asset_groups"
class=
"form-control m-b"
size=
"5"
multiple
>
{% for asset_group in asset_groups %}
<option
value=
"{{ asset_group.id }}"
>
{{ asset_group.name }}
</option>
{% endfor %}
</select>
</div>
</div>
<div
class=
"row"
>
<div
class=
"col-sm-5"
><h4>
命令组
</h4>
<div>
<select
id=
"cmd_groups"
name=
"cmd_groups"
class=
"form-control m-b"
size=
"5"
multiple
>
{% for cmd_group in cmd_groups %}
<option
value=
"{{ cmd_group.id }}"
>
{{ cmd_group.name }}
</option>
{% endfor %}
</select>
</div>
</div>
<div
class=
"col-sm-1"
>
<div
class=
"btn-group"
style=
"margin-top: 12px;"
>
<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-1"
>
<div
class=
"btn-group"
style=
"margin-top: 50px;"
>
<button
type=
"button"
class=
"btn btn-white"
onclick=
"move('cmd_groups', 'cmd_groups_select')"
><i
class=
"fa fa-chevron-right"
></i></button>
<button
type=
"button"
class=
"btn btn-white"
onclick=
"move('cmd_groups_select', 'cmd_groups')"
><i
class=
"fa fa-chevron-left"
></i>
</button>
<div
class=
"col-sm-3"
>
<div>
<select
id=
"asset_groups_select"
name=
"asset_groups_select"
class=
"form-control m-b"
size=
"5"
multiple
>
</select>
</div>
</div>
</div>
</div>
<div
class=
"col-sm-5"
><h4>
命令组
</h4>
<div>
<select
id=
"cmd_groups_select"
name=
"cmd_groups_select"
class=
"form-control m-b"
size=
"5"
multiple
>
</select>
<div
class=
"hr-line-dashed"
></div>
<div
class=
"form-group"
>
<label
for=
""
class=
"col-sm-2 control-label"
>
命令组
</label>
<div
class=
"col-sm-4"
>
<div>
<select
id=
"cmd_groups"
name=
"cmd_groups"
class=
"form-control m-b"
size=
"5"
multiple
>
{% for cmd_group in cmd_groups %}
<option
value=
"{{ cmd_group.id }}"
>
{{ cmd_group.name }}
</option>
{% endfor %}
</select>
</div>
</div>
<div
class=
"col-sm-1"
>
<div
class=
"btn-group"
style=
"margin-top: 12px;"
>
<button
type=
"button"
class=
"btn btn-white"
onclick=
"move('cmd_groups', 'cmd_groups_select')"
><i
class=
"fa fa-chevron-right"
></i></button>
<button
type=
"button"
class=
"btn btn-white"
onclick=
"move('cmd_groups_select', 'cmd_groups')"
><i
class=
"fa fa-chevron-left"
></i>
</button>
</div>
</div>
<div
class=
"col-sm-3"
>
<div>
<select
id=
"cmd_groups_select"
name=
"cmd_groups_select"
class=
"form-control m-b"
size=
"5"
multiple
>
</select>
</div>
</div>
</div>
</div>
</div>
<div
class=
"hr-line-dashed"
></div>
<div
class=
"hr-line-dashed"
></div>
<div
class=
"form-group"
>
<label
for=
"group_name"
class=
"col-sm-2 control-label"
>
备注
</label>
<div
class=
"col-sm-8"
>
<input
id=
"comment"
name=
"comment"
placeholder=
"备注说明"
type=
"text"
class=
"form-control"
>
</div>
</div>
<div
class=
"hr-line-dashed"
></div>
<div
class=
"hr-line-dashed"
></div>
</div>
<div
class=
"row"
>
<div
class=
"form-group"
>
<div
class=
"col-sm-4 col-sm-offset-2"
>
<button
class=
"btn btn-white"
type=
"submit"
>
取消
</button>
<button
class=
"btn btn-primary"
type=
"submit"
onclick=
"javascript: (function(){$('#sudoPerm option').each(function(){$(this).prop('selected', true)})})()"
>
确认保存
</button>
<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
class=
"btn btn-primary"
type=
"submit"
onclick=
"javascript: (function(){$('#sudoPerm option').each(function(){$(this).prop('selected', true)})})()"
>
确认保存
</button>
</div>
</div>
</div>
</div>
</div>
</form>
</form>
</div>
</div>
...
...
templates/nav.html
View file @
d7de3edc
...
...
@@ -33,8 +33,23 @@
<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
id=
"perm_list"
><a
href=
"/jperm/perm_list/"
>
主机授权
</a></li>
<li
id=
"perm_sudo"
><a
href=
"/jperm/sudo_add/"
>
Sudo添加
</a></li>
<li
id=
"perm_sudo"
><a
href=
"/jperm/sudo_list/"
>
Sudo查看
</a></li>
<li
class=
"active"
>
<a
href=
"#"
>
Sudo授权
<span
class=
"fa arrow"
></span></a>
<ul
class=
"nav nav-third-level"
>
<li
id=
"cmd_add"
>
<a
href=
"/jperm/cmd_add/"
>
命令组添加
</a>
</li>
<li
id=
"cmd_list"
>
<a
href=
"/jperm/cmd_list/"
>
命令组查看
</a>
</li>
<li
id=
"sudo_add"
>
<a
href=
"/jperm/sudo_add/"
>
Sudo添加
</a>
</li>
<li
id=
"sudo_list"
>
<a
href=
"/jperm/sudo_list/"
>
Sudo查看
</a>
</li>
</ul>
</li>
</ul>
</li>
<li
id=
"jlog"
>
...
...
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