diff --git a/apps/i18n/lina/en.json b/apps/i18n/lina/en.json index fff447db0..0cd3f2ef2 100644 --- a/apps/i18n/lina/en.json +++ b/apps/i18n/lina/en.json @@ -202,7 +202,7 @@ "BuiltinVariable": "Built-in variables", "BulkUnblock": "Batch unlock", "CACertificate": "Ca certificate", - "CAS": "Cas", + "CAS": "CAS", "CMPP2": "Cmpp v2.0", "CTYunPrivate": "Tianyi private cloud", "CalculationResults": "Error in cron expression", @@ -394,7 +394,7 @@ "DeviceCreate": "Create asset - device", "DeviceUpdate": "Update the asset - device", "Digit": "Number", - "DingTalk": "Dingtalk", + "DingTalk": "DingTalk", "DingTalkOAuth": "DingTalk OAuth", "DingTalkTest": "Test", "Disable": "Disable", @@ -609,7 +609,7 @@ "Last30Days": "Monthly", "Last7Days": "Weekly", "LastPublishedTime": "Last publish time", - "Ldap": "Ldap", + "Ldap": "LDAP", "LdapBulkImport": "User import", "LdapConnectTest": "Test connection", "LdapLoginTest": "Test login", @@ -730,9 +730,9 @@ "Now": "Now", "Number": "No.", "NumberOfVisits": "Visits", - "OAuth2": "Oauth2", + "OAuth2": "OAuth2", "OAuth2LogoTip": "Note: authentication provider (recommended image size: 64px*64px)", - "OIDC": "Oidc", + "OIDC": "OIDC", "ObjectNotFoundOrDeletedMsg": "No corresponding resources found or it has been deleted.", "Offline": "Offline", "OfflineSelected": "Offline selected", @@ -1281,7 +1281,7 @@ "VirtualApps": "VApp", "Volcengine": "Volcengine", "Warning": "Warning", - "WeCom": "Wecom", + "WeCom": "WeCom", "WeComOAuth": "WeCom OAuth", "WeComTest": "Test", "WebCreate": "Create asset - web", @@ -1310,5 +1310,6 @@ "SiteURLTip": "For example: https://demo.jumpserver.org", "Settings...": "Settings...", "EmailTemplate": "Template", - "EmailTemplateHelpTip": "Email template is used for sending emails and includes the email subject prefix and email content" + "EmailTemplateHelpTip": "Email template is used for sending emails and includes the email subject prefix and email content", + "ForgotPasswordURL": "Forgot password URL" } \ No newline at end of file diff --git a/apps/settings/serializers/auth/base.py b/apps/settings/serializers/auth/base.py index 881764492..a9292acfc 100644 --- a/apps/settings/serializers/auth/base.py +++ b/apps/settings/serializers/auth/base.py @@ -24,12 +24,21 @@ class AuthSettingSerializer(serializers.Serializer): AUTH_PASSKEY = serializers.BooleanField(default=False, label=_("Passkey Auth")) EMAIL_SUFFIX = serializers.CharField( required=False, max_length=1024, label=_("Email suffix"), - help_text=_('This is used by default if no email is returned during SSO authentication') + help_text=_( + "After third-party user authentication is successful, " + "if the third-party authentication service platform does not return the user's email " + "information, the system will automatically create the user using this email suffix" + ) ) FORGOT_PASSWORD_URL = serializers.CharField( required=False, allow_blank=True, max_length=1024, - label=_("Forgot Password URL") + label=_("Forgot Password"), + help_text=_("The URL for Forgotten Password on the user login page") ) LOGIN_REDIRECT_MSG_ENABLED = serializers.BooleanField( - required=False, label=_("Login redirection prompt") + required=False, label=_("Login redirection"), + help_text=_( + "Should an flash page be displayed before the user is redirected to third-party " + "authentication when the administrator enables third-party redirect authentication" + ) ) diff --git a/apps/settings/serializers/auth/cas.py b/apps/settings/serializers/auth/cas.py index d66dadd7d..4ab017eaf 100644 --- a/apps/settings/serializers/auth/cas.py +++ b/apps/settings/serializers/auth/cas.py @@ -15,7 +15,10 @@ class CASSettingSerializer(serializers.Serializer): required=False, allow_null=True, allow_blank=True, max_length=1024, label=_('Proxy Server') ) - CAS_LOGOUT_COMPLETELY = serializers.BooleanField(required=False, label=_('Logout completely')) + CAS_LOGOUT_COMPLETELY = serializers.BooleanField( + required=False, label=_('Logout completely'), + help_text=_('When the user signs out, they also be logged out from the CAS Server') + ) CAS_VERSION = serializers.IntegerField( required=False, label=_('Version'), min_value=1, max_value=3 ) @@ -25,8 +28,17 @@ class CASSettingSerializer(serializers.Serializer): CAS_APPLY_ATTRIBUTES_TO_USER = serializers.BooleanField( required=False, label=_('Enable attributes map') ) - CAS_RENAME_ATTRIBUTES = serializers.JSONField(required=False, label=_('User attribute')) + CAS_RENAME_ATTRIBUTES = serializers.JSONField( + required=False, label=_('User attribute'), + help_text=_( + "User attribute mapping, where the `key` is the CAS service user attribute name " + "and the `value` is the JumpServer user attribute name" + ) + ) CAS_CREATE_USER = serializers.BooleanField( required=False, label=_('Create user'), - help_text=_('Automatically create a new user if not found.') + help_text=_( + 'After successful user authentication, if the user does not exist, ' + 'automatically create the user' + ) ) diff --git a/apps/settings/serializers/auth/ldap.py b/apps/settings/serializers/auth/ldap.py index 16db90d3f..ada7ea84b 100644 --- a/apps/settings/serializers/auth/ldap.py +++ b/apps/settings/serializers/auth/ldap.py @@ -40,24 +40,32 @@ class LDAPSettingSerializer(serializers.Serializer): AUTH_LDAP_SERVER_URI = serializers.CharField( required=True, max_length=1024, label=_('Server'), - help_text=_('eg: ldap://localhost:389') + help_text=_('LDAP server URI') + ) + AUTH_LDAP_BIND_DN = serializers.CharField( + required=False, max_length=1024, label=_('Bind DN'), + help_text=_('Binding Distinguished Name') ) - AUTH_LDAP_BIND_DN = serializers.CharField(required=False, max_length=1024, label=_('Bind DN')) AUTH_LDAP_BIND_PASSWORD = EncryptedField( - max_length=1024, required=False, label=_('Password') + max_length=1024, required=False, label=_('Password'), + help_text=_('Binding password') ) AUTH_LDAP_SEARCH_OU = serializers.CharField( - max_length=1024, allow_blank=True, required=False, label=_('User OU'), - help_text=_('Use | split multi OUs') + max_length=1024, allow_blank=True, required=False, label=_('Search OU'), + help_text=_( + 'User Search Base, if there are multiple OUs, you can separate them with the `|` symbol' + ) ) AUTH_LDAP_SEARCH_FILTER = serializers.CharField( - max_length=1024, required=True, label=_('User search filter'), - help_text=_('Choice may be (cn|uid|sAMAccountName)=%(user)s)') + max_length=1024, required=True, label=_('Search filter'), + help_text=_('Selection could include (cn|uid|sAMAccountName=%(user)s)') ) AUTH_LDAP_USER_ATTR_MAP = serializers.JSONField( required=True, label=_('User attribute'), - help_text=_('User attr map present how to map LDAP user attr to ' - 'jumpserver, username,name,email is jumpserver attr') + help_text=_( + 'User attribute mapping, where the `key` is the JumpServer user attribute name and the ' + '`value` is the LDAP service user attribute name' + ) ) AUTH_LDAP_SYNC_ORG_IDS = serializers.ListField( required=False, label=_('Organization'), max_length=36 @@ -85,7 +93,9 @@ class LDAPSettingSerializer(serializers.Serializer): 'improve the speed of user authentication., 0 means no cache' ) ) - AUTH_LDAP_SEARCH_PAGED_SIZE = serializers.IntegerField(required=False, label=_('Search paged size (piece)')) + AUTH_LDAP_SEARCH_PAGED_SIZE = serializers.IntegerField( + required=False, label=_('Search paged size (piece)') + ) AUTH_LDAP_SYNC_RECEIVERS = serializers.ListField( required=False, label=_('Recipient'), max_length=36 ) diff --git a/apps/settings/serializers/auth/oidc.py b/apps/settings/serializers/auth/oidc.py index 44cecfbd5..2f974286e 100644 --- a/apps/settings/serializers/auth/oidc.py +++ b/apps/settings/serializers/auth/oidc.py @@ -13,7 +13,8 @@ class CommonSettingSerializer(serializers.Serializer): # OpenID 公有配置参数 (version <= 1.5.8 或 version >= 1.5.8) BASE_SITE_URL = serializers.CharField( required=False, allow_null=True, allow_blank=True, - max_length=1024, label=_('Base site URL') + max_length=1024, label=_('Base site URL'), + help_text=_("The current site's URL is used to construct the callback address") ) AUTH_OPENID_CLIENT_ID = serializers.CharField( required=False, max_length=1024, label=_('Client Id') @@ -35,8 +36,10 @@ class CommonSettingSerializer(serializers.Serializer): ) AUTH_OPENID_USER_ATTR_MAP = serializers.JSONField( required=True, label=_('User attribute'), - help_text=_('User attr map present how to map OpenID user attr to ' - 'jumpserver, username,name,email is jumpserver attr') + help_text=_( + "User attribute mapping, where the `key` is the JumpServer user attribute name " + "and the `value` is the OIDC service user attribute name" + ) ) AUTH_OPENID_PKCE = serializers.BooleanField(required=False, label=_('Enable PKCE')) AUTH_OPENID_CODE_CHALLENGE_METHOD = serializers.ChoiceField( @@ -48,7 +51,10 @@ class CommonSettingSerializer(serializers.Serializer): class KeycloakSettingSerializer(CommonSettingSerializer): # OpenID 旧配置参数 (version <= 1.5.8 (discarded)) AUTH_OPENID_KEYCLOAK = serializers.BooleanField( - label=_("Use Keycloak"), required=False, default=False + label=_("Use Keycloak"), required=False, default=False, + help_text=_( + "Use Keycloak as the OpenID Connect server, or use standard OpenID Connect Protocol" + ) ) AUTH_OPENID_SERVER_URL = serializers.CharField( required=False, max_length=1024, label=_('Server') @@ -60,7 +66,9 @@ class KeycloakSettingSerializer(CommonSettingSerializer): class OIDCSettingSerializer(KeycloakSettingSerializer): # OpenID 新配置参数 (version >= 1.5.9) - AUTH_OPENID = serializers.BooleanField(required=False, label=_('OIDC')) + AUTH_OPENID = serializers.BooleanField( + required=False, label=_('OIDC'), help_text=_('OpenID Connect') + ) AUTH_OPENID_PROVIDER_ENDPOINT = serializers.CharField( required=False, max_length=1024, label=_('Provider endpoint') ) @@ -85,15 +93,21 @@ class OIDCSettingSerializer(KeycloakSettingSerializer): AUTH_OPENID_PROVIDER_SIGNATURE_KEY = serializers.CharField( required=False, max_length=1024, allow_null=True, label=_('Signing key') ) - AUTH_OPENID_SCOPES = serializers.CharField(required=False, max_length=1024, label=_('Scopes')) + AUTH_OPENID_SCOPES = serializers.CharField( + required=False, max_length=1024, label=_('Scopes') + ) AUTH_OPENID_ID_TOKEN_MAX_AGE = serializers.IntegerField( required=False, label=_('ID Token max age (s)') ) AUTH_OPENID_ID_TOKEN_INCLUDE_CLAIMS = serializers.BooleanField( required=False, label=_('ID Token include claims') ) - AUTH_OPENID_USE_STATE = serializers.BooleanField(required=False, label=_('Use state')) - AUTH_OPENID_USE_NONCE = serializers.BooleanField(required=False, label=_('Use nonce')) + AUTH_OPENID_USE_STATE = serializers.BooleanField( + required=False, label=_('Use state') + ) + AUTH_OPENID_USE_NONCE = serializers.BooleanField( + required=False, label=_('Use nonce') + ) AUTH_OPENID_ALWAYS_UPDATE_USER = serializers.BooleanField( required=False, label=_('Always update user') ) diff --git a/apps/users/models/user.py b/apps/users/models/user.py index 6cd20b7ab..52ff822d8 100644 --- a/apps/users/models/user.py +++ b/apps/users/models/user.py @@ -668,11 +668,13 @@ class MFAMixin: @property def mfa_force_enabled(self): force_level = settings.SECURITY_MFA_AUTH + # 1 All users if force_level in [True, 1]: return True - # 2 管理员强制开启 + # 2 仅管理员强制开启 if force_level == 2 and self.is_org_admin: return True + # 3 仅用户开启 return self.mfa_level == 2 def enable_mfa(self):