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
abb1a40a
Commit
abb1a40a
authored
Jan 12, 2018
by
ibuler
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[Feature] 添加basic settings
parent
121f56f4
Show whitespace changes
Inline
Side-by-side
Showing
29 changed files
with
584 additions
and
68 deletions
+584
-68
admin_user.py
apps/assets/views/admin_user.py
+1
-1
asset.py
apps/assets/views/asset.py
+1
-1
api.py
apps/common/api.py
+70
-2
fields.py
apps/common/fields.py
+37
-0
forms.py
apps/common/forms.py
+59
-2
models.py
apps/common/models.py
+21
-0
serializers.py
apps/common/serializers.py
+11
-0
signals.py
apps/common/signals.py
+1
-0
signals_handler.py
apps/common/signals_handler.py
+18
-3
basic_setting.html
apps/common/templates/common/basic_setting.html
+101
-0
email_setting.html
apps/common/templates/common/email_setting.html
+34
-6
ldap_setting.html
apps/common/templates/common/ldap_setting.html
+100
-0
api_urls.py
apps/common/urls/api_urls.py
+2
-0
view_urls.py
apps/common/urls/view_urls.py
+2
-0
utils.py
apps/common/utils.py
+1
-1
views.py
apps/common/views.py
+64
-12
settings.py
apps/jumpserver/settings.py
+26
-13
views.py
apps/ops/views.py
+1
-1
views.py
apps/perms/views.py
+2
-2
jumpserver.js
apps/static/js/jumpserver.js
+9
-0
_nav.html
apps/templates/_nav.html
+6
-6
command.py
apps/terminal/views/command.py
+1
-1
session.py
apps/terminal/views/session.py
+1
-1
authentication.py
apps/users/authentication.py
+1
-1
user.py
apps/users/models/user.py
+2
-5
signals.py
apps/users/signals.py
+8
-5
utils.py
apps/users/utils.py
+2
-2
login.py
apps/users/views/login.py
+2
-2
user.py
apps/users/views/user.py
+0
-1
No files found.
apps/assets/views/admin_user.py
View file @
abb1a40a
...
@@ -85,7 +85,7 @@ class AdminUserDetailView(AdminUserRequiredMixin, DetailView):
...
@@ -85,7 +85,7 @@ class AdminUserDetailView(AdminUserRequiredMixin, DetailView):
class
AdminUserAssetsView
(
AdminUserRequiredMixin
,
SingleObjectMixin
,
ListView
):
class
AdminUserAssetsView
(
AdminUserRequiredMixin
,
SingleObjectMixin
,
ListView
):
paginate_by
=
settings
.
CONFIG
.
DISPLAY_PER_PAGE
paginate_by
=
settings
.
DISPLAY_PER_PAGE
template_name
=
'assets/admin_user_assets.html'
template_name
=
'assets/admin_user_assets.html'
context_object_name
=
'admin_user'
context_object_name
=
'admin_user'
object
=
None
object
=
None
...
...
apps/assets/views/asset.py
View file @
abb1a40a
...
@@ -92,7 +92,7 @@ class AssetCreateView(AdminUserRequiredMixin, SuccessMessageMixin, CreateView):
...
@@ -92,7 +92,7 @@ class AssetCreateView(AdminUserRequiredMixin, SuccessMessageMixin, CreateView):
class
AssetModalListView
(
AdminUserRequiredMixin
,
ListView
):
class
AssetModalListView
(
AdminUserRequiredMixin
,
ListView
):
paginate_by
=
settings
.
CONFIG
.
DISPLAY_PER_PAGE
paginate_by
=
settings
.
DISPLAY_PER_PAGE
model
=
Asset
model
=
Asset
context_object_name
=
'asset_modal_list'
context_object_name
=
'asset_modal_list'
template_name
=
'assets/asset_modal_list.html'
template_name
=
'assets/asset_modal_list.html'
...
...
apps/common/api.py
View file @
abb1a40a
# -*- coding: utf-8 -*-
# -*- coding: utf-8 -*-
#
#
import
json
from
rest_framework.views
import
APIView
from
rest_framework.views
import
APIView
from
rest_framework.views
import
Response
from
rest_framework.views
import
Response
from
ldap3
import
Server
,
Connection
from
django.core.mail
import
get_connection
,
send_mail
from
django.core.mail
import
get_connection
,
send_mail
from
django.utils.translation
import
ugettext_lazy
as
_
from
django.utils.translation
import
ugettext_lazy
as
_
from
django.conf
import
settings
from
.permissions
import
IsSuperUser
from
.permissions
import
IsSuperUser
from
.serializers
import
MailTestSerializer
from
.serializers
import
MailTestSerializer
,
LDAPTestSerializer
class
MailTestingAPI
(
APIView
):
class
MailTestingAPI
(
APIView
):
...
@@ -27,7 +31,6 @@ class MailTestingAPI(APIView):
...
@@ -27,7 +31,6 @@ class MailTestingAPI(APIView):
"use_tls"
:
serializer
.
validated_data
[
"EMAIL_USE_TLS"
]
"use_tls"
:
serializer
.
validated_data
[
"EMAIL_USE_TLS"
]
}
}
connection
=
get_connection
(
timeout
=
5
,
**
kwargs
)
connection
=
get_connection
(
timeout
=
5
,
**
kwargs
)
try
:
try
:
connection
.
open
()
connection
.
open
()
except
Exception
as
e
:
except
Exception
as
e
:
...
@@ -40,3 +43,68 @@ class MailTestingAPI(APIView):
...
@@ -40,3 +43,68 @@ class MailTestingAPI(APIView):
return
Response
({
"error"
:
str
(
e
)},
status
=
401
)
return
Response
({
"error"
:
str
(
e
)},
status
=
401
)
return
Response
({
"msg"
:
self
.
success_message
.
format
(
email_host_user
)})
return
Response
({
"msg"
:
self
.
success_message
.
format
(
email_host_user
)})
else
:
return
Response
({
"error"
:
str
(
serializer
.
errors
)},
status
=
401
)
class
LDAPTestingAPI
(
APIView
):
permission_classes
=
(
IsSuperUser
,)
serializer_class
=
LDAPTestSerializer
success_message
=
_
(
"Test ldap success"
)
def
post
(
self
,
request
):
serializer
=
self
.
serializer_class
(
data
=
request
.
data
)
if
serializer
.
is_valid
():
host
=
serializer
.
validated_data
[
"AUTH_LDAP_SERVER_URI"
]
bind_dn
=
serializer
.
validated_data
[
"AUTH_LDAP_BIND_DN"
]
password
=
serializer
.
validated_data
[
"AUTH_LDAP_BIND_PASSWORD"
]
use_ssl
=
serializer
.
validated_data
.
get
(
"AUTH_LDAP_START_TLS"
,
False
)
search_ou
=
serializer
.
validated_data
[
"AUTH_LDAP_SEARCH_OU"
]
search_filter
=
serializer
.
validated_data
[
"AUTH_LDAP_SEARCH_FILTER"
]
attr_map
=
serializer
.
validated_data
[
"AUTH_LDAP_USER_ATTR_MAP"
]
print
(
serializer
.
validated_data
)
try
:
attr_map
=
json
.
loads
(
attr_map
)
except
json
.
JSONDecodeError
:
return
Response
({
"error"
:
"AUTH_LDAP_USER_ATTR_MAP not valid"
},
status
=
401
)
server
=
Server
(
host
,
use_ssl
=
use_ssl
)
conn
=
Connection
(
server
,
bind_dn
,
password
)
try
:
conn
.
bind
()
except
Exception
as
e
:
return
Response
({
"error"
:
str
(
e
)},
status
=
401
)
print
(
search_ou
)
print
(
search_filter
%
({
"user"
:
"*"
}))
print
(
attr_map
.
values
())
ok
=
conn
.
search
(
search_ou
,
search_filter
%
({
"user"
:
"*"
}),
attributes
=
list
(
attr_map
.
values
()))
if
not
ok
:
return
Response
({
"error"
:
"Search no entry matched"
},
status
=
401
)
users
=
[]
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
:
return
Response
({
"msg"
:
"Match {} s users"
.
format
(
len
(
users
))})
else
:
return
Response
({
"error"
:
"Have user but attr mapping error"
},
status
=
401
)
else
:
return
Response
({
"error"
:
str
(
serializer
.
errors
)},
status
=
401
)
class
DjangoSettingsAPI
(
APIView
):
def
get
(
self
,
request
):
configs
=
{}
for
i
in
dir
(
settings
):
if
i
.
isupper
():
configs
[
i
]
=
str
(
getattr
(
settings
,
i
))
return
Response
(
configs
)
apps/common/fields.py
0 → 100644
View file @
abb1a40a
# -*- coding: utf-8 -*-
#
import
json
from
django
import
forms
from
django.utils
import
six
from
django.core.exceptions
import
ValidationError
class
DictField
(
forms
.
Field
):
widget
=
forms
.
Textarea
def
to_python
(
self
,
value
):
"""Returns a Python boolean object."""
# Explicitly check for the string 'False', which is what a hidden field
# will submit for False. Also check for '0', since this is what
# RadioSelect will provide. Because bool("True") == bool('1') == True,
# we don't need to handle that explicitly.
if
isinstance
(
value
,
six
.
string_types
):
try
:
print
(
value
)
value
=
json
.
loads
(
value
)
return
value
except
json
.
JSONDecodeError
:
pass
value
=
{}
return
value
def
validate
(
self
,
value
):
print
(
value
)
if
not
value
and
self
.
required
:
raise
ValidationError
(
self
.
error_messages
[
'required'
],
code
=
'required'
)
def
has_changed
(
self
,
initial
,
data
):
# Sometimes data or initial may be a string equivalent of a boolean
# so we should run it through to_python first to get a boolean value
return
self
.
to_python
(
initial
)
!=
self
.
to_python
(
data
)
apps/common/forms.py
View file @
abb1a40a
...
@@ -7,6 +7,7 @@ from django.utils.translation import ugettext_lazy as _
...
@@ -7,6 +7,7 @@ from django.utils.translation import ugettext_lazy as _
from
django.db
import
transaction
from
django.db
import
transaction
from
.models
import
Setting
from
.models
import
Setting
from
.fields
import
DictField
def
to_model_value
(
value
):
def
to_model_value
(
value
):
...
@@ -18,7 +19,10 @@ def to_model_value(value):
...
@@ -18,7 +19,10 @@ def to_model_value(value):
def
to_form_value
(
value
):
def
to_form_value
(
value
):
try
:
try
:
return
json
.
loads
(
value
)
data
=
json
.
loads
(
value
)
if
isinstance
(
data
,
dict
):
data
=
value
return
data
except
json
.
JSONDecodeError
:
except
json
.
JSONDecodeError
:
return
''
return
''
...
@@ -26,7 +30,6 @@ def to_form_value(value):
...
@@ -26,7 +30,6 @@ def to_form_value(value):
class
BaseForm
(
forms
.
Form
):
class
BaseForm
(
forms
.
Form
):
def
__init__
(
self
,
*
args
,
**
kwargs
):
def
__init__
(
self
,
*
args
,
**
kwargs
):
super
()
.
__init__
(
*
args
,
**
kwargs
)
super
()
.
__init__
(
*
args
,
**
kwargs
)
if
not
self
.
is_bound
:
settings
=
Setting
.
objects
.
all
()
settings
=
Setting
.
objects
.
all
()
for
name
,
field
in
self
.
fields
.
items
():
for
name
,
field
in
self
.
fields
.
items
():
db_value
=
getattr
(
settings
,
name
)
.
value
db_value
=
getattr
(
settings
,
name
)
.
value
...
@@ -37,12 +40,16 @@ class BaseForm(forms.Form):
...
@@ -37,12 +40,16 @@ class BaseForm(forms.Form):
if
not
self
.
is_bound
:
if
not
self
.
is_bound
:
raise
ValueError
(
"Form is not bound"
)
raise
ValueError
(
"Form is not bound"
)
settings
=
Setting
.
objects
.
all
()
if
self
.
is_valid
():
if
self
.
is_valid
():
with
transaction
.
atomic
():
with
transaction
.
atomic
():
for
name
,
value
in
self
.
cleaned_data
.
items
():
for
name
,
value
in
self
.
cleaned_data
.
items
():
field
=
self
.
fields
[
name
]
field
=
self
.
fields
[
name
]
if
isinstance
(
field
.
widget
,
forms
.
PasswordInput
)
and
not
value
:
if
isinstance
(
field
.
widget
,
forms
.
PasswordInput
)
and
not
value
:
continue
continue
if
value
==
to_form_value
(
getattr
(
settings
,
name
)
.
value
):
continue
defaults
=
{
defaults
=
{
'name'
:
name
,
'name'
:
name
,
'value'
:
to_model_value
(
value
)
'value'
:
to_model_value
(
value
)
...
@@ -52,6 +59,24 @@ class BaseForm(forms.Form):
...
@@ -52,6 +59,24 @@ class BaseForm(forms.Form):
raise
ValueError
(
self
.
errors
)
raise
ValueError
(
self
.
errors
)
class
BasicSettingForm
(
BaseForm
):
SITE_URL
=
forms
.
URLField
(
label
=
_
(
"Current SITE URL"
),
help_text
=
"http://jumpserver.abc.com:8080"
)
USER_GUIDE_URL
=
forms
.
URLField
(
label
=
_
(
"User Guide URL"
),
help_text
=
_
(
"User first login update profile done redirect to it"
)
)
EMAIL_SUBJECT_PREFIX
=
forms
.
CharField
(
max_length
=
1024
,
label
=
_
(
"Email Subject Prefix"
),
initial
=
"[Jumpserver] "
)
AUTH_LDAP
=
forms
.
BooleanField
(
label
=
_
(
"Enable LDAP Auth"
),
initial
=
False
,
required
=
False
)
class
EmailSettingForm
(
BaseForm
):
class
EmailSettingForm
(
BaseForm
):
EMAIL_HOST
=
forms
.
CharField
(
EMAIL_HOST
=
forms
.
CharField
(
max_length
=
1024
,
label
=
_
(
"SMTP host"
),
initial
=
'smtp.jumpserver.org'
max_length
=
1024
,
label
=
_
(
"SMTP host"
),
initial
=
'smtp.jumpserver.org'
...
@@ -72,3 +97,35 @@ class EmailSettingForm(BaseForm):
...
@@ -72,3 +97,35 @@ class EmailSettingForm(BaseForm):
label
=
_
(
"Use TLS"
),
initial
=
False
,
required
=
False
,
label
=
_
(
"Use TLS"
),
initial
=
False
,
required
=
False
,
help_text
=
_
(
"If SMTP port is 587, may be select"
)
help_text
=
_
(
"If SMTP port is 587, may be select"
)
)
)
class
LDAPSettingForm
(
BaseForm
):
AUTH_LDAP_SERVER_URI
=
forms
.
CharField
(
label
=
_
(
"LDAP server"
),
initial
=
'ldap://localhost:389'
)
AUTH_LDAP_BIND_DN
=
forms
.
CharField
(
label
=
_
(
"Bind DN"
),
initial
=
'cn=admin,dc=jumpserver,dc=org'
)
AUTH_LDAP_BIND_PASSWORD
=
forms
.
CharField
(
label
=
_
(
"Password"
),
initial
=
''
,
widget
=
forms
.
PasswordInput
,
required
=
False
)
AUTH_LDAP_SEARCH_OU
=
forms
.
CharField
(
label
=
_
(
"User OU"
),
initial
=
'ou=tech,dc=jumpserver,dc=org'
)
AUTH_LDAP_SEARCH_FILTER
=
forms
.
CharField
(
label
=
_
(
"User search filter"
),
initial
=
'(cn=
%(user)
s)'
)
AUTH_LDAP_USER_ATTR_MAP
=
DictField
(
label
=
_
(
"User attr map"
),
initial
=
json
.
dumps
({
"username"
:
"cn"
,
"name"
:
"sn"
,
"email"
:
"mail"
})
)
# AUTH_LDAP_GROUP_SEARCH_OU = CONFIG.AUTH_LDAP_GROUP_SEARCH_OU
# AUTH_LDAP_GROUP_SEARCH_FILTER = CONFIG.AUTH_LDAP_GROUP_SEARCH_FILTER
AUTH_LDAP_START_TLS
=
forms
.
BooleanField
(
label
=
_
(
"Use SSL"
),
initial
=
False
,
required
=
False
)
apps/common/models.py
View file @
abb1a40a
import
json
import
json
import
ldap
from
django.db
import
models
from
django.db
import
models
from
django.utils.translation
import
ugettext_lazy
as
_
from
django.utils.translation
import
ugettext_lazy
as
_
from
django.conf
import
settings
from
django.conf
import
settings
from
django_auth_ldap.config
import
LDAPSearch
class
SettingQuerySet
(
models
.
QuerySet
):
class
SettingQuerySet
(
models
.
QuerySet
):
...
@@ -30,6 +32,13 @@ class Setting(models.Model):
...
@@ -30,6 +32,13 @@ class Setting(models.Model):
def
__str__
(
self
):
def
__str__
(
self
):
return
self
.
name
return
self
.
name
@property
def
value_
(
self
):
try
:
return
json
.
loads
(
self
.
value
)
except
json
.
JSONDecodeError
:
return
None
@classmethod
@classmethod
def
refresh_all_settings
(
cls
):
def
refresh_all_settings
(
cls
):
settings_list
=
cls
.
objects
.
all
()
settings_list
=
cls
.
objects
.
all
()
...
@@ -43,5 +52,17 @@ class Setting(models.Model):
...
@@ -43,5 +52,17 @@ class Setting(models.Model):
return
return
setattr
(
settings
,
self
.
name
,
value
)
setattr
(
settings
,
self
.
name
,
value
)
if
self
.
name
==
"AUTH_LDAP"
:
if
self
.
value_
and
settings
.
AUTH_LDAP_BACKEND
not
in
settings
.
AUTHENTICATION_BACKENDS
:
settings
.
AUTHENTICATION_BACKENDS
.
insert
(
0
,
settings
.
AUTH_LDAP_BACKEND
)
elif
not
self
.
value_
and
settings
.
AUTH_LDAP_BACKEND
in
settings
.
AUTHENTICATION_BACKENDS
:
settings
.
AUTHENTICATION_BACKENDS
.
remove
(
settings
.
AUTH_LDAP_BACKEND
)
if
self
.
name
==
"AUTH_LDAP_SEARCH_FILTER"
:
settings
.
AUTH_LDAP_USER_SEARCH
=
LDAPSearch
(
settings
.
AUTH_LDAP_SEARCH_OU
,
ldap
.
SCOPE_SUBTREE
,
settings
.
AUTH_LDAP_SEARCH_FILTER
,
)
class
Meta
:
class
Meta
:
db_table
=
"settings"
db_table
=
"settings"
apps/common/serializers.py
View file @
abb1a40a
...
@@ -8,3 +8,14 @@ class MailTestSerializer(serializers.Serializer):
...
@@ -8,3 +8,14 @@ class MailTestSerializer(serializers.Serializer):
EMAIL_HOST_PASSWORD
=
serializers
.
CharField
()
EMAIL_HOST_PASSWORD
=
serializers
.
CharField
()
EMAIL_USE_SSL
=
serializers
.
BooleanField
(
default
=
False
)
EMAIL_USE_SSL
=
serializers
.
BooleanField
(
default
=
False
)
EMAIL_USE_TLS
=
serializers
.
BooleanField
(
default
=
False
)
EMAIL_USE_TLS
=
serializers
.
BooleanField
(
default
=
False
)
class
LDAPTestSerializer
(
serializers
.
Serializer
):
AUTH_LDAP_SERVER_URI
=
serializers
.
CharField
(
max_length
=
1024
)
AUTH_LDAP_BIND_DN
=
serializers
.
CharField
(
max_length
=
1024
)
AUTH_LDAP_BIND_PASSWORD
=
serializers
.
CharField
()
AUTH_LDAP_SEARCH_OU
=
serializers
.
CharField
()
AUTH_LDAP_SEARCH_FILTER
=
serializers
.
CharField
()
AUTH_LDAP_USER_ATTR_MAP
=
serializers
.
CharField
()
AUTH_LDAP_START_TLS
=
serializers
.
BooleanField
(
required
=
False
)
apps/common/signals.py
View file @
abb1a40a
...
@@ -4,3 +4,4 @@
...
@@ -4,3 +4,4 @@
from
django.dispatch
import
Signal
from
django.dispatch
import
Signal
django_ready
=
Signal
()
django_ready
=
Signal
()
ldap_auth_enable
=
Signal
(
providing_args
=
[
"enabled"
])
apps/common/signals_handler.py
View file @
abb1a40a
# -*- coding: utf-8 -*-
# -*- coding: utf-8 -*-
#
#
import
ldap
from
django.dispatch
import
receiver
from
django.dispatch
import
receiver
from
django.db.models.signals
import
post_save
from
django.db.models.signals
import
post_save
from
django.conf
import
settings
from
django_auth_ldap.config
import
LDAPSearch
from
.models
import
Setting
from
.models
import
Setting
from
.utils
import
get_logger
from
.utils
import
get_logger
from
.signals
import
django_ready
from
.signals
import
django_ready
,
ldap_auth_enable
logger
=
get_logger
(
__file__
)
logger
=
get_logger
(
__file__
)
...
@@ -25,3 +26,17 @@ def refresh_all_settings_on_django_ready(sender, **kwargs):
...
@@ -25,3 +26,17 @@ def refresh_all_settings_on_django_ready(sender, **kwargs):
logger
.
debug
(
"Receive django ready signal"
)
logger
.
debug
(
"Receive django ready signal"
)
logger
.
debug
(
" - fresh all settings"
)
logger
.
debug
(
" - fresh all settings"
)
Setting
.
refresh_all_settings
()
Setting
.
refresh_all_settings
()
@receiver
(
ldap_auth_enable
,
dispatch_uid
=
"my_unique_identifier"
)
def
ldap_auth_on_changed
(
sender
,
enabled
=
True
,
**
kwargs
):
if
enabled
:
logger
.
debug
(
"Enable LDAP auth"
)
if
settings
.
AUTH_LDAP_BACKEND
not
in
settings
.
AUTH_LDAP_BACKEND
:
settings
.
AUTHENTICATION_BACKENDS
.
insert
(
0
,
settings
.
AUTH_LDAP_BACKEND
)
else
:
logger
.
debug
(
"Disable LDAP auth"
)
if
settings
.
AUTH_LDAP_BACKEND
in
settings
.
AUTHENTICATION_BACKENDS
:
settings
.
AUTHENTICATION_BACKENDS
.
remove
(
settings
.
AUTH_LDAP_BACKEND
)
apps/common/templates/common/basic_setting.html
0 → 100644
View file @
abb1a40a
{% extends 'base.html' %}
{% load static %}
{% load bootstrap3 %}
{% load i18n %}
{% load common_tags %}
{% block content %}
<div
class=
"wrapper wrapper-content animated fadeInRight"
>
<div
class=
"row"
>
<div
class=
"col-sm-12"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"panel-options"
>
<ul
class=
"nav nav-tabs"
>
<li
class=
"active"
>
<a
href=
""
class=
"text-center"
><i
class=
"fa fa-cubes"
></i>
{% trans 'Basic setting' %}
</a>
</li>
<li>
<a
href=
"{% url 'settings:email-setting' %}"
class=
"text-center"
><i
class=
"fa fa-envelope"
></i>
{% trans 'Email setting' %}
</a>
</li>
<li>
<a
href=
"{% url 'settings:ldap-setting' %}"
class=
"text-center"
><i
class=
"fa fa-archive"
></i>
{% trans 'LDAP setting' %}
</a>
</li>
</ul>
</div>
<div
class=
"tab-content"
>
<div
class=
"col-sm-12"
style=
"padding-left:0"
>
<div
class=
"ibox-content"
style=
"border-width: 0;padding-top: 40px;"
>
<form
action=
""
method=
"post"
class=
"form-horizontal"
>
{% if form.non_field_errors %}
<div
class=
"alert alert-danger"
>
{{ form.non_field_errors }}
</div>
{% endif %}
{% csrf_token %}
{% for field in form %}
{% if not field.field|is_bool_field %}
{% bootstrap_field field layout="horizontal" %}
{% else %}
<div
class=
"form-group"
>
<label
for=
"{{ field.id_for_label }}"
class=
"col-sm-2 control-label"
>
{{ field.label }}
</label>
<div
class=
"col-sm-8"
>
<div
class=
"col-sm-1"
>
{{ field }}
</div>
<div
class=
"col-sm-9"
>
<span
class=
"help-block"
>
{{ field.help_text }}
</span>
</div>
</div>
</div>
{% endif %}
{% endfor %}
<div
class=
"hr-line-dashed"
></div>
<div
class=
"form-group"
>
<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
id=
"submit_button"
class=
"btn btn-primary"
type=
"submit"
>
{% trans 'Submit' %}
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% block custom_foot_js %}
<script>
$
(
document
).
ready
(
function
()
{
})
.
on
(
"click"
,
".btn-test"
,
function
()
{
var
data
=
{};
var
form
=
$
(
"form"
).
serializeArray
();
$
.
each
(
form
,
function
(
i
,
field
)
{
data
[
field
.
name
]
=
field
.
value
;
});
var
the_url
=
"{% url 'api-common:mail-testing' %}"
;
function
error
(
message
)
{
toastr
.
error
(
message
)
}
function
success
(
message
)
{
toastr
.
success
(
message
.
msg
)
}
APIUpdateAttr
({
url
:
the_url
,
body
:
JSON
.
stringify
(
data
),
method
:
"POST"
,
flash_message
:
false
,
success
:
success
,
error
:
error
});
})
</script>
{% endblock %}
apps/common/templates/common/email_setting.html
View file @
abb1a40a
...
@@ -4,10 +4,6 @@
...
@@ -4,10 +4,6 @@
{% load i18n %}
{% load i18n %}
{% load common_tags %}
{% load common_tags %}
{% block custom_head_css_js %}
<link
href=
"{% static 'css/plugins/select2/select2.min.css' %}"
rel=
"stylesheet"
>
<script
src=
"{% static 'js/plugins/select2/select2.full.min.js' %}"
></script>
{% endblock %}
{% block content %}
{% block content %}
<div
class=
"wrapper wrapper-content animated fadeInRight"
>
<div
class=
"wrapper wrapper-content animated fadeInRight"
>
<div
class=
"row"
>
<div
class=
"row"
>
...
@@ -16,10 +12,13 @@
...
@@ -16,10 +12,13 @@
<div
class=
"panel-options"
>
<div
class=
"panel-options"
>
<ul
class=
"nav nav-tabs"
>
<ul
class=
"nav nav-tabs"
>
<li>
<li>
<a
href=
""
class=
"text-center"
><i
class=
"fa fa-cubes"
></i>
{% trans 'Basic setting' %}
</a>
<a
href=
"
{% url 'settings:basic-setting' %}
"
class=
"text-center"
><i
class=
"fa fa-cubes"
></i>
{% trans 'Basic setting' %}
</a>
</li>
</li>
<li
class=
"active"
>
<li
class=
"active"
>
<a
class=
"text-center"
><i
class=
"fa fa-envelope"
></i>
{% trans 'Email setting' %}
</a>
<a
href=
"{% url 'settings:email-setting' %}"
class=
"text-center"
><i
class=
"fa fa-envelope"
></i>
{% trans 'Email setting' %}
</a>
</li>
<li>
<a
href=
"{% url 'settings:ldap-setting' %}"
class=
"text-center"
><i
class=
"fa fa-archive"
></i>
{% trans 'LDAP setting' %}
</a>
</li>
</li>
</ul>
</ul>
</div>
</div>
...
@@ -53,6 +52,7 @@
...
@@ -53,6 +52,7 @@
<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
id=
"submit_button"
class=
"btn btn-primary"
type=
"submit"
>
{% trans 'Submit' %}
</button>
</div>
</div>
...
@@ -69,5 +69,33 @@
...
@@ -69,5 +69,33 @@
{% endblock %}
{% endblock %}
{% block custom_foot_js %}
{% block custom_foot_js %}
<script>
<script>
$
(
document
).
ready
(
function
()
{
})
.
on
(
"click"
,
".btn-test"
,
function
()
{
var
data
=
{};
var
form
=
$
(
"form"
).
serializeArray
();
$
.
each
(
form
,
function
(
i
,
field
)
{
data
[
field
.
name
]
=
field
.
value
;
});
var
the_url
=
"{% url 'api-common:mail-testing' %}"
;
function
error
(
message
)
{
toastr
.
error
(
message
)
}
function
success
(
message
)
{
toastr
.
success
(
message
.
msg
)
}
APIUpdateAttr
({
url
:
the_url
,
body
:
JSON
.
stringify
(
data
),
method
:
"POST"
,
flash_message
:
false
,
success
:
success
,
error
:
error
});
})
</script>
</script>
{% endblock %}
{% endblock %}
apps/common/templates/common/ldap_setting.html
0 → 100644
View file @
abb1a40a
{% extends 'base.html' %}
{% load static %}
{% load bootstrap3 %}
{% load i18n %}
{% load common_tags %}
{% block content %}
<div
class=
"wrapper wrapper-content animated fadeInRight"
>
<div
class=
"row"
>
<div
class=
"col-sm-12"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"panel-options"
>
<ul
class=
"nav nav-tabs"
>
<li>
<a
href=
"{% url 'settings:basic-setting' %}"
class=
"text-center"
><i
class=
"fa fa-cubes"
></i>
{% trans 'Basic setting' %}
</a>
</li>
<li>
<a
href=
"{% url 'settings:email-setting' %}"
class=
"text-center"
><i
class=
"fa fa-envelope"
></i>
{% trans 'Email setting' %}
</a>
</li>
<li
class=
"active"
>
<a
href=
"{% url 'settings:ldap-setting' %}"
class=
"text-center"
><i
class=
"fa fa-archive"
></i>
{% trans 'LDAP setting' %}
</a>
</li>
</ul>
</div>
<div
class=
"tab-content"
>
<div
class=
"col-sm-12"
style=
"padding-left:0"
>
<div
class=
"ibox-content"
style=
"border-width: 0;padding-top: 40px;"
>
<form
action=
""
method=
"post"
class=
"form-horizontal"
>
{% if form.non_field_errors %}
<div
class=
"alert alert-danger"
>
{{ form.non_field_errors }}
</div>
{% endif %}
{% csrf_token %}
{% for field in form %}
{% if not field.field|is_bool_field %}
{% bootstrap_field field layout="horizontal" %}
{% else %}
<div
class=
"form-group"
>
<label
for=
"{{ field.id_for_label }}"
class=
"col-sm-2 control-label"
>
{{ field.label }}
</label>
<div
class=
"col-sm-8"
>
<div
class=
"col-sm-1"
>
{{ field }}
</div>
<div
class=
"col-sm-9"
>
<span
class=
"help-block"
>
{{ field.help_text }}
</span>
</div>
</div>
</div>
{% endif %}
{% endfor %}
<div
class=
"hr-line-dashed"
></div>
<div
class=
"form-group"
>
<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
id=
"submit_button"
class=
"btn btn-primary"
type=
"submit"
>
{% trans 'Submit' %}
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% block custom_foot_js %}
<script>
$
(
document
).
ready
(
function
()
{
})
.
on
(
"click"
,
".btn-test"
,
function
()
{
var
data
=
{};
var
form
=
$
(
"form"
).
serializeArray
();
$
.
each
(
form
,
function
(
i
,
field
)
{
data
[
field
.
name
]
=
field
.
value
;
});
var
the_url
=
"{% url 'api-common:ldap-testing' %}"
;
function
error
(
message
)
{
toastr
.
error
(
message
)
}
function
success
(
message
)
{
toastr
.
success
(
message
.
msg
)
}
APIUpdateAttr
({
url
:
the_url
,
body
:
JSON
.
stringify
(
data
),
method
:
"POST"
,
flash_message
:
false
,
success
:
success
,
error
:
error
});
})
</script>
{% endblock %}
apps/common/urls/api_urls.py
View file @
abb1a40a
...
@@ -8,4 +8,6 @@ app_name = 'common'
...
@@ -8,4 +8,6 @@ app_name = 'common'
urlpatterns
=
[
urlpatterns
=
[
url
(
r'^v1/mail/testing/$'
,
api
.
MailTestingAPI
.
as_view
(),
name
=
'mail-testing'
),
url
(
r'^v1/mail/testing/$'
,
api
.
MailTestingAPI
.
as_view
(),
name
=
'mail-testing'
),
url
(
r'^v1/ldap/testing/$'
,
api
.
LDAPTestingAPI
.
as_view
(),
name
=
'ldap-testing'
),
url
(
r'^v1/django-settings/$'
,
api
.
DjangoSettingsAPI
.
as_view
(),
name
=
'django-settings'
),
]
]
apps/common/urls/view_urls.py
View file @
abb1a40a
...
@@ -7,5 +7,7 @@ from .. import views
...
@@ -7,5 +7,7 @@ from .. import views
app_name
=
'common'
app_name
=
'common'
urlpatterns
=
[
urlpatterns
=
[
url
(
r'^$'
,
views
.
BasicSettingView
.
as_view
(),
name
=
'basic-setting'
),
url
(
r'^email/$'
,
views
.
EmailSettingView
.
as_view
(),
name
=
'email-setting'
),
url
(
r'^email/$'
,
views
.
EmailSettingView
.
as_view
(),
name
=
'email-setting'
),
url
(
r'^ldap/$'
,
views
.
LDAPSettingView
.
as_view
(),
name
=
'ldap-setting'
),
]
]
apps/common/utils.py
View file @
abb1a40a
...
@@ -91,7 +91,7 @@ class Signer(metaclass=Singleton):
...
@@ -91,7 +91,7 @@ class Signer(metaclass=Singleton):
def
date_expired_default
():
def
date_expired_default
():
try
:
try
:
years
=
int
(
settings
.
CONFIG
.
DEFAULT_EXPIRED_YEARS
)
years
=
int
(
settings
.
DEFAULT_EXPIRED_YEARS
)
except
TypeError
:
except
TypeError
:
years
=
70
years
=
70
return
timezone
.
now
()
+
timezone
.
timedelta
(
days
=
365
*
years
)
return
timezone
.
now
()
+
timezone
.
timedelta
(
days
=
365
*
years
)
...
...
apps/common/views.py
View file @
abb1a40a
from
django.views.generic
import
View
from
django.views.generic
import
View
,
TemplateView
from
django.shortcuts
import
render
from
django.shortcuts
import
render
,
redirect
from
django.contrib
import
messages
from
django.contrib
import
messages
from
django.utils.translation
import
ugettext
as
_
from
django.utils.translation
import
ugettext
as
_
from
.forms
import
EmailSettingForm
from
.forms
import
EmailSettingForm
,
LDAPSettingForm
,
BasicSettingForm
from
.mixins
import
AdminUserRequiredMixin
from
.mixins
import
AdminUserRequiredMixin
from
.signals
import
ldap_auth_enable
class
EmailSettingView
(
AdminUserRequiredMixin
,
View
):
class
BasicSettingView
(
AdminUserRequiredMixin
,
TemplateView
):
form_class
=
BasicSettingForm
template_name
=
"common/basic_setting.html"
def
get_context_data
(
self
,
**
kwargs
):
context
=
{
'app'
:
_
(
'Settings'
),
'action'
:
_
(
'Basic setting'
),
'form'
:
self
.
form_class
(),
}
kwargs
.
update
(
context
)
return
super
()
.
get_context_data
(
**
kwargs
)
def
post
(
self
,
request
):
form
=
self
.
form_class
(
request
.
POST
)
if
form
.
is_valid
():
form
.
save
()
if
"AUTH_LDAP"
in
form
.
cleaned_data
:
ldap_auth_enable
.
send
(
form
.
cleaned_data
[
"AUTH_LDAP"
])
messages
.
success
(
request
,
_
(
"Update basic setting successfully"
))
return
redirect
(
'settings:basic-setting'
)
else
:
context
=
self
.
get_context_data
()
context
.
update
({
"form"
:
form
})
return
render
(
request
,
self
.
template_name
,
context
)
class
EmailSettingView
(
AdminUserRequiredMixin
,
TemplateView
):
form_class
=
EmailSettingForm
form_class
=
EmailSettingForm
template_name
=
"common/email_setting.html"
template_name
=
"common/email_setting.html"
def
get
(
self
,
request
):
def
get
_context_data
(
self
,
**
kwargs
):
context
=
{
context
=
{
'app'
:
'settings'
,
'app'
:
_
(
'Settings'
)
,
'action'
:
'Email setting'
,
'action'
:
_
(
'Email setting'
)
,
"form"
:
EmailSettingForm
(),
'form'
:
self
.
form_class
(),
}
}
return
render
(
request
,
self
.
template_name
,
context
)
kwargs
.
update
(
context
)
return
super
()
.
get_context_data
(
**
kwargs
)
def
post
(
self
,
request
):
def
post
(
self
,
request
):
form
=
self
.
form_class
(
request
.
POST
)
form
=
self
.
form_class
(
request
.
POST
)
if
form
.
is_valid
():
if
form
.
is_valid
():
form
.
save
()
form
.
save
()
messages
.
success
(
request
,
_
(
"Update email setting successfully"
))
messages
.
success
(
request
,
_
(
"Update email setting successfully"
))
return
redirect
(
'settings:email-setting'
)
else
:
context
=
self
.
get_context_data
()
context
.
update
({
"form"
:
form
})
return
render
(
request
,
self
.
template_name
,
context
)
class
LDAPSettingView
(
AdminUserRequiredMixin
,
TemplateView
):
form_class
=
LDAPSettingForm
template_name
=
"common/ldap_setting.html"
def
get_context_data
(
self
,
**
kwargs
):
context
=
{
context
=
{
'app'
:
'settings'
,
'app'
:
_
(
'Settings'
)
,
'action'
:
'Email setting'
,
'action'
:
_
(
'LDAP setting'
)
,
"form"
:
EmailSettingForm
(),
'form'
:
self
.
form_class
(),
}
}
kwargs
.
update
(
context
)
return
super
()
.
get_context_data
(
**
kwargs
)
def
post
(
self
,
request
):
form
=
self
.
form_class
(
request
.
POST
)
if
form
.
is_valid
():
form
.
save
()
messages
.
success
(
request
,
_
(
"Update ldap setting successfully"
))
return
redirect
(
'settings:ldap-setting'
)
else
:
context
=
self
.
get_context_data
()
context
.
update
({
"form"
:
form
})
return
render
(
request
,
self
.
template_name
,
context
)
return
render
(
request
,
self
.
template_name
,
context
)
apps/jumpserver/settings.py
View file @
abb1a40a
...
@@ -15,7 +15,6 @@ import sys
...
@@ -15,7 +15,6 @@ import sys
import
ldap
import
ldap
from
django_auth_ldap.config
import
LDAPSearch
from
django_auth_ldap.config
import
LDAPSearch
from
django.urls
import
reverse_lazy
from
django.urls
import
reverse_lazy
...
@@ -303,18 +302,28 @@ AUTH_USER_MODEL = 'users.User'
...
@@ -303,18 +302,28 @@ AUTH_USER_MODEL = 'users.User'
# Auth LDAP settings
# Auth LDAP settings
if
CONFIG
.
AUTH_LDAP
:
AUTH_LDAP
=
CONFIG
.
AUTH_LDAP
AUTHENTICATION_BACKENDS
.
insert
(
0
,
'django_auth_ldap.backend.LDAPBackend'
)
AUTH_LDAP_SERVER_URI
=
CONFIG
.
AUTH_LDAP_SERVER_URI
AUTH_LDAP_SERVER_URI
=
CONFIG
.
AUTH_LDAP_SERVER_URI
AUTH_LDAP_BIND_DN
=
CONFIG
.
AUTH_LDAP_BIND_DN
AUTH_LDAP_BIND_DN
=
CONFIG
.
AUTH_LDAP_BIND_DN
AUTH_LDAP_BIND_PASSWORD
=
CONFIG
.
AUTH_LDAP_BIND_PASSWORD
AUTH_LDAP_BIND_PASSWORD
=
CONFIG
.
AUTH_LDAP_BIND_PASSWORD
AUTH_LDAP_SEARCH_OU
=
CONFIG
.
AUTH_LDAP_SEARCH_OU
AUTH_LDAP_USER_SEARCH
=
LDAPSearch
(
AUTH_LDAP_SEARCH_FILTER
=
CONFIG
.
AUTH_LDAP_SEARCH_FILTER
CONFIG
.
AUTH_LDAP_SEARCH_OU
,
AUTH_LDAP_START_TLS
=
CONFIG
.
AUTH_LDAP_START_TLS
ldap
.
SCOPE_SUBTREE
,
AUTH_LDAP_USER_ATTR_MAP
=
CONFIG
.
AUTH_LDAP_USER_ATTR_MAP
CONFIG
.
AUTH_LDAP_SEARCH_FILTER
AUTH_LDAP_USER_SEARCH
=
LDAPSearch
(
)
AUTH_LDAP_SEARCH_OU
,
ldap
.
SCOPE_SUBTREE
,
AUTH_LDAP_SEARCH_FILTER
,
AUTH_LDAP_START_TLS
=
CONFIG
.
AUTH_LDAP_START_TLS
)
AUTH_LDAP_USER_ATTR_MAP
=
CONFIG
.
AUTH_LDAP_USER_ATTR_MAP
AUTH_LDAP_GROUP_SEARCH_OU
=
CONFIG
.
AUTH_LDAP_GROUP_SEARCH_OU
AUTH_LDAP_GROUP_SEARCH_FILTER
=
CONFIG
.
AUTH_LDAP_GROUP_SEARCH_FILTER
AUTH_LDAP_GROUP_SEARCH
=
LDAPSearch
(
AUTH_LDAP_GROUP_SEARCH_OU
,
ldap
.
SCOPE_SUBTREE
,
AUTH_LDAP_GROUP_SEARCH_FILTER
)
AUTH_LDAP_ALWAYS_UPDATE_USER
=
True
AUTH_LDAP_BACKEND
=
'django_auth_ldap.backend.LDAPBackend'
if
AUTH_LDAP
:
AUTHENTICATION_BACKENDS
.
insert
(
0
,
AUTH_LDAP_BACKEND
)
# Celery using redis as broker
# Celery using redis as broker
CELERY_BROKER_URL
=
'redis://:
%(password)
s@
%(host)
s:
%(port)
s/3'
%
{
CELERY_BROKER_URL
=
'redis://:
%(password)
s@
%(host)
s:
%(port)
s/3'
%
{
...
@@ -367,3 +376,7 @@ BOOTSTRAP3 = {
...
@@ -367,3 +376,7 @@ BOOTSTRAP3 = {
'set_placeholder'
:
True
,
'set_placeholder'
:
True
,
'success_css_class'
:
''
,
'success_css_class'
:
''
,
}
}
TOKEN_EXPIRATION
=
CONFIG
.
TOKEN_EXPIRATION
or
3600
DISPLAY_PER_PAGE
=
CONFIG
.
DISPLAY_PER_PAGE
DEFAULT_EXPIRED_YEARS
=
70
apps/ops/views.py
View file @
abb1a40a
...
@@ -10,7 +10,7 @@ from .hands import AdminUserRequiredMixin
...
@@ -10,7 +10,7 @@ from .hands import AdminUserRequiredMixin
class
TaskListView
(
AdminUserRequiredMixin
,
DatetimeSearchMixin
,
ListView
):
class
TaskListView
(
AdminUserRequiredMixin
,
DatetimeSearchMixin
,
ListView
):
paginate_by
=
settings
.
CONFIG
.
DISPLAY_PER_PAGE
paginate_by
=
settings
.
DISPLAY_PER_PAGE
model
=
Task
model
=
Task
ordering
=
(
'-date_created'
,)
ordering
=
(
'-date_created'
,)
context_object_name
=
'task_list'
context_object_name
=
'task_list'
...
...
apps/perms/views.py
View file @
abb1a40a
...
@@ -93,7 +93,7 @@ class AssetPermissionUserView(AdminUserRequiredMixin,
...
@@ -93,7 +93,7 @@ class AssetPermissionUserView(AdminUserRequiredMixin,
ListView
):
ListView
):
template_name
=
'perms/asset_permission_user.html'
template_name
=
'perms/asset_permission_user.html'
context_object_name
=
'asset_permission'
context_object_name
=
'asset_permission'
paginate_by
=
settings
.
CONFIG
.
DISPLAY_PER_PAGE
paginate_by
=
settings
.
DISPLAY_PER_PAGE
object
=
None
object
=
None
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
...
@@ -123,7 +123,7 @@ class AssetPermissionAssetView(AdminUserRequiredMixin,
...
@@ -123,7 +123,7 @@ class AssetPermissionAssetView(AdminUserRequiredMixin,
ListView
):
ListView
):
template_name
=
'perms/asset_permission_asset.html'
template_name
=
'perms/asset_permission_asset.html'
context_object_name
=
'asset_permission'
context_object_name
=
'asset_permission'
paginate_by
=
settings
.
CONFIG
.
DISPLAY_PER_PAGE
paginate_by
=
settings
.
DISPLAY_PER_PAGE
object
=
None
object
=
None
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
...
...
apps/static/js/jumpserver.js
View file @
abb1a40a
...
@@ -157,6 +157,11 @@ function APIUpdateAttr(props) {
...
@@ -157,6 +157,11 @@ function APIUpdateAttr(props) {
props
=
props
||
{};
props
=
props
||
{};
var
success_message
=
props
.
success_message
||
'更新成功!'
;
var
success_message
=
props
.
success_message
||
'更新成功!'
;
var
fail_message
=
props
.
fail_message
||
'更新时发生未知错误.'
;
var
fail_message
=
props
.
fail_message
||
'更新时发生未知错误.'
;
var
flash_message
=
true
;
if
(
props
.
flash_message
===
false
){
flash_message
=
false
;
}
$
.
ajax
({
$
.
ajax
({
url
:
props
.
url
,
url
:
props
.
url
,
type
:
props
.
method
||
"PATCH"
,
type
:
props
.
method
||
"PATCH"
,
...
@@ -164,12 +169,16 @@ function APIUpdateAttr(props) {
...
@@ -164,12 +169,16 @@ function APIUpdateAttr(props) {
contentType
:
props
.
content_type
||
"application/json; charset=utf-8"
,
contentType
:
props
.
content_type
||
"application/json; charset=utf-8"
,
dataType
:
props
.
data_type
||
"json"
dataType
:
props
.
data_type
||
"json"
}).
done
(
function
(
data
,
textStatue
,
jqXHR
)
{
}).
done
(
function
(
data
,
textStatue
,
jqXHR
)
{
if
(
flash_message
)
{
toastr
.
success
(
success_message
);
toastr
.
success
(
success_message
);
}
if
(
typeof
props
.
success
===
'function'
)
{
if
(
typeof
props
.
success
===
'function'
)
{
return
props
.
success
(
data
);
return
props
.
success
(
data
);
}
}
}).
fail
(
function
(
jqXHR
,
textStatus
,
errorThrown
)
{
}).
fail
(
function
(
jqXHR
,
textStatus
,
errorThrown
)
{
if
(
flash_message
)
{
toastr
.
error
(
fail_message
);
toastr
.
error
(
fail_message
);
}
if
(
typeof
props
.
error
===
'function'
)
{
if
(
typeof
props
.
error
===
'function'
)
{
return
props
.
error
(
jqXHR
.
responseText
);
return
props
.
error
(
jqXHR
.
responseText
);
}
}
...
...
apps/templates/_nav.html
View file @
abb1a40a
...
@@ -69,8 +69,8 @@
...
@@ -69,8 +69,8 @@
{#
<li
id=
"download"
><a
href=
""
>
{% trans 'File download' %}
</a></li>
#}
{#
<li
id=
"download"
><a
href=
""
>
{% trans 'File download' %}
</a></li>
#}
{#
</ul>
#}
{#
</ul>
#}
{#
</li>
#}
{#
</li>
#}
{#
<li
id=
""
>
#}
<li
id=
"settings"
>
{#
<a
href=
""
>
#}
<a
href=
"{% url 'settings:email-setting' %}"
>
{#
<i
class=
"fa fa-gears"
></i>
<span
class=
"nav-label"
>
{% trans 'Settings' %}
</span><span
class=
"label label-info pull-right"
></span>
#}
<i
class=
"fa fa-gears"
></i>
<span
class=
"nav-label"
>
{% trans 'Settings' %}
</span><span
class=
"label label-info pull-right"
></span>
{#
</a>
#}
</a>
{#
</li>
#}
</li>
\ No newline at end of file
\ No newline at end of file
apps/terminal/views/command.py
View file @
abb1a40a
...
@@ -19,7 +19,7 @@ class CommandListView(DatetimeSearchMixin, ListView):
...
@@ -19,7 +19,7 @@ class CommandListView(DatetimeSearchMixin, ListView):
model
=
Command
model
=
Command
template_name
=
"terminal/command_list.html"
template_name
=
"terminal/command_list.html"
context_object_name
=
'command_list'
context_object_name
=
'command_list'
paginate_by
=
settings
.
CONFIG
.
DISPLAY_PER_PAGE
paginate_by
=
settings
.
DISPLAY_PER_PAGE
command
=
user
=
asset
=
system_user
=
""
command
=
user
=
asset
=
system_user
=
""
date_from
=
date_to
=
None
date_from
=
date_to
=
None
...
...
apps/terminal/views/session.py
View file @
abb1a40a
...
@@ -26,7 +26,7 @@ class SessionListView(AdminUserRequiredMixin, DatetimeSearchMixin, ListView):
...
@@ -26,7 +26,7 @@ class SessionListView(AdminUserRequiredMixin, DatetimeSearchMixin, ListView):
model
=
Session
model
=
Session
template_name
=
'terminal/session_list.html'
template_name
=
'terminal/session_list.html'
context_object_name
=
'session_list'
context_object_name
=
'session_list'
paginate_by
=
settings
.
CONFIG
.
DISPLAY_PER_PAGE
paginate_by
=
settings
.
DISPLAY_PER_PAGE
user
=
asset
=
system_user
=
''
user
=
asset
=
system_user
=
''
date_from
=
date_to
=
None
date_from
=
date_to
=
None
...
...
apps/users/authentication.py
View file @
abb1a40a
...
@@ -113,7 +113,7 @@ class AccessKeyAuthentication(authentication.BaseAuthentication):
...
@@ -113,7 +113,7 @@ class AccessKeyAuthentication(authentication.BaseAuthentication):
class
AccessTokenAuthentication
(
authentication
.
BaseAuthentication
):
class
AccessTokenAuthentication
(
authentication
.
BaseAuthentication
):
keyword
=
'Bearer'
keyword
=
'Bearer'
model
=
User
model
=
User
expiration
=
settings
.
CONFIG
.
TOKEN_EXPIRATION
or
3600
expiration
=
settings
.
TOKEN_EXPIRATION
or
3600
def
authenticate
(
self
,
request
):
def
authenticate
(
self
,
request
):
auth
=
authentication
.
get_authorization_header
(
request
)
.
split
()
auth
=
authentication
.
get_authorization_header
(
request
)
.
split
()
...
...
apps/users/models/user.py
View file @
abb1a40a
...
@@ -148,12 +148,7 @@ class User(AbstractUser):
...
@@ -148,12 +148,7 @@ class User(AbstractUser):
def
save
(
self
,
*
args
,
**
kwargs
):
def
save
(
self
,
*
args
,
**
kwargs
):
if
not
self
.
name
:
if
not
self
.
name
:
self
.
name
=
self
.
username
self
.
name
=
self
.
username
super
()
.
save
(
*
args
,
**
kwargs
)
super
()
.
save
(
*
args
,
**
kwargs
)
# Add the current user to the default group.
if
not
self
.
groups
.
count
():
group
=
UserGroup
.
initial
()
self
.
groups
.
add
(
group
)
@property
@property
def
private_token
(
self
):
def
private_token
(
self
):
...
@@ -253,6 +248,7 @@ class User(AbstractUser):
...
@@ -253,6 +248,7 @@ class User(AbstractUser):
#: Use this method initial user
#: Use this method initial user
@classmethod
@classmethod
def
initial
(
cls
):
def
initial
(
cls
):
from
.group
import
UserGroup
user
=
cls
(
username
=
'admin'
,
user
=
cls
(
username
=
'admin'
,
email
=
'admin@jumpserver.org'
,
email
=
'admin@jumpserver.org'
,
name
=
_
(
'Administrator'
),
name
=
_
(
'Administrator'
),
...
@@ -268,6 +264,7 @@ class User(AbstractUser):
...
@@ -268,6 +264,7 @@ class User(AbstractUser):
from
random
import
seed
,
choice
from
random
import
seed
,
choice
import
forgery_py
import
forgery_py
from
django.db
import
IntegrityError
from
django.db
import
IntegrityError
from
.group
import
UserGroup
seed
()
seed
()
for
i
in
range
(
count
):
for
i
in
range
(
count
):
...
...
apps/users/signals.py
View file @
abb1a40a
...
@@ -2,16 +2,19 @@
...
@@ -2,16 +2,19 @@
#
#
from
django.dispatch
import
Signal
,
receiver
from
django.dispatch
import
Signal
,
receiver
from
django.db.models.signals
import
post_save
from
common.utils
import
get_logger
from
common.utils
import
get_logger
from
.models
import
User
logger
=
get_logger
(
__file__
)
logger
=
get_logger
(
__file__
)
on_user_created
=
Signal
(
providing_args
=
[
'user'
,
'request'
])
@receiver
(
on_user_created
)
@receiver
(
post_save
,
sender
=
User
)
def
send_user_add_mail_to_user
(
sender
,
user
=
None
,
**
kwargs
):
def
on_user_created
(
sender
,
instance
=
None
,
created
=
False
,
**
kwargs
):
if
created
:
logger
.
debug
(
"Receive user `{}` create signal"
.
format
(
instance
.
name
))
from
.utils
import
send_user_created_mail
from
.utils
import
send_user_created_mail
logger
.
debug
(
"Receive asset create signal, update asset hardware info"
)
logger
.
info
(
" - Sending welcome mail ..."
.
format
(
instance
.
name
)
)
send_user_created_mail
(
user
)
send_user_created_mail
(
instance
)
apps/users/utils.py
View file @
abb1a40a
...
@@ -151,12 +151,12 @@ def check_user_valid(**kwargs):
...
@@ -151,12 +151,12 @@ def check_user_valid(**kwargs):
return
None
,
_
(
'Password or SSH public key invalid'
)
return
None
,
_
(
'Password or SSH public key invalid'
)
def
refresh_token
(
token
,
user
,
expiration
=
settings
.
CONFIG
.
TOKEN_EXPIRATION
or
3600
):
def
refresh_token
(
token
,
user
,
expiration
=
settings
.
TOKEN_EXPIRATION
or
3600
):
cache
.
set
(
token
,
user
.
id
,
expiration
)
cache
.
set
(
token
,
user
.
id
,
expiration
)
def
generate_token
(
request
,
user
):
def
generate_token
(
request
,
user
):
expiration
=
settings
.
CONFIG
.
TOKEN_EXPIRATION
or
3600
expiration
=
settings
.
TOKEN_EXPIRATION
or
3600
remote_addr
=
request
.
META
.
get
(
'REMOTE_ADDR'
,
''
)
remote_addr
=
request
.
META
.
get
(
'REMOTE_ADDR'
,
''
)
if
not
isinstance
(
remote_addr
,
bytes
):
if
not
isinstance
(
remote_addr
,
bytes
):
remote_addr
=
remote_addr
.
encode
(
"utf-8"
)
remote_addr
=
remote_addr
.
encode
(
"utf-8"
)
...
...
apps/users/views/login.py
View file @
abb1a40a
...
@@ -185,7 +185,7 @@ class UserFirstLoginView(LoginRequiredMixin, SessionWizardView):
...
@@ -185,7 +185,7 @@ class UserFirstLoginView(LoginRequiredMixin, SessionWizardView):
user
.
is_public_key_valid
=
True
user
.
is_public_key_valid
=
True
user
.
save
()
user
.
save
()
context
=
{
context
=
{
'user_guide_url'
:
settings
.
CONFIG
.
USER_GUIDE_URL
'user_guide_url'
:
settings
.
USER_GUIDE_URL
}
}
return
render
(
self
.
request
,
'users/first_login_done.html'
,
context
)
return
render
(
self
.
request
,
'users/first_login_done.html'
,
context
)
...
@@ -216,7 +216,7 @@ class UserFirstLoginView(LoginRequiredMixin, SessionWizardView):
...
@@ -216,7 +216,7 @@ class UserFirstLoginView(LoginRequiredMixin, SessionWizardView):
class
LoginLogListView
(
DatetimeSearchMixin
,
ListView
):
class
LoginLogListView
(
DatetimeSearchMixin
,
ListView
):
template_name
=
'users/login_log_list.html'
template_name
=
'users/login_log_list.html'
model
=
LoginLog
model
=
LoginLog
paginate_by
=
settings
.
CONFIG
.
DISPLAY_PER_PAGE
paginate_by
=
settings
.
DISPLAY_PER_PAGE
user
=
keyword
=
""
user
=
keyword
=
""
date_to
=
date_from
=
None
date_to
=
date_from
=
None
...
...
apps/users/views/user.py
View file @
abb1a40a
...
@@ -76,7 +76,6 @@ class UserCreateView(AdminUserRequiredMixin, SuccessMessageMixin, CreateView):
...
@@ -76,7 +76,6 @@ class UserCreateView(AdminUserRequiredMixin, SuccessMessageMixin, CreateView):
user
=
form
.
save
(
commit
=
False
)
user
=
form
.
save
(
commit
=
False
)
user
.
created_by
=
self
.
request
.
user
.
username
or
'System'
user
.
created_by
=
self
.
request
.
user
.
username
or
'System'
user
.
save
()
user
.
save
()
on_user_created
.
send
(
self
.
__class__
,
user
=
user
)
return
super
()
.
form_valid
(
form
)
return
super
()
.
form_valid
(
form
)
...
...
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