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
e1be8679
Commit
e1be8679
authored
Jul 03, 2018
by
BaiJiangJie
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[Update] 更新用户登录日志,记录登录失败日志并添加MFA启用状态信息
parent
442d4e72
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
217 additions
and
79 deletions
+217
-79
django.mo
apps/i18n/zh/LC_MESSAGES/django.mo
+0
-0
django.po
apps/i18n/zh/LC_MESSAGES/django.po
+73
-45
api.py
apps/users/api.py
+52
-14
authentication.py
apps/users/models/authentication.py
+28
-0
login_log_list.html
apps/users/templates/users/login_log_list.html
+6
-0
utils.py
apps/users/utils.py
+6
-6
login.py
apps/users/views/login.py
+52
-14
No files found.
apps/i18n/zh/LC_MESSAGES/django.mo
View file @
e1be8679
No preview for this file type
apps/i18n/zh/LC_MESSAGES/django.po
View file @
e1be8679
...
...
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Jumpserver 0.3.3\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-0
6-25 12:19
+0800\n"
"POT-Creation-Date: 2018-0
7-03 16:48
+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: ibuler <ibuler@qq.com>\n"
"Language-Team: Jumpserver team<ibuler@qq.com>\n"
...
...
@@ -118,7 +118,7 @@ msgstr "端口"
msgid "Asset"
msgstr "资产"
#: assets/forms/domain.py:54 assets/forms/user.py:79 assets/forms/user.py:13
8
#: assets/forms/domain.py:54 assets/forms/user.py:79 assets/forms/user.py:13
9
#: assets/models/base.py:21 assets/models/cluster.py:18
#: assets/models/domain.py:17 assets/models/group.py:20
#: assets/models/label.py:17 assets/templates/assets/admin_user_detail.html:56
...
...
@@ -147,14 +147,14 @@ msgstr "资产"
msgid "Name"
msgstr "名称"
#: assets/forms/domain.py:55 assets/forms/user.py:80 assets/forms/user.py:1
39
#: assets/forms/domain.py:55 assets/forms/user.py:80 assets/forms/user.py:1
40
#: assets/models/base.py:22 assets/templates/assets/admin_user_detail.html:60
#: assets/templates/assets/admin_user_list.html:24
#: assets/templates/assets/domain_gateway_list.html:60
#: assets/templates/assets/system_user_detail.html:62
#: assets/templates/assets/system_user_list.html:27
#: perms/templates/perms/asset_permission_user.html:55 users/forms.py:13
#: users/forms.py:31 users/models/authentication.py:
45
users/models/user.py:47
#: users/forms.py:31 users/models/authentication.py:
70
users/models/user.py:47
#: users/templates/users/_select_user_modal.html:14
#: users/templates/users/login.html:56
#: users/templates/users/login_log_list.html:49
...
...
@@ -192,21 +192,21 @@ msgstr "ssh密钥不合法"
msgid "Password and private key file must be input one"
msgstr "密码和私钥, 必须输入一个"
#: assets/forms/user.py:12
4
#: assets/forms/user.py:12
5
msgid "* Automatic login mode, must fill in the username."
msgstr "自动登录模式,必须填写用户名"
#: assets/forms/user.py:14
4
#: assets/forms/user.py:14
5
msgid "Auto push system user to asset"
msgstr "自动推送系统用户到资产"
#: assets/forms/user.py:14
5
#: assets/forms/user.py:14
6
msgid ""
"High level will be using login asset as default, if user was granted more "
"than 2 system user"
msgstr "高优先级的系统用户将会作为默认登录用户"
#: assets/forms/user.py:14
7
#: assets/forms/user.py:14
8
msgid ""
"If you choose manual login mode, you do not need to fill in the username and "
"password."
...
...
@@ -1237,7 +1237,7 @@ msgid "Filename"
msgstr "文件名"
#: audits/models.py:15 audits/templates/audits/ftp_log_list.html:77
#: ops/templates/ops/task_list.html:39
#: ops/templates/ops/task_list.html:39
users/models/authentication.py:66
msgid "Success"
msgstr "成功"
...
...
@@ -1485,7 +1485,8 @@ msgstr ""
msgid "discard time"
msgstr ""
#: common/models.py:29 users/templates/users/user_detail.html:96
#: common/models.py:29 users/models/authentication.py:51
#: users/templates/users/user_detail.html:96
msgid "Enabled"
msgstr "启用"
...
...
@@ -1803,7 +1804,7 @@ msgid "Versions"
msgstr "版本"
#: ops/templates/ops/task_list.html:40
#: users/templates/users/login_log_list.html:5
4
#: users/templates/users/login_log_list.html:5
7
msgid "Date"
msgstr "日期"
...
...
@@ -2045,7 +2046,7 @@ msgstr "关闭"
#: templates/_nav.html:10 users/views/group.py:28 users/views/group.py:44
#: users/views/group.py:62 users/views/group.py:79 users/views/group.py:95
#: users/views/login.py:
277 users/views/login.py:335
users/views/user.py:65
#: users/views/login.py:
311 users/views/login.py:369
users/views/user.py:65
#: users/views/user.py:80 users/views/user.py:102 users/views/user.py:175
#: users/views/user.py:330 users/views/user.py:380 users/views/user.py:415
msgid "Users"
...
...
@@ -2406,8 +2407,9 @@ msgstr ""
msgid "* Enable MFA authentication to make the account more secure."
msgstr "* 启用MFA认证,使账号更加安全."
#: users/forms.py:143 users/models/user.py:71
#: users/forms.py:143 users/models/
authentication.py:75 users/models/
user.py:71
#: users/templates/users/first_login.html:45
#: users/templates/users/login_log_list.html:54
msgid "MFA"
msgstr "MFA"
...
...
@@ -2467,23 +2469,53 @@ msgstr "ssh公钥"
msgid "Private Token"
msgstr "ssh密钥"
#: users/models/authentication.py:46
#: users/models/authentication.py:50 users/templates/users/user_detail.html:98
msgid "Disabled"
msgstr "禁用"
#: users/models/authentication.py:52 users/models/authentication.py:60
msgid "-"
msgstr ""
#: users/models/authentication.py:61
msgid "Username/password check failed"
msgstr "用户名/密码 校验失败"
#: users/models/authentication.py:62
msgid "MFA authentication failed"
msgstr "MFA 认证失败"
#: users/models/authentication.py:67
msgid "Failed"
msgstr "失败"
#: users/models/authentication.py:71
msgid "Login type"
msgstr "登录方式"
#: users/models/authentication.py:
47
#: users/models/authentication.py:
72
msgid "Login ip"
msgstr "登录IP"
#: users/models/authentication.py:
48
#: users/models/authentication.py:
73
msgid "Login city"
msgstr "登录城市"
#: users/models/authentication.py:
49
#: users/models/authentication.py:
74
msgid "User agent"
msgstr "Agent"
#: users/models/authentication.py:50
#: users/models/authentication.py:76
#: users/templates/users/login_log_list.html:55
msgid "Reason"
msgstr "原因"
#: users/models/authentication.py:77
#: users/templates/users/login_log_list.html:56
msgid "Status"
msgstr "状态"
#: users/models/authentication.py:78
msgid "Date login"
msgstr "登录日期"
...
...
@@ -2646,7 +2678,7 @@ msgid "Can't provide security? Please contact the administrator!"
msgstr "如果不能提供MFA验证码,请联系管理员!"
#: users/templates/users/reset_password.html:46
#: users/templates/users/user_detail.html:352 users/utils.py:8
0
#: users/templates/users/user_detail.html:352 users/utils.py:8
1
msgid "Reset password"
msgstr "重置密码"
...
...
@@ -2696,10 +2728,6 @@ msgstr "授权的资产"
msgid "Force enabled"
msgstr "强制启用"
#: users/templates/users/user_detail.html:98
msgid "Disabled"
msgstr "禁用"
#: users/templates/users/user_detail.html:119
#: users/templates/users/user_profile.html:108
msgid "Last login"
...
...
@@ -2867,11 +2895,11 @@ msgstr "新的公钥已设置成功,请下载对应的私钥"
msgid "Update user"
msgstr "更新用户"
#: users/utils.py:4
1
#: users/utils.py:4
2
msgid "Create account successfully"
msgstr "创建账户成功"
#: users/utils.py:4
3
#: users/utils.py:4
4
#, python-format
msgid ""
"\n"
...
...
@@ -2916,7 +2944,7 @@ msgstr ""
" </br>\n"
" "
#: users/utils.py:8
2
#: users/utils.py:8
3
#, python-format
msgid ""
"\n"
...
...
@@ -2960,11 +2988,11 @@ msgstr ""
" </br>\n"
" "
#: users/utils.py:11
3
#: users/utils.py:11
4
msgid "SSH Key Reset"
msgstr "重置ssh密钥"
#: users/utils.py:11
5
#: users/utils.py:11
6
#, python-format
msgid ""
"\n"
...
...
@@ -2989,15 +3017,15 @@ msgstr ""
" </br>\n"
" "
#: users/utils.py:14
8
#: users/utils.py:14
9
msgid "User not exist"
msgstr "用户不存在"
#: users/utils.py:15
0
#: users/utils.py:15
1
msgid "Disabled or expired"
msgstr "禁用或失效"
#: users/utils.py:16
3
#: users/utils.py:16
4
msgid "Password or SSH public key invalid"
msgstr "密码或密钥不合法"
...
...
@@ -3017,60 +3045,60 @@ msgstr "更新用户组"
msgid "User group granted asset"
msgstr "用户组授权资产"
#: users/views/login.py:6
2
#: users/views/login.py:6
3
msgid "Please enable cookies and try again."
msgstr "设置你的浏览器支持cookie"
#: users/views/login.py:1
28
users/views/user.py:500 users/views/user.py:525
#: users/views/login.py:1
59
users/views/user.py:500 users/views/user.py:525
msgid "MFA code invalid"
msgstr "MFA码认证失败"
#: users/views/login.py:1
54
#: users/views/login.py:1
88
msgid "Logout success"
msgstr "退出登录成功"
#: users/views/login.py:1
55
#: users/views/login.py:1
89
msgid "Logout success, return login page"
msgstr "退出登录成功,返回到登录页面"
#: users/views/login.py:
171
#: users/views/login.py:
205
msgid "Email address invalid, please input again"
msgstr "邮箱地址错误,重新输入"
#: users/views/login.py:
184
#: users/views/login.py:
218
msgid "Send reset password message"
msgstr "发送重置密码邮件"
#: users/views/login.py:
185
#: users/views/login.py:
219
msgid "Send reset password mail success, login your mail box and follow it "
msgstr ""
"发送重置邮件成功, 请登录邮箱查看, 按照提示操作 (如果没收到,请等待3-5分钟)"
#: users/views/login.py:
198
#: users/views/login.py:
232
msgid "Reset password success"
msgstr "重置密码成功"
#: users/views/login.py:
199
#: users/views/login.py:
233
msgid "Reset password success, return to login page"
msgstr "重置密码成功,返回到登录页面"
#: users/views/login.py:2
20 users/views/login.py:233
#: users/views/login.py:2
54 users/views/login.py:267
msgid "Token invalid or expired"
msgstr "Token错误或失效"
#: users/views/login.py:2
29
#: users/views/login.py:2
63
msgid "Password not same"
msgstr "密码不一致"
#: users/views/login.py:2
39
users/views/user.py:118 users/views/user.py:398
#: users/views/login.py:2
73
users/views/user.py:118 users/views/user.py:398
msgid "* Your password does not meet the requirements"
msgstr "* 您的密码不符合要求"
#: users/views/login.py:
277
#: users/views/login.py:
311
msgid "First login"
msgstr "首次登陆"
#: users/views/login.py:3
36
#: users/views/login.py:3
70
msgid "Login log list"
msgstr "登录日志"
...
...
apps/users/api.py
View file @
e1be8679
...
...
@@ -14,7 +14,7 @@ from .serializers import UserSerializer, UserGroupSerializer, \
UserGroupUpdateMemeberSerializer
,
UserPKUpdateSerializer
,
\
UserUpdateGroupSerializer
,
ChangeUserPasswordSerializer
from
.tasks
import
write_login_log_async
from
.models
import
User
,
UserGroup
from
.models
import
User
,
UserGroup
,
LoginLog
from
.permissions
import
IsSuperUser
,
IsValidUser
,
IsCurrentUserOrReadOnly
,
\
IsSuperUserOrAppUser
from
.utils
import
check_user_valid
,
generate_token
,
get_login_ip
,
check_otp_code
...
...
@@ -153,10 +153,25 @@ class UserOtpAuthApi(APIView):
return
Response
({
'msg'
:
'请先进行用户名和密码验证'
},
status
=
401
)
if
not
check_otp_code
(
user
.
otp_secret_key
,
otp_code
):
# Write login failed log
kwargs
=
{
'username'
:
user
.
username
,
'mfa'
:
int
(
user
.
otp_enabled
),
'reason'
:
LoginLog
.
REASON_MFA
,
'status'
:
False
}
self
.
write_login_log
(
request
,
**
kwargs
)
return
Response
({
'msg'
:
'MFA认证失败'
},
status
=
401
)
# Write login success log
kwargs
=
{
'username'
:
user
.
username
,
'mfa'
:
int
(
user
.
otp_enabled
),
'reason'
:
LoginLog
.
REASON_NOTHING
,
'status'
:
True
}
self
.
write_login_log
(
request
,
**
kwargs
)
token
=
generate_token
(
request
,
user
)
self
.
write_login_log
(
request
,
user
)
return
Response
(
{
'token'
:
token
,
...
...
@@ -165,7 +180,7 @@ class UserOtpAuthApi(APIView):
)
@staticmethod
def
write_login_log
(
request
,
user
):
def
write_login_log
(
request
,
**
kwargs
):
login_ip
=
request
.
data
.
get
(
'remote_addr'
,
None
)
login_type
=
request
.
data
.
get
(
'login_type'
,
''
)
user_agent
=
request
.
data
.
get
(
'HTTP_USER_AGENT'
,
''
)
...
...
@@ -173,10 +188,13 @@ class UserOtpAuthApi(APIView):
if
not
login_ip
:
login_ip
=
get_login_ip
(
request
)
write_login_log_async
.
delay
(
user
.
username
,
ip
=
login_ip
,
type
=
login_type
,
user_agent
=
user_agent
,
)
data
=
{
'ip'
:
login_ip
,
'type'
:
login_type
,
'user_agent'
:
user_agent
}
kwargs
.
update
(
data
)
write_login_log_async
.
delay
(
**
kwargs
)
class
UserAuthApi
(
APIView
):
...
...
@@ -187,11 +205,26 @@ class UserAuthApi(APIView):
user
,
msg
=
self
.
check_user_valid
(
request
)
if
not
user
:
# Write login failed log
kwargs
=
{
'username'
:
request
.
data
.
get
(
'username'
,
''
),
'mfa'
:
LoginLog
.
MFA_UNKNOWN
,
'reason'
:
LoginLog
.
REASON_PASSWORD
,
'status'
:
False
}
self
.
write_login_log
(
request
,
**
kwargs
)
return
Response
({
'msg'
:
msg
},
status
=
401
)
if
not
user
.
otp_enabled
:
# Write login success log
kwargs
=
{
'username'
:
user
.
username
,
'mfa'
:
int
(
user
.
otp_enabled
),
'reason'
:
LoginLog
.
REASON_NOTHING
,
'status'
:
True
}
self
.
write_login_log
(
request
,
**
kwargs
)
token
=
generate_token
(
request
,
user
)
self
.
write_login_log
(
request
,
user
)
return
Response
(
{
'token'
:
token
,
...
...
@@ -208,7 +241,8 @@ class UserAuthApi(APIView):
'otp_url'
:
reverse
(
'api-users:user-otp-auth'
),
'seed'
:
seed
,
'user'
:
self
.
serializer_class
(
user
)
.
data
},
status
=
300
)
},
status
=
300
)
@staticmethod
def
check_user_valid
(
request
):
...
...
@@ -222,7 +256,7 @@ class UserAuthApi(APIView):
return
user
,
msg
@staticmethod
def
write_login_log
(
request
,
user
):
def
write_login_log
(
request
,
**
kwargs
):
login_ip
=
request
.
data
.
get
(
'remote_addr'
,
None
)
login_type
=
request
.
data
.
get
(
'login_type'
,
''
)
user_agent
=
request
.
data
.
get
(
'HTTP_USER_AGENT'
,
''
)
...
...
@@ -230,10 +264,14 @@ class UserAuthApi(APIView):
if
not
login_ip
:
login_ip
=
get_login_ip
(
request
)
write_login_log_async
.
delay
(
user
.
username
,
ip
=
login_ip
,
type
=
login_type
,
user_agent
=
user_agent
,
)
data
=
{
'ip'
:
login_ip
,
'type'
:
login_type
,
'user_agent'
:
user_agent
,
}
kwargs
.
update
(
data
)
write_login_log_async
.
delay
(
**
kwargs
)
class
UserConnectionTokenApi
(
APIView
):
...
...
apps/users/models/authentication.py
View file @
e1be8679
...
...
@@ -41,12 +41,40 @@ class LoginLog(models.Model):
(
'W'
,
'Web'
),
(
'T'
,
'Terminal'
),
)
MFA_DISABLED
=
0
MFA_ENABLED
=
1
MFA_UNKNOWN
=
2
MFA_CHOICE
=
(
(
MFA_DISABLED
,
_
(
'Disabled'
)),
(
MFA_ENABLED
,
_
(
'Enabled'
)),
(
MFA_UNKNOWN
,
_
(
'-'
)),
)
REASON_NOTHING
=
0
REASON_PASSWORD
=
1
REASON_MFA
=
2
REASON_CHOICE
=
(
(
REASON_NOTHING
,
_
(
'-'
)),
(
REASON_PASSWORD
,
_
(
'Username/password check failed'
)),
(
REASON_MFA
,
_
(
'MFA authentication failed'
)),
)
STATUS_CHOICE
=
(
(
True
,
_
(
'Success'
)),
(
False
,
_
(
'Failed'
))
)
id
=
models
.
UUIDField
(
default
=
uuid
.
uuid4
,
primary_key
=
True
)
username
=
models
.
CharField
(
max_length
=
20
,
verbose_name
=
_
(
'Username'
))
type
=
models
.
CharField
(
choices
=
LOGIN_TYPE_CHOICE
,
max_length
=
2
,
verbose_name
=
_
(
'Login type'
))
ip
=
models
.
GenericIPAddressField
(
verbose_name
=
_
(
'Login ip'
))
city
=
models
.
CharField
(
max_length
=
254
,
blank
=
True
,
null
=
True
,
verbose_name
=
_
(
'Login city'
))
user_agent
=
models
.
CharField
(
max_length
=
254
,
blank
=
True
,
null
=
True
,
verbose_name
=
_
(
'User agent'
))
mfa
=
models
.
SmallIntegerField
(
default
=
MFA_DISABLED
,
choices
=
MFA_CHOICE
,
verbose_name
=
_
(
'MFA'
))
reason
=
models
.
SmallIntegerField
(
default
=
REASON_NOTHING
,
choices
=
REASON_CHOICE
,
verbose_name
=
_
(
'Reason'
))
status
=
models
.
BooleanField
(
max_length
=
2
,
default
=
True
,
choices
=
STATUS_CHOICE
,
verbose_name
=
_
(
'Status'
))
datetime
=
models
.
DateTimeField
(
auto_now_add
=
True
,
verbose_name
=
_
(
'Date login'
))
class
Meta
:
...
...
apps/users/templates/users/login_log_list.html
View file @
e1be8679
...
...
@@ -51,6 +51,9 @@
<th
class=
"text-center"
>
{% trans 'UA' %}
</th>
<th
class=
"text-center"
>
{% trans 'IP' %}
</th>
<th
class=
"text-center"
>
{% trans 'City' %}
</th>
<th
class=
"text-center"
>
{% trans 'MFA' %}
</th>
<th
class=
"text-center"
>
{% trans 'Reason' %}
</th>
<th
class=
"text-center"
>
{% trans 'Status' %}
</th>
<th
class=
"text-center"
>
{% trans 'Date' %}
</th>
{% endblock %}
...
...
@@ -65,6 +68,9 @@
</td>
<td
class=
"text-center"
>
{{ login_log.ip }}
</td>
<td
class=
"text-center"
>
{{ login_log.city }}
</td>
<td
class=
"text-center"
>
{{ login_log.get_mfa_display }}
</td>
<td
class=
"text-center"
>
{{ login_log.get_reason_display }}
</td>
<td
class=
"text-center"
>
{{ login_log.get_status_display }}
</td>
<td
class=
"text-center"
>
{{ login_log.datetime }}
</td>
</tr>
{% endfor %}
...
...
apps/users/utils.py
View file @
e1be8679
...
...
@@ -13,7 +13,7 @@ import ipaddress
from
django.http
import
Http404
from
django.conf
import
settings
from
django.contrib.auth.mixins
import
UserPassesTestMixin
from
django.contrib.auth
import
authenticate
,
login
as
auth_login
from
django.contrib.auth
import
authenticate
from
django.utils.translation
import
ugettext
as
_
from
django.core.cache
import
cache
...
...
@@ -22,6 +22,7 @@ from common.utils import reverse, get_object_or_none
from
common.models
import
Setting
from
common.forms
import
SecuritySettingForm
from
.models
import
User
,
LoginLog
# from .tasks import write_login_log_async
logger
=
logging
.
getLogger
(
'jumpserver'
)
...
...
@@ -200,16 +201,15 @@ def get_login_ip(request):
return
login_ip
def
write_login_log
(
username
,
type
=
''
,
ip
=
''
,
user_agent
=
''
):
def
write_login_log
(
*
args
,
**
kwargs
):
ip
=
kwargs
.
get
(
'ip'
,
''
)
if
not
(
ip
and
validate_ip
(
ip
)):
ip
=
ip
[:
15
]
city
=
"Unknown"
else
:
city
=
get_ip_city
(
ip
)
LoginLog
.
objects
.
create
(
username
=
username
,
type
=
type
,
ip
=
ip
,
city
=
city
,
user_agent
=
user_agent
)
kwargs
.
update
({
'ip'
:
ip
,
'city'
:
city
})
LoginLog
.
objects
.
create
(
**
kwargs
)
def
get_ip_city
(
ip
,
timeout
=
10
):
...
...
apps/users/views/login.py
View file @
e1be8679
...
...
@@ -25,8 +25,9 @@ from common.utils import get_object_or_none
from
common.mixins
import
DatetimeSearchMixin
,
AdminUserRequiredMixin
from
common.models
import
Setting
from
..models
import
User
,
LoginLog
from
..utils
import
send_reset_password_mail
,
check_otp_code
,
get_login_ip
,
redirect_user_first_login_or_index
,
\
get_user_or_tmp_user
,
set_tmp_user_to_cache
,
get_password_check_rules
,
check_password_rules
from
..utils
import
send_reset_password_mail
,
check_otp_code
,
get_login_ip
,
\
redirect_user_first_login_or_index
,
get_user_or_tmp_user
,
\
set_tmp_user_to_cache
,
get_password_check_rules
,
check_password_rules
from
..tasks
import
write_login_log_async
from
..
import
forms
...
...
@@ -65,6 +66,15 @@ class UserLoginView(FormView):
return
redirect
(
self
.
get_success_url
())
def
form_invalid
(
self
,
form
):
# Write login failed log
kwargs
=
{
'username'
:
form
.
cleaned_data
.
get
(
'username'
),
'mfa'
:
LoginLog
.
MFA_UNKNOWN
,
'reason'
:
LoginLog
.
REASON_PASSWORD
,
'status'
:
False
}
self
.
write_login_log
(
**
kwargs
)
ip
=
get_login_ip
(
self
.
request
)
cache
.
set
(
self
.
key_prefix
.
format
(
ip
),
1
,
3600
)
old_form
=
form
...
...
@@ -91,7 +101,14 @@ class UserLoginView(FormView):
elif
not
user
.
otp_enabled
:
# 0 & T,F
auth_login
(
self
.
request
,
user
)
self
.
write_login_log
()
# Write login success log
kwargs
=
{
'username'
:
self
.
request
.
user
.
username
,
'mfa'
:
int
(
self
.
request
.
user
.
otp_enabled
),
'reason'
:
LoginLog
.
REASON_NOTHING
,
'status'
:
True
}
self
.
write_login_log
(
**
kwargs
)
return
redirect_user_first_login_or_index
(
self
.
request
,
self
.
redirect_field_name
)
def
get_context_data
(
self
,
**
kwargs
):
...
...
@@ -101,13 +118,16 @@ class UserLoginView(FormView):
kwargs
.
update
(
context
)
return
super
()
.
get_context_data
(
**
kwargs
)
def
write_login_log
(
self
):
def
write_login_log
(
self
,
**
kwargs
):
login_ip
=
get_login_ip
(
self
.
request
)
user_agent
=
self
.
request
.
META
.
get
(
'HTTP_USER_AGENT'
,
''
)
write_login_log_async
.
delay
(
self
.
request
.
user
.
username
,
type
=
'W'
,
ip
=
login_ip
,
user_agent
=
user_agent
)
data
=
{
'ip'
:
login_ip
,
'type'
:
'W'
,
'user_agent'
:
user_agent
}
kwargs
.
update
(
data
)
write_login_log_async
.
delay
(
**
kwargs
)
class
UserLoginOtpView
(
FormView
):
...
...
@@ -122,22 +142,40 @@ class UserLoginOtpView(FormView):
if
check_otp_code
(
otp_secret_key
,
otp_code
):
auth_login
(
self
.
request
,
user
)
self
.
write_login_log
()
# Write login success log
kwargs
=
{
'username'
:
self
.
request
.
user
.
username
,
'mfa'
:
int
(
self
.
request
.
user
.
otp_enabled
),
'reason'
:
LoginLog
.
REASON_NOTHING
,
'status'
:
True
}
self
.
write_login_log
(
**
kwargs
)
return
redirect
(
self
.
get_success_url
())
else
:
# Write login failed log
kwargs
=
{
'username'
:
user
.
username
,
'mfa'
:
int
(
user
.
otp_enabled
),
'reason'
:
LoginLog
.
REASON_MFA
,
'status'
:
False
}
self
.
write_login_log
(
**
kwargs
)
form
.
add_error
(
'otp_code'
,
_
(
'MFA code invalid'
))
return
super
()
.
form_invalid
(
form
)
def
get_success_url
(
self
):
return
redirect_user_first_login_or_index
(
self
.
request
,
self
.
redirect_field_name
)
def
write_login_log
(
self
):
def
write_login_log
(
self
,
**
kwargs
):
login_ip
=
get_login_ip
(
self
.
request
)
user_agent
=
self
.
request
.
META
.
get
(
'HTTP_USER_AGENT'
,
''
)
write_login_log_async
.
delay
(
self
.
request
.
user
.
username
,
type
=
'W'
,
ip
=
login_ip
,
user_agent
=
user_agent
)
data
=
{
'ip'
:
login_ip
,
'type'
:
'W'
,
'user_agent'
:
user_agent
}
kwargs
.
update
(
data
)
write_login_log_async
.
delay
(
**
kwargs
)
@method_decorator
(
never_cache
,
name
=
'dispatch'
)
...
...
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