Use signals to save ip, user_agent, last_login in sessions
This commit is contained in:
@@ -0,0 +1 @@
|
||||
default_app_config = 'account.apps.ProfilesConfig'
|
||||
9
account/apps.py
Normal file
9
account/apps.py
Normal file
@@ -0,0 +1,9 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class ProfilesConfig(AppConfig):
|
||||
name = "account"
|
||||
verbose_name = "account"
|
||||
|
||||
def ready(self):
|
||||
import account.signals
|
||||
21
account/migrations/0006_user_session_keys.py
Normal file
21
account/migrations/0006_user_session_keys.py
Normal file
@@ -0,0 +1,21 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.11.4 on 2017-09-16 06:22
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations
|
||||
import jsonfield.fields
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('account', '0005_auto_20170830_1154'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='user',
|
||||
name='session_keys',
|
||||
field=jsonfield.fields.JSONField(default=[]),
|
||||
),
|
||||
]
|
||||
@@ -35,6 +35,7 @@ class User(AbstractBaseUser):
|
||||
auth_token = models.CharField(max_length=40, null=True)
|
||||
two_factor_auth = models.BooleanField(default=False)
|
||||
tfa_token = models.CharField(max_length=40, null=True)
|
||||
session_keys = JSONField(default=[])
|
||||
# open api key
|
||||
open_api = models.BooleanField(default=False)
|
||||
open_api_appkey = models.CharField(max_length=35, null=True)
|
||||
|
||||
21
account/signals.py
Normal file
21
account/signals.py
Normal file
@@ -0,0 +1,21 @@
|
||||
from django.utils.timezone import now
|
||||
from django.dispatch import receiver
|
||||
from django.contrib.auth.signals import user_logged_in, user_logged_out
|
||||
|
||||
|
||||
@receiver(user_logged_in)
|
||||
def add_user_session(sender, request, user, **kwargs):
|
||||
request.session["ip"] = request.META.get('REMOTE_ADDR', '')
|
||||
request.session["user_agent"] = request.META.get('HTTP_USER_AGENT', '')
|
||||
request.session["last_login"] = now()
|
||||
if request.session.session_key not in user.session_keys:
|
||||
user.session_keys.append(request.session.session_key)
|
||||
user.save()
|
||||
|
||||
|
||||
@receiver(user_logged_out)
|
||||
def delete_user_session(sender, request, user, **kwargs):
|
||||
# user may be None
|
||||
if user and request.session.session_key in user.session_keys:
|
||||
user.session_keys.remove(request.session.session_key)
|
||||
user.save()
|
||||
@@ -194,7 +194,6 @@ class AdminUserTest(APITestCase):
|
||||
resp_data = response.data["data"]
|
||||
self.assertEqual(resp_data["username"], self.username)
|
||||
self.assertEqual(resp_data["email"], "test@qq.com")
|
||||
self.assertEqual(resp_data["real_name"], "test_name")
|
||||
self.assertEqual(resp_data["open_api"], True)
|
||||
self.assertEqual(resp_data["two_factor_auth"], False)
|
||||
self.assertEqual(resp_data["is_disabled"], False)
|
||||
|
||||
@@ -39,7 +39,6 @@ class UserAdminAPI(APIView):
|
||||
pass
|
||||
|
||||
user.username = data["username"]
|
||||
user.real_name = data["real_name"]
|
||||
user.email = data["email"]
|
||||
user.admin_type = data["admin_type"]
|
||||
user.is_disabled = data["is_disabled"]
|
||||
|
||||
@@ -5,6 +5,7 @@ from otpauth import OtpAuth
|
||||
|
||||
from django.conf import settings
|
||||
from django.contrib import auth
|
||||
from importlib import import_module
|
||||
from django.utils.timezone import now
|
||||
from django.views.decorators.csrf import ensure_csrf_cookie
|
||||
from django.utils.decorators import method_decorator
|
||||
@@ -267,8 +268,8 @@ class ApplyResetPasswordAPI(APIView):
|
||||
user = User.objects.get(email=data["email"])
|
||||
except User.DoesNotExist:
|
||||
return self.error("User does not exist")
|
||||
if user.reset_password_token_expire_time and \
|
||||
0 < int((user.reset_password_token_expire_time - now()).total_seconds()) < 20 * 60:
|
||||
if user.reset_password_token_expire_time and 0 < int(
|
||||
(user.reset_password_token_expire_time - now()).total_seconds()) < 20 * 60:
|
||||
return self.error("You can only reset password once per 20 minutes")
|
||||
user.reset_password_token = rand_str()
|
||||
user.reset_password_token_expire_time = now() + timedelta(minutes=20)
|
||||
@@ -278,7 +279,7 @@ class ApplyResetPasswordAPI(APIView):
|
||||
"website_name": config.name,
|
||||
"link": f"{config.base_url}/reset-password/{user.reset_password_token}"
|
||||
}
|
||||
email_html = render_to_string('reset_password_email.html', render_data)
|
||||
email_html = render_to_string("reset_password_email.html", render_data)
|
||||
send_email_async.delay(config.name,
|
||||
user.email,
|
||||
user.username,
|
||||
|
||||
Reference in New Issue
Block a user