Commit 34040fcd authored by ibuler's avatar ibuler

[Update] 移动model

parent 1969fb79
# -*- coding: utf-8 -*-
#
...@@ -38,14 +38,4 @@ class Migration(migrations.Migration): ...@@ -38,14 +38,4 @@ class Migration(migrations.Migration):
('datetime', models.DateTimeField(auto_now=True)), ('datetime', models.DateTimeField(auto_now=True)),
], ],
), ),
migrations.CreateModel(
name='UserLoginLog',
fields=[
],
options={
'proxy': True,
'indexes': [],
},
bases=('users.loginlog',),
),
] ]
# Generated by Django 2.1.7 on 2019-02-28 09:15
from django.db import migrations, models, connection
import django.utils.timezone
import uuid
class Migration(migrations.Migration):
dependencies = [
('audits', '0004_operatelog_passwordchangelog_userloginlog'),
]
operations = [
migrations.CreateModel(
name='UserLoginLog',
fields=[
('id', models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False)),
('username', models.CharField(max_length=128, verbose_name='Username')),
('type', models.CharField(choices=[('W', 'Web'), ('T', 'Terminal')], max_length=2, verbose_name='Login type')),
('ip', models.GenericIPAddressField(verbose_name='Login ip')),
('city', models.CharField(blank=True, max_length=254, null=True, verbose_name='Login city')),
('user_agent', models.CharField(blank=True, max_length=254, null=True, verbose_name='User agent')),
('mfa', models.SmallIntegerField(choices=[(0, 'Disabled'), (1, 'Enabled'), (2, '-')], default=2, verbose_name='MFA')),
('reason', models.SmallIntegerField(choices=[(0, '-'), (1, 'Username/password check failed'), (2, 'MFA authentication failed'), (3, 'Username does not exist'), (4, 'Password expired')], default=0, verbose_name='Reason')),
('status', models.BooleanField(choices=[(True, 'Success'), (False, 'Failed')], default=True, max_length=2, verbose_name='Status')),
('datetime', models.DateTimeField(default=django.utils.timezone.now, verbose_name='Date login')),
],
options={
'ordering': ['-datetime', 'username'],
},
),
]
drop_table_sql = "DROP TABLE audits_userloginlog"
rename_table_sql = "RENAME TABLE users_loginlog TO audits_userloginlog"
table_exist = 'users_loginlog' in connection.introspection.table_names()
if table_exist:
operations.append(migrations.RunSQL(drop_table_sql))
operations.append(migrations.RunSQL(rename_table_sql))
...@@ -2,9 +2,9 @@ import uuid ...@@ -2,9 +2,9 @@ import uuid
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.utils import timezone
from orgs.mixins import OrgModelMixin from orgs.mixins import OrgModelMixin
from .hands import LoginLog
__all__ = [ __all__ = [
'FTPLog', 'OperateLog', 'PasswordChangeLog', 'UserLoginLog', 'FTPLog', 'OperateLog', 'PasswordChangeLog', 'UserLoginLog',
...@@ -55,6 +55,50 @@ class PasswordChangeLog(models.Model): ...@@ -55,6 +55,50 @@ class PasswordChangeLog(models.Model):
return "{} change {}'s password".format(self.change_by, self.user) return "{} change {}'s password".format(self.change_by, self.user)
class UserLoginLog(LoginLog): class UserLoginLog(models.Model):
LOGIN_TYPE_CHOICE = (
('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_NOT_EXIST = 3
REASON_PASSWORD_EXPIRED = 4
REASON_CHOICE = (
(REASON_NOTHING, _('-')),
(REASON_PASSWORD, _('Username/password check failed')),
(REASON_MFA, _('MFA authentication failed')),
(REASON_NOT_EXIST, _("Username does not exist")),
(REASON_PASSWORD_EXPIRED, _("Password expired")),
)
STATUS_CHOICE = (
(True, _('Success')),
(False, _('Failed'))
)
id = models.UUIDField(default=uuid.uuid4, primary_key=True)
username = models.CharField(max_length=128, 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_UNKNOWN, choices=MFA_CHOICE, verbose_name=_('MFA'))
reason = models.SmallIntegerField(default=0, choices=REASON_CHOICE, verbose_name=_('Reason'))
status = models.BooleanField(max_length=2, default=True, choices=STATUS_CHOICE, verbose_name=_('Status'))
datetime = models.DateTimeField(default=timezone.now, verbose_name=_('Date login'))
class Meta: class Meta:
proxy = True ordering = ['-datetime', 'username']
...@@ -8,7 +8,6 @@ from common.permissions import AdminUserRequiredMixin ...@@ -8,7 +8,6 @@ from common.permissions import AdminUserRequiredMixin
from orgs.utils import current_org from orgs.utils import current_org
from ops.views import CommandExecutionListView as UserCommandExecutionListView from ops.views import CommandExecutionListView as UserCommandExecutionListView
from users.models import User
from .models import FTPLog, OperateLog, PasswordChangeLog, UserLoginLog from .models import FTPLog, OperateLog, PasswordChangeLog, UserLoginLog
......
...@@ -16,8 +16,9 @@ from common.utils import get_logger, get_request_ip ...@@ -16,8 +16,9 @@ from common.utils import get_logger, get_request_ip
from common.permissions import IsOrgAdminOrAppUser from common.permissions import IsOrgAdminOrAppUser
from orgs.mixins import RootOrgViewMixin from orgs.mixins import RootOrgViewMixin
from users.serializers import UserSerializer from users.serializers import UserSerializer
from users.models import User, LoginLog from users.models import User
from assets.models import Asset, SystemUser from assets.models import Asset, SystemUser
from audits.models import UserLoginLog as LoginLog
from users.utils import ( from users.utils import (
check_user_valid, check_otp_code, increase_login_failed_count, check_user_valid, check_otp_code, increase_login_failed_count,
is_block_login, clean_failed_count is_block_login, clean_failed_count
......
...@@ -8,13 +8,13 @@ from django.core.cache import cache ...@@ -8,13 +8,13 @@ from django.core.cache import cache
from django.conf import settings from django.conf import settings
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from django.utils.six import text_type from django.utils.six import text_type
from django.utils.translation import ugettext_lazy as _ from django.contrib.auth import get_user_model
from rest_framework import HTTP_HEADER_ENCODING from rest_framework import HTTP_HEADER_ENCODING
from rest_framework import authentication, exceptions from rest_framework import authentication, exceptions
from rest_framework.authentication import CSRFCheck from rest_framework.authentication import CSRFCheck
from common.utils import get_object_or_none, make_signature, http_to_unixtime from common.utils import get_object_or_none, make_signature, http_to_unixtime
from users.models import User, AccessKey, PrivateToken from ..models import AccessKey, PrivateToken
def get_request_date_header(request): def get_request_date_header(request):
...@@ -42,7 +42,6 @@ class AccessKeyAuthentication(authentication.BaseAuthentication): ...@@ -42,7 +42,6 @@ class AccessKeyAuthentication(authentication.BaseAuthentication):
失败 失败
""" """
keyword = 'Sign' keyword = 'Sign'
model = AccessKey
def authenticate(self, request): def authenticate(self, request):
auth = authentication.get_authorization_header(request).split() auth = authentication.get_authorization_header(request).split()
...@@ -109,7 +108,7 @@ class AccessKeyAuthentication(authentication.BaseAuthentication): ...@@ -109,7 +108,7 @@ class AccessKeyAuthentication(authentication.BaseAuthentication):
class AccessTokenAuthentication(authentication.BaseAuthentication): class AccessTokenAuthentication(authentication.BaseAuthentication):
keyword = 'Bearer' keyword = 'Bearer'
model = User model = get_user_model()
expiration = settings.TOKEN_EXPIRATION or 3600 expiration = settings.TOKEN_EXPIRATION or 3600
def authenticate(self, request): def authenticate(self, request):
...@@ -133,10 +132,9 @@ class AccessTokenAuthentication(authentication.BaseAuthentication): ...@@ -133,10 +132,9 @@ class AccessTokenAuthentication(authentication.BaseAuthentication):
raise exceptions.AuthenticationFailed(msg) raise exceptions.AuthenticationFailed(msg)
return self.authenticate_credentials(token) return self.authenticate_credentials(token)
@staticmethod def authenticate_credentials(self, token):
def authenticate_credentials(token):
user_id = cache.get(token) user_id = cache.get(token)
user = get_object_or_none(User, id=user_id) user = get_object_or_none(self.model, id=user_id)
if not user: if not user:
msg = _('Invalid token or cache refreshed.') msg = _('Invalid token or cache refreshed.')
......
# -*- coding: utf-8 -*-
#
# -*- coding: utf-8 -*-
#
from django import forms
from django.contrib.auth.forms import AuthenticationForm
from django.utils.translation import gettext_lazy as _
from captcha.fields import CaptchaField
class UserLoginForm(AuthenticationForm):
username = forms.CharField(label=_('Username'), max_length=100)
password = forms.CharField(
label=_('Password'), widget=forms.PasswordInput,
max_length=128, strip=False
)
def confirm_login_allowed(self, user):
if not user.is_staff:
raise forms.ValidationError(
self.error_messages['inactive'],
code='inactive',)
class UserLoginCaptchaForm(UserLoginForm):
captcha = CaptchaField()
class UserCheckOtpCodeForm(forms.Form):
otp_code = forms.CharField(label=_('MFA code'), max_length=6)
# Generated by Django 2.1.7 on 2019-02-28 08:07
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import uuid
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='AccessKey',
fields=[
('id',
models.UUIDField(default=uuid.uuid4, editable=False,
primary_key=True, serialize=False,
verbose_name='AccessKeyID')),
('secret',
models.UUIDField(default=uuid.uuid4, editable=False,
verbose_name='AccessKeySecret')),
('user', models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name='access_keys',
to=settings.AUTH_USER_MODEL, verbose_name='User')),
],
),
migrations.CreateModel(
name='PrivateToken',
fields=[
('key',
models.CharField(max_length=40, primary_key=True,
serialize=False, verbose_name='Key')),
('created', models.DateTimeField(auto_now_add=True,
verbose_name='Created')),
('user', models.OneToOneField(
on_delete=django.db.models.deletion.CASCADE,
related_name='auth_token',
to=settings.AUTH_USER_MODEL, verbose_name='User')),
],
options={
'verbose_name': 'Private Token',
},
),
]
import uuid
from django.db import models
from django.utils.translation import ugettext_lazy as _
from rest_framework.authtoken.models import Token
from django.conf import settings
class AccessKey(models.Model):
id = models.UUIDField(verbose_name='AccessKeyID', primary_key=True,
default=uuid.uuid4, editable=False)
secret = models.UUIDField(verbose_name='AccessKeySecret',
default=uuid.uuid4, editable=False)
user = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name='User',
on_delete=models.CASCADE, related_name='access_keys')
def get_id(self):
return str(self.id)
def get_secret(self):
return str(self.secret)
def get_full_value(self):
return '{}:{}'.format(self.id, self.secret)
def __str__(self):
return str(self.id)
class PrivateToken(Token):
"""Inherit from auth token, otherwise migration is boring"""
class Meta:
verbose_name = _('Private Token')
\ No newline at end of file
# -*- coding: utf-8 -*-
#
from rest_framework import serializers
from .models import AccessKey
__all__ = ['AccessKeySerializer']
class AccessKeySerializer(serializers.ModelSerializer):
class Meta:
model = AccessKey
fields = ['id', 'secret']
read_only_fields = ['id', 'secret']
...@@ -5,7 +5,7 @@ from common.utils import get_ip_city, validate_ip ...@@ -5,7 +5,7 @@ from common.utils import get_ip_city, validate_ip
def write_login_log(*args, **kwargs): def write_login_log(*args, **kwargs):
from users.models import LoginLog from audits.models import UserLoginLog
default_city = _("Unknown") default_city = _("Unknown")
ip = kwargs.get('ip', '') ip = kwargs.get('ip', '')
if not (ip and validate_ip(ip)): if not (ip and validate_ip(ip)):
...@@ -14,5 +14,5 @@ def write_login_log(*args, **kwargs): ...@@ -14,5 +14,5 @@ def write_login_log(*args, **kwargs):
else: else:
city = get_ip_city(ip) or default_city city = get_ip_city(ip) or default_city
kwargs.update({'ip': ip, 'city': city}) kwargs.update({'ip': ip, 'city': city})
LoginLog.objects.create(**kwargs) UserLoginLog.objects.create(**kwargs)
...@@ -17,14 +17,15 @@ from django.views.generic.edit import FormView ...@@ -17,14 +17,15 @@ from django.views.generic.edit import FormView
from django.conf import settings from django.conf import settings
from common.utils import 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
from users import forms from audits.models import UserLoginLog as LoginLog
from users.models import User, LoginLog
from users.utils import ( from users.utils import (
check_otp_code, is_block_login, clean_failed_count, get_user_or_tmp_user, check_otp_code, is_block_login, clean_failed_count, get_user_or_tmp_user,
set_tmp_user_to_cache, increase_login_failed_count, set_tmp_user_to_cache, increase_login_failed_count,
redirect_user_first_login_or_index, redirect_user_first_login_or_index,
) )
from ..signals import post_auth_success, post_auth_failed
from .. import forms
__all__ = [ __all__ = [
......
...@@ -23,7 +23,7 @@ def on_org_create_or_update(sender, instance=None, created=False, **kwargs): ...@@ -23,7 +23,7 @@ def on_org_create_or_update(sender, instance=None, created=False, **kwargs):
set_current_org(old_org) set_current_org(old_org)
if instance and not created: if instance and not created:
instance.expire_cache() instance.expire_user_cache()
@receiver(m2m_changed, sender=Organization.users.through) @receiver(m2m_changed, sender=Organization.users.through)
......
# ~*~ coding: utf-8 ~*~ # ~*~ coding: utf-8 ~*~
from django import forms from django import forms
from django.contrib.auth.forms import AuthenticationForm
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from captcha.fields import CaptchaField
from common.utils import validate_ssh_public_key from common.utils import validate_ssh_public_key
from orgs.mixins import OrgModelForm from orgs.mixins import OrgModelForm
...@@ -11,24 +9,6 @@ from orgs.utils import current_org ...@@ -11,24 +9,6 @@ from orgs.utils import current_org
from .models import User, UserGroup from .models import User, UserGroup
class UserLoginForm(AuthenticationForm):
username = forms.CharField(label=_('Username'), max_length=100)
password = forms.CharField(
label=_('Password'), widget=forms.PasswordInput,
max_length=128, strip=False
)
def confirm_login_allowed(self, user):
if not user.is_staff:
raise forms.ValidationError(
self.error_messages['inactive'],
code='inactive',)
class UserLoginCaptchaForm(UserLoginForm):
captcha = CaptchaField()
class UserCheckPasswordForm(forms.Form): class UserCheckPasswordForm(forms.Form):
username = forms.CharField(label=_('Username'), max_length=100) username = forms.CharField(label=_('Username'), max_length=100)
password = forms.CharField( password = forms.CharField(
......
...@@ -4,10 +4,8 @@ from __future__ import unicode_literals ...@@ -4,10 +4,8 @@ from __future__ import unicode_literals
import common.utils import common.utils
from django.contrib.auth.hashers import make_password from django.contrib.auth.hashers import make_password
from django.conf import settings
import django.contrib.auth.models import django.contrib.auth.models
from django.db import migrations, models from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone import django.utils.timezone
import uuid import uuid
...@@ -75,40 +73,6 @@ class Migration(migrations.Migration): ...@@ -75,40 +73,6 @@ class Migration(migrations.Migration):
('objects', django.contrib.auth.models.UserManager()), ('objects', django.contrib.auth.models.UserManager()),
], ],
), ),
migrations.CreateModel(
name='AccessKey',
fields=[
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False, verbose_name='AccessKeyID')),
('secret', models.UUIDField(default=uuid.uuid4, editable=False, verbose_name='AccessKeySecret')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='access_key', to=settings.AUTH_USER_MODEL, verbose_name='User')),
],
),
migrations.CreateModel(
name='LoginLog',
fields=[
('id', models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False)),
('username', models.CharField(max_length=20, verbose_name='Username')),
('type', models.CharField(choices=[('W', 'Web'), ('T', 'Terminal')], max_length=2, verbose_name='Login type')),
('ip', models.GenericIPAddressField(verbose_name='Login ip')),
('city', models.CharField(blank=True, max_length=254, null=True, verbose_name='Login city')),
('user_agent', models.CharField(blank=True, max_length=254, null=True, verbose_name='User agent')),
('datetime', models.DateTimeField(auto_now_add=True, verbose_name='Date login')),
],
options={
'ordering': ['-datetime', 'username'],
},
),
migrations.CreateModel(
name='PrivateToken',
fields=[
('key', models.CharField(max_length=40, primary_key=True, serialize=False, verbose_name='Key')),
('created', models.DateTimeField(auto_now_add=True, verbose_name='Created')),
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='auth_token', to=settings.AUTH_USER_MODEL, verbose_name='User')),
],
options={
'verbose_name': 'Private Token',
},
),
migrations.CreateModel( migrations.CreateModel(
name='UserGroup', name='UserGroup',
fields=[ fields=[
......
...@@ -12,19 +12,4 @@ class Migration(migrations.Migration): ...@@ -12,19 +12,4 @@ class Migration(migrations.Migration):
] ]
operations = [ operations = [
migrations.AddField(
model_name='loginlog',
name='mfa',
field=models.SmallIntegerField(choices=[(0, 'Disabled'), (1, 'Enabled'), (2, '-')], default=2, verbose_name='MFA'),
),
migrations.AddField(
model_name='loginlog',
name='reason',
field=models.SmallIntegerField(choices=[(0, '-'), (1, 'Username/password check failed'), (2, 'MFA authentication failed')], default=0, verbose_name='Reason'),
),
migrations.AddField(
model_name='loginlog',
name='status',
field=models.BooleanField(choices=[(True, 'Success'), (False, 'Failed')], default=True, max_length=2, verbose_name='Status'),
),
] ]
...@@ -10,14 +10,4 @@ class Migration(migrations.Migration): ...@@ -10,14 +10,4 @@ class Migration(migrations.Migration):
] ]
operations = [ operations = [
migrations.AlterField(
model_name='loginlog',
name='reason',
field=models.SmallIntegerField(choices=[(0, '-'), (1, 'Username/password check failed'), (2, 'MFA authentication failed'), (3, 'Username does not exist')], default=0, verbose_name='Reason'),
),
migrations.AlterField(
model_name='loginlog',
name='username',
field=models.CharField(max_length=128, verbose_name='Username'),
),
] ]
# Generated by Django 2.1.1 on 2018-11-23 03:13 # Generated by Django 2.1.1 on 2018-11-23 03:13
from django.conf import settings
from django.db import migrations, models from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration): class Migration(migrations.Migration):
...@@ -17,14 +15,4 @@ class Migration(migrations.Migration): ...@@ -17,14 +15,4 @@ class Migration(migrations.Migration):
name='date_password_last_updated', name='date_password_last_updated',
field=models.DateTimeField(auto_now_add=True, null=True, verbose_name='Date password last updated'), field=models.DateTimeField(auto_now_add=True, null=True, verbose_name='Date password last updated'),
), ),
migrations.AlterField(
model_name='accesskey',
name='user',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='access_keys', to=settings.AUTH_USER_MODEL, verbose_name='User'),
),
migrations.AlterField(
model_name='loginlog',
name='reason',
field=models.SmallIntegerField(choices=[(0, '-'), (1, 'Username/password check failed'), (2, 'MFA authentication failed'), (3, 'Username does not exist'), (4, 'Password expired')], default=0, verbose_name='Reason'),
),
] ]
...@@ -4,5 +4,4 @@ ...@@ -4,5 +4,4 @@
from .user import * from .user import *
from .group import * from .group import *
from .authentication import *
from .utils import * from .utils import *
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
import uuid
from django.db import models
from django.utils import timezone
from django.utils.translation import ugettext_lazy as _
from rest_framework.authtoken.models import Token
from .user import User
__all__ = ['AccessKey', 'PrivateToken', 'LoginLog']
class AccessKey(models.Model):
id = models.UUIDField(verbose_name='AccessKeyID', primary_key=True,
default=uuid.uuid4, editable=False)
secret = models.UUIDField(verbose_name='AccessKeySecret',
default=uuid.uuid4, editable=False)
user = models.ForeignKey(User, verbose_name='User',
on_delete=models.CASCADE, related_name='access_keys')
def get_id(self):
return str(self.id)
def get_secret(self):
return str(self.secret)
def get_full_value(self):
return '{}:{}'.format(self.id, self.secret)
def __str__(self):
return str(self.id)
class PrivateToken(Token):
"""Inherit from auth token, otherwise migration is boring"""
class Meta:
verbose_name = _('Private Token')
class LoginLog(models.Model):
LOGIN_TYPE_CHOICE = (
('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_NOT_EXIST = 3
REASON_PASSWORD_EXPIRED = 4
REASON_CHOICE = (
(REASON_NOTHING, _('-')),
(REASON_PASSWORD, _('Username/password check failed')),
(REASON_MFA, _('MFA authentication failed')),
(REASON_NOT_EXIST, _("Username does not exist")),
(REASON_PASSWORD_EXPIRED, _("Password expired")),
)
STATUS_CHOICE = (
(True, _('Success')),
(False, _('Failed'))
)
id = models.UUIDField(default=uuid.uuid4, primary_key=True)
username = models.CharField(max_length=128, 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_UNKNOWN, 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(default=timezone.now, verbose_name=_('Date login'))
class Meta:
ordering = ['-datetime', 'username']
...@@ -16,7 +16,6 @@ from django.utils import timezone ...@@ -16,7 +16,6 @@ from django.utils import timezone
from django.shortcuts import reverse from django.shortcuts import reverse
from common.utils import get_signer, date_expired_default from common.utils import get_signer, date_expired_default
from orgs.utils import current_org
__all__ = ['User'] __all__ = ['User']
...@@ -104,6 +103,8 @@ class User(AbstractUser): ...@@ -104,6 +103,8 @@ class User(AbstractUser):
verbose_name=_('Date password last updated') verbose_name=_('Date password last updated')
) )
user_cache_key_prefix = '_User_{}'
def __str__(self): def __str__(self):
return '{0.name}({0.username})'.format(self) return '{0.name}({0.username})'.format(self)
...@@ -281,6 +282,7 @@ class User(AbstractUser): ...@@ -281,6 +282,7 @@ class User(AbstractUser):
self.role = 'Admin' self.role = 'Admin'
self.is_active = True self.is_active = True
super().save(*args, **kwargs) super().save(*args, **kwargs)
self.expire_user_cache()
@property @property
def private_token(self): def private_token(self):
...@@ -422,8 +424,26 @@ class User(AbstractUser): ...@@ -422,8 +424,26 @@ class User(AbstractUser):
def delete(self, using=None, keep_parents=False): def delete(self, using=None, keep_parents=False):
if self.pk == 1 or self.username == 'admin': if self.pk == 1 or self.username == 'admin':
return return
self.expire_user_cache()
return super(User, self).delete() return super(User, self).delete()
def expire_user_cache(self):
key = self.user_cache_key_prefix.format(self.id)
cache.delete(key)
@classmethod
def get_user_or_from_cache(cls, uid):
key = cls.user_cache_key_prefix.format(uid)
user = cache.get(key)
if user:
return user
try:
user = cls.objects.get(id=uid)
cache.set(key, user, 3600)
except cls.DoesNotExist:
user = None
return user
class Meta: class Meta:
ordering = ['username'] ordering = ['username']
verbose_name = _("User") verbose_name = _("User")
......
...@@ -2,15 +2,9 @@ ...@@ -2,15 +2,9 @@
# #
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from rest_framework import serializers from rest_framework import serializers
from ..models import User, AccessKey from ..models import User
from authentication.serializers import AccessKeySerializer
class AccessKeySerializer(serializers.ModelSerializer):
class Meta:
model = AccessKey
fields = ['id', 'secret']
read_only_fields = ['id', 'secret']
class ServiceAccountSerializer(serializers.ModelSerializer): class ServiceAccountSerializer(serializers.ModelSerializer):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment