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
6700dc96
Commit
6700dc96
authored
Feb 27, 2019
by
BaiJiangJie
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[Update] users认证逻辑迁移到authentication中
parent
21714cc4
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
263 additions
and
239 deletions
+263
-239
__init__.py
apps/authentication/api/__init__.py
+4
-0
auth.py
apps/authentication/api/auth.py
+200
-0
authentication.py
apps/authentication/authentication.py
+1
-1
api_urls.py
apps/authentication/urls/api_urls.py
+18
-0
view_urls.py
apps/authentication/urls/view_urls.py
+8
-2
__init__.py
apps/authentication/views/__init__.py
+1
-0
login.py
apps/authentication/views/login.py
+14
-19
settings.py
apps/jumpserver/settings.py
+5
-5
urls.py
apps/jumpserver/urls.py
+1
-0
_header_bar.html
apps/templates/_header_bar.html
+2
-2
auth.py
apps/users/api/auth.py
+0
-195
api_urls.py
apps/users/urls/api_urls.py
+0
-4
views_urls.py
apps/users/urls/views_urls.py
+1
-3
utils.py
apps/users/utils.py
+4
-4
login.py
apps/users/views/login.py
+3
-3
user.py
apps/users/views/user.py
+1
-1
No files found.
apps/authentication/api/__init__.py
0 → 100644
View file @
6700dc96
# -*- coding: utf-8 -*-
#
from
.auth
import
*
apps/authentication/api/auth.py
0 → 100644
View file @
6700dc96
# -*- coding: utf-8 -*-
#
import
uuid
from
django.core.cache
import
cache
from
django.urls
import
reverse
from
django.shortcuts
import
get_object_or_404
from
django.utils.translation
import
ugettext
as
_
from
rest_framework.permissions
import
AllowAny
from
rest_framework.response
import
Response
from
rest_framework.views
import
APIView
from
common.utils
import
get_logger
,
get_request_ip
from
common.permissions
import
IsOrgAdminOrAppUser
from
orgs.mixins
import
RootOrgViewMixin
from
authentication.signals
import
post_auth_success
,
post_auth_failed
from
users.serializers
import
UserSerializer
from
users.models
import
User
,
LoginLog
from
users.utils
import
(
check_user_valid
,
check_otp_code
,
increase_login_failed_count
,
is_block_login
,
clean_failed_count
)
from
users.hands
import
Asset
,
SystemUser
logger
=
get_logger
(
__name__
)
class
UserAuthApi
(
RootOrgViewMixin
,
APIView
):
permission_classes
=
(
AllowAny
,)
serializer_class
=
UserSerializer
def
post
(
self
,
request
):
# limit login
username
=
request
.
data
.
get
(
'username'
)
ip
=
request
.
data
.
get
(
'remote_addr'
,
None
)
ip
=
ip
or
get_request_ip
(
request
)
if
is_block_login
(
username
,
ip
):
msg
=
_
(
"Log in frequently and try again later"
)
logger
.
warn
(
msg
+
': '
+
username
+
':'
+
ip
)
return
Response
({
'msg'
:
msg
},
status
=
401
)
user
,
msg
=
self
.
check_user_valid
(
request
)
if
not
user
:
username
=
request
.
data
.
get
(
'username'
,
''
)
exist
=
User
.
objects
.
filter
(
username
=
username
)
.
first
()
reason
=
LoginLog
.
REASON_PASSWORD
if
exist
else
LoginLog
.
REASON_NOT_EXIST
self
.
send_auth_signal
(
success
=
False
,
username
=
username
,
reason
=
reason
)
increase_login_failed_count
(
username
,
ip
)
return
Response
({
'msg'
:
msg
},
status
=
401
)
if
user
.
password_has_expired
:
self
.
send_auth_signal
(
success
=
False
,
username
=
username
,
reason
=
LoginLog
.
REASON_PASSWORD_EXPIRED
)
msg
=
_
(
"The user {} password has expired, please update."
.
format
(
user
.
username
))
logger
.
info
(
msg
)
return
Response
({
'msg'
:
msg
},
status
=
401
)
if
not
user
.
otp_enabled
:
self
.
send_auth_signal
(
success
=
True
,
user
=
user
)
# 登陆成功,清除原来的缓存计数
clean_failed_count
(
username
,
ip
)
token
=
user
.
create_bearer_token
(
request
)
return
Response
(
{
'token'
:
token
,
'user'
:
self
.
serializer_class
(
user
)
.
data
}
)
seed
=
uuid
.
uuid4
()
.
hex
cache
.
set
(
seed
,
user
,
300
)
return
Response
(
{
'code'
:
101
,
'msg'
:
_
(
'Please carry seed value and '
'conduct MFA secondary certification'
),
'otp_url'
:
reverse
(
'api-auth:user-otp-auth'
),
'seed'
:
seed
,
'user'
:
self
.
serializer_class
(
user
)
.
data
},
status
=
300
)
@staticmethod
def
check_user_valid
(
request
):
username
=
request
.
data
.
get
(
'username'
,
''
)
password
=
request
.
data
.
get
(
'password'
,
''
)
public_key
=
request
.
data
.
get
(
'public_key'
,
''
)
user
,
msg
=
check_user_valid
(
username
=
username
,
password
=
password
,
public_key
=
public_key
)
return
user
,
msg
def
send_auth_signal
(
self
,
success
=
True
,
user
=
None
,
username
=
''
,
reason
=
''
):
if
success
:
post_auth_success
.
send
(
sender
=
self
.
__class__
,
user
=
user
,
request
=
self
.
request
)
else
:
post_auth_failed
.
send
(
sender
=
self
.
__class__
,
username
=
username
,
request
=
self
.
request
,
reason
=
reason
)
class
UserConnectionTokenApi
(
RootOrgViewMixin
,
APIView
):
permission_classes
=
(
IsOrgAdminOrAppUser
,)
def
post
(
self
,
request
):
user_id
=
request
.
data
.
get
(
'user'
,
''
)
asset_id
=
request
.
data
.
get
(
'asset'
,
''
)
system_user_id
=
request
.
data
.
get
(
'system_user'
,
''
)
token
=
str
(
uuid
.
uuid4
())
user
=
get_object_or_404
(
User
,
id
=
user_id
)
asset
=
get_object_or_404
(
Asset
,
id
=
asset_id
)
system_user
=
get_object_or_404
(
SystemUser
,
id
=
system_user_id
)
value
=
{
'user'
:
user_id
,
'username'
:
user
.
username
,
'asset'
:
asset_id
,
'hostname'
:
asset
.
hostname
,
'system_user'
:
system_user_id
,
'system_user_name'
:
system_user
.
name
}
cache
.
set
(
token
,
value
,
timeout
=
20
)
return
Response
({
"token"
:
token
},
status
=
201
)
def
get
(
self
,
request
):
token
=
request
.
query_params
.
get
(
'token'
)
user_only
=
request
.
query_params
.
get
(
'user-only'
,
None
)
value
=
cache
.
get
(
token
,
None
)
if
not
value
:
return
Response
(
''
,
status
=
404
)
if
not
user_only
:
return
Response
(
value
)
else
:
return
Response
({
'user'
:
value
[
'user'
]})
def
get_permissions
(
self
):
if
self
.
request
.
query_params
.
get
(
'user-only'
,
None
):
self
.
permission_classes
=
(
AllowAny
,)
return
super
()
.
get_permissions
()
class
UserToken
(
APIView
):
permission_classes
=
(
AllowAny
,)
def
post
(
self
,
request
):
if
not
request
.
user
.
is_authenticated
:
username
=
request
.
data
.
get
(
'username'
,
''
)
email
=
request
.
data
.
get
(
'email'
,
''
)
password
=
request
.
data
.
get
(
'password'
,
''
)
public_key
=
request
.
data
.
get
(
'public_key'
,
''
)
user
,
msg
=
check_user_valid
(
username
=
username
,
email
=
email
,
password
=
password
,
public_key
=
public_key
)
else
:
user
=
request
.
user
msg
=
None
if
user
:
token
=
user
.
create_bearer_token
(
request
)
return
Response
({
'Token'
:
token
,
'Keyword'
:
'Bearer'
},
status
=
200
)
else
:
return
Response
({
'error'
:
msg
},
status
=
406
)
class
UserOtpAuthApi
(
RootOrgViewMixin
,
APIView
):
permission_classes
=
(
AllowAny
,)
serializer_class
=
UserSerializer
def
post
(
self
,
request
):
otp_code
=
request
.
data
.
get
(
'otp_code'
,
''
)
seed
=
request
.
data
.
get
(
'seed'
,
''
)
user
=
cache
.
get
(
seed
,
None
)
if
not
user
:
return
Response
(
{
'msg'
:
_
(
'Please verify the user name and password first'
)},
status
=
401
)
if
not
check_otp_code
(
user
.
otp_secret_key
,
otp_code
):
self
.
send_auth_signal
(
success
=
False
,
username
=
user
.
username
,
reason
=
LoginLog
.
REASON_MFA
)
return
Response
({
'msg'
:
_
(
'MFA certification failed'
)},
status
=
401
)
self
.
send_auth_signal
(
success
=
True
,
user
=
user
)
token
=
user
.
create_bearer_token
(
request
)
data
=
{
'token'
:
token
,
'user'
:
self
.
serializer_class
(
user
)
.
data
}
return
Response
(
data
)
def
send_auth_signal
(
self
,
success
=
True
,
user
=
None
,
username
=
''
,
reason
=
''
):
if
success
:
post_auth_success
.
send
(
sender
=
self
.
__class__
,
user
=
user
,
request
=
self
.
request
)
else
:
post_auth_failed
.
send
(
sender
=
self
.
__class__
,
username
=
username
,
request
=
self
.
request
,
reason
=
reason
)
apps/
users
/authentication.py
→
apps/
authentication
/authentication.py
View file @
6700dc96
...
...
@@ -14,7 +14,7 @@ from rest_framework import authentication, exceptions
from
rest_framework.authentication
import
CSRFCheck
from
common.utils
import
get_object_or_none
,
make_signature
,
http_to_unixtime
from
.models
import
User
,
AccessKey
,
PrivateToken
from
users
.models
import
User
,
AccessKey
,
PrivateToken
def
get_request_date_header
(
request
):
...
...
apps/authentication/urls/api_urls.py
View file @
6700dc96
# coding:utf-8
#
from
__future__
import
absolute_import
from
django.urls
import
path
from
..
import
api
app_name
=
'authentication'
urlpatterns
=
[
# path('token/', api.UserToken.as_view(), name='user-token'),
path
(
'auth/'
,
api
.
UserAuthApi
.
as_view
(),
name
=
'user-auth'
),
path
(
'connection-token/'
,
api
.
UserConnectionTokenApi
.
as_view
(),
name
=
'connection-token'
),
path
(
'otp/auth/'
,
api
.
UserOtpAuthApi
.
as_view
(),
name
=
'user-otp-auth'
),
]
apps/authentication/urls/view_urls.py
View file @
6700dc96
...
...
@@ -2,6 +2,7 @@
#
from
django.urls
import
path
from
..
import
views
app_name
=
'authentication'
...
...
@@ -9,6 +10,11 @@ app_name = 'authentication'
urlpatterns
=
[
# openid
path
(
'openid/login/'
,
views
.
OpenIDLoginView
.
as_view
(),
name
=
'openid-login'
),
path
(
'openid/login/complete/'
,
views
.
OpenIDLoginCompleteView
.
as_view
(),
name
=
'openid-login-complete'
),
path
(
'openid/login/complete/'
,
views
.
OpenIDLoginCompleteView
.
as_view
(),
name
=
'openid-login-complete'
),
# login
path
(
'login/'
,
views
.
UserLoginView
.
as_view
(),
name
=
'login'
),
path
(
'login/otp/'
,
views
.
UserLoginOtpView
.
as_view
(),
name
=
'login-otp'
),
path
(
'logout/'
,
views
.
UserLogoutView
.
as_view
(),
name
=
'logout'
),
]
apps/authentication/views/__init__.py
View file @
6700dc96
...
...
@@ -2,3 +2,4 @@
#
from
.openid
import
*
from
.login
import
*
apps/authentication/views/login.py
View file @
6700dc96
# ~*~ coding: utf-8 ~*~
#
from
__future__
import
unicode_literals
import
os
from
django.core.cache
import
cache
from
django.shortcuts
import
render
from
django.utils
import
timezone
from
django.contrib.auth
import
login
as
auth_login
,
logout
as
auth_logout
from
django.contrib.auth.mixins
import
LoginRequiredMixin
from
django.views.generic
import
ListView
from
django.core.files.storage
import
default_storage
from
django.http
import
HttpResponseRedirect
,
HttpResponse
from
django.http
import
HttpResponse
from
django.shortcuts
import
reverse
,
redirect
from
django.utils.decorators
import
method_decorator
from
django.utils.translation
import
ugettext
as
_
...
...
@@ -19,23 +15,20 @@ from django.views.decorators.debug import sensitive_post_parameters
from
django.views.generic.base
import
TemplateView
from
django.views.generic.edit
import
FormView
from
django.conf
import
settings
from
formtools.wizard.views
import
SessionWizardView
from
common.utils
import
get_
object_or_none
,
get_
request_ip
from
common.utils
import
get_request_ip
from
authentication.signals
import
post_auth_success
,
post_auth_failed
from
users.models
import
User
,
LoginLog
from
users.utils
import
send_reset_password_mail
,
check_otp_code
,
\
redirect_user_first_login_or_index
,
get_user_or_tmp_user
,
\
set_tmp_user_to_cache
,
get_password_check_rules
,
check_password_rules
,
\
is_block_login
,
increase_login_failed_count
,
clean_failed_count
from
users
import
forms
from
users.models
import
User
,
LoginLog
from
users.utils
import
(
check_otp_code
,
is_block_login
,
clean_failed_count
,
get_user_or_tmp_user
,
set_tmp_user_to_cache
,
increase_login_failed_count
,
redirect_user_first_login_or_index
,
)
__all__
=
[
'UserLoginView'
,
'UserLoginOtpView'
,
'UserLogoutView'
,
'UserForgotPasswordView'
,
'UserForgotPasswordSendmailSuccessView'
,
'UserResetPasswordView'
,
'UserResetPasswordSuccessView'
,
'UserFirstLoginView'
,
'LoginLogListView'
]
...
...
@@ -122,7 +115,7 @@ class UserLoginView(FormView):
if
user
.
otp_enabled
and
user
.
otp_secret_key
:
# 1,2,mfa_setting & T
return
reverse
(
'
users
:login-otp'
)
return
reverse
(
'
authentication
:login-otp'
)
elif
user
.
otp_enabled
and
not
user
.
otp_secret_key
:
# 1,2,mfa_setting & F
return
reverse
(
'users:user-otp-enable-authentication'
)
...
...
@@ -169,7 +162,9 @@ class UserLoginOtpView(FormView):
success
=
False
,
username
=
user
.
username
,
reason
=
LoginLog
.
REASON_MFA
)
form
.
add_error
(
'otp_code'
,
_
(
'MFA code invalid, or ntp sync server time'
))
form
.
add_error
(
'otp_code'
,
_
(
'MFA code invalid, or ntp sync server time'
)
)
return
super
()
.
form_invalid
(
form
)
def
get_success_url
(
self
):
...
...
@@ -202,7 +197,7 @@ class UserLogoutView(TemplateView):
'title'
:
_
(
'Logout success'
),
'messages'
:
_
(
'Logout success, return login page'
),
'interval'
:
1
,
'redirect_url'
:
reverse
(
'
users
:login'
),
'redirect_url'
:
reverse
(
'
authentication
:login'
),
'auto_redirect'
:
True
,
}
kwargs
.
update
(
context
)
...
...
apps/jumpserver/settings.py
View file @
6700dc96
...
...
@@ -135,7 +135,7 @@ TEMPLATES = [
# WSGI_APPLICATION = 'jumpserver.wsgi.applications'
LOGIN_REDIRECT_URL
=
reverse_lazy
(
'index'
)
LOGIN_URL
=
reverse_lazy
(
'
users
:login'
)
LOGIN_URL
=
reverse_lazy
(
'
authentication
:login'
)
SESSION_COOKIE_DOMAIN
=
CONFIG
.
SESSION_COOKIE_DOMAIN
CSRF_COOKIE_DOMAIN
=
CONFIG
.
CSRF_COOKIE_DOMAIN
...
...
@@ -343,10 +343,10 @@ REST_FRAMEWORK = {
),
'DEFAULT_AUTHENTICATION_CLASSES'
:
(
# 'rest_framework.authentication.BasicAuthentication',
'
users
.authentication.AccessKeyAuthentication'
,
'
users
.authentication.AccessTokenAuthentication'
,
'
users
.authentication.PrivateTokenAuthentication'
,
'
users
.authentication.SessionAuthentication'
,
'
authentication
.authentication.AccessKeyAuthentication'
,
'
authentication
.authentication.AccessTokenAuthentication'
,
'
authentication
.authentication.PrivateTokenAuthentication'
,
'
authentication
.authentication.SessionAuthentication'
,
),
'DEFAULT_FILTER_BACKENDS'
:
(
'django_filters.rest_framework.DjangoFilterBackend'
,
...
...
apps/jumpserver/urls.py
View file @
6700dc96
...
...
@@ -21,6 +21,7 @@ api_v1_patterns = [
path
(
'audits/v1/'
,
include
(
'audits.urls.api_urls'
,
namespace
=
'api-audits'
)),
path
(
'orgs/v1/'
,
include
(
'orgs.urls.api_urls'
,
namespace
=
'api-orgs'
)),
path
(
'settings/v1/'
,
include
(
'settings.urls.api_urls'
,
namespace
=
'api-settings'
)),
path
(
'authentication/v1/'
,
include
(
'authentication.urls.api_urls'
,
namespace
=
'api-auth'
)),
]))
]
...
...
apps/templates/_header_bar.html
View file @
6700dc96
...
...
@@ -94,10 +94,10 @@
<li><a
id=
"switch_user"
><i
class=
"fa fa-exchange"
></i><span>
{% trans 'User page' %}
</span></a></li>
{% endif %}
{% endif %}
<li><a
href=
"{% url '
users
:logout' %}"
><i
class=
"fa fa-sign-out"
></i>
{% trans 'Logout' %}
</a></li>
<li><a
href=
"{% url '
authentication
:logout' %}"
><i
class=
"fa fa-sign-out"
></i>
{% trans 'Logout' %}
</a></li>
</ul>
{% else %}
<a
href=
"{% url '
users
:login' %}"
>
<a
href=
"{% url '
authentication
:login' %}"
>
<i
class=
"fa fa-sign-in"
></i>
{% trans 'Login' %}
</a>
{% endif %}
...
...
apps/users/api/auth.py
View file @
6700dc96
# -*- coding: utf-8 -*-
#
import
uuid
from
django.core.cache
import
cache
from
django.urls
import
reverse
from
django.shortcuts
import
get_object_or_404
from
django.utils.translation
import
ugettext
as
_
from
rest_framework.permissions
import
AllowAny
from
rest_framework.response
import
Response
from
rest_framework.views
import
APIView
from
common.utils
import
get_logger
,
get_request_ip
from
common.permissions
import
IsOrgAdminOrAppUser
from
orgs.mixins
import
RootOrgViewMixin
from
authentication.signals
import
post_auth_success
,
post_auth_failed
from
..serializers
import
UserSerializer
from
..models
import
User
,
LoginLog
from
..utils
import
check_user_valid
,
check_otp_code
,
\
increase_login_failed_count
,
is_block_login
,
\
clean_failed_count
from
..hands
import
Asset
,
SystemUser
logger
=
get_logger
(
__name__
)
class
UserAuthApi
(
RootOrgViewMixin
,
APIView
):
permission_classes
=
(
AllowAny
,)
serializer_class
=
UserSerializer
def
post
(
self
,
request
):
# limit login
username
=
request
.
data
.
get
(
'username'
)
ip
=
request
.
data
.
get
(
'remote_addr'
,
None
)
ip
=
ip
or
get_request_ip
(
request
)
if
is_block_login
(
username
,
ip
):
msg
=
_
(
"Log in frequently and try again later"
)
logger
.
warn
(
msg
+
': '
+
username
+
':'
+
ip
)
return
Response
({
'msg'
:
msg
},
status
=
401
)
user
,
msg
=
self
.
check_user_valid
(
request
)
if
not
user
:
username
=
request
.
data
.
get
(
'username'
,
''
)
exist
=
User
.
objects
.
filter
(
username
=
username
)
.
first
()
reason
=
LoginLog
.
REASON_PASSWORD
if
exist
else
LoginLog
.
REASON_NOT_EXIST
self
.
send_auth_signal
(
success
=
False
,
username
=
username
,
reason
=
reason
)
increase_login_failed_count
(
username
,
ip
)
return
Response
({
'msg'
:
msg
},
status
=
401
)
if
user
.
password_has_expired
:
self
.
send_auth_signal
(
success
=
False
,
username
=
username
,
reason
=
LoginLog
.
REASON_PASSWORD_EXPIRED
)
msg
=
_
(
"The user {} password has expired, please update."
.
format
(
user
.
username
))
logger
.
info
(
msg
)
return
Response
({
'msg'
:
msg
},
status
=
401
)
if
not
user
.
otp_enabled
:
self
.
send_auth_signal
(
success
=
True
,
user
=
user
)
# 登陆成功,清除原来的缓存计数
clean_failed_count
(
username
,
ip
)
token
=
user
.
create_bearer_token
(
request
)
return
Response
(
{
'token'
:
token
,
'user'
:
self
.
serializer_class
(
user
)
.
data
}
)
seed
=
uuid
.
uuid4
()
.
hex
cache
.
set
(
seed
,
user
,
300
)
return
Response
(
{
'code'
:
101
,
'msg'
:
_
(
'Please carry seed value and '
'conduct MFA secondary certification'
),
'otp_url'
:
reverse
(
'api-users:user-otp-auth'
),
'seed'
:
seed
,
'user'
:
self
.
serializer_class
(
user
)
.
data
},
status
=
300
)
@staticmethod
def
check_user_valid
(
request
):
username
=
request
.
data
.
get
(
'username'
,
''
)
password
=
request
.
data
.
get
(
'password'
,
''
)
public_key
=
request
.
data
.
get
(
'public_key'
,
''
)
user
,
msg
=
check_user_valid
(
username
=
username
,
password
=
password
,
public_key
=
public_key
)
return
user
,
msg
def
send_auth_signal
(
self
,
success
=
True
,
user
=
None
,
username
=
''
,
reason
=
''
):
if
success
:
post_auth_success
.
send
(
sender
=
self
.
__class__
,
user
=
user
,
request
=
self
.
request
)
else
:
post_auth_failed
.
send
(
sender
=
self
.
__class__
,
username
=
username
,
request
=
self
.
request
,
reason
=
reason
)
class
UserConnectionTokenApi
(
RootOrgViewMixin
,
APIView
):
permission_classes
=
(
IsOrgAdminOrAppUser
,)
def
post
(
self
,
request
):
user_id
=
request
.
data
.
get
(
'user'
,
''
)
asset_id
=
request
.
data
.
get
(
'asset'
,
''
)
system_user_id
=
request
.
data
.
get
(
'system_user'
,
''
)
token
=
str
(
uuid
.
uuid4
())
user
=
get_object_or_404
(
User
,
id
=
user_id
)
asset
=
get_object_or_404
(
Asset
,
id
=
asset_id
)
system_user
=
get_object_or_404
(
SystemUser
,
id
=
system_user_id
)
value
=
{
'user'
:
user_id
,
'username'
:
user
.
username
,
'asset'
:
asset_id
,
'hostname'
:
asset
.
hostname
,
'system_user'
:
system_user_id
,
'system_user_name'
:
system_user
.
name
}
cache
.
set
(
token
,
value
,
timeout
=
20
)
return
Response
({
"token"
:
token
},
status
=
201
)
def
get
(
self
,
request
):
token
=
request
.
query_params
.
get
(
'token'
)
user_only
=
request
.
query_params
.
get
(
'user-only'
,
None
)
value
=
cache
.
get
(
token
,
None
)
if
not
value
:
return
Response
(
''
,
status
=
404
)
if
not
user_only
:
return
Response
(
value
)
else
:
return
Response
({
'user'
:
value
[
'user'
]})
def
get_permissions
(
self
):
if
self
.
request
.
query_params
.
get
(
'user-only'
,
None
):
self
.
permission_classes
=
(
AllowAny
,)
return
super
()
.
get_permissions
()
class
UserToken
(
APIView
):
permission_classes
=
(
AllowAny
,)
def
post
(
self
,
request
):
if
not
request
.
user
.
is_authenticated
:
username
=
request
.
data
.
get
(
'username'
,
''
)
email
=
request
.
data
.
get
(
'email'
,
''
)
password
=
request
.
data
.
get
(
'password'
,
''
)
public_key
=
request
.
data
.
get
(
'public_key'
,
''
)
user
,
msg
=
check_user_valid
(
username
=
username
,
email
=
email
,
password
=
password
,
public_key
=
public_key
)
else
:
user
=
request
.
user
msg
=
None
if
user
:
token
=
user
.
create_bearer_token
(
request
)
return
Response
({
'Token'
:
token
,
'Keyword'
:
'Bearer'
},
status
=
200
)
else
:
return
Response
({
'error'
:
msg
},
status
=
406
)
class
UserOtpAuthApi
(
RootOrgViewMixin
,
APIView
):
permission_classes
=
(
AllowAny
,)
serializer_class
=
UserSerializer
def
post
(
self
,
request
):
otp_code
=
request
.
data
.
get
(
'otp_code'
,
''
)
seed
=
request
.
data
.
get
(
'seed'
,
''
)
user
=
cache
.
get
(
seed
,
None
)
if
not
user
:
return
Response
(
{
'msg'
:
_
(
'Please verify the user name and password first'
)},
status
=
401
)
if
not
check_otp_code
(
user
.
otp_secret_key
,
otp_code
):
self
.
send_auth_signal
(
success
=
False
,
username
=
user
.
username
,
reason
=
LoginLog
.
REASON_MFA
)
return
Response
({
'msg'
:
_
(
'MFA certification failed'
)},
status
=
401
)
self
.
send_auth_signal
(
success
=
True
,
user
=
user
)
token
=
user
.
create_bearer_token
(
request
)
data
=
{
'token'
:
token
,
'user'
:
self
.
serializer_class
(
user
)
.
data
}
return
Response
(
data
)
def
send_auth_signal
(
self
,
success
=
True
,
user
=
None
,
username
=
''
,
reason
=
''
):
if
success
:
post_auth_success
.
send
(
sender
=
self
.
__class__
,
user
=
user
,
request
=
self
.
request
)
else
:
post_auth_failed
.
send
(
sender
=
self
.
__class__
,
username
=
username
,
request
=
self
.
request
,
reason
=
reason
)
apps/users/urls/api_urls.py
View file @
6700dc96
...
...
@@ -15,11 +15,7 @@ router.register(r'groups', api.UserGroupViewSet, 'user-group')
urlpatterns
=
[
# path('token/', api.UserToken.as_view(), name='user-token'),
path
(
'connection-token/'
,
api
.
UserConnectionTokenApi
.
as_view
(),
name
=
'connection-token'
),
path
(
'profile/'
,
api
.
UserProfileApi
.
as_view
(),
name
=
'user-profile'
),
path
(
'auth/'
,
api
.
UserAuthApi
.
as_view
(),
name
=
'user-auth'
),
path
(
'otp/auth/'
,
api
.
UserOtpAuthApi
.
as_view
(),
name
=
'user-otp-auth'
),
path
(
'otp/reset/'
,
api
.
UserResetOTPApi
.
as_view
(),
name
=
'my-otp-reset'
),
path
(
'users/<uuid:pk>/otp/reset/'
,
api
.
UserResetOTPApi
.
as_view
(),
name
=
'user-reset-otp'
),
path
(
'users/<uuid:pk>/password/'
,
api
.
UserChangePasswordApi
.
as_view
(),
name
=
'change-user-password'
),
...
...
apps/users/urls/views_urls.py
View file @
6700dc96
...
...
@@ -9,8 +9,6 @@ app_name = 'users'
urlpatterns
=
[
# Login view
path
(
'login/'
,
views
.
UserLoginView
.
as_view
(),
name
=
'login'
),
path
(
'logout/'
,
views
.
UserLogoutView
.
as_view
(),
name
=
'logout'
),
path
(
'login/otp/'
,
views
.
UserLoginOtpView
.
as_view
(),
name
=
'login-otp'
),
path
(
'password/forgot/'
,
views
.
UserForgotPasswordView
.
as_view
(),
name
=
'forgot-password'
),
path
(
'password/forgot/sendmail-success/'
,
views
.
UserForgotPasswordSendmailSuccessView
.
as_view
(),
name
=
'forgot-password-sendmail-success'
),
path
(
'password/reset/'
,
views
.
UserResetPasswordView
.
as_view
(),
name
=
'reset-password'
),
...
...
@@ -50,5 +48,5 @@ urlpatterns = [
# Login log
# Abandon
path
(
'login-log/'
,
views
.
LoginLogListView
.
as_view
(),
name
=
'login-log-list'
),
#
path('login-log/', views.LoginLogListView.as_view(), name='login-log-list'),
]
apps/users/utils.py
View file @
6700dc96
...
...
@@ -62,7 +62,7 @@ def send_user_created_mail(user):
'rest_password_token'
:
user
.
generate_reset_token
(),
'forget_password_url'
:
reverse
(
'users:forgot-password'
,
external
=
True
),
'email'
:
user
.
email
,
'login_url'
:
reverse
(
'
users
:login'
,
external
=
True
),
'login_url'
:
reverse
(
'
authentication
:login'
,
external
=
True
),
}
if
settings
.
DEBUG
:
try
:
...
...
@@ -98,7 +98,7 @@ def send_reset_password_mail(user):
'rest_password_token'
:
user
.
generate_reset_token
(),
'forget_password_url'
:
reverse
(
'users:forgot-password'
,
external
=
True
),
'email'
:
user
.
email
,
'login_url'
:
reverse
(
'
users
:login'
,
external
=
True
),
'login_url'
:
reverse
(
'
authentication
:login'
,
external
=
True
),
}
if
settings
.
DEBUG
:
logger
.
debug
(
message
)
...
...
@@ -136,7 +136,7 @@ def send_password_expiration_reminder_mail(user):
'update_password_url'
:
reverse
(
'users:user-password-update'
,
external
=
True
),
'forget_password_url'
:
reverse
(
'users:forgot-password'
,
external
=
True
),
'email'
:
user
.
email
,
'login_url'
:
reverse
(
'
users
:login'
,
external
=
True
),
'login_url'
:
reverse
(
'
authentication
:login'
,
external
=
True
),
}
if
settings
.
DEBUG
:
logger
.
debug
(
message
)
...
...
@@ -158,7 +158,7 @@ def send_reset_ssh_key_mail(user):
</br>
"""
)
%
{
'name'
:
user
.
name
,
'login_url'
:
reverse
(
'
users
:login'
,
external
=
True
),
'login_url'
:
reverse
(
'
authentication
:login'
,
external
=
True
),
}
if
settings
.
DEBUG
:
logger
.
debug
(
message
)
...
...
apps/users/views/login.py
View file @
6700dc96
...
...
@@ -24,7 +24,7 @@ from .. import forms
__all__
=
[
'UserLoginView'
,
'UserForgotPasswordSendmailSuccessView'
,
'UserResetPasswordSuccessView'
,
'UserResetPasswordSuccessView'
,
'UserResetPasswordView'
,
'UserForgotPasswordView'
,
'UserResetPasswordView'
,
'UserForgotPasswordView'
,
'UserFirstLoginView'
,
]
...
...
@@ -58,7 +58,7 @@ class UserForgotPasswordSendmailSuccessView(TemplateView):
'title'
:
_
(
'Send reset password message'
),
'messages'
:
_
(
'Send reset password mail success, '
'login your mail box and follow it '
),
'redirect_url'
:
reverse
(
'
users
:login'
),
'redirect_url'
:
reverse
(
'
authentication
:login'
),
}
kwargs
.
update
(
context
)
return
super
()
.
get_context_data
(
**
kwargs
)
...
...
@@ -71,7 +71,7 @@ class UserResetPasswordSuccessView(TemplateView):
context
=
{
'title'
:
_
(
'Reset password success'
),
'messages'
:
_
(
'Reset password success, return to login page'
),
'redirect_url'
:
reverse
(
'
users
:login'
),
'redirect_url'
:
reverse
(
'
authentication
:login'
),
'auto_redirect'
:
True
,
}
kwargs
.
update
(
context
)
...
...
apps/users/views/user.py
View file @
6700dc96
...
...
@@ -574,7 +574,7 @@ class UserOtpSettingsSuccessView(TemplateView):
'title'
:
title
,
'messages'
:
describe
,
'interval'
:
1
,
'redirect_url'
:
reverse
(
'
users
:login'
),
'redirect_url'
:
reverse
(
'
authentication
:login'
),
'auto_redirect'
:
True
,
}
kwargs
.
update
(
context
)
...
...
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