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
b82a66c8
Commit
b82a66c8
authored
6 years ago
by
BaiJiangJie
Committed by
老广
6 years ago
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[Update] 优化LDAP用户导入功能 (#2550)
parent
f6cd193f
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
83 additions
and
60 deletions
+83
-60
django.mo
apps/locale/zh/LC_MESSAGES/django.mo
+0
-0
django.po
apps/locale/zh/LC_MESSAGES/django.po
+0
-0
api.py
apps/settings/api.py
+46
-43
models.py
apps/settings/models.py
+2
-0
_ldap_list_users_modal.html
apps/settings/templates/settings/_ldap_list_users_modal.html
+20
-9
ldap_setting.html
apps/settings/templates/settings/ldap_setting.html
+12
-6
api_urls.py
apps/settings/urls/api_urls.py
+2
-2
utils.py
apps/settings/utils.py
+0
-0
_modal.html
apps/templates/_modal.html
+1
-0
No files found.
apps/locale/zh/LC_MESSAGES/django.mo
View file @
b82a66c8
No preview for this file type
This diff is collapsed.
Click to expand it.
apps/locale/zh/LC_MESSAGES/django.po
View file @
b82a66c8
This diff is collapsed.
Click to expand it.
apps/settings/api.py
View file @
b82a66c8
...
@@ -5,18 +5,21 @@ import os
...
@@ -5,18 +5,21 @@ import os
import
json
import
json
import
jms_storage
import
jms_storage
from
ldap3
import
Server
,
Connection
from
rest_framework.views
import
Response
,
APIView
from
rest_framework.views
import
Response
,
APIView
from
django.conf
import
settings
from
django.conf
import
settings
from
django.core.mail
import
send_mail
from
django.core.mail
import
send_mail
from
django.utils.translation
import
ugettext_lazy
as
_
from
django.utils.translation
import
ugettext_lazy
as
_
from
.models
import
Setting
from
.models
import
Setting
from
.utils
import
get_ldap_users_list
,
save_user
from
.utils
import
LDAPUtil
from
common.permissions
import
IsOrgAdmin
,
IsSuperUser
from
common.permissions
import
IsOrgAdmin
,
IsSuperUser
from
common.utils
import
get_logger
from
.serializers
import
MailTestSerializer
,
LDAPTestSerializer
from
.serializers
import
MailTestSerializer
,
LDAPTestSerializer
logger
=
get_logger
(
__file__
)
class
MailTestingAPI
(
APIView
):
class
MailTestingAPI
(
APIView
):
permission_classes
=
(
IsOrgAdmin
,)
permission_classes
=
(
IsOrgAdmin
,)
serializer_class
=
MailTestSerializer
serializer_class
=
MailTestSerializer
...
@@ -46,9 +49,8 @@ class LDAPTestingAPI(APIView):
...
@@ -46,9 +49,8 @@ class LDAPTestingAPI(APIView):
serializer_class
=
LDAPTestSerializer
serializer_class
=
LDAPTestSerializer
success_message
=
_
(
"Test ldap success"
)
success_message
=
_
(
"Test ldap success"
)
def
post
(
self
,
request
):
@staticmethod
serializer
=
self
.
serializer_class
(
data
=
request
.
data
)
def
get_ldap_util
(
serializer
):
if
serializer
.
is_valid
():
host
=
serializer
.
validated_data
[
"AUTH_LDAP_SERVER_URI"
]
host
=
serializer
.
validated_data
[
"AUTH_LDAP_SERVER_URI"
]
bind_dn
=
serializer
.
validated_data
[
"AUTH_LDAP_BIND_DN"
]
bind_dn
=
serializer
.
validated_data
[
"AUTH_LDAP_BIND_DN"
]
password
=
serializer
.
validated_data
[
"AUTH_LDAP_BIND_PASSWORD"
]
password
=
serializer
.
validated_data
[
"AUTH_LDAP_BIND_PASSWORD"
]
...
@@ -56,68 +58,69 @@ class LDAPTestingAPI(APIView):
...
@@ -56,68 +58,69 @@ class LDAPTestingAPI(APIView):
search_ougroup
=
serializer
.
validated_data
[
"AUTH_LDAP_SEARCH_OU"
]
search_ougroup
=
serializer
.
validated_data
[
"AUTH_LDAP_SEARCH_OU"
]
search_filter
=
serializer
.
validated_data
[
"AUTH_LDAP_SEARCH_FILTER"
]
search_filter
=
serializer
.
validated_data
[
"AUTH_LDAP_SEARCH_FILTER"
]
attr_map
=
serializer
.
validated_data
[
"AUTH_LDAP_USER_ATTR_MAP"
]
attr_map
=
serializer
.
validated_data
[
"AUTH_LDAP_USER_ATTR_MAP"
]
try
:
try
:
attr_map
=
json
.
loads
(
attr_map
)
attr_map
=
json
.
loads
(
attr_map
)
except
json
.
JSONDecodeError
:
except
json
.
JSONDecodeError
:
return
Response
({
"error"
:
"AUTH_LDAP_USER_ATTR_MAP not valid"
},
status
=
401
)
return
Response
({
"error"
:
"AUTH_LDAP_USER_ATTR_MAP not valid"
},
status
=
401
)
server
=
Server
(
host
,
use_ssl
=
use_ssl
)
util
=
LDAPUtil
(
conn
=
Connection
(
server
,
bind_dn
,
password
)
use_settings_config
=
False
,
server_uri
=
host
,
bind_dn
=
bind_dn
,
password
=
password
,
use_ssl
=
use_ssl
,
search_ougroup
=
search_ougroup
,
search_filter
=
search_filter
,
attr_map
=
attr_map
)
return
util
def
post
(
self
,
request
):
serializer
=
self
.
serializer_class
(
data
=
request
.
data
)
if
not
serializer
.
is_valid
():
return
Response
({
"error"
:
str
(
serializer
.
errors
)},
status
=
401
)
util
=
self
.
get_ldap_util
(
serializer
)
try
:
try
:
conn
.
bind
()
users
=
util
.
get_search_user_items
()
except
Exception
as
e
:
except
Exception
as
e
:
return
Response
({
"error"
:
str
(
e
)},
status
=
401
)
return
Response
({
"error"
:
str
(
e
)},
status
=
401
)
users
=
[]
for
search_ou
in
str
(
search_ougroup
)
.
split
(
"|"
):
ok
=
conn
.
search
(
search_ou
,
search_filter
%
({
"user"
:
"*"
}),
attributes
=
list
(
attr_map
.
values
()))
if
not
ok
:
return
Response
({
"error"
:
_
(
"Search no entry matched in ou {}"
)
.
format
(
search_ou
)},
status
=
401
)
for
entry
in
conn
.
entries
:
user
=
{}
for
attr
,
mapping
in
attr_map
.
items
():
if
hasattr
(
entry
,
mapping
):
user
[
attr
]
=
getattr
(
entry
,
mapping
)
users
.
append
(
user
)
if
len
(
users
)
>
0
:
if
len
(
users
)
>
0
:
return
Response
({
"msg"
:
_
(
"Match {} s users"
)
.
format
(
len
(
users
))})
return
Response
({
"msg"
:
_
(
"Match {} s users"
)
.
format
(
len
(
users
))})
else
:
else
:
return
Response
({
"error"
:
"Have user but attr mapping error"
},
status
=
401
)
return
Response
({
"error"
:
"Have user but attr mapping error"
},
status
=
401
)
else
:
return
Response
({
"error"
:
str
(
serializer
.
errors
)},
status
=
401
)
class
LDAP
SyncAPI
(
APIView
):
class
LDAP
UserListApi
(
APIView
):
permission_classes
=
(
IsOrgAdmin
,)
permission_classes
=
(
IsOrgAdmin
,)
def
get
(
self
,
request
):
def
get
(
self
,
request
):
ldap_users_list
=
get_ldap_users_list
()
util
=
LDAPUtil
()
if
not
isinstance
(
ldap_users_list
,
list
):
try
:
return
Response
(
ldap_users_list
,
status
=
401
)
users
=
util
.
get_search_user_items
()
return
Response
(
ldap_users_list
)
except
Exception
as
e
:
users
=
[]
logger
.
error
(
e
,
exc_info
=
True
)
else
:
users
=
sorted
(
users
,
key
=
lambda
u
:
(
u
[
'existing'
],
u
[
'username'
]))
return
Response
(
users
)
class
LDAP
Confirm
SyncAPI
(
APIView
):
class
LDAP
User
SyncAPI
(
APIView
):
permission_classes
=
(
IsOrgAdmin
,)
permission_classes
=
(
IsOrgAdmin
,)
def
post
(
self
,
request
):
def
post
(
self
,
request
):
user_names
=
request
.
data
.
get
(
'user_names'
,
''
)
user_names
=
request
.
data
.
get
(
'user_names'
,
''
)
if
not
user_names
:
error
=
_
(
'User is not currently selected, please check the user '
util
=
LDAPUtil
()
'you want to import'
)
try
:
return
Response
({
'error'
:
error
},
status
=
401
)
result
=
util
.
sync_users
(
username_set
=
user_names
)
except
Exception
as
e
:
ldap_users_list
=
get_ldap_users_list
(
user_names
=
user_names
)
logger
.
error
(
e
,
exc_info
=
True
)
if
not
isinstance
(
ldap_users_list
,
list
):
return
Response
({
'error'
:
str
(
e
)},
status
=
401
)
return
Response
(
ldap_users_list
,
status
=
401
)
else
:
msg
=
_
(
"succeed: {} failed: {} total: {}"
)
.
format
(
save_result
=
save_user
(
ldap_users_list
)
result
[
'succeed'
],
result
[
'failed'
],
result
[
'total'
]
if
'error'
in
save_result
.
keys
():
)
return
Response
(
save_result
,
status
=
401
)
return
Response
({
'msg'
:
msg
})
return
Response
(
save_result
)
class
ReplayStorageCreateAPI
(
APIView
):
class
ReplayStorageCreateAPI
(
APIView
):
...
...
This diff is collapsed.
Click to expand it.
apps/settings/models.py
View file @
b82a66c8
...
@@ -79,6 +79,8 @@ class Setting(models.Model):
...
@@ -79,6 +79,8 @@ class Setting(models.Model):
obj
.
cleaned_value
=
data
obj
.
cleaned_value
=
data
else
:
else
:
value
=
obj
.
cleaned_value
value
=
obj
.
cleaned_value
if
value
is
None
:
value
=
{}
value
.
update
(
data
)
value
.
update
(
data
)
obj
.
cleaned_value
=
value
obj
.
cleaned_value
=
value
obj
.
save
()
obj
.
save
()
...
...
This diff is collapsed.
Click to expand it.
apps/settings/templates/settings/_ldap_list_users_modal.html
View file @
b82a66c8
...
@@ -4,7 +4,10 @@
...
@@ -4,7 +4,10 @@
{% block modal_class %}modal-lg{% endblock %}
{% block modal_class %}modal-lg{% endblock %}
{% block modal_id %}ldap_list_users_modal{% endblock %}
{% block modal_id %}ldap_list_users_modal{% endblock %}
{% block modal_title%}{% trans "Ldap users" %}{% endblock %}
{% block modal_title%}{% trans "LDAP user list" %}{% endblock %}
{% block modal_help_message%}
<div
class=
"alert alert-info help-message"
style=
"width: 838px; margin-left: 30px"
>
{% trans 'Please submit the LDAP configuration before import' %}
</div>
{% endblock %}
{% block modal_body %}
{% block modal_body %}
<link
href=
"{% static 'css/plugins/ztree/awesomeStyle/awesome.css' %}"
rel=
"stylesheet"
>
<link
href=
"{% static 'css/plugins/ztree/awesomeStyle/awesome.css' %}"
rel=
"stylesheet"
>
<script
type=
"text/javascript"
src=
"{% static 'js/plugins/ztree/jquery.ztree.all.min.js' %}"
></script>
<script
type=
"text/javascript"
src=
"{% static 'js/plugins/ztree/jquery.ztree.all.min.js' %}"
></script>
...
@@ -34,7 +37,7 @@
...
@@ -34,7 +37,7 @@
<th
class=
"text-center"
>
{% trans 'Username' %}
</th>
<th
class=
"text-center"
>
{% trans 'Username' %}
</th>
<th
class=
"text-center"
>
{% trans 'Name' %}
</th>
<th
class=
"text-center"
>
{% trans 'Name' %}
</th>
<th
class=
"text-center"
>
{% trans 'Email' %}
</th>
<th
class=
"text-center"
>
{% trans 'Email' %}
</th>
<th
class=
"text-center"
>
{% trans '
Is imported
' %}
</th>
<th
class=
"text-center"
>
{% trans '
Existing
' %}
</th>
</tr>
</tr>
</thead>
</thead>
<tbody>
<tbody>
...
@@ -47,16 +50,25 @@
...
@@ -47,16 +50,25 @@
<script>
<script>
var
ldap_users_table
=
0
;
var
ldap_users_table
=
0
;
function
initLdapTable
()
{
function
initLdap
Users
Table
()
{
if
(
ldap_users_table
){
if
(
ldap_users_table
){
return
return
}
}
var
options
=
{
var
options
=
{
ele
:
$
(
'#ldap_list_users_table'
),
ele
:
$
(
'#ldap_list_users_table'
),
ajax_url
:
'{% url "api-settings:ldap-sync" %}'
,
ajax_url
:
'{% url "api-settings:ldap-user-list" %}'
,
columnDefs
:
[
{
targets
:
4
,
createdCell
:
function
(
td
,
cellData
,
rowData
)
{
if
(
cellData
){
$
(
td
).
html
(
'<i class="fa fa-check text-navy"></i>'
)
}
else
{
$
(
td
).
html
(
'<i class="fa fa-times text-danger"></i>'
)
}
}}
],
columns
:
[
columns
:
[
{
data
:
"username"
},{
data
:
"username"
},
{
data
:
"name"
},
{
data
:
"username"
},{
data
:
"username"
},
{
data
:
"name"
},
{
data
:
"email"
},
{
data
:
'
is_imported
'
}
{
data
:
"email"
},
{
data
:
'
existing
'
}
],
],
pageLength
:
10
pageLength
:
10
};
};
...
@@ -68,8 +80,7 @@ function initLdapTable() {
...
@@ -68,8 +80,7 @@ function initLdapTable() {
$
(
document
).
ready
(
function
(){
$
(
document
).
ready
(
function
(){
}).
on
(
'show.bs.modal'
,
function
()
{
}).
on
(
'show.bs.modal'
,
function
()
{
initLdapTable
();
initLdapUsersTable
();
})
})
.
on
(
'click'
,
'.close_btn1'
,
function
()
{
.
on
(
'click'
,
'.close_btn1'
,
function
()
{
window
.
location
.
reload
()
window
.
location
.
reload
()
...
@@ -82,9 +93,9 @@ $(document).ready(function(){
...
@@ -82,9 +93,9 @@ $(document).ready(function(){
{% endblock %}
{% endblock %}
{% block modal_button %}
{% block modal_button %}
{{ block.super }}
<button
data-dismiss=
"modal"
class=
"btn btn-white close_btn2"
type=
"button"
>
{% trans "Close" %}
</button>
<button
class=
"btn btn-primary"
type=
"button"
id=
"{% block modal_confirm_id %}btn_ldap_modal_confirm{% endblock %}"
>
{% trans 'Import' %}
</button>
{% endblock %}
{% endblock %}
{% block modal_confirm_id %}btn_ldap_modal_confirm{% endblock %}
This diff is collapsed.
Click to expand it.
apps/settings/templates/settings/ldap_setting.html
View file @
b82a66c8
...
@@ -58,11 +58,11 @@
...
@@ -58,11 +58,11 @@
<div
class=
"hr-line-dashed"
></div>
<div
class=
"hr-line-dashed"
></div>
<div
class=
"form-group"
>
<div
class=
"form-group"
>
<div
class=
"col-sm-4 col-sm-offset-2"
>
<div
class=
"col-sm-4 col-sm-offset-2"
>
<button
class=
"btn btn-default btn-test"
type=
"button"
>
{% trans 'Test connection' %}
</button>
<button
class=
"btn btn-default"
type=
"reset"
>
{% trans 'Reset' %}
</button>
<button
class=
"btn btn-default"
type=
"reset"
>
{% trans 'Reset' %}
</button>
<button
id=
"submit_button"
class=
"btn btn-primary"
type=
"submit"
>
{% trans 'Submit
' %}
</button>
<button
class=
"btn btn-default btn-test"
type=
"button"
>
{% trans 'Test connection
' %}
</button>
{#
<button
class=
"btn btn-primary sync_button "
data-toggle=
"modal"
data-target=
"#sync_users_modal"
type=
"button"
>
{% trans 'Synchronization' %}
</button>
#}
{#
<button
class=
"btn btn-primary sync_button "
data-toggle=
"modal"
data-target=
"#sync_users_modal"
type=
"button"
>
{% trans 'Synchronization' %}
</button>
#}
<button
class=
"btn btn-primary sync_button "
data-toggle=
"modal"
data-target=
"#ldap_list_users_modal"
type=
"button"
>
{% trans 'Sync User' %}
</button>
<button
id=
"submit_button"
class=
"btn btn-primary"
type=
"submit"
>
{% trans 'Submit' %}
</button>
<button
class=
"btn btn-default sync_button "
data-toggle=
"modal"
data-target=
"#ldap_list_users_modal"
type=
"button"
>
{% trans 'Bulk import' %}
</button>
</div>
</div>
</div>
</div>
</form>
</form>
...
@@ -108,11 +108,17 @@ $(document).ready(function () {
...
@@ -108,11 +108,17 @@ $(document).ready(function () {
})
})
.
on
(
"click"
,
"#btn_ldap_modal_confirm"
,
function
()
{
.
on
(
"click"
,
"#btn_ldap_modal_confirm"
,
function
()
{
var
user_names
=
[];
var
user_names
=
[];
var
cheked
=
$
(
"tbody input[type='checkbox']:checked"
).
each
(
function
()
{
$
(
"tbody input[type='checkbox']:checked"
).
each
(
function
()
{
user_names
.
push
(
$
(
this
).
attr
(
'id'
));
user_names
.
push
(
$
(
this
).
attr
(
'id'
));
});
});
var
the_url
=
"{% url "
api
-
settings
:
ldap
-
comfirm
-
sync
" %}"
;
if
(
user_names
.
length
===
0
){
var
msg
=
"{% trans 'User is not currently selected, please check the user you want to import'%}"
toastr
.
error
(
msg
);
return
}
var
the_url
=
"{% url "
api
-
settings
:
ldap
-
user
-
sync
" %}"
;
function
error
(
message
)
{
function
error
(
message
)
{
toastr
.
error
(
message
)
toastr
.
error
(
message
)
...
...
This diff is collapsed.
Click to expand it.
apps/settings/urls/api_urls.py
View file @
b82a66c8
...
@@ -9,8 +9,8 @@ app_name = 'common'
...
@@ -9,8 +9,8 @@ app_name = 'common'
urlpatterns
=
[
urlpatterns
=
[
path
(
'mail/testing/'
,
api
.
MailTestingAPI
.
as_view
(),
name
=
'mail-testing'
),
path
(
'mail/testing/'
,
api
.
MailTestingAPI
.
as_view
(),
name
=
'mail-testing'
),
path
(
'ldap/testing/'
,
api
.
LDAPTestingAPI
.
as_view
(),
name
=
'ldap-testing'
),
path
(
'ldap/testing/'
,
api
.
LDAPTestingAPI
.
as_view
(),
name
=
'ldap-testing'
),
path
(
'ldap/
sync/'
,
api
.
LDAPSyncAPI
.
as_view
(),
name
=
'ldap-sync
'
),
path
(
'ldap/
users/'
,
api
.
LDAPUserListApi
.
as_view
(),
name
=
'ldap-user-list
'
),
path
(
'ldap/
comfirm/sync/'
,
api
.
LDAPConfirmSyncAPI
.
as_view
(),
name
=
'ldap-comfirm
-sync'
),
path
(
'ldap/
users/sync/'
,
api
.
LDAPUserSyncAPI
.
as_view
(),
name
=
'ldap-user
-sync'
),
path
(
'terminal/replay-storage/create/'
,
api
.
ReplayStorageCreateAPI
.
as_view
(),
name
=
'replay-storage-create'
),
path
(
'terminal/replay-storage/create/'
,
api
.
ReplayStorageCreateAPI
.
as_view
(),
name
=
'replay-storage-create'
),
path
(
'terminal/replay-storage/delete/'
,
api
.
ReplayStorageDeleteAPI
.
as_view
(),
name
=
'replay-storage-delete'
),
path
(
'terminal/replay-storage/delete/'
,
api
.
ReplayStorageDeleteAPI
.
as_view
(),
name
=
'replay-storage-delete'
),
path
(
'terminal/command-storage/create/'
,
api
.
CommandStorageCreateAPI
.
as_view
(),
name
=
'command-storage-create'
),
path
(
'terminal/command-storage/create/'
,
api
.
CommandStorageCreateAPI
.
as_view
(),
name
=
'command-storage-create'
),
...
...
This diff is collapsed.
Click to expand it.
apps/settings/utils.py
View file @
b82a66c8
This diff is collapsed.
Click to expand it.
apps/templates/_modal.html
View file @
b82a66c8
...
@@ -12,6 +12,7 @@
...
@@ -12,6 +12,7 @@
<h4
class=
"modal-title"
>
{% block modal_title %}{% endblock %}
</h4>
<h4
class=
"modal-title"
>
{% block modal_title %}{% endblock %}
</h4>
<small>
{% block modal_comment %}{% endblock %}
</small>
<small>
{% block modal_comment %}{% endblock %}
</small>
</div>
</div>
{% block modal_help_message %}{% endblock %}
<div
class=
"modal-body"
>
<div
class=
"modal-body"
>
{% block modal_body %}
{% block modal_body %}
{% endblock %}
{% endblock %}
...
...
This diff is collapsed.
Click to expand it.
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