mirror of https://github.com/jumpserver/jumpserver
Co-authored-by: xinwen <coderWen@126.com>pull/5201/head
parent
80b03e73f6
commit
7c7de96158
|
@ -0,0 +1,18 @@
|
|||
# Generated by Django 3.1 on 2020-12-09 03:03
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('audits', '0010_auto_20200811_1122'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='userloginlog',
|
||||
name='backend',
|
||||
field=models.CharField(default='', max_length=32, verbose_name='Login backend'),
|
||||
),
|
||||
]
|
|
@ -105,6 +105,7 @@ class UserLoginLog(models.Model):
|
|||
reason = models.CharField(default='', max_length=128, blank=True, 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'))
|
||||
backend = models.CharField(max_length=32, default='', verbose_name=_('Login backend'))
|
||||
|
||||
@classmethod
|
||||
def get_login_logs(cls, date_from=None, date_to=None, user=None, keyword=None):
|
||||
|
|
|
@ -31,7 +31,8 @@ class UserLoginLogSerializer(serializers.ModelSerializer):
|
|||
model = models.UserLoginLog
|
||||
fields = (
|
||||
'id', 'username', 'type', 'type_display', 'ip', 'city', 'user_agent',
|
||||
'mfa', 'reason', 'status', 'status_display', 'datetime', 'mfa_display'
|
||||
'mfa', 'reason', 'status', 'status_display', 'datetime', 'mfa_display',
|
||||
'backend'
|
||||
)
|
||||
extra_kwargs = {
|
||||
"user_agent": {'label': _('User agent')}
|
||||
|
|
|
@ -5,6 +5,8 @@ from django.db.models.signals import post_save, post_delete
|
|||
from django.dispatch import receiver
|
||||
from django.db import transaction
|
||||
from django.utils import timezone
|
||||
from django.contrib.auth import BACKEND_SESSION_KEY
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from rest_framework.renderers import JSONRenderer
|
||||
from rest_framework.request import Request
|
||||
|
||||
|
@ -32,6 +34,19 @@ MODELS_NEED_RECORD = (
|
|||
)
|
||||
|
||||
|
||||
LOGIN_BACKEND = {
|
||||
'PublicKeyAuthBackend': _('SSH Key'),
|
||||
'RadiusBackend': User.Source.radius.label,
|
||||
'RadiusRealmBackend': User.Source.radius.label,
|
||||
'LDAPAuthorizationBackend': User.Source.ldap.label,
|
||||
'ModelBackend': _('Password'),
|
||||
'SSOAuthentication': _('SSO'),
|
||||
'CASBackend': User.Source.cas.label,
|
||||
'OIDCAuthCodeBackend': User.Source.openid.label,
|
||||
'OIDCAuthPasswordBackend': User.Source.openid.label,
|
||||
}
|
||||
|
||||
|
||||
def create_operate_log(action, sender, resource):
|
||||
user = current_request.user if current_request else None
|
||||
if not user or not user.is_authenticated:
|
||||
|
@ -109,6 +124,12 @@ def on_audits_log_create(sender, instance=None, **kwargs):
|
|||
sys_logger.info(msg)
|
||||
|
||||
|
||||
def get_login_backend(request):
|
||||
backend = request.session.get(BACKEND_SESSION_KEY, '')
|
||||
backend = backend.rsplit('.', maxsplit=1)[-1]
|
||||
return LOGIN_BACKEND.get(backend, '')
|
||||
|
||||
|
||||
def generate_data(username, request):
|
||||
user_agent = request.META.get('HTTP_USER_AGENT', '')
|
||||
login_ip = get_request_ip(request) or '0.0.0.0'
|
||||
|
@ -122,7 +143,8 @@ def generate_data(username, request):
|
|||
'ip': login_ip,
|
||||
'type': login_type,
|
||||
'user_agent': user_agent,
|
||||
'datetime': timezone.now()
|
||||
'datetime': timezone.now(),
|
||||
'backend': get_login_backend(request)
|
||||
}
|
||||
return data
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ class CreateUserMixin:
|
|||
email_suffix = settings.EMAIL_SUFFIX
|
||||
email = '{}@{}'.format(username, email_suffix)
|
||||
user = User(username=username, name=username, email=email)
|
||||
user.source = user.SOURCE_RADIUS
|
||||
user.source = user.Source.radius.value
|
||||
user.save()
|
||||
return user
|
||||
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
import uuid
|
||||
from functools import partial
|
||||
|
||||
from django.utils import timezone
|
||||
from django.utils.translation import ugettext_lazy as _, ugettext as __
|
||||
from rest_framework.authtoken.models import Token
|
||||
from django.conf import settings
|
||||
from django.utils.crypto import get_random_string
|
||||
|
||||
from common.db import models
|
||||
from common.mixins.models import CommonModelMixin
|
||||
|
|
|
@ -333,7 +333,7 @@ class LDAPImportUtil(object):
|
|||
def update_or_create(self, user):
|
||||
user['email'] = self.get_user_email(user)
|
||||
if user['username'] not in ['admin']:
|
||||
user['source'] = User.SOURCE_LDAP
|
||||
user['source'] = User.Source.ldap.value
|
||||
obj, created = User.objects.update_or_create(
|
||||
username=user['username'], defaults=user
|
||||
)
|
||||
|
|
|
@ -28,7 +28,7 @@ class UserCreateUpdateFormMixin(OrgModelForm):
|
|||
)
|
||||
source = forms.ChoiceField(
|
||||
choices=get_source_choices, required=True,
|
||||
initial=User.SOURCE_LOCAL, label=_("Source")
|
||||
initial=User.Source.local.value, label=_("Source")
|
||||
)
|
||||
public_key = forms.CharField(
|
||||
label=_('ssh public key'), max_length=5000, required=False,
|
||||
|
|
|
@ -7,10 +7,10 @@ import string
|
|||
import random
|
||||
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.hashers import make_password
|
||||
from django.contrib.auth.models import AbstractUser
|
||||
from django.core.cache import cache
|
||||
from django.db import models
|
||||
from django.db.models import TextChoices
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils import timezone
|
||||
|
@ -481,18 +481,12 @@ class MFAMixin:
|
|||
|
||||
|
||||
class User(AuthMixin, TokenMixin, RoleMixin, MFAMixin, AbstractUser):
|
||||
SOURCE_LOCAL = 'local'
|
||||
SOURCE_LDAP = 'ldap'
|
||||
SOURCE_OPENID = 'openid'
|
||||
SOURCE_RADIUS = 'radius'
|
||||
SOURCE_CAS = 'cas'
|
||||
SOURCE_CHOICES = (
|
||||
(SOURCE_LOCAL, _('Local')),
|
||||
(SOURCE_LDAP, 'LDAP/AD'),
|
||||
(SOURCE_OPENID, 'OpenID'),
|
||||
(SOURCE_RADIUS, 'Radius'),
|
||||
(SOURCE_CAS, 'CAS'),
|
||||
)
|
||||
class Source(TextChoices):
|
||||
local = 'local', _('Local')
|
||||
ldap = 'ldap', 'LDAP/AD'
|
||||
openid = 'openid', 'OpenID'
|
||||
radius = 'radius', 'Radius'
|
||||
cas = 'cas', 'CAS'
|
||||
|
||||
id = models.UUIDField(default=uuid.uuid4, primary_key=True)
|
||||
username = models.CharField(
|
||||
|
@ -542,7 +536,7 @@ class User(AuthMixin, TokenMixin, RoleMixin, MFAMixin, AbstractUser):
|
|||
max_length=30, default='', blank=True, verbose_name=_('Created by')
|
||||
)
|
||||
source = models.CharField(
|
||||
max_length=30, default=SOURCE_LOCAL, choices=SOURCE_CHOICES,
|
||||
max_length=30, default=Source.local.value, choices=Source.choices,
|
||||
verbose_name=_('Source')
|
||||
)
|
||||
date_password_last_updated = models.DateTimeField(
|
||||
|
@ -593,7 +587,7 @@ class User(AuthMixin, TokenMixin, RoleMixin, MFAMixin, AbstractUser):
|
|||
|
||||
@property
|
||||
def is_local(self):
|
||||
return self.source == self.SOURCE_LOCAL
|
||||
return self.source == self.Source.local.value
|
||||
|
||||
def set_unprovide_attr_if_need(self):
|
||||
if not self.name:
|
||||
|
@ -663,6 +657,6 @@ class User(AuthMixin, TokenMixin, RoleMixin, MFAMixin, AbstractUser):
|
|||
user.groups.add(UserGroup.initial())
|
||||
|
||||
def can_send_created_mail(self):
|
||||
if self.email and self.source == self.SOURCE_LOCAL:
|
||||
if self.email and self.source == self.Source.local.value:
|
||||
return True
|
||||
return False
|
||||
|
|
|
@ -28,7 +28,7 @@ def on_user_create(sender, user=None, **kwargs):
|
|||
@receiver(cas_user_authenticated)
|
||||
def on_cas_user_authenticated(sender, user, created, **kwargs):
|
||||
if created:
|
||||
user.source = user.SOURCE_CAS
|
||||
user.source = user.Source.cas.value
|
||||
user.save()
|
||||
|
||||
|
||||
|
@ -37,7 +37,7 @@ def on_ldap_create_user(sender, user, ldap_user, **kwargs):
|
|||
if user and user.username not in ['admin']:
|
||||
exists = User.objects.filter(username=user.username).exists()
|
||||
if not exists:
|
||||
user.source = user.SOURCE_LDAP
|
||||
user.source = user.Source.ldap.value
|
||||
user.save()
|
||||
|
||||
|
||||
|
@ -46,9 +46,9 @@ def on_openid_create_or_update_user(sender, request, user, created, name, userna
|
|||
if created:
|
||||
logger.debug(
|
||||
"Receive OpenID user created signal: {}, "
|
||||
"Set user source is: {}".format(user, User.SOURCE_OPENID)
|
||||
"Set user source is: {}".format(user, User.Source.openid.value)
|
||||
)
|
||||
user.source = User.SOURCE_OPENID
|
||||
user.source = User.Source.openid.value
|
||||
user.save()
|
||||
elif not created and settings.AUTH_OPENID_ALWAYS_UPDATE_USER:
|
||||
logger.debug(
|
||||
|
|
|
@ -22,7 +22,7 @@ logger = get_logger(__file__)
|
|||
|
||||
@shared_task
|
||||
def check_password_expired():
|
||||
users = User.objects.filter(source=User.SOURCE_LOCAL).exclude(role=User.ROLE.APP)
|
||||
users = User.objects.filter(source=User.Source.local.value).exclude(role=User.ROLE.APP)
|
||||
for user in users:
|
||||
if not user.is_valid:
|
||||
continue
|
||||
|
|
|
@ -362,18 +362,17 @@ def get_current_org_members(exclude=()):
|
|||
|
||||
def get_source_choices():
|
||||
from .models import User
|
||||
choices_all = dict(User.SOURCE_CHOICES)
|
||||
choices = [
|
||||
(User.SOURCE_LOCAL, choices_all[User.SOURCE_LOCAL]),
|
||||
(User.Source.local.value, User.Source.local.label),
|
||||
]
|
||||
if settings.AUTH_LDAP:
|
||||
choices.append((User.SOURCE_LDAP, choices_all[User.SOURCE_LDAP]))
|
||||
choices.append((User.Source.ldap.value, User.Source.ldap.label))
|
||||
if settings.AUTH_OPENID:
|
||||
choices.append((User.SOURCE_OPENID, choices_all[User.SOURCE_OPENID]))
|
||||
choices.append((User.Source.openid.value, User.Source.openid.label))
|
||||
if settings.AUTH_RADIUS:
|
||||
choices.append((User.SOURCE_RADIUS, choices_all[User.SOURCE_RADIUS]))
|
||||
choices.append((User.Source.radius.value, User.Source.radius.label))
|
||||
if settings.AUTH_CAS:
|
||||
choices.append((User.SOURCE_CAS, choices_all[User.SOURCE_CAS]))
|
||||
choices.append((User.Source.cas.value, User.Source.cas.label))
|
||||
return choices
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue