mirror of
https://github.com/jumpserver/jumpserver.git
synced 2025-09-10 11:49:10 +00:00
Asset meta (#3539)
- 更改了资产表单,影响 - 资产创建和更新 - 增加了资产平台数据库,影响 - 平台创建更新和删除 - 更改了资产的platform字段,又一个字符字段,改为一个外键,影响 - 资产创建和更新 - 资产连接 [windows,linux] - 测试连接等ansible任务 - 自动化云导入 - 更改了资产的序列化器,影响 - 资产创建更新列表 - 统一了树列表基础模板,影响 - 资产列表页,权限列表页,vault页,资产收集页 - 统一了导入导出组件,影响 - 资产导入导出 - 用户导入导出 - 用户组导入导出 - 系统用户导入导出 - 管理用户导入导出 - vault导出导出 - 收集用户列表导入导出 - 修改用户更新密码信号,影响 - 修改用户密码产生的改密日志 - 新增Model instance序列化工具函数,影响 - 操作日志生成 - 修改api mixin,新增 serializer_classes字段,serializer_classes = {"default": "", "display": "", "list": .., "other_action": ""}, 根据用户请求的方式返回不同的serializer_class,影响 - 用户的viewset - 资产权限的viewset - 统一系统配置中的tab切换 - 统一没有nav的页面,影响 - 重置密码 - 忘记密码 - 重置中设置密码 - 独立的message页面 - 修改用户组列表页,不再返还用户组下的用户,仅有数量 - 组织的一些方法变为layzproperty,避免重复计算 - 修改用户组详情页,影响 - 用户组增加删除用户
This commit is contained in:
199
apps/users/forms/user.py
Normal file
199
apps/users/forms/user.py
Normal file
@@ -0,0 +1,199 @@
|
||||
|
||||
from django import forms
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from common.utils import validate_ssh_public_key
|
||||
from orgs.mixins.forms import OrgModelForm
|
||||
from ..models import User
|
||||
from ..utils import (
|
||||
check_password_rules, get_current_org_members, get_source_choices
|
||||
)
|
||||
|
||||
|
||||
__all__ = [
|
||||
'UserCreateForm', 'UserUpdateForm', 'UserBulkUpdateForm',
|
||||
'UserCheckOtpCodeForm', 'UserCheckPasswordForm'
|
||||
]
|
||||
|
||||
|
||||
class UserCreateUpdateFormMixin(OrgModelForm):
|
||||
role_choices = ((i, n) for i, n in User.ROLE_CHOICES if i != User.ROLE_APP)
|
||||
password = forms.CharField(
|
||||
label=_('Password'), widget=forms.PasswordInput,
|
||||
max_length=128, strip=False, required=False,
|
||||
)
|
||||
role = forms.ChoiceField(
|
||||
choices=role_choices, required=True,
|
||||
initial=User.ROLE_USER, label=_("Role")
|
||||
)
|
||||
source = forms.ChoiceField(
|
||||
choices=get_source_choices, required=True,
|
||||
initial=User.SOURCE_LOCAL, label=_("Source")
|
||||
)
|
||||
public_key = forms.CharField(
|
||||
label=_('ssh public key'), max_length=5000, required=False,
|
||||
widget=forms.Textarea(attrs={'placeholder': _('ssh-rsa AAAA...')}),
|
||||
help_text=_('Paste user id_rsa.pub here.')
|
||||
)
|
||||
|
||||
class Meta:
|
||||
model = User
|
||||
fields = [
|
||||
'username', 'name', 'email', 'groups', 'wechat',
|
||||
'source', 'phone', 'role', 'date_expired',
|
||||
'comment', 'mfa_level'
|
||||
]
|
||||
widgets = {
|
||||
'mfa_level': forms.RadioSelect(),
|
||||
'groups': forms.SelectMultiple(
|
||||
attrs={
|
||||
'class': 'select2',
|
||||
'data-placeholder': _('Join user groups')
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.request = kwargs.pop("request", None)
|
||||
super(UserCreateUpdateFormMixin, self).__init__(*args, **kwargs)
|
||||
|
||||
roles = []
|
||||
# Super admin user
|
||||
if self.request.user.is_superuser:
|
||||
roles.append((User.ROLE_ADMIN, dict(User.ROLE_CHOICES).get(User.ROLE_ADMIN)))
|
||||
roles.append((User.ROLE_USER, dict(User.ROLE_CHOICES).get(User.ROLE_USER)))
|
||||
roles.append((User.ROLE_AUDITOR, dict(User.ROLE_CHOICES).get(User.ROLE_AUDITOR)))
|
||||
|
||||
# Org admin user
|
||||
else:
|
||||
user = kwargs.get('instance')
|
||||
# Update
|
||||
if user:
|
||||
role = kwargs.get('instance').role
|
||||
roles.append((role, dict(User.ROLE_CHOICES).get(role)))
|
||||
# Create
|
||||
else:
|
||||
roles.append((User.ROLE_USER, dict(User.ROLE_CHOICES).get(User.ROLE_USER)))
|
||||
|
||||
field = self.fields['role']
|
||||
field.choices = set(roles)
|
||||
|
||||
def clean_public_key(self):
|
||||
public_key = self.cleaned_data['public_key']
|
||||
if not public_key:
|
||||
return public_key
|
||||
if self.instance.public_key and public_key == self.instance.public_key:
|
||||
msg = _('Public key should not be the same as your old one.')
|
||||
raise forms.ValidationError(msg)
|
||||
|
||||
if not validate_ssh_public_key(public_key):
|
||||
raise forms.ValidationError(_('Not a valid ssh public key'))
|
||||
return public_key
|
||||
|
||||
def clean_password(self):
|
||||
password_strategy = self.data.get('password_strategy')
|
||||
# 创建-不设置密码
|
||||
if password_strategy == '0':
|
||||
return
|
||||
password = self.data.get('password')
|
||||
# 更新-密码为空
|
||||
if password_strategy is None and not password:
|
||||
return
|
||||
if not check_password_rules(password):
|
||||
msg = _('* Your password does not meet the requirements')
|
||||
raise forms.ValidationError(msg)
|
||||
return password
|
||||
|
||||
def save(self, commit=True):
|
||||
password = self.cleaned_data.get('password')
|
||||
mfa_level = self.cleaned_data.get('mfa_level')
|
||||
public_key = self.cleaned_data.get('public_key')
|
||||
user = super().save(commit=commit)
|
||||
if password:
|
||||
user.reset_password(password)
|
||||
if mfa_level:
|
||||
user.mfa_level = mfa_level
|
||||
user.save()
|
||||
if public_key:
|
||||
user.public_key = public_key
|
||||
user.save()
|
||||
return user
|
||||
|
||||
|
||||
class UserCreateForm(UserCreateUpdateFormMixin):
|
||||
EMAIL_SET_PASSWORD = _('Reset link will be generated and sent to the user')
|
||||
CUSTOM_PASSWORD = _('Set password')
|
||||
PASSWORD_STRATEGY_CHOICES = (
|
||||
(0, EMAIL_SET_PASSWORD),
|
||||
(1, CUSTOM_PASSWORD)
|
||||
)
|
||||
password_strategy = forms.ChoiceField(
|
||||
choices=PASSWORD_STRATEGY_CHOICES, required=True, initial=0,
|
||||
widget=forms.RadioSelect(), label=_('Password strategy')
|
||||
)
|
||||
|
||||
|
||||
class UserUpdateForm(UserCreateUpdateFormMixin):
|
||||
pass
|
||||
|
||||
|
||||
class UserBulkUpdateForm(OrgModelForm):
|
||||
users = forms.ModelMultipleChoiceField(
|
||||
required=True,
|
||||
label=_('Select users'),
|
||||
queryset=User.objects.none(),
|
||||
widget=forms.SelectMultiple(
|
||||
attrs={
|
||||
'class': 'users-select2',
|
||||
'data-placeholder': _('Select users')
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.set_fields_queryset()
|
||||
|
||||
def set_fields_queryset(self):
|
||||
users_field = self.fields['users']
|
||||
users_field.queryset = get_current_org_members()
|
||||
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ['users', 'groups', 'date_expired']
|
||||
widgets = {
|
||||
"groups": forms.SelectMultiple(
|
||||
attrs={
|
||||
'class': 'select2',
|
||||
'data-placeholder': _('User group')
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
def save(self, commit=True):
|
||||
changed_fields = []
|
||||
for field in self._meta.fields:
|
||||
if self.data.get(field) is not None:
|
||||
changed_fields.append(field)
|
||||
|
||||
cleaned_data = {k: v for k, v in self.cleaned_data.items()
|
||||
if k in changed_fields}
|
||||
users = cleaned_data.pop('users', '')
|
||||
groups = cleaned_data.pop('groups', [])
|
||||
users = User.objects.filter(id__in=[user.id for user in users])
|
||||
users.update(**cleaned_data)
|
||||
if groups:
|
||||
for user in users:
|
||||
user.groups.set(groups)
|
||||
return users
|
||||
|
||||
|
||||
class UserCheckPasswordForm(forms.Form):
|
||||
password = forms.CharField(
|
||||
label=_('Password'), widget=forms.PasswordInput,
|
||||
max_length=128, strip=False
|
||||
)
|
||||
|
||||
|
||||
class UserCheckOtpCodeForm(forms.Form):
|
||||
otp_code = forms.CharField(label=_('MFA code'), max_length=6)
|
Reference in New Issue
Block a user