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
12c8cf6b
Commit
12c8cf6b
authored
Apr 19, 2018
by
BaiJiangjie
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[Update] 添加OTP认证功能
parent
33bc73ab
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
130 additions
and
66 deletions
+130
-66
django.mo
apps/i18n/zh/LC_MESSAGES/django.mo
+0
-0
django.po
apps/i18n/zh/LC_MESSAGES/django.po
+0
-0
api.py
apps/users/api.py
+59
-23
user.py
apps/users/models/user.py
+1
-1
serializers.py
apps/users/serializers.py
+1
-1
_base_otp.html
apps/users/templates/users/_base_otp.html
+1
-1
login_otp.html
apps/users/templates/users/login_otp.html
+1
-1
user_otp_enable_bind.html
apps/users/templates/users/user_otp_enable_bind.html
+3
-4
user_password_authentication.html
apps/users/templates/users/user_password_authentication.html
+3
-3
user_profile.html
apps/users/templates/users/user_profile.html
+1
-2
api_urls.py
apps/users/urls/api_urls.py
+1
-0
utils.py
apps/users/utils.py
+14
-10
login.py
apps/users/views/login.py
+6
-5
user.py
apps/users/views/user.py
+38
-15
requirements.txt
requirements/requirements.txt
+1
-0
No files found.
apps/i18n/zh/LC_MESSAGES/django.mo
View file @
12c8cf6b
No preview for this file type
apps/i18n/zh/LC_MESSAGES/django.po
View file @
12c8cf6b
This diff is collapsed.
Click to expand it.
apps/users/api.py
View file @
12c8cf6b
...
@@ -2,6 +2,7 @@
...
@@ -2,6 +2,7 @@
import
uuid
import
uuid
from
django.core.cache
import
cache
from
django.core.cache
import
cache
from
django.urls
import
reverse
from
rest_framework
import
generics
from
rest_framework
import
generics
from
rest_framework.permissions
import
AllowAny
,
IsAuthenticated
from
rest_framework.permissions
import
AllowAny
,
IsAuthenticated
...
@@ -139,40 +140,75 @@ class UserProfile(APIView):
...
@@ -139,40 +140,75 @@ class UserProfile(APIView):
return
Response
(
self
.
serializer_class
(
request
.
user
)
.
data
)
return
Response
(
self
.
serializer_class
(
request
.
user
)
.
data
)
class
UserAuthApi
(
APIView
):
class
User
Otp
AuthApi
(
APIView
):
permission_classes
=
(
AllowAny
,)
permission_classes
=
(
AllowAny
,)
serializer_class
=
UserSerializer
serializer_class
=
UserSerializer
def
post
(
self
,
request
):
def
post
(
self
,
request
):
otp_check
=
request
.
data
.
get
(
'otp_check'
,
None
)
otp_code
=
request
.
data
.
get
(
'otp_code'
,
''
)
seed
=
request
.
data
.
get
(
'seed'
,
''
)
user
=
cache
.
get
(
seed
,
None
)
if
not
user
:
return
Response
({
'msg'
:
'请先进行用户名和密码验证'
},
status
=
401
)
if
not
check_otp_code
(
user
.
otp_secret_key
,
otp_code
):
return
Response
({
'msg'
:
'otp认证失败'
},
status
=
401
)
token
=
generate_token
(
request
,
user
)
self
.
write_login_log
(
request
,
user
)
return
Response
(
{
'token'
:
token
,
'user'
:
self
.
serializer_class
(
user
)
.
data
}
)
if
otp_check
:
@staticmethod
# otp验证
def
write_login_log
(
request
,
user
):
return
self
.
check_auth_otp
(
request
)
login_ip
=
request
.
data
.
get
(
'remote_addr'
,
None
)
else
:
login_type
=
request
.
data
.
get
(
'login_type'
,
''
)
# password验证
user_agent
=
request
.
data
.
get
(
'HTTP_USER_AGENT'
,
''
)
return
self
.
check_auth_password
(
request
)
if
not
login_ip
:
login_ip
=
get_login_ip
(
request
)
def
check_auth_password
(
self
,
request
):
write_login_log_async
.
delay
(
user
.
username
,
ip
=
login_ip
,
type
=
login_type
,
user_agent
=
user_agent
,
)
class
UserAuthApi
(
APIView
):
permission_classes
=
(
AllowAny
,)
serializer_class
=
UserSerializer
def
post
(
self
,
request
):
user
,
msg
=
self
.
check_user_valid
(
request
)
user
,
msg
=
self
.
check_user_valid
(
request
)
if
user
:
if
not
user
:
token
=
generate_token
(
request
,
user
)
if
not
user
.
otp_enabled
:
self
.
write_login_log
(
request
,
user
)
return
Response
({
'token'
:
token
,
'user'
:
self
.
serializer_class
(
user
)
.
data
})
else
:
return
Response
({
'msg'
:
msg
},
status
=
401
)
return
Response
({
'msg'
:
msg
},
status
=
401
)
def
check_auth_otp
(
self
,
request
):
if
not
user
.
otp_enabled
:
otp_code
=
request
.
data
.
get
(
'otp_code'
,
''
)
user
,
msg
=
self
.
check_user_valid
(
request
)
if
user
:
token
=
generate_token
(
request
,
user
)
token
=
generate_token
(
request
,
user
)
if
check_otp_code
(
user
.
otp_secret_key
,
otp_code
):
self
.
write_login_log
(
request
,
user
)
self
.
write_login_log
(
request
,
user
)
return
Response
(
return
Response
({
'token'
:
token
,
'user'
:
self
.
serializer_class
(
user
)
.
data
})
{
return
Response
({
'msg'
:
msg
},
status
=
401
)
'token'
:
token
,
'user'
:
self
.
serializer_class
(
user
)
.
data
}
)
seed
=
uuid
.
uuid4
()
.
hex
cache
.
set
(
seed
,
user
,
300
)
return
Response
(
{
'code'
:
101
,
'msg'
:
'请携带seed值,进行OTP二次认证'
,
'otp_url'
:
reverse
(
'api-users:user-otp-auth'
),
'seed'
:
seed
,
'user'
:
self
.
serializer_class
(
user
)
.
data
},
status
=
300
)
@staticmethod
@staticmethod
def
check_user_valid
(
request
):
def
check_user_valid
(
request
):
...
...
apps/users/models/user.py
View file @
12c8cf6b
...
@@ -232,7 +232,7 @@ class User(AbstractUser):
...
@@ -232,7 +232,7 @@ class User(AbstractUser):
def
disable_otp
(
self
):
def
disable_otp
(
self
):
self
.
otp_level
=
0
self
.
otp_level
=
0
self
.
otp_secret_key
=
''
self
.
otp_secret_key
=
None
def
to_json
(
self
):
def
to_json
(
self
):
return
OrderedDict
({
return
OrderedDict
({
...
...
apps/users/serializers.py
View file @
12c8cf6b
...
@@ -21,7 +21,7 @@ class UserSerializer(BulkSerializerMixin, serializers.ModelSerializer):
...
@@ -21,7 +21,7 @@ class UserSerializer(BulkSerializerMixin, serializers.ModelSerializer):
list_serializer_class
=
BulkListSerializer
list_serializer_class
=
BulkListSerializer
exclude
=
[
exclude
=
[
'first_name'
,
'last_name'
,
'password'
,
'_private_key'
,
'first_name'
,
'last_name'
,
'password'
,
'_private_key'
,
'_public_key'
,
'otp_secret_key'
,
'user_permissions'
'_public_key'
,
'
_
otp_secret_key'
,
'user_permissions'
]
]
def
get_field_names
(
self
,
declared_fields
,
info
):
def
get_field_names
(
self
,
declared_fields
,
info
):
...
...
apps/users/templates/users/_base_otp.html
View file @
12c8cf6b
...
@@ -25,7 +25,7 @@
...
@@ -25,7 +25,7 @@
<div>
<div>
<a
href=
"{% url 'index' %}"
>
首页
</a>
<a
href=
"{% url 'index' %}"
>
首页
</a>
<b>
丨
</b>
<b>
丨
</b>
<a
href=
"
#"
>
帮助中心
</a>
<a
href=
"
http://docs.jumpserver.org/zh/docs/"
>
文档
</a>
<b>
丨
</b>
<b>
丨
</b>
<a
href=
"https://www.github.com/jumpserver/"
>
GitHub
</a>
<a
href=
"https://www.github.com/jumpserver/"
>
GitHub
</a>
</div>
</div>
...
...
apps/users/templates/users/login_otp.html
View file @
12c8cf6b
...
@@ -66,7 +66,7 @@
...
@@ -66,7 +66,7 @@
<button
type=
"submit"
class=
"btn btn-primary block full-width m-b"
>
{% trans 'Next' %}
</button>
<button
type=
"submit"
class=
"btn btn-primary block full-width m-b"
>
{% trans 'Next' %}
</button>
<a
href=
"#"
>
<a
href=
"#"
>
<small>
{% trans "Can't provide
security
? Please contact the administrator" %}
</small>
<small>
{% trans "Can't provide
otp code
? Please contact the administrator" %}
</small>
</a>
</a>
</form>
</form>
...
...
apps/users/templates/users/user_otp_enable_bind.html
View file @
12c8cf6b
...
@@ -7,10 +7,8 @@
...
@@ -7,10 +7,8 @@
<div
class=
"verify"
>
<div
class=
"verify"
>
<p
style=
"margin:20px auto;"
><strong
style=
"color: #000000"
>
使用手机 Google Authenticator 应用扫描以下二维码,获取6位验证码
</strong></p>
<p
style=
"margin:20px auto;"
><strong
style=
"color: #000000"
>
使用手机 Google Authenticator 应用扫描以下二维码,获取6位验证码
</strong></p>
<div
id=
"qr_code"
></div>
<div
id=
"qr_code"
></div>
<form
class=
""
role=
"form"
method=
"post"
action=
""
>
<form
class=
""
role=
"form"
method=
"post"
action=
""
>
{% csrf_token %}
{% csrf_token %}
...
@@ -18,12 +16,13 @@
...
@@ -18,12 +16,13 @@
<input
type=
"text"
class=
""
name=
"otp_code"
placeholder=
"{% trans 'Six figures' %}"
required=
""
>
<input
type=
"text"
class=
""
name=
"otp_code"
placeholder=
"{% trans 'Six figures' %}"
required=
""
>
</div>
</div>
<button
type=
"submit"
class=
"next"
>
{% trans 'Next' %}
</button>
{% if 'otp_code' in form.errors %}
{% if 'otp_code' in form.errors %}
<p
style=
"color: #ed5565"
>
{{ form.otp_code.errors.as_text }}
</p>
<p
style=
"color: #ed5565"
>
{{ form.otp_code.errors.as_text }}
</p>
{% endif %}
{% endif %}
<button
type=
"submit"
class=
"next"
>
{% trans 'Next' %}
</button>
</form>
</form>
</div>
</div>
...
...
apps/users/templates/users/user_password_authentication.html
View file @
12c8cf6b
...
@@ -5,6 +5,7 @@
...
@@ -5,6 +5,7 @@
{% block content %}
{% block content %}
<form
class=
""
role=
"form"
method=
"post"
action=
""
>
<form
class=
""
role=
"form"
method=
"post"
action=
""
>
{% csrf_token %}
{% csrf_token %}
<div
class=
"form-input"
>
<div
class=
"form-input"
>
<input
type=
"text"
class=
""
name=
"{{ form.username.html_name }}"
value=
"{{ form.username.value }}"
readonly=
"readonly"
required=
""
>
<input
type=
"text"
class=
""
name=
"{{ form.username.html_name }}"
value=
"{{ form.username.value }}"
readonly=
"readonly"
required=
""
>
</div>
</div>
...
@@ -13,13 +14,12 @@
...
@@ -13,13 +14,12 @@
<input
type=
"password"
class=
""
name=
"{{ form.password.html_name }}"
placeholder=
"{% trans 'Password' %}"
required=
""
>
<input
type=
"password"
class=
""
name=
"{{ form.password.html_name }}"
placeholder=
"{% trans 'Password' %}"
required=
""
>
</div>
</div>
<button
type=
"submit"
class=
"next"
>
{% trans 'Next' %}
</button>
{% if 'password' in form.errors %}
{% if 'password' in form.errors %}
<p
class=
"red-fonts"
>
{{ form.password.errors.as_text }}
</p>
<p
class=
"red-fonts"
>
{{ form.password.errors.as_text }}
</p>
{% endif %}
{% endif %}
<button
type=
"submit"
class=
"next"
>
{% trans 'Next' %}
</button>
</form>
</form>
{% endblock %}
{% endblock %}
apps/users/templates/users/user_profile.html
View file @
12c8cf6b
...
@@ -152,8 +152,7 @@
...
@@ -152,8 +152,7 @@
href=
"
href=
"
{% if request.user.otp_enabled and request.user.otp_secret_key %}
{% if request.user.otp_enabled and request.user.otp_secret_key %}
{% if request.user.otp_force_enabled %}
{% if request.user.otp_force_enabled %}
javascript:void(0)
"
disabled
>
{% trans 'Disable' %}
"
><span
style=
"color:#ed5565"
>
{% trans 'Disable' %}
</span>
{% else %}
{% else %}
{% url 'users:user-otp-disable-authentication' %}
{% url 'users:user-otp-disable-authentication' %}
">{% trans 'Disable' %}
">{% trans 'Disable' %}
...
...
apps/users/urls/api_urls.py
View file @
12c8cf6b
...
@@ -20,6 +20,7 @@ urlpatterns = [
...
@@ -20,6 +20,7 @@ urlpatterns = [
url
(
r'^v1/connection-token/$'
,
api
.
UserConnectionTokenApi
.
as_view
(),
name
=
'connection-token'
),
url
(
r'^v1/connection-token/$'
,
api
.
UserConnectionTokenApi
.
as_view
(),
name
=
'connection-token'
),
url
(
r'^v1/profile/$'
,
api
.
UserProfile
.
as_view
(),
name
=
'user-profile'
),
url
(
r'^v1/profile/$'
,
api
.
UserProfile
.
as_view
(),
name
=
'user-profile'
),
url
(
r'^v1/auth/$'
,
api
.
UserAuthApi
.
as_view
(),
name
=
'user-auth'
),
url
(
r'^v1/auth/$'
,
api
.
UserAuthApi
.
as_view
(),
name
=
'user-auth'
),
url
(
r'^v1/otp/auth/$'
,
api
.
UserOtpAuthApi
.
as_view
(),
name
=
'user-otp-auth'
),
url
(
r'^v1/users/(?P<pk>[0-9a-zA-Z\-]{36})/password/$'
,
url
(
r'^v1/users/(?P<pk>[0-9a-zA-Z\-]{36})/password/$'
,
api
.
ChangeUserPasswordApi
.
as_view
(),
name
=
'change-user-password'
),
api
.
ChangeUserPasswordApi
.
as_view
(),
name
=
'change-user-password'
),
url
(
r'^v1/users/(?P<pk>[0-9a-zA-Z\-]{36})/password/reset/$'
,
url
(
r'^v1/users/(?P<pk>[0-9a-zA-Z\-]{36})/password/reset/$'
,
...
...
apps/users/utils.py
View file @
12c8cf6b
...
@@ -224,16 +224,14 @@ def get_ip_city(ip, timeout=10):
...
@@ -224,16 +224,14 @@ def get_ip_city(ip, timeout=10):
return
city
return
city
def
get_user
(
request
):
def
get_tmp_user_from_session
(
request
):
if
is_login
(
request
):
user_id
=
request
.
session
.
get
(
'tmp_user_id'
)
user
=
request
.
user
user
=
get_object_or_none
(
User
,
pk
=
user_id
)
else
:
user
=
cache
.
get
(
request
.
session
.
session_key
)
return
user
return
user
def
is_login
(
request
):
def
set_tmp_user_to_session
(
request
,
user
):
re
turn
isinstance
(
request
.
user
,
User
)
re
quest
.
session
[
'tmp_user_id'
]
=
str
(
user
.
id
)
def
redirect_user_first_login_or_index
(
request
,
redirect_field_name
):
def
redirect_user_first_login_or_index
(
request
,
redirect_field_name
):
...
@@ -244,9 +242,15 @@ def redirect_user_first_login_or_index(request, redirect_field_name):
...
@@ -244,9 +242,15 @@ def redirect_user_first_login_or_index(request, redirect_field_name):
request
.
GET
.
get
(
redirect_field_name
,
reverse
(
'index'
)))
request
.
GET
.
get
(
redirect_field_name
,
reverse
(
'index'
)))
def
generate_otp_uri
(
user
,
issuer
=
"Jumpserver"
):
def
generate_otp_uri
(
request
,
issuer
=
"Jumpserver"
):
otp_secret_key
=
base64
.
b32encode
(
os
.
urandom
(
10
))
.
decode
(
'utf-8'
)
if
request
.
user
.
is_authenticated
:
cache
.
set
(
'otp_secret_key'
,
otp_secret_key
,
300
)
user
=
request
.
user
else
:
user
=
get_tmp_user_from_session
(
request
)
otp_secret_key
=
cache
.
get
(
request
.
session
.
session_key
+
'otp_key'
,
''
)
if
not
otp_secret_key
:
otp_secret_key
=
base64
.
b32encode
(
os
.
urandom
(
10
))
.
decode
(
'utf-8'
)
cache
.
set
(
request
.
session
.
session_key
+
'otp_key'
,
otp_secret_key
,
600
)
totp
=
pyotp
.
TOTP
(
otp_secret_key
)
totp
=
pyotp
.
TOTP
(
otp_secret_key
)
return
totp
.
provisioning_uri
(
name
=
user
.
username
,
issuer_name
=
issuer
)
return
totp
.
provisioning_uri
(
name
=
user
.
username
,
issuer_name
=
issuer
)
...
...
apps/users/views/login.py
View file @
12c8cf6b
...
@@ -19,12 +19,12 @@ from django.views.generic.base import TemplateView
...
@@ -19,12 +19,12 @@ from django.views.generic.base import TemplateView
from
django.views.generic.edit
import
FormView
from
django.views.generic.edit
import
FormView
from
formtools.wizard.views
import
SessionWizardView
from
formtools.wizard.views
import
SessionWizardView
from
django.conf
import
settings
from
django.conf
import
settings
from
django.core.cache
import
cache
from
common.utils
import
get_object_or_none
from
common.utils
import
get_object_or_none
from
common.mixins
import
DatetimeSearchMixin
,
AdminUserRequiredMixin
from
common.mixins
import
DatetimeSearchMixin
,
AdminUserRequiredMixin
from
..models
import
User
,
LoginLog
from
..models
import
User
,
LoginLog
from
..utils
import
send_reset_password_mail
,
check_otp_code
,
get_login_ip
,
redirect_user_first_login_or_index
from
..utils
import
send_reset_password_mail
,
check_otp_code
,
get_login_ip
,
redirect_user_first_login_or_index
,
\
get_tmp_user_from_session
,
set_tmp_user_to_session
from
..tasks
import
write_login_log_async
from
..tasks
import
write_login_log_async
from
..
import
forms
from
..
import
forms
...
@@ -54,11 +54,12 @@ class UserLoginView(FormView):
...
@@ -54,11 +54,12 @@ class UserLoginView(FormView):
def
form_valid
(
self
,
form
):
def
form_valid
(
self
,
form
):
if
not
self
.
request
.
session
.
test_cookie_worked
():
if
not
self
.
request
.
session
.
test_cookie_worked
():
return
HttpResponse
(
_
(
"Please enable cookies and try again."
))
return
HttpResponse
(
_
(
"Please enable cookies and try again."
))
cache
.
set
(
self
.
request
.
session
.
session_key
,
form
.
get_user
(),
600
)
set_tmp_user_to_session
(
self
.
request
,
form
.
get_user
())
return
redirect
(
self
.
get_success_url
())
return
redirect
(
self
.
get_success_url
())
def
get_success_url
(
self
):
def
get_success_url
(
self
):
user
=
cache
.
get
(
self
.
request
.
session
.
session_key
)
user
=
get_tmp_user_from_session
(
self
.
request
)
if
user
.
otp_enabled
and
user
.
otp_secret_key
:
if
user
.
otp_enabled
and
user
.
otp_secret_key
:
# 1,2 & T
# 1,2 & T
...
@@ -94,7 +95,7 @@ class UserLoginOtpView(FormView):
...
@@ -94,7 +95,7 @@ class UserLoginOtpView(FormView):
redirect_field_name
=
'next'
redirect_field_name
=
'next'
def
form_valid
(
self
,
form
):
def
form_valid
(
self
,
form
):
user
=
cache
.
get
(
self
.
request
.
session
.
session_key
)
user
=
get_tmp_user_from_session
(
self
.
request
)
otp_code
=
form
.
cleaned_data
.
get
(
'otp_code'
)
otp_code
=
form
.
cleaned_data
.
get
(
'otp_code'
)
otp_secret_key
=
user
.
otp_secret_key
otp_secret_key
=
user
.
otp_secret_key
...
...
apps/users/views/user.py
View file @
12c8cf6b
...
@@ -35,7 +35,7 @@ from common.mixins import JSONResponseMixin
...
@@ -35,7 +35,7 @@ from common.mixins import JSONResponseMixin
from
common.utils
import
get_logger
,
get_object_or_none
,
is_uuid
,
ssh_key_gen
from
common.utils
import
get_logger
,
get_object_or_none
,
is_uuid
,
ssh_key_gen
from
..
import
forms
from
..
import
forms
from
..models
import
User
,
UserGroup
from
..models
import
User
,
UserGroup
from
..utils
import
AdminUserRequiredMixin
,
generate_otp_uri
,
check_otp_code
,
get_
user
,
is_logi
n
from
..utils
import
AdminUserRequiredMixin
,
generate_otp_uri
,
check_otp_code
,
get_
tmp_user_from_sessio
n
from
..signals
import
post_user_create
from
..signals
import
post_user_create
from
..tasks
import
write_login_log_async
from
..tasks
import
write_login_log_async
...
@@ -400,20 +400,31 @@ class UserOtpEnableAuthenticationView(FormView):
...
@@ -400,20 +400,31 @@ class UserOtpEnableAuthenticationView(FormView):
form_class
=
forms
.
UserCheckPasswordForm
form_class
=
forms
.
UserCheckPasswordForm
def
get_form
(
self
,
form_class
=
None
):
def
get_form
(
self
,
form_class
=
None
):
if
self
.
request
.
user
.
is_authenticated
:
user
=
self
.
request
.
user
else
:
user
=
get_tmp_user_from_session
(
self
.
request
)
form
=
super
()
.
get_form
(
form_class
=
form_class
)
form
=
super
()
.
get_form
(
form_class
=
form_class
)
form
[
'username'
]
.
initial
=
get_user
(
self
.
request
)
.
username
form
[
'username'
]
.
initial
=
user
.
username
return
form
return
form
def
get_context_data
(
self
,
**
kwargs
):
def
get_context_data
(
self
,
**
kwargs
):
if
self
.
request
.
user
.
is_authenticated
:
user
=
self
.
request
.
user
else
:
user
=
get_tmp_user_from_session
(
self
.
request
)
context
=
{
context
=
{
'user'
:
get_user
(
self
.
request
)
'user'
:
user
}
}
kwargs
.
update
(
context
)
kwargs
.
update
(
context
)
return
super
()
.
get_context_data
(
**
kwargs
)
return
super
()
.
get_context_data
(
**
kwargs
)
def
form_valid
(
self
,
form
):
def
form_valid
(
self
,
form
):
if
self
.
request
.
user
.
is_authenticated
:
user
=
self
.
request
.
user
else
:
user
=
get_tmp_user_from_session
(
self
.
request
)
password
=
form
.
cleaned_data
.
get
(
'password'
)
password
=
form
.
cleaned_data
.
get
(
'password'
)
user
=
get_user
(
self
.
request
)
user
=
authenticate
(
username
=
user
.
username
,
password
=
password
)
user
=
authenticate
(
username
=
user
.
username
,
password
=
password
)
if
not
user
:
if
not
user
:
form
.
add_error
(
"password"
,
_
(
"Password invalid"
))
form
.
add_error
(
"password"
,
_
(
"Password invalid"
))
...
@@ -428,8 +439,12 @@ class UserOtpEnableInstallAppView(TemplateView):
...
@@ -428,8 +439,12 @@ class UserOtpEnableInstallAppView(TemplateView):
template_name
=
'users/user_otp_enable_install_app.html'
template_name
=
'users/user_otp_enable_install_app.html'
def
get_context_data
(
self
,
**
kwargs
):
def
get_context_data
(
self
,
**
kwargs
):
if
self
.
request
.
user
.
is_authenticated
:
user
=
self
.
request
.
user
else
:
user
=
get_tmp_user_from_session
(
self
.
request
)
context
=
{
context
=
{
'user'
:
get_user
(
self
.
request
)
'user'
:
user
}
}
kwargs
.
update
(
context
)
kwargs
.
update
(
context
)
return
super
()
.
get_context_data
(
**
kwargs
)
return
super
()
.
get_context_data
(
**
kwargs
)
...
@@ -441,16 +456,20 @@ class UserOtpEnableBindView(TemplateView, FormView):
...
@@ -441,16 +456,20 @@ class UserOtpEnableBindView(TemplateView, FormView):
success_url
=
reverse_lazy
(
'users:user-otp-settings-success'
)
success_url
=
reverse_lazy
(
'users:user-otp-settings-success'
)
def
get_context_data
(
self
,
**
kwargs
):
def
get_context_data
(
self
,
**
kwargs
):
if
self
.
request
.
user
.
is_authenticated
:
user
=
self
.
request
.
user
else
:
user
=
get_tmp_user_from_session
(
self
.
request
)
context
=
{
context
=
{
'otp_uri'
:
generate_otp_uri
(
user
=
get_user
(
self
.
request
)
),
'otp_uri'
:
generate_otp_uri
(
self
.
request
),
'user'
:
get_user
(
self
.
request
)
'user'
:
user
}
}
kwargs
.
update
(
context
)
kwargs
.
update
(
context
)
return
super
()
.
get_context_data
(
**
kwargs
)
return
super
()
.
get_context_data
(
**
kwargs
)
def
form_valid
(
self
,
form
):
def
form_valid
(
self
,
form
):
otp_code
=
form
.
cleaned_data
.
get
(
'otp_code'
)
otp_code
=
form
.
cleaned_data
.
get
(
'otp_code'
)
otp_secret_key
=
cache
.
get
(
'otp_secret_key
'
)
otp_secret_key
=
cache
.
get
(
self
.
request
.
session
.
session_key
+
'otp_key'
,
'
'
)
if
check_otp_code
(
otp_secret_key
,
otp_code
):
if
check_otp_code
(
otp_secret_key
,
otp_code
):
self
.
save_otp
(
otp_secret_key
)
self
.
save_otp
(
otp_secret_key
)
...
@@ -461,7 +480,10 @@ class UserOtpEnableBindView(TemplateView, FormView):
...
@@ -461,7 +480,10 @@ class UserOtpEnableBindView(TemplateView, FormView):
return
self
.
form_invalid
(
form
)
return
self
.
form_invalid
(
form
)
def
save_otp
(
self
,
otp_secret_key
):
def
save_otp
(
self
,
otp_secret_key
):
user
=
get_user
(
self
.
request
)
if
self
.
request
.
user
.
is_authenticated
:
user
=
self
.
request
.
user
else
:
user
=
get_tmp_user_from_session
(
self
.
request
)
user
.
enable_otp
()
user
.
enable_otp
()
user
.
otp_secret_key
=
otp_secret_key
user
.
otp_secret_key
=
otp_secret_key
user
.
save
()
user
.
save
()
...
@@ -489,11 +511,8 @@ class UserOtpDisableAuthenticationView(FormView):
...
@@ -489,11 +511,8 @@ class UserOtpDisableAuthenticationView(FormView):
class
UserOtpSettingsSuccessView
(
TemplateView
):
class
UserOtpSettingsSuccessView
(
TemplateView
):
template_name
=
'flash_message_standalone.html'
template_name
=
'flash_message_standalone.html'
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
# def get(self, request, *args, **kwargs):
response
=
super
()
.
get
(
request
,
*
args
,
**
kwargs
)
# return super().get(request, *args, **kwargs)
if
is_login
(
request
):
auth_logout
(
request
)
return
response
def
get_context_data
(
self
,
**
kwargs
):
def
get_context_data
(
self
,
**
kwargs
):
title
,
describe
=
self
.
get_title_describe
()
title
,
describe
=
self
.
get_title_describe
()
...
@@ -508,7 +527,11 @@ class UserOtpSettingsSuccessView(TemplateView):
...
@@ -508,7 +527,11 @@ class UserOtpSettingsSuccessView(TemplateView):
return
super
()
.
get_context_data
(
**
kwargs
)
return
super
()
.
get_context_data
(
**
kwargs
)
def
get_title_describe
(
self
):
def
get_title_describe
(
self
):
user
=
get_user
(
self
.
request
)
if
self
.
request
.
user
.
is_authenticated
:
user
=
self
.
request
.
user
auth_logout
(
self
.
request
)
else
:
user
=
get_tmp_user_from_session
(
self
.
request
)
title
=
_
(
'OTP enable success'
)
title
=
_
(
'OTP enable success'
)
describe
=
_
(
'OTP enable success, return login page'
)
describe
=
_
(
'OTP enable success, return login page'
)
if
not
user
.
otp_enabled
:
if
not
user
.
otp_enabled
:
...
...
requirements/requirements.txt
View file @
12c8cf6b
...
@@ -54,6 +54,7 @@ pyasn1==0.4.2
...
@@ -54,6 +54,7 @@ pyasn1==0.4.2
pycparser==2.18
pycparser==2.18
pycrypto==2.6.1
pycrypto==2.6.1
pyldap==2.4.45
pyldap==2.4.45
pyotp==2.2.6
PyNaCl==1.2.1
PyNaCl==1.2.1
python-dateutil==2.6.1
python-dateutil==2.6.1
python-gssapi==0.6.4
python-gssapi==0.6.4
...
...
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