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
72a18d6a
Commit
72a18d6a
authored
Oct 24, 2015
by
ibuler@qq.com
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
use map
parent
79e81340
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
292 additions
and
56 deletions
+292
-56
models.py
jperm/models.py
+8
-0
perm_api.py
jperm/perm_api.py
+19
-3
urls.py
jperm/urls.py
+10
-31
views.py
jperm/views.py
+0
-0
tasks.py
jumpserver/tasks.py
+1
-0
user_api.py
juser/user_api.py
+18
-20
user_perm.yaml
playbook/user_perm.yaml
+1
-1
sys_user_add.html
templates/jperm/sys_user_add.html
+131
-0
sys_user_list.html
templates/jperm/sys_user_list.html
+103
-0
nav.html
templates/nav.html
+1
-1
No files found.
jperm/models.py
View file @
72a18d6a
...
...
@@ -11,3 +11,11 @@ class PermLog(models.Model):
results
=
models
.
CharField
(
max_length
=
1000
,
null
=
True
,
blank
=
True
,
default
=
''
)
is_success
=
models
.
BooleanField
(
default
=
False
)
is_finish
=
models
.
BooleanField
(
default
=
False
)
class
SysUser
(
models
.
Model
):
username
=
models
.
CharField
(
max_length
=
100
)
password
=
models
.
CharField
(
max_length
=
100
)
comment
=
models
.
CharField
(
max_length
=
100
,
null
=
True
,
blank
=
True
,
default
=
''
)
jperm/perm_api.py
View file @
72a18d6a
...
...
@@ -76,8 +76,8 @@ def perm_user_api(perm_info):
try
:
new_ip
=
[
asset
.
ip
for
asset
in
new_assets
if
isinstance
(
asset
,
Asset
)]
del_ip
=
[
asset
.
ip
for
asset
in
del_assets
if
isinstance
(
asset
,
Asset
)]
new_username
=
[
user
.
username
for
user
in
new_users
if
isinstance
(
user
,
User
)
]
del_username
=
[
user
.
username
for
user
in
del_users
if
isinstance
(
user
,
User
)
]
new_username
=
[
user
.
username
for
user
in
new_users
]
del_username
=
[
user
.
username
for
user
in
del_users
]
except
IndexError
:
raise
ServerError
(
"Error: function perm_user_api传入参数类型错误"
)
...
...
@@ -90,7 +90,7 @@ def perm_user_api(perm_info):
playbook
=
get_playbook
(
os
.
path
.
join
(
BASE_DIR
,
'playbook'
,
'user_perm.yaml'
),
{
'the_new_group'
:
'new'
,
'the_del_group'
:
'del'
,
'the_new_users'
:
the_new_users
,
'the_del_users'
:
the_del_users
,
'
the_pub_key'
:
'/tmp/id_rsa.pub'
})
'
KEY_DIR'
:
os
.
path
.
join
(
SSH_KEY_DIR
,
'sysuser'
)
})
print
playbook
,
inventory
...
...
@@ -264,6 +264,22 @@ def _public_perm_api(info):
return
results
def
push_user
(
user
,
asset_groups_id
):
assets
=
[]
if
not
user
:
return
{
'error'
:
'没有该用户'
}
for
group_id
in
asset_groups_id
:
asset_group
=
get_object
(
AssetGroup
,
id
=
group_id
)
if
asset_group
:
assets
.
extend
(
asset_group
.
asset_set
.
all
())
perm_info
=
{
'action'
:
'Push user:'
+
user
.
username
,
'new'
:
{
'users'
:
[
user
],
'assets'
:
assets
}
}
results
=
perm_user_api
(
perm_info
)
return
results
...
...
jperm/urls.py
View file @
72a18d6a
...
...
@@ -2,34 +2,13 @@ from django.conf.urls import patterns, include, url
from
jperm.views
import
*
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'log/$'
,
log
),
# (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'),
# (r'^perm_user_detail/$', 'perm_user_detail'),
# (r'^perm_detail/$', 'perm_detail'),
# (r'^perm_del/$', 'perm_del'),
# (r'^perm_asset_detail/$', 'perm_asset_detail'),
# (r'^sudo_list/$', view_splitter, {'su': sudo_list, 'adm': sudo_list_adm}),
# (r'^sudo_del/$', 'sudo_del'),
# (r'^sudo_edit/$', view_splitter, {'su': sudo_edit, 'adm': sudo_edit_adm}),
# (r'^sudo_refresh/$', 'sudo_refresh'),
# (r'^sudo_detail/$', 'sudo_detail'),
# (r'^cmd_add/$', view_splitter, {'su': cmd_add, 'adm': cmd_add_adm}),
# (r'^cmd_list/$', 'cmd_list'),
# (r'^cmd_del/$', 'cmd_del'),
# (r'^cmd_edit/$', 'cmd_edit'),
# (r'^cmd_detail/$', 'cmd_detail'),
# (r'^apply/$', 'perm_apply'),
# (r'^apply_show/(\w+)/$', 'perm_apply_log'),
# (r'^apply_exec/$', 'perm_apply_exec'),
# (r'^apply_info/$', 'perm_apply_info'),
# (r'^apply_del/$', 'perm_apply_del'),
# (r'^apply_search/$', 'perm_apply_search'),
)
(
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'^log/$'
,
log
),
(
r'^sys_user_add/$'
,
sys_user_add
),
(
r'^sys_user_list/$'
,
sys_user_list
),
(
r'^sys_user_del/$'
,
sys_user_del
),
(
r'^sys_user_edit/$'
,
sys_user_edit
),
)
jperm/views.py
View file @
72a18d6a
This diff is collapsed.
Click to expand it.
jumpserver/tasks.py
View file @
72a18d6a
...
...
@@ -32,6 +32,7 @@ def playbook_run(inventory, playbook, default_user=None, default_port=None, defa
become
=
True
,
become_user
=
'root'
)
results
=
playbook
.
run
()
print
results
results_r
=
{
'unreachable'
:
[],
'failures'
:
[],
'success'
:
[]}
for
hostname
,
result
in
results
.
items
():
if
result
.
get
(
'unreachable'
,
2
):
...
...
juser/user_api.py
View file @
72a18d6a
# coding: utf-8
from
Crypto.PublicKey
import
RSA
from
subprocess
import
call
from
juser.models
import
AdminGroup
from
jumpserver.api
import
*
...
...
@@ -115,30 +116,27 @@ def db_del_user(username):
user
.
delete
()
def
gen_ssh_key
(
username
,
password
=
None
,
length
=
2048
):
def
gen_ssh_key
(
username
,
password
=
''
,
key_dir
=
os
.
path
.
join
(
BASE_DIR
,
'keys/user/'
),
authorized_keys
=
True
,
home
=
"/home"
,
length
=
2048
):
"""
generate a user ssh key in a property dir
生成一个用户ssh密钥对
"""
print
"gen_ssh_key"
+
str
(
time
.
time
())
private_key_dir
=
os
.
path
.
join
(
BASE_DIR
,
'keys/jumpserver/'
)
private_key_file
=
os
.
path
.
join
(
private_key_dir
,
username
+
".pem"
)
public_key_dir
=
'/home/
%
s/.ssh/'
%
username
public_key_file
=
os
.
path
.
join
(
public_key_dir
,
'authorized_keys'
)
is_dir
(
private_key_dir
)
is_dir
(
public_key_dir
,
username
,
mode
=
0700
)
key
=
RSA
.
generate
(
length
)
with
open
(
private_key_file
,
'w'
)
as
pri_f
:
pri_f
.
write
(
key
.
exportKey
(
'PEM'
,
password
))
os
.
chmod
(
private_key_file
,
0600
)
print
"gen_ssh_pub_key"
+
str
(
time
.
time
())
pub_key
=
key
.
publickey
()
with
open
(
public_key_file
,
'w'
)
as
pub_f
:
pub_f
.
write
(
pub_key
.
exportKey
(
'OpenSSH'
))
os
.
chmod
(
public_key_file
,
0600
)
bash
(
'chown
%
s:
%
s
%
s'
%
(
username
,
username
,
public_key_file
))
print
"gen_ssh_key_end"
+
str
(
time
.
time
())
private_key_file
=
os
.
path
.
join
(
key_dir
,
username
)
if
os
.
path
.
isfile
(
private_key_file
):
os
.
unlink
(
private_key_file
)
ret
=
bash
(
'ssh-keygen -t rsa -f
%
s -b
%
s -P "
%
s"'
%
(
private_key_file
,
length
,
password
))
if
authorized_keys
:
auth_key_dir
=
os
.
path
.
join
(
home
,
username
,
'.ssh'
)
is_dir
(
auth_key_dir
,
username
,
mode
=
0700
)
authorized_key_file
=
os
.
path
.
join
(
auth_key_dir
,
'authorized_keys'
)
with
open
(
private_key_file
+
'.pub'
)
as
pub_f
:
with
open
(
authorized_key_file
,
'w'
)
as
auth_f
:
auth_f
.
write
(
pub_f
.
read
())
os
.
chmod
(
authorized_key_file
,
0600
)
bash
(
'chown
%
s:
%
s
%
s'
%
(
username
,
username
,
authorized_key_file
))
def
server_add_user
(
username
,
password
,
ssh_key_pwd
,
ssh_key_login_need
):
...
...
playbook/user_perm.yaml
View file @
72a18d6a
...
...
@@ -13,5 +13,5 @@
file
:
name=/home/{{ item }}/.ssh mode=700 owner={{ item }} group={{ item }} state=directory
with_items
:
[
the_new_users
]
-
name
:
set authorizied_file
copy
:
src=
the_pub_key
dest=/home/{{ item }}/.ssh/authorizied_keys owner={{ item }} group={{ item }} mode=600
copy
:
src=
KEY_DIR/{{ item }}.pub
dest=/home/{{ item }}/.ssh/authorizied_keys owner={{ item }} group={{ item }} mode=600
with_items
:
[
the_new_users
]
templates/jperm/sys_user_add.html
0 → 100644
View file @
72a18d6a
{% 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=
"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 %}
\ No newline at end of file
templates/jperm/sys_user_list.html
0 → 100644
View file @
72a18d6a
{% 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-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 %}
\ No newline at end of file
templates/nav.html
View file @
72a18d6a
...
...
@@ -36,7 +36,7 @@
</li>
<li
class=
"sudo_list sudo_edit sudo_add cmd_list cmd_edit cmd_add sudo_detail"
>
<a
href=
"/jperm/s
udo_list/"
>
命令授权
</a>
<a
href=
"/jperm/s
ys_user_list/"
>
系统用户
</a>
</li>
<li
class=
"apply_show online"
><a
href=
"/jperm/apply_show/online/"
>
权限审批
</a></li>
<li
class=
"apply_show online"
><a
href=
"/jperm/log/"
>
授权记录
</a></li>
...
...
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