mirror of
https://github.com/jumpserver/jumpserver.git
synced 2026-03-18 11:02:09 +00:00
perf: update zip and agreement
This commit is contained in:
129
apps/authentication/templates/authentication/agreement.html
Normal file
129
apps/authentication/templates/authentication/agreement.html
Normal file
@@ -0,0 +1,129 @@
|
||||
<!doctype html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>User Agreement & Privacy Policy</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<style>
|
||||
body {
|
||||
font-family:
|
||||
-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial,
|
||||
'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', sans-serif;
|
||||
line-height: 1.7;
|
||||
color: #333;
|
||||
max-width: 960px;
|
||||
margin: 0 auto;
|
||||
padding: 24px;
|
||||
background: #fff;
|
||||
}
|
||||
h1,
|
||||
h2,
|
||||
h3 {
|
||||
color: #111;
|
||||
margin-top: 1.6em;
|
||||
}
|
||||
h1 {
|
||||
font-size: 26px;
|
||||
border-bottom: 2px solid #eee;
|
||||
padding-bottom: 8px;
|
||||
}
|
||||
h2 {
|
||||
font-size: 20px;
|
||||
}
|
||||
p,
|
||||
li {
|
||||
font-size: 14px;
|
||||
}
|
||||
ul {
|
||||
padding-left: 20px;
|
||||
}
|
||||
.lang {
|
||||
margin-top: 48px;
|
||||
padding-top: 24px;
|
||||
border-top: 2px dashed #ddd;
|
||||
}
|
||||
.note {
|
||||
background: #f8f9fa;
|
||||
border-left: 4px solid #409eff;
|
||||
padding: 12px 16px;
|
||||
margin: 16px 0;
|
||||
font-size: 13px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- ================= ENGLISH ================= -->
|
||||
<div>
|
||||
<h1>User Agreement & Privacy Policy</h1>
|
||||
|
||||
<p>
|
||||
<strong>Version:</strong> 2026-01<br />
|
||||
<strong>Effective Date:</strong> Feb 1, 2026
|
||||
</p>
|
||||
|
||||
<h2>1. User Agreement</h2>
|
||||
|
||||
<h3>1.1 Product Nature</h3>
|
||||
<p>
|
||||
This system is an enterprise-grade system deployed in a private environment. All
|
||||
deployment environments and data are fully controlled by the customer.
|
||||
</p>
|
||||
|
||||
<h3>1.2 User Obligations</h3>
|
||||
<ul>
|
||||
<li>Use the system only within authorized scope;</li>
|
||||
<li>Do not perform illegal or unauthorized activities;</li>
|
||||
<li>Do not bypass or interfere with security controls and audit mechanisms.</li>
|
||||
</ul>
|
||||
|
||||
<h3>1.3 Account Security</h3>
|
||||
<p>
|
||||
Users are responsible for safeguarding their credentials. Risks caused by improper
|
||||
credential management shall be borne by the user or customer.
|
||||
</p>
|
||||
|
||||
<h2>2. Privacy Policy</h2>
|
||||
|
||||
<h3>2.1 Scope</h3>
|
||||
<p>
|
||||
This policy applies to the privately deployed version of this system. All personal
|
||||
data is stored within the customer's own environment. The software provider does not
|
||||
access, store, or transmit such data.
|
||||
</p>
|
||||
|
||||
<h3>2.2 Personal Information We Process</h3>
|
||||
<ul>
|
||||
<li>Username</li>
|
||||
<li>Phone number</li>
|
||||
<li>Email address</li>
|
||||
</ul>
|
||||
|
||||
<h3>2.3 Authentication Information</h3>
|
||||
<p>
|
||||
Passwords are never stored in plaintext. Only irreversible encrypted password hashes
|
||||
are stored for authentication.
|
||||
</p>
|
||||
|
||||
<h3>2.4 Facial Recognition Data</h3>
|
||||
<p>
|
||||
Facial recognition is an optional premium feature and is disabled by default. If
|
||||
enabled, facial image or feature data will be processed solely for identity
|
||||
verification.
|
||||
</p>
|
||||
<p>
|
||||
Such data is considered sensitive personal information and is stored only within the
|
||||
customer's local environment.
|
||||
</p>
|
||||
|
||||
<h3>2.5 Cookies and Similar Technologies</h3>
|
||||
<p>
|
||||
Necessary cookies and session identifiers are used to maintain login sessions and
|
||||
system security. These technologies are not used for advertising or cross-site
|
||||
tracking.
|
||||
</p>
|
||||
|
||||
<h3>2.6 Policy Updates</h3>
|
||||
<p>Material changes to this policy will require renewed user consent.</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
165
apps/authentication/templates/authentication/agreement_zh.html
Normal file
165
apps/authentication/templates/authentication/agreement_zh.html
Normal file
@@ -0,0 +1,165 @@
|
||||
<!doctype html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>用户协议与隐私政策</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<style>
|
||||
body {
|
||||
font-family:
|
||||
-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial,
|
||||
'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', sans-serif;
|
||||
line-height: 1.7;
|
||||
color: #333;
|
||||
max-width: 960px;
|
||||
margin: 0 auto;
|
||||
padding: 24px;
|
||||
background: #fff;
|
||||
}
|
||||
h1,
|
||||
h2,
|
||||
h3 {
|
||||
color: #111;
|
||||
margin-top: 1.6em;
|
||||
}
|
||||
h1 {
|
||||
font-size: 26px;
|
||||
border-bottom: 2px solid #eee;
|
||||
padding-bottom: 8px;
|
||||
}
|
||||
h2 {
|
||||
font-size: 20px;
|
||||
}
|
||||
p,
|
||||
li {
|
||||
font-size: 14px;
|
||||
}
|
||||
ul {
|
||||
padding-left: 20px;
|
||||
}
|
||||
.lang {
|
||||
margin-top: 48px;
|
||||
padding-top: 24px;
|
||||
border-top: 2px dashed #ddd;
|
||||
}
|
||||
.note {
|
||||
background: #f8f9fa;
|
||||
border-left: 4px solid #409eff;
|
||||
padding: 12px 16px;
|
||||
margin: 16px 0;
|
||||
font-size: 13px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div>
|
||||
<h1>用户协议与隐私政策</h1>
|
||||
|
||||
<p>
|
||||
<strong>版本号:</strong>2026-01<br />
|
||||
<strong>生效日期:</strong>2026-02-01
|
||||
</p>
|
||||
|
||||
<div class="note">本软件为企业级私有化部署系统,仅供客户内部授权人员使用。</div>
|
||||
|
||||
<h2>一、用户协议</h2>
|
||||
|
||||
<h3>1. 产品性质</h3>
|
||||
<p>
|
||||
本系统为企业级运维与安全管理系统,
|
||||
采用私有化部署方式运行,系统的部署环境、运行环境及数据均由客户自行控制。
|
||||
</p>
|
||||
|
||||
<h3>2. 用户行为规范</h3>
|
||||
<ul>
|
||||
<li>用户应在客户授权范围内使用本系统;</li>
|
||||
<li>不得利用本系统从事违法、违规或未授权行为;</li>
|
||||
<li>不得破坏、规避或干扰系统的安全审计与控制机制。</li>
|
||||
</ul>
|
||||
|
||||
<h3>3. 账号与凭证安全</h3>
|
||||
<p>
|
||||
用户应妥善保管自身账号及认证凭证。
|
||||
因用户个人原因导致的账号安全风险,由用户或客户自行承担。
|
||||
</p>
|
||||
|
||||
<h3>4. 协议变更</h3>
|
||||
<p>如本协议内容发生实质性变更,系统将提示用户重新确认。</p>
|
||||
|
||||
<hr />
|
||||
|
||||
<h2>二、隐私政策</h2>
|
||||
|
||||
<h3>1. 适用范围</h3>
|
||||
<p>
|
||||
本隐私政策适用于本系统私有化部署版本。 系统所产生的数据均存储于客户自有环境中,
|
||||
软件提供方不接触、不存储、不回传客户业务数据或个人信息。
|
||||
</p>
|
||||
|
||||
<h3>2. 我们收集和使用的个人信息</h3>
|
||||
|
||||
<h4>2.1 基本账号信息</h4>
|
||||
<ul>
|
||||
<li>用户名</li>
|
||||
<li>手机号码</li>
|
||||
<li>电子邮箱</li>
|
||||
</ul>
|
||||
<p>用于账号管理、身份识别与安全通知。</p>
|
||||
|
||||
<h4>2.2 身份认证信息</h4>
|
||||
<p>系统不会以明文形式存储用户密码, 仅以不可逆加密方式保存密码摘要,用于身份校验。</p>
|
||||
|
||||
<h4>2.3 日志与审计信息</h4>
|
||||
<ul>
|
||||
<li>登录时间、登录 IP</li>
|
||||
<li>用户操作审计日志</li>
|
||||
</ul>
|
||||
<p>用于安全审计、合规留痕与问题追溯。</p>
|
||||
|
||||
<h3>3. 敏感个人信息的处理(人脸识别)</h3>
|
||||
<p>人脸识别功能为可选增值服务,默认不开启, 仅在客户或用户主动启用后生效。</p>
|
||||
<p>
|
||||
如启用该功能,系统将采集并处理用户的人脸图像或特征信息,
|
||||
用于身份认证与防止账号冒用。
|
||||
</p>
|
||||
<p>
|
||||
上述信息属于敏感个人信息, 仅存储和处理于客户自有部署环境中,
|
||||
不会传输至软件提供方服务器。
|
||||
</p>
|
||||
<p>用户或客户管理员可随时关闭人脸识别功能, 并删除已采集的人脸信息。</p>
|
||||
|
||||
<h3>4. Cookie 与同类技术</h3>
|
||||
<p>
|
||||
为保障系统正常运行、登录状态维持及安全防护, 系统会在用户设备中存储必要的 Cookie
|
||||
或会话标识 (如 Session、CSRF Token)。
|
||||
</p>
|
||||
<p>上述技术仅用于系统功能实现, 不用于广告投放或跨站追踪。</p>
|
||||
|
||||
<h3>5. 数据存储位置与期限</h3>
|
||||
<p>系统中的个人信息均存储于客户自有环境中, 具体保存期限由客户根据自身管理要求决定。</p>
|
||||
|
||||
<h3>6. 信息共享、转让与披露</h3>
|
||||
<p>
|
||||
软件提供方不会共享、转让或披露系统中的个人信息,
|
||||
但法律法规或司法机关另有要求的除外。
|
||||
</p>
|
||||
|
||||
<h3>7. 用户权利</h3>
|
||||
<ul>
|
||||
<li>查询、更正个人信息</li>
|
||||
<li>删除个人信息(在权限允许范围内)</li>
|
||||
<li>关闭或删除人脸识别信息</li>
|
||||
</ul>
|
||||
|
||||
<h3>8. 安全措施</h3>
|
||||
<ul>
|
||||
<li>加密存储与传输</li>
|
||||
<li>访问控制与权限管理</li>
|
||||
<li>操作审计与日志留存</li>
|
||||
</ul>
|
||||
|
||||
<h3>9. 隐私政策更新</h3>
|
||||
<p>如本隐私政策发生实质性变更, 系统将要求用户重新确认后方可继续使用。</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -84,5 +84,6 @@ urlpatterns = [
|
||||
|
||||
path('captcha/', include('captcha.urls')),
|
||||
|
||||
path('oauth2-provider/', include(('authentication.backends.oauth2_provider.urls', 'authentication'), namespace='oauth2-provider'))
|
||||
path('oauth2-provider/', include(('authentication.backends.oauth2_provider.urls', 'authentication'), namespace='oauth2-provider')),
|
||||
path('agreement/', views.AgreementView.as_view(), name='agreement'),
|
||||
]
|
||||
|
||||
@@ -7,3 +7,4 @@ from .login import *
|
||||
from .mfa import *
|
||||
from .slack import *
|
||||
from .wecom import *
|
||||
from .agreement import *
|
||||
13
apps/authentication/views/agreement.py
Normal file
13
apps/authentication/views/agreement.py
Normal file
@@ -0,0 +1,13 @@
|
||||
from django.views.generic import TemplateView
|
||||
from django.utils.translation import get_language
|
||||
|
||||
__all__ = ['AgreementView']
|
||||
|
||||
class AgreementView(TemplateView):
|
||||
|
||||
def get_template_names(self):
|
||||
current_lang = get_language() or 'zh-cn'
|
||||
if current_lang.startswith('zh'):
|
||||
return 'authentication/agreement_zh.html'
|
||||
else:
|
||||
return 'authentication/agreement.html'
|
||||
@@ -2,6 +2,7 @@ import os
|
||||
import stat
|
||||
import hashlib
|
||||
from pathlib import Path
|
||||
from rest_framework.exceptions import ValidationError
|
||||
from zipfile import ZipFile, BadZipFile
|
||||
|
||||
|
||||
@@ -14,7 +15,7 @@ MAX_TOTAL_SIZE = 1 * 1024 * 1024 * 1024 # 1GB
|
||||
MAX_COMPRESSION_RATIO = 100 # 解压 / 压缩
|
||||
|
||||
|
||||
class ZipSecurityError(Exception):
|
||||
class ZipSecurityError(ValidationError):
|
||||
pass
|
||||
|
||||
|
||||
|
||||
@@ -1639,5 +1639,9 @@
|
||||
"AccountSecretReadDisabled": "Account secret reading has been disabled by administrator",
|
||||
"AccessToken": "Access tokens",
|
||||
"AccessTokenTip": "Access Token is a temporary credential generated through the OAuth2 (Authorization Code Grant) flow using the JumpServer client, which is used to access protected resources.",
|
||||
"Revoke": "Revoke"
|
||||
}
|
||||
"Revoke": "Revoke",
|
||||
"ReadAgreeTo": "I have read and agree to the",
|
||||
"TermsOfService": "Terms of Service",
|
||||
"PrivacyPolicy": "Privacy Policy",
|
||||
"and": "and"
|
||||
}
|
||||
|
||||
@@ -1650,5 +1650,9 @@
|
||||
"AccessTokenTip": "访问令牌是通过 JumpServer 客户端使用 OAuth2(授权码授权)流程生成的临时凭证,用于访问受保护的资源。",
|
||||
"Revoke": "撤销",
|
||||
"AccountSecretReadDisabled": "账号密码读取功能已被管理员禁用",
|
||||
"Automations": "自动化"
|
||||
}
|
||||
"Automations": "自动化",
|
||||
"ReadAgreeTo": "我已阅读并同意",
|
||||
"TermsOfService": "服务条款",
|
||||
"PrivacyPolicy": "隐私政策",
|
||||
"and": "和"
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import os
|
||||
import shutil
|
||||
import zipfile
|
||||
|
||||
from django.conf import settings
|
||||
from django.core.exceptions import SuspiciousFileOperation
|
||||
@@ -13,6 +12,7 @@ from common.api.generic import JMSBulkModelViewSet
|
||||
from common.exceptions import JMSException
|
||||
from common.permissions import IsOwnerOrAdminWritable
|
||||
from common.utils.http import is_true
|
||||
from common.utils.zip import safe_extract_zip
|
||||
from rbac.permissions import RBACPermission
|
||||
from ..const import Scope
|
||||
from ..exception import PlaybookNoValidEntry
|
||||
@@ -27,9 +27,7 @@ from django.utils._os import safe_join
|
||||
|
||||
|
||||
def unzip_playbook(src, dest):
|
||||
fz = zipfile.ZipFile(src, 'r')
|
||||
for file in fz.namelist():
|
||||
fz.extract(file, dest)
|
||||
safe_extract_zip(src, dest)
|
||||
|
||||
|
||||
class PlaybookViewSet(JMSBulkModelViewSet):
|
||||
|
||||
@@ -2,7 +2,6 @@ import os
|
||||
import os.path
|
||||
import re
|
||||
import shutil
|
||||
import zipfile
|
||||
from typing import Callable
|
||||
|
||||
from django.conf import settings
|
||||
@@ -22,6 +21,7 @@ from common.utils import is_uuid
|
||||
from common.utils.http import is_true
|
||||
from terminal import serializers
|
||||
from terminal.models import AppletPublication, Applet
|
||||
from common.utils.zip import safe_extract_zip
|
||||
|
||||
__all__ = ['AppletViewSet', 'AppletPublicationViewSet']
|
||||
|
||||
@@ -47,10 +47,7 @@ class DownloadUploadMixin:
|
||||
shutil.rmtree(extract_to)
|
||||
|
||||
try:
|
||||
with zipfile.ZipFile(path) as zp:
|
||||
if zp.testzip() is not None:
|
||||
raise ValidationError({'error': _('Invalid zip file')})
|
||||
zp.extractall(extract_to)
|
||||
safe_extract_zip(path, extract_to)
|
||||
except RuntimeError as e:
|
||||
raise ValidationError({'error': _('Invalid zip file') + ': {}'.format(e)})
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import os.path
|
||||
import shutil
|
||||
import zipfile
|
||||
from typing import Callable
|
||||
|
||||
from django.core.files.storage import default_storage
|
||||
@@ -16,6 +15,7 @@ from common.api import JMSBulkModelViewSet
|
||||
from common.serializers import FileSerializer
|
||||
from terminal import serializers
|
||||
from terminal.models import VirtualAppPublication, VirtualApp
|
||||
from common.utils.zip import safe_extract_zip
|
||||
|
||||
__all__ = ['VirtualAppViewSet', 'VirtualAppPublicationViewSet']
|
||||
|
||||
@@ -38,10 +38,7 @@ class UploadMixin:
|
||||
if os.path.exists(extract_to):
|
||||
shutil.rmtree(extract_to)
|
||||
try:
|
||||
with zipfile.ZipFile(path) as zp:
|
||||
if zp.testzip() is not None:
|
||||
raise ValidationError({'error': _('Invalid zip file')})
|
||||
zp.extractall(extract_to)
|
||||
safe_extract_zip(path, extract_to)
|
||||
except RuntimeError as e:
|
||||
raise ValidationError({'error': _('Invalid zip file') + ': {}'.format(e)})
|
||||
tmp_dir = safe_join(extract_to, file.name.replace('.zip', ''))
|
||||
|
||||
Reference in New Issue
Block a user