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
c21cdc21
Commit
c21cdc21
authored
Aug 31, 2015
by
ibuler
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
添加忘记密码
parent
44c69ded
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
366 additions
and
257 deletions
+366
-257
views.py
jperm/views.py
+64
-64
jumpserver.conf
jumpserver.conf
+1
-2
api.py
jumpserver/api.py
+86
-89
views.py
jumpserver/views.py
+1
-1
models.py
juser/models.py
+4
-3
urls.py
juser/urls.py
+4
-1
user_api.py
juser/user_api.py
+79
-56
views.py
juser/views.py
+0
-0
style.css
static/css/style.css
+2
-2
forget_password.html
templates/juser/forget_password.html
+54
-0
reset_password.html
templates/juser/reset_password.html
+51
-0
user_add.html
templates/juser/user_add.html
+2
-2
user_edit.html
templates/juser/user_edit.html
+0
-23
user_list.html
templates/juser/user_list.html
+17
-13
login.html
templates/login.html
+1
-1
No files found.
jperm/views.py
View file @
c21cdc21
...
@@ -262,70 +262,70 @@ def unicode2str(unicode_list):
...
@@ -262,70 +262,70 @@ def unicode2str(unicode_list):
return
[
str
(
i
)
for
i
in
unicode_list
]
return
[
str
(
i
)
for
i
in
unicode_list
]
def
sudo_ldap_add
(
user_group
,
user_runas
,
asset_groups_select
,
#
def sudo_ldap_add(user_group, user_runas, asset_groups_select,
cmd_groups_select
):
#
cmd_groups_select):
if
not
LDAP_ENABLE
:
#
if not LDAP_ENABLE:
return
True
#
return True
#
assets
=
[]
#
assets = []
cmds
=
[]
#
cmds = []
user_runas
=
user_runas
.
split
(
','
)
#
user_runas = user_runas.split(',')
if
len
(
asset_groups_select
)
==
1
and
asset_groups_select
[
0
]
.
name
==
'ALL'
:
#
if len(asset_groups_select) == 1 and asset_groups_select[0].name == 'ALL':
asset_all
=
True
#
asset_all = True
else
:
#
else:
asset_all
=
False
#
asset_all = False
for
asset_group
in
asset_groups_select
:
#
for asset_group in asset_groups_select:
assets
.
extend
(
asset_group
.
asset_set
.
all
())
#
assets.extend(asset_group.asset_set.all())
#
if
user_group
.
name
==
'ALL'
:
#
if user_group.name == 'ALL':
user_all
=
True
#
user_all = True
users
=
[]
#
users = []
else
:
#
else:
user_all
=
False
#
user_all = False
users
=
user_group
.
user_set
.
all
()
#
users = user_group.user_set.all()
#
for
cmd_group
in
cmd_groups_select
:
#
for cmd_group in cmd_groups_select:
cmds
.
extend
(
cmd_group
.
cmd
.
split
(
','
))
#
cmds.extend(cmd_group.cmd.split(','))
#
if
user_all
:
#
if user_all:
users_name
=
[
'ALL'
]
#
users_name = ['ALL']
else
:
#
else:
users_name
=
list
(
set
([
user
.
username
for
user
in
users
]))
#
users_name = list(set([user.username for user in users]))
#
if
asset_all
:
#
if asset_all:
assets_ip
=
[
'ALL'
]
#
assets_ip = ['ALL']
else
:
#
else:
assets_ip
=
list
(
set
([
asset
.
ip
for
asset
in
assets
]))
#
assets_ip = list(set([asset.ip for asset in assets]))
#
name
=
'sudo
%
s'
%
user_group
.
id
#
name = 'sudo%s' % user_group.id
sudo_dn
=
'cn=
%
s,ou=Sudoers,
%
s'
%
(
name
,
LDAP_BASE_DN
)
#
sudo_dn = 'cn=%s,ou=Sudoers,%s' % (name, LDAP_BASE_DN)
sudo_attr
=
{
'objectClass'
:
[
'top'
,
'sudoRole'
],
#
sudo_attr = {'objectClass': ['top', 'sudoRole'],
'cn'
:
[
'
%
s'
%
name
],
#
'cn': ['%s' % name],
'sudoCommand'
:
unicode2str
(
cmds
),
#
'sudoCommand': unicode2str(cmds),
'sudoHost'
:
unicode2str
(
assets_ip
),
#
'sudoHost': unicode2str(assets_ip),
'sudoOption'
:
[
'!authenticate'
],
#
'sudoOption': ['!authenticate'],
'sudoRunAsUser'
:
unicode2str
(
user_runas
),
#
'sudoRunAsUser': unicode2str(user_runas),
'sudoUser'
:
unicode2str
(
users_name
)}
#
'sudoUser': unicode2str(users_name)}
ldap_conn
.
delete
(
sudo_dn
)
#
ldap_conn.delete(sudo_dn)
ldap_conn
.
add
(
sudo_dn
,
sudo_attr
)
#
ldap_conn.add(sudo_dn, sudo_attr)
#
def
sudo_update
(
user_group
,
user_runas
,
asset_groups_select
,
cmd_groups_select
,
comment
):
#
def sudo_update(user_group, user_runas, asset_groups_select, cmd_groups_select, comment):
asset_groups_select_list
,
cmd_groups_select_list
=
\
#
asset_groups_select_list, cmd_groups_select_list = \
asset_cmd_groups_get
(
asset_groups_select
,
cmd_groups_select
)
#
asset_cmd_groups_get(asset_groups_select, cmd_groups_select)
sudo_perm
=
user_group
.
sudoperm_set
.
all
()
#
sudo_perm = user_group.sudoperm_set.all()
if
sudo_perm
:
#
if sudo_perm:
sudo_perm
.
update
(
user_runas
=
user_runas
,
comment
=
comment
)
#
sudo_perm.update(user_runas=user_runas, comment=comment)
sudo_perm
=
sudo_perm
[
0
]
#
sudo_perm = sudo_perm[0]
sudo_perm
.
asset_group
=
asset_groups_select_list
#
sudo_perm.asset_group = asset_groups_select_list
sudo_perm
.
cmd_group
=
cmd_groups_select_list
#
sudo_perm.cmd_group = cmd_groups_select_list
else
:
#
else:
sudo_perm
=
SudoPerm
(
user_group
=
user_group
,
user_runas
=
user_runas
,
comment
=
comment
)
#
sudo_perm = SudoPerm(user_group=user_group, user_runas=user_runas, comment=comment)
sudo_perm
.
save
()
#
sudo_perm.save()
sudo_perm
.
asset_group
=
asset_groups_select_list
#
sudo_perm.asset_group = asset_groups_select_list
sudo_perm
.
cmd_group
=
cmd_groups_select_list
#
sudo_perm.cmd_group = cmd_groups_select_list
#
sudo_ldap_add
(
user_group
,
user_runas
,
asset_groups_select_list
,
cmd_groups_select_list
)
#
sudo_ldap_add(user_group, user_runas, asset_groups_select_list, cmd_groups_select_list)
@require_super_user
@require_super_user
...
...
jumpserver.conf
View file @
c21cdc21
#coding: utf8
#coding: utf8
[
base
]
[
base
]
ip
=
192
.
168
.
20
.
209
url
=
http
://
192
.
168
.
244
.
129
port
=
80
key
=
88
aaaf7ffe3c6c04
key
=
88
aaaf7ffe3c6c04
log
=
debug
log
=
debug
...
...
jumpserver/api.py
View file @
c21cdc21
...
@@ -6,15 +6,12 @@ import getpass
...
@@ -6,15 +6,12 @@ import getpass
from
Crypto.Cipher
import
AES
from
Crypto.Cipher
import
AES
import
crypt
import
crypt
from
binascii
import
b2a_hex
,
a2b_hex
from
binascii
import
b2a_hex
,
a2b_hex
import
ldap
from
ldap
import
modlist
import
hashlib
import
hashlib
import
datetime
import
datetime
import
random
import
random
import
subprocess
import
subprocess
import
paramiko
import
paramiko
import
struct
,
fcntl
,
signal
,
socket
,
select
,
fnmatch
import
struct
,
fcntl
,
signal
,
socket
,
select
,
fnmatch
from
functools
import
partial
from
django.core.paginator
import
Paginator
,
EmptyPage
,
InvalidPage
from
django.core.paginator
import
Paginator
,
EmptyPage
,
InvalidPage
from
django.http
import
HttpResponse
,
Http404
from
django.http
import
HttpResponse
,
Http404
...
@@ -23,7 +20,7 @@ from juser.models import User, UserGroup
...
@@ -23,7 +20,7 @@ from juser.models import User, UserGroup
from
jasset.models
import
Asset
,
BisGroup
,
IDC
from
jasset.models
import
Asset
,
BisGroup
,
IDC
from
jlog.models
import
Log
from
jlog.models
import
Log
from
jasset.models
import
AssetAlias
from
jasset.models
import
AssetAlias
from
django.core.exceptions
import
ObjectDoesNotExist
from
django.core.exceptions
import
ObjectDoesNotExist
,
MultipleObjectsReturned
from
django.http
import
HttpResponseRedirect
from
django.http
import
HttpResponseRedirect
from
django.shortcuts
import
render_to_response
from
django.shortcuts
import
render_to_response
from
django.core.mail
import
send_mail
from
django.core.mail
import
send_mail
...
@@ -48,9 +45,8 @@ SSH_KEY_DIR = os.path.join(BASE_DIR, 'keys')
...
@@ -48,9 +45,8 @@ SSH_KEY_DIR = os.path.join(BASE_DIR, 'keys')
# SERVER_KEY_DIR = os.path.join(SSH_KEY_DIR, 'server')
# SERVER_KEY_DIR = os.path.join(SSH_KEY_DIR, 'server')
KEY
=
CONF
.
get
(
'base'
,
'key'
)
KEY
=
CONF
.
get
(
'base'
,
'key'
)
LOGIN_NAME
=
getpass
.
getuser
()
LOGIN_NAME
=
getpass
.
getuser
()
LDAP_ENABLE
=
CONF
.
getint
(
'ldap'
,
'ldap_enable'
)
# LDAP_ENABLE = CONF.getint('ldap', 'ldap_enable')
SEND_IP
=
CONF
.
get
(
'base'
,
'ip'
)
URL
=
CONF
.
get
(
'base'
,
'url'
)
SEND_PORT
=
CONF
.
get
(
'base'
,
'port'
)
MAIL_ENABLE
=
CONF
.
get
(
'mail'
,
'mail_enable'
)
MAIL_ENABLE
=
CONF
.
get
(
'mail'
,
'mail_enable'
)
MAIL_FROM
=
CONF
.
get
(
'mail'
,
'email_host_user'
)
MAIL_FROM
=
CONF
.
get
(
'mail'
,
'email_host_user'
)
log_dir
=
os
.
path
.
join
(
BASE_DIR
,
'logs'
)
log_dir
=
os
.
path
.
join
(
BASE_DIR
,
'logs'
)
...
@@ -73,73 +69,73 @@ def set_log(level):
...
@@ -73,73 +69,73 @@ def set_log(level):
return
logger_f
return
logger_f
class
LDAPMgmt
():
#
class LDAPMgmt():
"""
#
"""
LDAP class for add, select, del, update
#
LDAP class for add, select, del, update
LDAP 管理类,增删改查
#
LDAP 管理类,增删改查
"""
#
"""
def
__init__
(
self
,
#
def __init__(self,
host_url
,
#
host_url,
base_dn
,
#
base_dn,
root_cn
,
#
root_cn,
root_pw
):
#
root_pw):
self
.
ldap_host
=
host_url
#
self.ldap_host = host_url
self
.
ldap_base_dn
=
base_dn
#
self.ldap_base_dn = base_dn
self
.
conn
=
ldap
.
initialize
(
host_url
)
#
self.conn = ldap.initialize(host_url)
self
.
conn
.
set_option
(
ldap
.
OPT_REFERRALS
,
0
)
#
self.conn.set_option(ldap.OPT_REFERRALS, 0)
self
.
conn
.
protocol_version
=
ldap
.
VERSION3
#
self.conn.protocol_version = ldap.VERSION3
self
.
conn
.
simple_bind_s
(
root_cn
,
root_pw
)
#
self.conn.simple_bind_s(root_cn, root_pw)
#
def
list
(
self
,
filter
,
scope
=
ldap
.
SCOPE_SUBTREE
,
attr
=
None
):
#
def list(self, filter, scope=ldap.SCOPE_SUBTREE, attr=None):
"""
#
"""
query
#
query
查询
#
查询
"""
#
"""
result
=
{}
#
result = {}
try
:
#
try:
ldap_result
=
self
.
conn
.
search_s
(
self
.
ldap_base_dn
,
scope
,
filter
,
attr
)
#
ldap_result = self.conn.search_s(self.ldap_base_dn, scope, filter, attr)
for
entry
in
ldap_result
:
#
for entry in ldap_result:
name
,
data
=
entry
#
name, data = entry
for
k
,
v
in
data
.
items
():
#
for k, v in data.items():
print
'
%
s:
%
s'
%
(
k
,
v
)
#
print '%s: %s' % (k, v)
result
[
k
]
=
v
#
result[k] = v
return
result
#
return result
except
ldap
.
LDAPError
,
e
:
#
except ldap.LDAPError, e:
print
e
#
print e
#
def
add
(
self
,
dn
,
attrs
):
#
def add(self, dn, attrs):
"""
#
"""
add
#
add
添加
#
添加
"""
#
"""
try
:
#
try:
ldif
=
modlist
.
addModlist
(
attrs
)
#
ldif = modlist.addModlist(attrs)
self
.
conn
.
add_s
(
dn
,
ldif
)
#
self.conn.add_s(dn, ldif)
except
ldap
.
LDAPError
,
e
:
#
except ldap.LDAPError, e:
print
e
#
print e
#
def
modify
(
self
,
dn
,
attrs
):
#
def modify(self, dn, attrs):
"""
#
"""
modify
#
modify
更改
#
更改
"""
#
"""
try
:
#
try:
attr_s
=
[]
#
attr_s = []
for
k
,
v
in
attrs
.
items
():
#
for k, v in attrs.items():
attr_s
.
append
((
2
,
k
,
v
))
#
attr_s.append((2, k, v))
self
.
conn
.
modify_s
(
dn
,
attr_s
)
#
self.conn.modify_s(dn, attr_s)
except
ldap
.
LDAPError
,
e
:
#
except ldap.LDAPError, e:
print
e
#
print e
#
def
delete
(
self
,
dn
):
#
def delete(self, dn):
"""
#
"""
delete
#
delete
删除
#
删除
"""
#
"""
try
:
#
try:
self
.
conn
.
delete_s
(
dn
)
#
self.conn.delete_s(dn)
except
ldap
.
LDAPError
,
e
:
#
except ldap.LDAPError, e:
print
e
#
print e
def
page_list_return
(
total
,
current
=
1
):
def
page_list_return
(
total
,
current
=
1
):
...
@@ -480,9 +476,10 @@ def get_object(model, **kwargs):
...
@@ -480,9 +476,10 @@ def get_object(model, **kwargs):
use this function for query
use this function for query
使用改封装函数查询数据库
使用改封装函数查询数据库
"""
"""
try
:
the_object
=
model
.
objects
.
filter
(
**
kwargs
)
the_object
=
model
.
objects
.
get
(
**
kwargs
)
if
len
(
the_object
)
==
1
:
except
ObjectDoesNotExist
:
the_object
=
the_object
[
0
]
else
:
the_object
=
None
the_object
=
None
return
the_object
return
the_object
...
@@ -498,10 +495,10 @@ def require_role(role='user'):
...
@@ -498,10 +495,10 @@ def require_role(role='user'):
if
not
request
.
session
.
get
(
'user_id'
):
if
not
request
.
session
.
get
(
'user_id'
):
return
HttpResponseRedirect
(
'/login/'
)
return
HttpResponseRedirect
(
'/login/'
)
elif
role
==
'admin'
:
elif
role
==
'admin'
:
if
request
.
session
.
get
(
'role_id'
,
0
)
!=
1
:
if
request
.
session
.
get
(
'role_id'
,
0
)
<
1
:
return
HttpResponseRedirect
(
'/'
)
return
HttpResponseRedirect
(
'/'
)
elif
role
==
'super'
:
elif
role
==
'super'
:
if
request
.
session
.
get
(
'role_id'
,
0
)
!=
2
:
if
request
.
session
.
get
(
'role_id'
,
0
)
<
2
:
return
HttpResponseRedirect
(
'/'
)
return
HttpResponseRedirect
(
'/'
)
return
func
(
request
,
*
args
,
**
kwargs
)
return
func
(
request
,
*
args
,
**
kwargs
)
return
__deco
return
__deco
...
@@ -531,8 +528,7 @@ def get_session_user_dept(request):
...
@@ -531,8 +528,7 @@ def get_session_user_dept(request):
user
=
User
.
objects
.
filter
(
id
=
user_id
)
user
=
User
.
objects
.
filter
(
id
=
user_id
)
if
user
:
if
user
:
user
=
user
[
0
]
user
=
user
[
0
]
dept
=
user
.
dept
return
user
,
None
return
user
,
dept
@require_role
@require_role
...
@@ -704,14 +700,14 @@ def http_error(request, emg):
...
@@ -704,14 +700,14 @@ def http_error(request, emg):
CRYPTOR
=
PyCrypt
(
KEY
)
CRYPTOR
=
PyCrypt
(
KEY
)
if
LDAP_ENABLE
:
#
if LDAP_ENABLE:
LDAP_HOST_URL
=
CONF
.
get
(
'ldap'
,
'host_url'
)
#
LDAP_HOST_URL = CONF.get('ldap', 'host_url')
LDAP_BASE_DN
=
CONF
.
get
(
'ldap'
,
'base_dn'
)
#
LDAP_BASE_DN = CONF.get('ldap', 'base_dn')
LDAP_ROOT_DN
=
CONF
.
get
(
'ldap'
,
'root_dn'
)
#
LDAP_ROOT_DN = CONF.get('ldap', 'root_dn')
LDAP_ROOT_PW
=
CONF
.
get
(
'ldap'
,
'root_pw'
)
#
LDAP_ROOT_PW = CONF.get('ldap', 'root_pw')
ldap_conn
=
LDAPMgmt
(
LDAP_HOST_URL
,
LDAP_BASE_DN
,
LDAP_ROOT_DN
,
LDAP_ROOT_PW
)
#
ldap_conn = LDAPMgmt(LDAP_HOST_URL, LDAP_BASE_DN, LDAP_ROOT_DN, LDAP_ROOT_PW)
else
:
#
else:
ldap_conn
=
None
#
ldap_conn = None
log_level
=
CONF
.
get
(
'base'
,
'log'
)
log_level
=
CONF
.
get
(
'base'
,
'log'
)
logger
=
set_log
(
log_level
)
logger
=
set_log
(
log_level
)
\ No newline at end of file
jumpserver/views.py
View file @
c21cdc21
...
@@ -213,7 +213,7 @@ def login(request):
...
@@ -213,7 +213,7 @@ def login(request):
user_filter
.
update
(
last_login
=
datetime
.
datetime
.
now
())
user_filter
.
update
(
last_login
=
datetime
.
datetime
.
now
())
if
user
.
role
==
'SU'
:
if
user
.
role
==
'SU'
:
request
.
session
[
'role_id'
]
=
2
request
.
session
[
'role_id'
]
=
2
elif
user
.
role
==
'
D
A'
:
elif
user
.
role
==
'
G
A'
:
request
.
session
[
'role_id'
]
=
1
request
.
session
[
'role_id'
]
=
1
else
:
else
:
request
.
session
[
'role_id'
]
=
0
request
.
session
[
'role_id'
]
=
0
...
...
juser/models.py
View file @
c21cdc21
...
@@ -30,8 +30,8 @@ class User(models.Model):
...
@@ -30,8 +30,8 @@ class User(models.Model):
name
=
models
.
CharField
(
max_length
=
80
)
name
=
models
.
CharField
(
max_length
=
80
)
email
=
models
.
EmailField
(
max_length
=
75
)
email
=
models
.
EmailField
(
max_length
=
75
)
role
=
models
.
CharField
(
max_length
=
2
,
choices
=
USER_ROLE_CHOICES
,
default
=
'CU'
)
role
=
models
.
CharField
(
max_length
=
2
,
choices
=
USER_ROLE_CHOICES
,
default
=
'CU'
)
uuid
=
models
.
CharField
(
max_length
=
100
)
group
=
models
.
ManyToManyField
(
UserGroup
)
group
=
models
.
ManyToManyField
(
UserGroup
)
ldap_pwd
=
models
.
CharField
(
max_length
=
128
)
ssh_key_pwd
=
models
.
CharField
(
max_length
=
200
)
ssh_key_pwd
=
models
.
CharField
(
max_length
=
200
)
is_active
=
models
.
BooleanField
(
default
=
True
)
is_active
=
models
.
BooleanField
(
default
=
True
)
last_login
=
models
.
DateTimeField
(
null
=
True
)
last_login
=
models
.
DateTimeField
(
null
=
True
)
...
@@ -128,4 +128,6 @@ class AdminGroup(models.Model):
...
@@ -128,4 +128,6 @@ class AdminGroup(models.Model):
"""
"""
user
=
models
.
ForeignKey
(
User
)
user
=
models
.
ForeignKey
(
User
)
group
=
models
.
ForeignKey
(
UserGroup
)
group
=
models
.
ForeignKey
(
UserGroup
)
\ No newline at end of file
juser/urls.py
View file @
c21cdc21
...
@@ -13,7 +13,10 @@ urlpatterns = patterns('juser.views',
...
@@ -13,7 +13,10 @@ urlpatterns = patterns('juser.views',
(
r'^group_del_ajax'
,
group_del_ajax
),
(
r'^group_del_ajax'
,
group_del_ajax
),
(
r'^group_edit/$'
,
group_edit
),
(
r'^group_edit/$'
,
group_edit
),
(
r'^user_add/$'
,
user_add
),
(
r'^user_add/$'
,
user_add
),
(
r'^user_list/$'
,
view_splitter
,
{
'su'
:
user_list
,
'adm'
:
user_list_adm
}),
(
r'^user_list/$'
,
user_list
),
(
r'^send_mail_retry/$'
,
send_mail_retry
),
(
r'^reset_password/$'
,
reset_password
),
(
r'^forget_password/$'
,
forget_password
),
(
r'^user_detail/$'
,
'user_detail'
),
(
r'^user_detail/$'
,
'user_detail'
),
(
r'^user_del/$'
,
'user_del'
),
(
r'^user_del/$'
,
'user_del'
),
(
r'^user_del_ajax/$'
,
'user_del_ajax'
),
(
r'^user_del_ajax/$'
,
'user_del_ajax'
),
...
...
juser/user_api.py
View file @
c21cdc21
...
@@ -101,11 +101,9 @@ def db_del_user(username):
...
@@ -101,11 +101,9 @@ def db_del_user(username):
delete a user from database
delete a user from database
从数据库中删除用户
从数据库中删除用户
"""
"""
try
:
user
=
get_object
(
User
,
username
=
username
)
user
=
User
.
objects
.
get
(
username
=
username
)
if
user
:
user
.
delete
()
user
.
delete
()
except
ObjectDoesNotExist
:
pass
def
gen_ssh_key
(
username
,
password
=
None
,
length
=
2048
):
def
gen_ssh_key
(
username
,
password
=
None
,
length
=
2048
):
...
@@ -134,13 +132,14 @@ def gen_ssh_key(username, password=None, length=2048):
...
@@ -134,13 +132,14 @@ def gen_ssh_key(username, password=None, length=2048):
print
"gen_ssh_key_end"
+
str
(
time
.
time
())
print
"gen_ssh_key_end"
+
str
(
time
.
time
())
def
server_add_user
(
username
,
password
,
ssh_key_pwd
):
def
server_add_user
(
username
,
password
,
ssh_key_pwd
,
ssh_key_login_need
):
"""
"""
add a system user in jumpserver
add a system user in jumpserver
在jumpserver服务器上添加一个用户
在jumpserver服务器上添加一个用户
"""
"""
bash
(
"useradd '
%
s'; echo '
%
s' | passwd --stdin '
%
s'"
%
(
username
,
password
,
username
))
bash
(
"useradd '
%
s'; echo '
%
s'; echo '
%
s' | passwd --stdin '
%
s'"
%
(
username
,
password
,
password
,
username
))
gen_ssh_key
(
username
,
ssh_key_pwd
)
if
ssh_key_login_need
:
gen_ssh_key
(
username
,
ssh_key_pwd
)
def
user_add_mail
(
user
,
kwargs
):
def
user_add_mail
(
user
,
kwargs
):
...
@@ -156,10 +155,10 @@ def user_add_mail(user, kwargs):
...
@@ -156,10 +155,10 @@ def user_add_mail(user, kwargs):
您的角色:
%
s
您的角色:
%
s
您的web登录密码:
%
s
您的web登录密码:
%
s
您的ssh密钥文件密码:
%
s
您的ssh密钥文件密码:
%
s
密钥下载地址:
http://
%
s:
%
s/juser/down_key/?
id=
%
s
密钥下载地址:
%
s/juser/down_key/?uu
id=
%
s
说明: 请登陆后再下载密钥!
说明: 请登陆后再下载密钥!
"""
%
(
user
.
name
,
user
.
username
,
user_role
.
get
(
user
.
role
,
u'普通用户'
),
"""
%
(
user
.
name
,
user
.
username
,
user_role
.
get
(
user
.
role
,
u'普通用户'
),
kwargs
.
get
(
'password'
),
kwargs
.
get
(
'ssh_key_pwd'
),
SEND_IP
,
SEND_PORT
,
user
.
id
)
kwargs
.
get
(
'password'
),
kwargs
.
get
(
'ssh_key_pwd'
),
URL
,
user
.
uu
id
)
send_mail
(
mail_title
,
mail_msg
,
MAIL_FROM
,
[
user
.
email
],
fail_silently
=
False
)
send_mail
(
mail_title
,
mail_msg
,
MAIL_FROM
,
[
user
.
email
],
fail_silently
=
False
)
...
@@ -171,49 +170,73 @@ def server_del_user(username):
...
@@ -171,49 +170,73 @@ def server_del_user(username):
bash
(
'userdel -r
%
s'
%
username
)
bash
(
'userdel -r
%
s'
%
username
)
def
ldap_add_user
(
username
,
ldap_pwd
):
def
get_display_msg
(
user
,
password
,
ssh_key_pwd
,
ssh_key_login_need
,
send_mail_need
):
"""
if
send_mail_need
:
add a user in ldap database
msg
=
u'添加用户
%
s 成功! 用户密码已发送到
%
s 邮箱!'
%
(
user
.
name
,
user
.
email
)
在LDAP中添加用户
return
msg
"""
user_dn
=
"uid=
%
s,ou=People,
%
s"
%
(
username
,
LDAP_BASE_DN
)
if
ssh_key_login_need
:
password_sha512
=
PyCrypt
.
gen_sha512
(
PyCrypt
.
random_pass
(
6
),
ldap_pwd
)
msg
=
u"""
user
=
get_object
(
User
,
username
=
username
)
跳板机地址:
%
s
if
not
user
:
用户名:
%
s
raise
ServerError
(
u'用户
%
s 不存在'
%
username
)
密码:
%
s
密钥密码:
%
s
user_attr
=
{
'uid'
:
[
str
(
username
)],
密钥下载url:
%
s/juser/down_key/?id=
%
s
'cn'
:
[
str
(
username
)],
该账号密码可以登陆web和跳板机。
'objectClass'
:
[
'account'
,
'posixAccount'
,
'top'
,
'shadowAccount'
],
"""
%
(
URL
,
user
.
username
,
password
,
ssh_key_pwd
,
URL
,
user
.
id
)
'userPassword'
:
[
'{crypt}
%
s'
%
password_sha512
],
else
:
'shadowLastChange'
:
[
'16328'
],
msg
=
u"""
'shadowMin'
:
[
'0'
],
跳板机地址:
%
s
\n
'shadowMax'
:
[
'99999'
],
用户名:
%
s
\n
'shadowWarning'
:
[
'7'
],
密码:
%
s
\n
'loginShell'
:
[
'/bin/bash'
],
该账号密码可以登陆web和跳板机。
'uidNumber'
:
[
str
(
user
.
id
)],
"""
%
(
URL
,
user
.
username
,
password
)
'gidNumber'
:
[
str
(
user
.
id
)],
'homeDirectory'
:
[
str
(
'/home/
%
s'
%
username
)]}
return
msg
group_dn
=
"cn=
%
s,ou=Group,
%
s"
%
(
username
,
LDAP_BASE_DN
)
# def ldap_add_user(username, ldap_pwd):
group_attr
=
{
'objectClass'
:
[
'posixGroup'
,
'top'
],
# """
'cn'
:
[
str
(
username
)],
# add a user in ldap database
'userPassword'
:
[
'{crypt}x'
],
# 在LDAP中添加用户
'gidNumber'
:
[
str
(
user
.
id
)]}
# """
# user_dn = "uid=%s,ou=People,%s" % (username, LDAP_BASE_DN)
ldap_conn
.
add
(
user_dn
,
user_attr
)
# password_sha512 = PyCrypt.gen_sha512(PyCrypt.random_pass(6), ldap_pwd)
ldap_conn
.
add
(
group_dn
,
group_attr
)
# user = get_object(User, username=username)
# if not user:
# raise ServerError(u'用户 %s 不存在' % username)
def
ldap_del_user
(
username
):
#
"""
# user_attr = {'uid': [str(username)],
delete a user in ldap database
# 'cn': [str(username)],
在ldap中删除某用户
# 'objectClass': ['account', 'posixAccount', 'top', 'shadowAccount'],
"""
# 'userPassword': ['{crypt}%s' % password_sha512],
user_dn
=
"uid=
%
s,ou=People,
%
s"
%
(
username
,
LDAP_BASE_DN
)
# 'shadowLastChange': ['16328'],
group_dn
=
"cn=
%
s,ou=Group,
%
s"
%
(
username
,
LDAP_BASE_DN
)
# 'shadowMin': ['0'],
sudo_dn
=
'cn=
%
s,ou=Sudoers,
%
s'
%
(
username
,
LDAP_BASE_DN
)
# 'shadowMax': ['99999'],
# 'shadowWarning': ['7'],
ldap_conn
.
delete
(
user_dn
)
# 'loginShell': ['/bin/bash'],
ldap_conn
.
delete
(
group_dn
)
# 'uidNumber': [str(user.id)],
ldap_conn
.
delete
(
sudo_dn
)
# 'gidNumber': [str(user.id)],
\ No newline at end of file
# 'homeDirectory': [str('/home/%s' % username)]}
#
# group_dn = "cn=%s,ou=Group,%s" % (username, LDAP_BASE_DN)
# group_attr = {'objectClass': ['posixGroup', 'top'],
# 'cn': [str(username)],
# 'userPassword': ['{crypt}x'],
# 'gidNumber': [str(user.id)]}
#
# ldap_conn.add(user_dn, user_attr)
# ldap_conn.add(group_dn, group_attr)
# def ldap_del_user(username):
# """
# delete a user in ldap database
# 在ldap中删除某用户
# """
# user_dn = "uid=%s,ou=People,%s" % (username, LDAP_BASE_DN)
# group_dn = "cn=%s,ou=Group,%s" % (username, LDAP_BASE_DN)
# sudo_dn = 'cn=%s,ou=Sudoers,%s' % (username, LDAP_BASE_DN)
#
# ldap_conn.delete(user_dn)
# ldap_conn.delete(group_dn)
# ldap_conn.delete(sudo_dn)
\ No newline at end of file
juser/views.py
View file @
c21cdc21
This diff is collapsed.
Click to expand it.
static/css/style.css
View file @
c21cdc21
...
@@ -3516,8 +3516,8 @@ body.modal-open {
...
@@ -3516,8 +3516,8 @@ body.modal-open {
z-index
:
100
;
z-index
:
100
;
}
}
.lockscreen.middle-box
{
.lockscreen.middle-box
{
width
:
2
00px
;
width
:
4
00px
;
margin-left
:
-
1
00px
;
margin-left
:
-
2
00px
;
margin-top
:
-190px
;
margin-top
:
-190px
;
}
}
.loginscreen.middle-box
{
.loginscreen.middle-box
{
...
...
templates/juser/forget_password.html
0 → 100644
View file @
c21cdc21
<html><head>
<meta
charset=
"utf-8"
>
<meta
name=
"viewport"
content=
"width=device-width, initial-scale=1.0"
>
<title>
忘记密码
</title>
<link
href=
"/static/css/bootstrap.min.css"
rel=
"stylesheet"
>
<link
href=
"/static/font-awesome/css/font-awesome.css"
rel=
"stylesheet"
>
<link
href=
"/static/css/animate.css"
rel=
"stylesheet"
>
<link
href=
"/static/css/style.css"
rel=
"stylesheet"
>
<style
type=
"text/css"
></style></head>
<body
class=
"gray-bg"
>
<div
class=
"lock-word animated fadeInDown"
>
<span
class=
"first-word"
>
Jumperver
</span>
</div>
<div
class=
"middle-box text-center lockscreen animated fadeInDown"
>
<div>
<div
class=
"m-b-md"
>
{#
<img
alt=
"image"
class=
"img-circle circle-border"
src=
"https://s3.amazonaws.com/uifaces/faces/twitter/ok/128.jpg"
>
#}
{% 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>
<h3>
忘记密码
</h3>
<p>
请输入您原来的信息
</p>
<form
class=
"m-t"
role=
"form"
action=
""
method=
"post"
>
<div
class=
"form-group"
>
<input
type=
"text"
name=
'username'
class=
"form-control"
placeholder=
"Username"
required=
""
>
</div>
<div
class=
"form-group"
>
<input
type=
"text"
name=
'email'
class=
"form-control"
placeholder=
"Email"
required=
""
>
</div>
<button
type=
"submit"
class=
"btn btn-primary block full-width"
>
确定
</button>
</form>
</div>
</div>
<!-- Mainly scripts -->
<script
src=
"/static/js/jquery-2.1.1.js"
></script>
<script
src=
"/static/js/bootstrap.min.js"
></script>
</body></html>
\ No newline at end of file
templates/juser/reset_password.html
0 → 100644
View file @
c21cdc21
<html><head>
<meta
charset=
"utf-8"
>
<meta
name=
"viewport"
content=
"width=device-width, initial-scale=1.0"
>
<title>
重置{{ name }}
</title>
<link
href=
"/static/css/bootstrap.min.css"
rel=
"stylesheet"
>
<link
href=
"/static/font-awesome/css/font-awesome.css"
rel=
"stylesheet"
>
<link
href=
"/static/css/animate.css"
rel=
"stylesheet"
>
<link
href=
"/static/css/style.css"
rel=
"stylesheet"
>
<style
type=
"text/css"
></style></head>
<body
class=
"gray-bg"
>
<div
class=
"lock-word animated fadeInDown"
>
<span
class=
"first-word"
>
Jump
</span><span>
Server
</span>
</div>
<div
class=
"middle-box text-center lockscreen animated fadeInDown"
>
<div>
<div
class=
"m-b-md"
>
{#
<img
alt=
"image"
class=
"img-circle circle-border"
src=
"https://s3.amazonaws.com/uifaces/faces/twitter/ok/128.jpg"
>
#}
{% 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>
<h3>
请输入新密码
</h3>
<form
class=
"m-t"
role=
"form"
action=
"{{ action }}"
method=
"post"
>
<div
class=
"form-group"
>
<input
type=
"password"
name=
'password'
class=
"form-control"
placeholder=
"New Password"
required=
""
>
<input
type=
"password"
name=
'password_confirm'
class=
"form-control"
placeholder=
"Password Confirm"
required=
""
>
</div>
<button
type=
"submit"
class=
"btn btn-primary block full-width"
>
确定
</button>
</form>
</div>
</div>
<!-- Mainly scripts -->
<script
src=
"/static/js/jquery-2.1.1.js"
></script>
<script
src=
"/static/js/bootstrap.min.js"
></script>
</body></html>
\ No newline at end of file
templates/juser/user_add.html
View file @
c21cdc21
...
@@ -96,7 +96,7 @@
...
@@ -96,7 +96,7 @@
<div
class=
"form-group"
><label
class=
"col-sm-2 control-label"
>
额外
</label>
<div
class=
"form-group"
><label
class=
"col-sm-2 control-label"
>
额外
</label>
<div
class=
"col-sm-2"
>
<div
class=
"col-sm-2"
>
<div
class=
"checkbox i-checks"
>
<div
class=
"checkbox i-checks"
>
<label><input
type=
"checkbox"
value=
"0"
name=
"extra"
checked
>
禁用
</label>
<label><input
type=
"checkbox"
value=
"0"
name=
"extra"
>
禁用
</label>
</div>
</div>
</div>
</div>
<div
class=
"col-sm-2"
>
<div
class=
"col-sm-2"
>
...
@@ -106,7 +106,7 @@
...
@@ -106,7 +106,7 @@
</div>
</div>
<div
class=
"col-sm-2"
>
<div
class=
"col-sm-2"
>
<div
class=
"checkbox i-checks"
>
<div
class=
"checkbox i-checks"
>
<label><input
type=
"checkbox"
value=
"
1
"
name=
"extra"
>
发送邮件
</label>
<label><input
type=
"checkbox"
value=
"
2
"
name=
"extra"
>
发送邮件
</label>
</div>
</div>
</div>
</div>
</div>
</div>
...
...
templates/juser/user_edit.html
View file @
c21cdc21
...
@@ -17,12 +17,6 @@
...
@@ -17,12 +17,6 @@
<a
class=
"dropdown-toggle"
data-toggle=
"dropdown"
href=
"#"
>
<a
class=
"dropdown-toggle"
data-toggle=
"dropdown"
href=
"#"
>
<i
class=
"fa fa-wrench"
></i>
<i
class=
"fa fa-wrench"
></i>
</a>
</a>
<ul
class=
"dropdown-menu dropdown-user"
>
<li><a
href=
"#"
>
未启用 1
</a>
</li>
<li><a
href=
"#"
>
未启用 2
</a>
</li>
</ul>
<a
class=
"close-link"
>
<a
class=
"close-link"
>
<i
class=
"fa fa-times"
></i>
<i
class=
"fa fa-times"
></i>
</a>
</a>
...
@@ -71,23 +65,6 @@
...
@@ -71,23 +65,6 @@
</div>
</div>
</div>
</div>
<div
class=
"hr-line-dashed"
></div>
<div
class=
"hr-line-dashed"
></div>
{% ifequal session_role_id 2 %}
<div
class=
"form-group"
>
<label
for=
"dept_id"
class=
"col-lg-2 control-label"
>
部门
<span
class=
"red-fonts"
>
*
</span></label>
<div
class=
"col-sm-8"
>
<select
id=
"dept_id"
name=
"dept_id"
class=
"form-control m-b"
>
{% for dept in dept_all %}
{% ifequal user.dept.id dept.id %}
<option
selected
value=
"{{ dept.id }}"
>
{{ dept.name }}
</option>
{% else %}
<option
value=
"{{ dept.id }}"
>
{{ dept.name }}
</option>
{% endifequal %}
{% endfor %}
</select>
</div>
</div>
<div
class=
"hr-line-dashed"
></div>
{% endifequal %}
<div
class=
"form-group"
>
<div
class=
"form-group"
>
<label
for=
"groups"
class=
"col-lg-2 control-label"
>
小组
</label>
<label
for=
"groups"
class=
"col-lg-2 control-label"
>
小组
</label>
<div
class=
"col-sm-8"
>
<div
class=
"col-sm-8"
>
...
...
templates/juser/user_list.html
View file @
c21cdc21
...
@@ -37,7 +37,7 @@
...
@@ -37,7 +37,7 @@
<input
type=
"text"
class=
"form-control input-sm"
id=
"search_input"
name=
"keyword"
placeholder=
"Search"
>
<input
type=
"text"
class=
"form-control input-sm"
id=
"search_input"
name=
"keyword"
placeholder=
"Search"
>
<div
class=
"input-group-btn"
>
<div
class=
"input-group-btn"
>
<button
id=
'search_btn'
type=
"submit"
class=
"btn btn-sm btn-primary"
>
<button
id=
'search_btn'
type=
"submit"
class=
"btn btn-sm btn-primary"
>
Search
- 搜索 -
</button>
</button>
</div>
</div>
</div>
</div>
...
@@ -52,7 +52,6 @@
...
@@ -52,7 +52,6 @@
</th>
</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>
<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>
...
@@ -68,20 +67,15 @@
...
@@ -68,20 +67,15 @@
</td>
</td>
<td
class=
"text-center"
>
{{ user.username }}
</td>
<td
class=
"text-center"
>
{{ user.username }}
</td>
<td
class=
"text-center"
>
{{ user.name }}
</td>
<td
class=
"text-center"
>
{{ user.name }}
</td>
<td
class=
"text-center"
>
{{ user.dept.name }}
</td>
<td
class=
"text-center"
title=
"{% for user_group in user.group.all %} {{ user_group.name }} {% endfor %}"
>
{{ user.group.all | group_str2 }}
</td>
<td
class=
"text-center"
title=
"{% for user_group in user.group.all %} {{ user_group.name }} {% endfor %}"
>
{{ user.group.all | group_str2 }}
</td>
<td
class=
"text-center"
>
{{ user.id | get_role }}
</td>
<td
class=
"text-center"
>
{{ user.id | get_role }}
</td>
<td
class=
"text-center"
>
{{ user.is_active|bool2str }}
</td>
<td
class=
"text-center"
>
{{ user.is_active|bool2str }}
</td>
<td
class=
"text-center"
><a
href=
"/juser/down_key/?id={{ user.id }}"
>
下载
</a></td>
<td
class=
"text-center"
><a
href=
"/juser/down_key/?id={{ user.id }}"
>
下载
</a></td>
<td
class=
"text-center"
>
<td
class=
"text-center"
>
<a
href=
"../user_detail/?id={{ user.id }}"
class=
"btn btn-xs btn-primary"
>
详情
</a>
<a
href=
"../user_detail/?id={{ user.id }}"
class=
"btn btn-xs btn-primary"
>
详情
</a>
{% ifequal session_role_id 2 %}
<a
href=
"../user_edit/?id={{ user.id }}"
class=
"btn btn-xs btn-info"
>
编辑
</a>
<a
href=
"../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
href=
"../user_del/?id={{ user.id }}"
class=
"btn btn-xs btn-danger {% if user.username == 'admin' %} disabled {% endif %}"
>
删除
</a>
<a
href=
"../user_del/?id={{ user.id }}"
class=
"btn btn-xs btn-danger {% if user.username == 'admin' %} disabled {% endif %}"
>
删除
</a>
{% else %}
<a
href=
"../user_edit/?id={{ user.id }}"
class=
"btn btn-xs btn-info {% if user.role != 'CU' %} disabled {% endif %}"
>
编辑
</a>
<a
href=
"../user_del/?id={{ user.id }}"
class=
"btn btn-xs btn-danger {% if user.role != 'CU' %} disabled {% endif %}"
>
删除
</a>
{% endifequal %}
</td>
</td>
</tr>
</tr>
{% endfor %}
{% endfor %}
...
@@ -101,6 +95,8 @@
...
@@ -101,6 +95,8 @@
</div>
</div>
</div>
</div>
{% endblock %}
{% block self_head_css_js %}
<script>
<script>
$
(
document
).
ready
(
function
(){
$
(
document
).
ready
(
function
(){
$
(
".iframe"
).
on
(
'click'
,
function
()
{
$
(
".iframe"
).
on
(
'click'
,
function
()
{
...
@@ -117,23 +113,30 @@
...
@@ -117,23 +113,30 @@
iframe
:
{
src
:
url
}
iframe
:
{
src
:
url
}
})
})
});
});
var
check_array
=
[];
var
check_array
=
[];
$
(
'#del_btn'
).
click
(
function
(){
$
(
'#del_btn'
).
click
(
function
(){
if
(
confirm
(
"确定删除"
))
{
if
(
confirm
(
"确定删除"
))
{
$
(
".gradeX input:checked"
).
each
(
function
()
{
check_array
.
push
(
$
(
this
).
attr
(
"value"
))
});
$
(
".gradeX input:checked"
).
each
(
function
()
{
check_array
.
push
(
$
(
this
).
attr
(
"value"
))
});
$
(
".gradeX input:checked"
).
closest
(
"tr"
).
remove
();
$
.
post
(
"/juser/user_del_ajax/"
,
$
.
post
(
"/juser/user_del_ajax/"
,
{
ids
:
check_array
.
join
(
","
)},
{
ids
:
check_array
.
join
(
","
)},
function
(
data
){
function
(
data
){
$
(
".gradeX input:checked"
).
closest
(
"tr"
).
remove
();
window
.
open
(
"/juser/user_list/"
,
"_self"
);
window
.
open
(
"/juser/user_list/"
,
"_self"
);
}
}
)
)
}
}
});
$
(
'.email'
).
click
(
function
(){
$
.
get
(
'/juser/send_mail_retry/?uuid='
+
$
(
this
).
attr
(
'value'
),
{},
function
(
data
){
alert
(
data
)
}
)
})
})
});
});
</script>
</script>
{% endblock %}
{% endblock %}
\ No newline at end of file
templates/login.html
View file @
c21cdc21
...
@@ -31,7 +31,7 @@
...
@@ -31,7 +31,7 @@
</div>
</div>
<button
type=
"submit"
class=
"btn btn-primary block full-width m-b"
>
Login
</button>
<button
type=
"submit"
class=
"btn btn-primary block full-width m-b"
>
Login
</button>
<a
href=
"
#"
><small>
Forgot password? Contact Administrator.
</small></a>
<a
href=
"
/juser/forget_password/"
><small>
Forgot password?
</small></a>
</form>
</form>
<p
class=
"m-t"
>
<small><b>
Copyright
</b>
Jumpserver.org Organization © 2014-2015
</small>
</p>
<p
class=
"m-t"
>
<small><b>
Copyright
</b>
Jumpserver.org Organization © 2014-2015
</small>
</p>
</div>
</div>
...
...
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