Compare commits

...

40 Commits

Author SHA1 Message Date
ibuler
d4dccb8876 fix: integrate with azure oidc 2025-07-10 11:32:10 +08:00
feng
3b24dd38b2 perf: Translate 2025-06-27 11:39:53 +08:00
feng
1a78eb8bb7 fix: ES search session count 2025-06-27 10:32:02 +08:00
ibuler
ede5fd906c fix: bitwardne request data encode 2025-06-26 15:23:46 +08:00
ibuler
0e15ba2197 perf: change some 18n 2025-06-26 14:53:32 +08:00
Bryan
a9399dd709 Merge pull request #15608 from jumpserver/dev
v4.10.2
2025-06-19 20:14:21 +08:00
Bryan
d0cb9e5432 Merge pull request #15412 from jumpserver/dev
v4.10.0
2025-05-15 17:11:43 +08:00
老广
558188da90 merge: dev to master
Ready to relase
2025-04-17 20:24:45 +08:00
Bryan
ad5460dab8 Merge pull request #15086 from jumpserver/dev
v4.8.0
2025-03-20 18:44:44 +08:00
Bryan
4d37dca0de Merge pull request #14901 from jumpserver/dev
v4.7.0
2025-02-20 10:21:16 +08:00
Bryan
2ca4002624 Merge pull request #14813 from jumpserver/dev
v4.6.0
2025-01-15 14:38:17 +08:00
Bryan
053d640e4c Merge pull request #14699 from jumpserver/dev
v4.5.0
2024-12-19 16:04:45 +08:00
Bryan
f3acc28ded Merge pull request #14697 from jumpserver/dev
v4.5.0
2024-12-19 15:57:11 +08:00
Bryan
25987545db Merge pull request #14511 from jumpserver/dev
v4.4.0
2024-11-21 19:00:35 +08:00
Bryan
6720ecc6e0 Merge pull request #14319 from jumpserver/dev
v4.3.0
2024-10-17 14:55:38 +08:00
老广
0b3a7bb020 Merge pull request #14203 from jumpserver/dev
merge: from dev to master
2024-09-19 19:37:19 +08:00
Bryan
56373e362b Merge pull request #13988 from jumpserver/dev
v4.1.0
2024-08-16 18:40:35 +08:00
Bryan
02fc045370 Merge pull request #13600 from jumpserver/dev
v4.0.0
2024-07-03 19:04:35 +08:00
Bryan
e4ac73896f Merge pull request #13452 from jumpserver/dev
v3.10.11-lts
2024-06-19 16:01:26 +08:00
Bryan
1518f792d6 Merge pull request #13236 from jumpserver/dev
v3.10.10-lts
2024-05-16 16:04:07 +08:00
Bai
67277dd622 fix: 修复仪表盘会话排序数量都是 1 的问题 2024-04-22 19:42:33 +08:00
Bryan
82e7f020ea Merge pull request #13094 from jumpserver/dev
v3.10.9 (dev to master)
2024-04-22 19:39:53 +08:00
Bryan
f20b9e01ab Merge pull request #13062 from jumpserver/dev
v3.10.8 dev to master
2024-04-18 18:01:20 +08:00
Bryan
8cf8a3701b Merge pull request #13059 from jumpserver/dev
v3.10.8
2024-04-18 17:16:37 +08:00
Bryan
7ba24293d1 Merge pull request #12736 from jumpserver/pr@dev@master_fix
fix: 解决冲突
2024-02-29 16:38:43 +08:00
Bai
f10114c9ed fix: 解决冲突 2024-02-29 16:37:10 +08:00
Bryan
cf31cbfb07 Merge pull request #12729 from jumpserver/dev
v3.10.4
2024-02-29 16:19:59 +08:00
wangruidong
0edad24d5d fix: 资产过期消息提示发送失败 2024-02-04 11:41:48 +08:00
ibuler
1f1c1a9157 fix: 修复定时检测用户是否活跃任务无法执行的问题 2024-01-23 09:28:38 +00:00
feng
6c9d271ae1 fix: redis 密码有特殊字符celery beat启动失败 2024-01-22 06:18:34 +00:00
Bai
6ff852e225 perf: 修复 Count 时没有去重的问题 2024-01-22 06:16:25 +00:00
Bryan
baa75dc735 Merge pull request #12566 from jumpserver/master
v3.10.2
2024-01-17 07:34:28 -04:00
Bryan
8a9f0436b8 Merge pull request #12565 from jumpserver/dev
v3.10.2
2024-01-17 07:23:30 -04:00
Bryan
a9620a3cbe Merge pull request #12461 from jumpserver/master
v3.10.1
2023-12-29 11:33:05 +05:00
Bryan
769e7dc8a0 Merge pull request #12460 from jumpserver/dev
v3.10.1
2023-12-29 11:20:36 +05:00
Bryan
2a70449411 Merge pull request #12458 from jumpserver/dev
v3.10.1
2023-12-29 11:01:13 +05:00
Bryan
8df720f19e Merge pull request #12401 from jumpserver/dev
v3.10
2023-12-21 15:14:19 +05:00
老广
dabbb45f6e Merge pull request #12144 from jumpserver/dev
v3.9.0
2023-11-16 18:23:05 +08:00
Bryan
ce24c1c3fd Merge pull request #11914 from jumpserver/dev
v3.8.0
2023-10-19 03:37:39 -05:00
Bryan
3c54c82ce9 Merge pull request #11636 from jumpserver/dev
v3.7.0
2023-09-21 17:02:48 +08:00
27 changed files with 195 additions and 102 deletions

11
.prettierrc Normal file
View File

@@ -0,0 +1,11 @@
{
"tabWidth": 4,
"useTabs": false,
"semi": true,
"singleQuote": true,
"trailingComma": "es5",
"bracketSpacing": true,
"arrowParens": "avoid",
"printWidth": 100,
"endOfLine": "lf"
}

View File

@@ -11,4 +11,4 @@ class ActionChoices(models.TextChoices):
notify_and_warn = 'notify_and_warn', _('Prompt and warn')
face_verify = 'face_verify', _('Face verify')
face_online = 'face_online', _('Face online')
change_secret = 'change_secret', _('Change secret')
change_secret = 'change_secret', _('Secret rotation')

View File

@@ -37,6 +37,7 @@ class UserConfirmationViewSet(JMSGenericViewSet):
backend_classes = ConfirmType.get_prop_backends(confirm_type)
if not backend_classes:
return
for backend_cls in backend_classes:
backend = backend_cls(self.request.user, self.request)
if not backend.check():
@@ -69,6 +70,7 @@ class UserConfirmationViewSet(JMSGenericViewSet):
ok, msg = backend.authenticate(secret_key, mfa_type)
if ok:
request.session['CONFIRM_LEVEL'] = ConfirmType.values.index(confirm_type) + 1
request.session['CONFIRM_TYPE'] = confirm_type
request.session['CONFIRM_TIME'] = int(time.time())
return Response('ok')
return Response({'error': msg}, status=400)

View File

@@ -224,7 +224,6 @@ class OIDCAuthCodeBackend(OIDCBaseBackend):
user_auth_failed.send(
sender=self.__class__, request=request, username=user.username,
reason="User is invalid", backend=settings.AUTH_BACKEND_OIDC_CODE
)
return None

View File

@@ -10,16 +10,15 @@ import datetime as dt
from calendar import timegm
from urllib.parse import urlparse
from django.conf import settings
from django.core.exceptions import SuspiciousOperation
from django.utils.encoding import force_bytes, smart_bytes
from jwkest import JWKESTException
from jwkest.jwk import KEYS
from jwkest.jws import JWS
from django.conf import settings
from common.utils import get_logger
logger = get_logger(__file__)
@@ -99,7 +98,8 @@ def _validate_claims(id_token, nonce=None, validate_nonce=True):
raise SuspiciousOperation('Incorrect id_token: nbf')
# Verifies that the token was issued in the allowed timeframe.
if utc_timestamp > id_token['iat'] + settings.AUTH_OPENID_ID_TOKEN_MAX_AGE:
max_age = settings.AUTH_OPENID_ID_TOKEN_MAX_AGE
if utc_timestamp > id_token['iat'] + max_age:
logger.debug(log_prompt.format('Incorrect id_token: iat'))
raise SuspiciousOperation('Incorrect id_token: iat')

View File

@@ -74,6 +74,7 @@ class PasskeyViewSet(AuthMixin, FlashMessageMixin, JMSModelViewSet):
if confirm_mfa:
request.session['CONFIRM_LEVEL'] = ConfirmType.values.index('mfa') + 1
request.session['CONFIRM_TIME'] = int(time.time())
request.session['CONFIRM_TYPE'] = ConfirmType.MFA
request.session['passkey_confirm_mfa'] = ''
return Response('ok')

View File

@@ -14,23 +14,29 @@ from orgs.utils import tmp_to_root_org
class UserConfirmation(permissions.BasePermission):
ttl = 60 * 5
min_level = 1
confirm_type = 'relogin'
min_type = 'relogin'
def has_permission(self, request, view):
if not settings.SECURITY_VIEW_AUTH_NEED_MFA:
return True
confirm_level = request.session.get('CONFIRM_LEVEL')
confirm_type = request.session.get('CONFIRM_TYPE')
confirm_time = request.session.get('CONFIRM_TIME')
ttl = self.get_ttl()
if not confirm_level or not confirm_time or \
confirm_level < self.min_level or \
confirm_time < time.time() - ttl:
raise UserConfirmRequired(code=self.confirm_type)
ttl = self.get_ttl(confirm_type)
now = int(time.time())
if not confirm_level or not confirm_time:
raise UserConfirmRequired(code=self.min_type)
if confirm_level < self.min_level or \
confirm_time < now - ttl:
raise UserConfirmRequired(code=self.min_type)
return True
def get_ttl(self):
if self.confirm_type == ConfirmType.MFA:
def get_ttl(self, confirm_type):
if confirm_type == ConfirmType.MFA:
ttl = settings.SECURITY_MFA_VERIFY_TTL
else:
ttl = self.ttl
@@ -40,7 +46,7 @@ class UserConfirmation(permissions.BasePermission):
def require(cls, confirm_type=ConfirmType.RELOGIN, ttl=60 * 5):
min_level = ConfirmType.values.index(confirm_type) + 1
name = 'UserConfirmationLevel{}TTL{}'.format(min_level, ttl)
return type(name, (cls,), {'min_level': min_level, 'ttl': ttl, 'confirm_type': confirm_type})
return type(name, (cls,), {'min_level': min_level, 'ttl': ttl, 'min_type': confirm_type})
class IsValidUserOrConnectionToken(IsValidUser):

View File

@@ -91,27 +91,30 @@
}
}
const publicKeyCredentialToJSON = (pubKeyCred) => {
if (pubKeyCred instanceof Array) {
const arr = []
for (const i of pubKeyCred) {
arr.push(publicKeyCredentialToJSON(i))
}
return arr
const publicKeyCredentialToJSON = pubKeyCred => {
if (pubKeyCred instanceof Array) {
const arr = []
for (const i of pubKeyCred) {
arr.push(publicKeyCredentialToJSON(i))
}
return arr
}
if (pubKeyCred instanceof ArrayBuffer || pubKeyCred instanceof Uint8Array) {
return encode(pubKeyCred)
}
if (pubKeyCred instanceof Object) {
const obj = {}
for (const key in pubKeyCred) {
obj[key] = publicKeyCredentialToJSON(pubKeyCred[key])
}
if (pubKeyCred instanceof ArrayBuffer) {
return encode(pubKeyCred)
}
return obj
}
if (pubKeyCred instanceof Object) {
const obj = {}
for (const key in pubKeyCred) {
obj[key] = publicKeyCredentialToJSON(pubKeyCred[key])
}
return obj
}
return pubKeyCred
return pubKeyCred
}
function GetAssertReq(getAssert) {

View File

@@ -315,6 +315,10 @@ class ES(object):
})
return _filter
@staticmethod
def is_keyword(props: dict, field: str) -> bool:
return props.get(field, {}).get("type", "keyword") == "keyword"
def get_query_body(self, **kwargs):
new_kwargs = {}
for k, v in kwargs.items():
@@ -347,13 +351,16 @@ class ES(object):
.get('mappings', {})
.get('properties', {})
)
org_id_type = props.get('org_id', {}).get('type', 'keyword')
common_keyword_able = exact_fields | keyword_fields
for k, v in kwargs.items():
if k == 'org_id' and org_id_type == 'keyword':
if k in ("org_id", "session") and self.is_keyword(props, k):
exact[k] = v
elif k in exact_fields.union(keyword_fields):
exact['{}.keyword'.format(k)] = v
elif k in common_keyword_able:
exact[f"{k}.keyword"] = v
elif k in match_fields:
match[k] = v
@@ -395,8 +402,8 @@ class ES(object):
'should': should + [
{'match': {k: v}} for k, v in match.items()
] + [
{'match': item} for item in search
],
{'match': item} for item in search
],
'filter': self.handle_exact_fields(exact) +
[
{
@@ -453,7 +460,7 @@ class QuerySet(DJQuerySet):
names, multi_args, multi_kwargs = zip(*filter_calls)
# input 输入
multi_args = tuple(reduce(lambda x, y: x + y, (sub for sub in multi_args if sub),()))
multi_args = tuple(reduce(lambda x, y: x + y, (sub for sub in multi_args if sub), ()))
args = self._grouped_search_args(multi_args)
striped_args = [{k.replace('__icontains', ''): v} for k, values in args.items() for v in values]
@@ -559,4 +566,4 @@ class QuerySet(DJQuerySet):
return iter(self.__execute())
def __len__(self):
return self.count()
return self.count()

View File

@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-06-19 20:06+0800\n"
"POT-Creation-Date: 2025-06-27 11:33+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -215,7 +215,7 @@ msgid "Push account"
msgstr ""
#: accounts/const/automation.py:26 accounts/risk_handlers.py:26
#: acls/const.py:14 audits/const.py:32 ops/const.py:9
#: audits/const.py:32 ops/const.py:9
msgid "Change secret"
msgstr ""
@@ -762,7 +762,7 @@ msgstr ""
#: accounts/serializers/account/account.py:279
#: accounts/templates/accounts/change_secret_failed_info.html:13
#: assets/const/automation.py:9
#: authentication/templates/authentication/passkey.html:174
#: authentication/templates/authentication/passkey.html:177
#: authentication/views/base.py:42 authentication/views/base.py:43
#: authentication/views/base.py:44 common/const/choices.py:67
#: settings/templates/ldap/_msg_import_ldap_user.html:26
@@ -1783,6 +1783,10 @@ msgstr ""
msgid "Face online"
msgstr ""
#: acls/const.py:14
msgid "Secret rotation"
msgstr ""
#: acls/models/base.py:37 assets/models/cmd_filter.py:76
#: terminal/models/component/endpoint.py:110 xpack/plugins/cloud/models.py:321
msgid "Priority"
@@ -3599,7 +3603,7 @@ msgstr ""
msgid "The value in the parameter must contain %s"
msgstr ""
#: authentication/api/confirm.py:50
#: authentication/api/confirm.py:51
msgid "This action require verify your MFA"
msgstr ""
@@ -4523,13 +4527,13 @@ msgstr ""
msgid "Copy success"
msgstr ""
#: authentication/templates/authentication/passkey.html:163
#: authentication/templates/authentication/passkey.html:166
msgid ""
"This page is not served over HTTPS. Please use HTTPS to ensure security of "
"your credentials."
msgstr ""
#: authentication/templates/authentication/passkey.html:174
#: authentication/templates/authentication/passkey.html:177
msgid "Do you want to retry ?"
msgstr ""

View File

@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-06-19 20:06+0800\n"
"POT-Creation-Date: 2025-06-27 11:33+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -241,7 +241,7 @@ msgid "Push account"
msgstr "Notificación de cuenta"
#: accounts/const/automation.py:26 accounts/risk_handlers.py:26
#: acls/const.py:14 audits/const.py:32 ops/const.py:9
#: audits/const.py:32 ops/const.py:9
msgid "Change secret"
msgstr "Cambiar contraseña"
@@ -795,7 +795,7 @@ msgstr "Estado"
#: accounts/serializers/account/account.py:279
#: accounts/templates/accounts/change_secret_failed_info.html:13
#: assets/const/automation.py:9
#: authentication/templates/authentication/passkey.html:174
#: authentication/templates/authentication/passkey.html:177
#: authentication/views/base.py:42 authentication/views/base.py:43
#: authentication/views/base.py:44 common/const/choices.py:67
#: settings/templates/ldap/_msg_import_ldap_user.html:26
@@ -1893,6 +1893,10 @@ msgstr "Verificación facial"
msgid "Face online"
msgstr "Facial en línea"
#: acls/const.py:14
msgid "Secret rotation"
msgstr "Rotación de contraseña"
#: acls/models/base.py:37 assets/models/cmd_filter.py:76
#: terminal/models/component/endpoint.py:110 xpack/plugins/cloud/models.py:321
msgid "Priority"
@@ -3807,7 +3811,7 @@ msgstr "Se pueden crear hasta 10 claves de acceso"
msgid "The value in the parameter must contain %s"
msgstr "El valor del parámetro debe incluir %s"
#: authentication/api/confirm.py:50
#: authentication/api/confirm.py:51
msgid "This action require verify your MFA"
msgstr ""
"Esta operación requiere la verificación de su MFA, por favor, habilítelo y "
@@ -4803,7 +4807,7 @@ msgstr "Regresar"
msgid "Copy success"
msgstr "Copiado con éxito"
#: authentication/templates/authentication/passkey.html:163
#: authentication/templates/authentication/passkey.html:166
msgid ""
"This page is not served over HTTPS. Please use HTTPS to ensure security of "
"your credentials."
@@ -4811,7 +4815,7 @@ msgstr ""
"Esta página no utiliza el protocolo HTTPS, por favor utiliza HTTPS para "
"asegurar la seguridad de tus credenciales."
#: authentication/templates/authentication/passkey.html:174
#: authentication/templates/authentication/passkey.html:177
msgid "Do you want to retry ?"
msgstr "¿Reintentar?"

View File

@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-06-19 20:06+0800\n"
"POT-Creation-Date: 2025-06-27 11:33+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -219,7 +219,7 @@ msgid "Push account"
msgstr "アカウントプッシュ"
#: accounts/const/automation.py:26 accounts/risk_handlers.py:26
#: acls/const.py:14 audits/const.py:32 ops/const.py:9
#: audits/const.py:32 ops/const.py:9
msgid "Change secret"
msgstr "パスワードを変更する"
@@ -786,7 +786,7 @@ msgstr "ステータス"
#: accounts/serializers/account/account.py:279
#: accounts/templates/accounts/change_secret_failed_info.html:13
#: assets/const/automation.py:9
#: authentication/templates/authentication/passkey.html:174
#: authentication/templates/authentication/passkey.html:177
#: authentication/views/base.py:42 authentication/views/base.py:43
#: authentication/views/base.py:44 common/const/choices.py:67
#: settings/templates/ldap/_msg_import_ldap_user.html:26
@@ -1806,6 +1806,10 @@ msgstr "顔認証"
msgid "Face online"
msgstr "顔オンライン"
#: acls/const.py:14
msgid "Secret rotation"
msgstr "パスワードのローテーション"
#: acls/models/base.py:37 assets/models/cmd_filter.py:76
#: terminal/models/component/endpoint.py:110 xpack/plugins/cloud/models.py:321
msgid "Priority"
@@ -3641,7 +3645,7 @@ msgstr "最大10個のアクセスキーを作成できます"
msgid "The value in the parameter must contain %s"
msgstr "パラメータの値には必ず %s が含まれます"
#: authentication/api/confirm.py:50
#: authentication/api/confirm.py:51
msgid "This action require verify your MFA"
msgstr "この操作には、MFAを検証する必要があります"
@@ -4567,13 +4571,13 @@ msgstr "返品"
msgid "Copy success"
msgstr "コピー成功"
#: authentication/templates/authentication/passkey.html:163
#: authentication/templates/authentication/passkey.html:166
msgid ""
"This page is not served over HTTPS. Please use HTTPS to ensure security of "
"your credentials."
msgstr "このページはHTTPSで提供されていません。HTTPSを使用して、資格情報のセキュリティを確保してください。"
#: authentication/templates/authentication/passkey.html:174
#: authentication/templates/authentication/passkey.html:177
msgid "Do you want to retry ?"
msgstr "再試行しますか?"

View File

@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-06-19 20:06+0800\n"
"POT-Creation-Date: 2025-06-27 11:33+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -219,7 +219,7 @@ msgid "Push account"
msgstr "계정 푸시"
#: accounts/const/automation.py:26 accounts/risk_handlers.py:26
#: acls/const.py:14 audits/const.py:32 ops/const.py:9
#: audits/const.py:32 ops/const.py:9
msgid "Change secret"
msgstr "비밀번호 변경"
@@ -771,7 +771,7 @@ msgstr "상태"
#: accounts/serializers/account/account.py:279
#: accounts/templates/accounts/change_secret_failed_info.html:13
#: assets/const/automation.py:9
#: authentication/templates/authentication/passkey.html:174
#: authentication/templates/authentication/passkey.html:177
#: authentication/views/base.py:42 authentication/views/base.py:43
#: authentication/views/base.py:44 common/const/choices.py:67
#: settings/templates/ldap/_msg_import_ldap_user.html:26
@@ -1796,6 +1796,10 @@ msgstr "안면 확인"
msgid "Face online"
msgstr "안면 온라인"
#: acls/const.py:14
msgid "Secret rotation"
msgstr "비밀번호 변경"
#: acls/models/base.py:37 assets/models/cmd_filter.py:76
#: terminal/models/component/endpoint.py:110 xpack/plugins/cloud/models.py:321
msgid "Priority"
@@ -3631,7 +3635,7 @@ msgstr "최대 10개의 액세스 키를 생성할 수 있습니다."
msgid "The value in the parameter must contain %s"
msgstr "매개변수의 값은 반드시 %s를 포함해야 합니다."
#: authentication/api/confirm.py:50
#: authentication/api/confirm.py:51
msgid "This action require verify your MFA"
msgstr "이 작업은 귀하의 MFA를 확인해야 하므로, 먼저 활성화하고 구성해야 합니다."
@@ -4560,14 +4564,14 @@ msgstr "뒤로"
msgid "Copy success"
msgstr "복사 성공"
#: authentication/templates/authentication/passkey.html:163
#: authentication/templates/authentication/passkey.html:166
msgid ""
"This page is not served over HTTPS. Please use HTTPS to ensure security of "
"your credentials."
msgstr ""
"이번 페이지는 HTTPS 프로토콜을 사용하지 않았습니다. 귀하의 자격 증명을 안전하게 유지하려면 HTTPS 프로토콜을 사용해 주세요."
#: authentication/templates/authentication/passkey.html:174
#: authentication/templates/authentication/passkey.html:177
msgid "Do you want to retry ?"
msgstr "재시도 하시겠습니까?"

View File

@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-06-19 20:06+0800\n"
"POT-Creation-Date: 2025-06-27 11:33+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -219,7 +219,7 @@ msgid "Push account"
msgstr "Push de Conta"
#: accounts/const/automation.py:26 accounts/risk_handlers.py:26
#: acls/const.py:14 audits/const.py:32 ops/const.py:9
#: audits/const.py:32 ops/const.py:9
msgid "Change secret"
msgstr "Alterar Senha"
@@ -774,7 +774,7 @@ msgstr "Status"
#: accounts/serializers/account/account.py:279
#: accounts/templates/accounts/change_secret_failed_info.html:13
#: assets/const/automation.py:9
#: authentication/templates/authentication/passkey.html:174
#: authentication/templates/authentication/passkey.html:177
#: authentication/views/base.py:42 authentication/views/base.py:43
#: authentication/views/base.py:44 common/const/choices.py:67
#: settings/templates/ldap/_msg_import_ldap_user.html:26
@@ -1869,6 +1869,10 @@ msgstr "Verificação facial"
msgid "Face online"
msgstr "Facial online"
#: acls/const.py:14
msgid "Secret rotation"
msgstr "Troca de senha"
#: acls/models/base.py:37 assets/models/cmd_filter.py:76
#: terminal/models/component/endpoint.py:110 xpack/plugins/cloud/models.py:321
msgid "Priority"
@@ -3761,7 +3765,7 @@ msgstr "Pode-se criar até 10 chaves de acesso"
msgid "The value in the parameter must contain %s"
msgstr "Os valores nos parâmetros devem incluir %s"
#: authentication/api/confirm.py:50
#: authentication/api/confirm.py:51
msgid "This action require verify your MFA"
msgstr ""
"Esta operação requer a verificação do seu MFA, por favor ative e configure "
@@ -4741,7 +4745,7 @@ msgstr "Voltar"
msgid "Copy success"
msgstr "Cópia bem sucedida"
#: authentication/templates/authentication/passkey.html:163
#: authentication/templates/authentication/passkey.html:166
msgid ""
"This page is not served over HTTPS. Please use HTTPS to ensure security of "
"your credentials."
@@ -4749,7 +4753,7 @@ msgstr ""
"Esta página não usa o protocolo HTTPS, por favor, use o protocolo HTTPS para"
" garantir a segurança de suas credenciais."
#: authentication/templates/authentication/passkey.html:174
#: authentication/templates/authentication/passkey.html:177
msgid "Do you want to retry ?"
msgstr "Deseja tentar novamente?"

View File

@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-06-19 20:06+0800\n"
"POT-Creation-Date: 2025-06-27 11:33+0800\n"
"PO-Revision-Date: 2025-06-11 11:51+0300\n"
"Last-Translator: \n"
"Language-Team: \n"
@@ -221,7 +221,7 @@ msgid "Push account"
msgstr "Публикация учетной записи"
#: accounts/const/automation.py:26 accounts/risk_handlers.py:26
#: acls/const.py:14 audits/const.py:32 ops/const.py:9
#: audits/const.py:32 ops/const.py:9
msgid "Change secret"
msgstr "Смена секрета"
@@ -775,7 +775,7 @@ msgstr "Статус"
#: accounts/serializers/account/account.py:279
#: accounts/templates/accounts/change_secret_failed_info.html:13
#: assets/const/automation.py:9
#: authentication/templates/authentication/passkey.html:174
#: authentication/templates/authentication/passkey.html:177
#: authentication/views/base.py:42 authentication/views/base.py:43
#: authentication/views/base.py:44 common/const/choices.py:67
#: settings/templates/ldap/_msg_import_ldap_user.html:26
@@ -1848,6 +1848,10 @@ msgstr "Проверка по лицу"
msgid "Face online"
msgstr "Лицо онлайн"
#: acls/const.py:14
msgid "Secret rotation"
msgstr "Смена пароля"
#: acls/models/base.py:37 assets/models/cmd_filter.py:76
#: terminal/models/component/endpoint.py:110 xpack/plugins/cloud/models.py:321
msgid "Priority"
@@ -3741,7 +3745,7 @@ msgstr "Максимально можно создать 10 ключей дос
msgid "The value in the parameter must contain %s"
msgstr "Значение в параметрах должно содержать %s"
#: authentication/api/confirm.py:50
#: authentication/api/confirm.py:51
msgid "This action require verify your MFA"
msgstr ""
"Эта операция требует подтверждения МФА, пожалуйста, сначала включите и "
@@ -4724,7 +4728,7 @@ msgstr "Вернуться"
msgid "Copy success"
msgstr "Успешно скопировано"
#: authentication/templates/authentication/passkey.html:163
#: authentication/templates/authentication/passkey.html:166
msgid ""
"This page is not served over HTTPS. Please use HTTPS to ensure security of "
"your credentials."
@@ -4732,7 +4736,7 @@ msgstr ""
"Эта страница не использует протокол HTTPS, пожалуйста, используйте HTTPS для"
" обеспечения безопасности ваших учетных данных."
#: authentication/templates/authentication/passkey.html:174
#: authentication/templates/authentication/passkey.html:177
msgid "Do you want to retry ?"
msgstr "Хотите попробовать снова?"

View File

@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: JumpServer 0.3.3\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-06-19 20:06+0800\n"
"POT-Creation-Date: 2025-06-27 11:33+0800\n"
"PO-Revision-Date: 2021-05-20 10:54+0800\n"
"Last-Translator: ibuler <ibuler@qq.com>\n"
"Language-Team: JumpServer team<ibuler@qq.com>\n"
@@ -217,7 +217,7 @@ msgid "Push account"
msgstr "账号推送"
#: accounts/const/automation.py:26 accounts/risk_handlers.py:26
#: acls/const.py:14 audits/const.py:32 ops/const.py:9
#: audits/const.py:32 ops/const.py:9
msgid "Change secret"
msgstr "改密"
@@ -764,7 +764,7 @@ msgstr "状态"
#: accounts/serializers/account/account.py:279
#: accounts/templates/accounts/change_secret_failed_info.html:13
#: assets/const/automation.py:9
#: authentication/templates/authentication/passkey.html:174
#: authentication/templates/authentication/passkey.html:177
#: authentication/views/base.py:42 authentication/views/base.py:43
#: authentication/views/base.py:44 common/const/choices.py:67
#: settings/templates/ldap/_msg_import_ldap_user.html:26
@@ -1812,6 +1812,10 @@ msgstr "人脸验证"
msgid "Face online"
msgstr "人脸在线"
#: acls/const.py:14
msgid "Secret rotation"
msgstr "密码轮换"
#: acls/models/base.py:37 assets/models/cmd_filter.py:76
#: terminal/models/component/endpoint.py:110 xpack/plugins/cloud/models.py:321
msgid "Priority"
@@ -3665,7 +3669,7 @@ msgstr "最多可以创建10个访问密钥"
msgid "The value in the parameter must contain %s"
msgstr "参数中的值必须包含 %s"
#: authentication/api/confirm.py:50
#: authentication/api/confirm.py:51
msgid "This action require verify your MFA"
msgstr "该操作需要验证您的 MFA, 请先开启并配置"
@@ -4593,13 +4597,13 @@ msgstr "返回"
msgid "Copy success"
msgstr "复制成功"
#: authentication/templates/authentication/passkey.html:163
#: authentication/templates/authentication/passkey.html:166
msgid ""
"This page is not served over HTTPS. Please use HTTPS to ensure security of "
"your credentials."
msgstr "本页面未使用 HTTPS 协议,请使用 HTTPS 协议以确保您的凭据安全。"
#: authentication/templates/authentication/passkey.html:174
#: authentication/templates/authentication/passkey.html:177
msgid "Do you want to retry ?"
msgstr "是否重试 "

View File

@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: JumpServer 0.3.3\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-06-19 20:06+0800\n"
"POT-Creation-Date: 2025-06-27 11:33+0800\n"
"PO-Revision-Date: 2021-05-20 10:54+0800\n"
"Last-Translator: ibuler <ibuler@qq.com>\n"
"Language-Team: JumpServer team<ibuler@qq.com>\n"
@@ -219,7 +219,7 @@ msgid "Push account"
msgstr "帳號推送"
#: accounts/const/automation.py:26 accounts/risk_handlers.py:26
#: acls/const.py:14 audits/const.py:32 ops/const.py:9
#: audits/const.py:32 ops/const.py:9
msgid "Change secret"
msgstr "更改密碼"
@@ -771,7 +771,7 @@ msgstr "狀態"
#: accounts/serializers/account/account.py:279
#: accounts/templates/accounts/change_secret_failed_info.html:13
#: assets/const/automation.py:9
#: authentication/templates/authentication/passkey.html:174
#: authentication/templates/authentication/passkey.html:177
#: authentication/views/base.py:42 authentication/views/base.py:43
#: authentication/views/base.py:44 common/const/choices.py:67
#: settings/templates/ldap/_msg_import_ldap_user.html:26
@@ -1788,6 +1788,10 @@ msgstr "人臉驗證"
msgid "Face online"
msgstr "人臉在線"
#: acls/const.py:14
msgid "Secret rotation"
msgstr "密碼輪換"
#: acls/models/base.py:37 assets/models/cmd_filter.py:76
#: terminal/models/component/endpoint.py:110 xpack/plugins/cloud/models.py:321
msgid "Priority"
@@ -3619,7 +3623,7 @@ msgstr "最多可以創建10個訪問金鑰"
msgid "The value in the parameter must contain %s"
msgstr "參數中的值必須包含 %s"
#: authentication/api/confirm.py:50
#: authentication/api/confirm.py:51
msgid "This action require verify your MFA"
msgstr "該操作需要驗證您的 MFA, 請先開啟並配置"
@@ -4544,13 +4548,13 @@ msgstr "返回"
msgid "Copy success"
msgstr "複製成功"
#: authentication/templates/authentication/passkey.html:163
#: authentication/templates/authentication/passkey.html:166
msgid ""
"This page is not served over HTTPS. Please use HTTPS to ensure security of "
"your credentials."
msgstr "本頁面未使用 HTTPS 協議,請使用 HTTPS 協議以確保您的憑據安全。"
#: authentication/templates/authentication/passkey.html:174
#: authentication/templates/authentication/passkey.html:177
msgid "Do you want to retry ?"
msgstr "是否重試 "

View File

@@ -174,6 +174,7 @@
"RDP File": "RDP File",
"RDP client options": "RDP client options",
"RDP color quality": "RDP color quality",
"RDP file reusable": "RDP file reusable",
"RDP connection speed": "RDP connection speed",
"RDP resolution": "RDP resolution",
"RDP smart size": "RDP smart size",
@@ -268,6 +269,7 @@
"cols": "Cols",
"confirm": "Confirm",
"connect info": "Connect info",
"Click to download rdp file": "Click to download rdp file",
"connectDisabledTipsMethodDisabled": "Tips: No valid remote application deployment machine found, current resource cannot be connected. Please contact the administrator for assistance",
"connectDisabledTipsNoAccount": "Tips: No valid authorization account found, current resource cannot be connected. Please contact the administrator for assistance",
"connectDisabledTipsNoConnectMethod": "Tips: No valid connection method found, current resource cannot be connected. Please contact the administrator for assistance",
@@ -278,4 +280,4 @@
"success": "Success",
"system user": "System user",
"user": "User"
}
}

View File

@@ -16,6 +16,7 @@
"Asset: ": "Activo: {{value}}",
"Assignees": "Responsable",
"Auto": "Automático",
"WordSep": " ",
"Automatic login next": "Iniciar sesión automáticamente la próxima vez (se puede volver a seleccionar haciendo clic derecho en la conexión de activos)",
"AvailableHotkeys": "atajos disponibles",
"Backspace as Ctrl+H": "Terminal de caracteres Retroceso como Ctrl+H",
@@ -172,6 +173,7 @@
"RDP File": "Archivo RDP",
"RDP client options": "Opciones del cliente RDP",
"RDP color quality": "Calidad de color RDP",
"RDP file reusable": "Archivo RDP reutilizable",
"RDP connection speed": "Velocidad de conexión RDP",
"RDP resolution": "Resolución RDP",
"RDP smart size": "Tamaño inteligente RDP",
@@ -266,6 +268,7 @@
"cols": "Número de columnas",
"confirm": "Confirmar",
"connect info": "Información de conexión",
"Click to download rdp file": "Haga clic para descargar el archivo RDP",
"connectDisabledTipsMethodDisabled": "Nota: No se encontró un servidor de aplicaciones remotas válido, los recursos actuales no se pueden conectar, por favor contacta a management para su resolución",
"connectDisabledTipsNoAccount": "Nota: No se encontró una cuenta de autorización válida, los recursos actuales no se pueden conectar, por favor contacte al administrador para su manejo",
"connectDisabledTipsNoConnectMethod": "Aviso: No se encontró un método de conexión válido, los recursos actuales no se pueden conectar, por favor, contacte al administrador para su resolución",
@@ -276,4 +279,4 @@
"success": "Éxito",
"system user": "Usuario del sistema",
"user": "Usuario"
}
}

View File

@@ -15,6 +15,7 @@
"Asset tree loading method": "資産ツリーのロード方法の設定",
"Asset: ": "アセット: {{value}}",
"Assignees": "受信者",
"WordSep": "\u200B",
"Auto": "自動",
"Automatic login next": "次回の自動登録 (右クリック資産接続は再選択できます)",
"AvailableHotkeys": "利用可能なショートカットキー",
@@ -172,6 +173,7 @@
"RDP File": "RDPファイル",
"RDP client options": "RDPクライアントオプション",
"RDP color quality": "RDP 色品質",
"RDP file reusable": "RDP ファイル再利用",
"RDP connection speed": "RDP 接続速度",
"RDP resolution": "RDP 解像度",
"RDP smart size": "RDP スマート・サイズ",
@@ -266,6 +268,7 @@
"cols": "列数",
"confirm": "確認",
"connect info": "接続情報",
"Click to download rdp file": "RDPファイルをダウンロードする",
"connectDisabledTipsMethodDisabled": "ヒント:有効なリモートアプリケーションデプロイメントマシンが見つかりませんでした。このリソースは接続できません。管理者に連絡してください",
"connectDisabledTipsNoAccount": "ヒント:有効な認可アカウントが見つかりませんでした。このリソースは接続できません。管理者に連絡してください",
"connectDisabledTipsNoConnectMethod": "ヒント:有効な接続方法が見つかりませんでした。このリソースは接続できません。管理者に連絡してください",
@@ -276,4 +279,4 @@
"success": "成功",
"system user": "システムユーザー",
"user": "ユーザー"
}
}

View File

@@ -15,6 +15,7 @@
"Asset tree loading method": "자산 트리 로딩 방식 설정",
"Asset: ": "자산: {{value}}",
"Assignees": "접수인",
"WordSep": " ",
"Auto": "자동",
"Automatic login next": "다음 번에 자동으로 로그인 (자산 연결을 우클릭하여 다시 선택할 수 있습니다)",
"AvailableHotkeys": "사용 가능한 단축키",
@@ -172,6 +173,7 @@
"RDP File": "RDP 파일",
"RDP client options": "RDP 클라이언트 옵션",
"RDP color quality": "RDP 색상 품질",
"RDP file reusable": "RDP 파일 재사용",
"RDP connection speed": "RDP 연결 속도",
"RDP resolution": "RDP 해상도",
"RDP smart size": "RDP 스마트 크기",
@@ -266,6 +268,7 @@
"cols": "열 수",
"confirm": "확인",
"connect info": "연결 정보",
"Click to download rdp file": "RDP 파일 다운로드",
"connectDisabledTipsMethodDisabled": "알림: 유효한 원격 애플리케이션 배포기를 찾을 수 없습니다. 현재 리소스에 연결할 수 없으니 관리자에게 문의해 주시기 바랍니다.",
"connectDisabledTipsNoAccount": "알림: 유효한 권한 계정을 찾을 수 없습니다. 현재 리소스에 연결할 수 없습니다. 관리자를 통해 처리해 주시기 바랍니다",
"connectDisabledTipsNoConnectMethod": "알림: 유효한 연결 방식을 찾을 수 없습니다. 현재 리소스에 연결할 수 없습니다. 관리자에게 문의하여 처리하십시오.",
@@ -276,4 +279,4 @@
"success": "성공",
"system user": "시스템 사용자",
"user": "사용자"
}
}

View File

@@ -15,6 +15,7 @@
"Asset tree loading method": " Configurar forma de carregamento da árvore de ativos ",
"Asset: ": "Ativo: {{value}}",
"Assignees": "Atendente",
"WordSep": " ",
"Auto": "Automático",
"Automatic login next": "Login Automático na Próxima Vez (Clique com o botão direito na conexão do ativo para escolher novamente)",
"AvailableHotkeys": "Teclas de atalho disponíveis",
@@ -45,6 +46,7 @@
"Confirm": "Confirmar",
"ConfirmCreation": "Confirmar criação",
"Connect": "Conectar",
"Click to download rdp file": "Clique para baixar o arquivo RDP",
"Connect checked": "Conecte selecionado",
"Connect command line": "Conectar linha de comando",
"Connect method": "Forma de conexão",
@@ -172,6 +174,7 @@
"RDP File": "Arquivo RDP",
"RDP client options": "Opções do cliente RDP",
"RDP color quality": " Qualidade de cor RDP ",
"RDP file reusable": "Arquivo RDP reutilizável",
"RDP connection speed": "Velocidade de conexão RDP",
"RDP resolution": "RDP Resolução",
"RDP smart size": "RDP Tamanho inteligente",
@@ -276,4 +279,4 @@
"success": " Sucesso",
"system user": "Usuário do Sistema",
"user": "Usuário"
}
}

View File

@@ -175,6 +175,8 @@
"RDP client options": "Опции клиента RDP",
"RDP color quality": "Качество цвета RDP",
"RDP connection speed": "Скорость подключения RDP",
"RDP file reusable": "RDP файл повторно используемый",
"Click to download rdp file": "Нажмите, чтобы скачать RDP файл",
"RDP resolution": "Разрешение RDP",
"RDP smart size": "Умный размер RDP",
"Re-use for a long time after opening": "После включения эта информация о подключении может использоваться длительное время и многократно",
@@ -279,4 +281,4 @@
"success": "успешно",
"system user": "системный пользователь",
"user": "пользователь"
}
}

View File

@@ -156,6 +156,7 @@
"Open in new window": "新窗口打开",
"Operator": "操作人",
"Password": "密码",
"WordSep": "\u200B",
"Password is token password on the table": "密码是表格中的 Token 密码",
"Password is your password login to system": "密码是你登录系统的密码",
"Pause": "暂停",
@@ -172,6 +173,7 @@
"RDP File": "RDP 文件",
"RDP client options": "RDP 客户端选项",
"RDP color quality": "RDP 颜色质量",
"RDP file reusable": "RDP 文件可重复用",
"RDP connection speed": "RDP 连接速度",
"RDP resolution": "RDP 分辨率",
"RDP smart size": "RDP 智能大小",
@@ -266,6 +268,7 @@
"cols": "列数",
"confirm": "确认",
"connect info": "连接信息",
"Click to download rdp file": "点击下载 RDP 文件",
"connectDisabledTipsMethodDisabled": "提示:未找到有效的远程应用发布机,当前资源无法连接,请联系管理员进行处理",
"connectDisabledTipsNoAccount": "提示:未找到有效的授权账号,当前资源无法连接,请联系管理员进行处理",
"connectDisabledTipsNoConnectMethod": "提示:未找到有效的连接方式,当前资源无法连接,请联系管理员进行处理",
@@ -276,4 +279,4 @@
"success": "成功",
"system user": "系统用户",
"user": "用户"
}
}

View File

@@ -30,6 +30,7 @@
"Checkbox": "多選",
"Choose a User": "選擇一個用戶",
"Click to copy": "點擊複製",
"Click to download rdp file": "點擊下載 RDP 檔案",
"Client": "用戶端",
"Clone Connect": "複製窗口",
"Close": "關閉",
@@ -174,6 +175,7 @@
"RDP client options": "RDP 用戶端選項",
"RDP color quality": "RDP 顏色質量",
"RDP connection speed": "RDP 連接速度",
"RDP file reusable": "RDP 檔案可重複使用",
"RDP resolution": "RDP 解析度",
"RDP smart size": "RDP 智慧大小",
"Re-use for a long time after opening": "開啟後該連接資訊可長時間多次使用",
@@ -261,6 +263,7 @@
"Web Terminal": "Web終端",
"Website": "官網",
"With secret accounts": "託管帳號",
"WordSep": "",
"Writable": "可寫",
"Yes": "是",
"asset": "資產",

View File

@@ -349,7 +349,7 @@ class Config(dict):
'AUTH_OPENID_PROVIDER_SIGNATURE_ALG': 'HS256',
'AUTH_OPENID_PROVIDER_SIGNATURE_KEY': None,
'AUTH_OPENID_SCOPES': 'openid profile email',
'AUTH_OPENID_ID_TOKEN_MAX_AGE': 60,
'AUTH_OPENID_ID_TOKEN_MAX_AGE': 600,
'AUTH_OPENID_ID_TOKEN_INCLUDE_CLAIMS': True,
'AUTH_OPENID_USE_STATE': True,
'AUTH_OPENID_USE_NONCE': True,

View File

@@ -155,11 +155,13 @@ def radius_create_user(sender, user, **kwargs):
@receiver(openid_create_or_update_user)
def on_openid_create_or_update_user(sender, user, created, attrs, **kwargs):
group_names = attrs.get('groups')
if created:
org_ids = bind_user_to_org_role(user)
group_names = attrs.get('groups')
bind_user_to_group(org_ids, group_names, user)
else:
org_ids = user.joined_orgs.values_list('id', flat=True)
bind_user_to_group(org_ids, group_names, user)
source = User.Source.openid.value
user_authenticated_handle(user, created, source, attrs, **kwargs)
@@ -235,6 +237,7 @@ def bind_user_to_group(org_ids, group_names, user):
return
org_ids = org_ids or [Organization.DEFAULT_ID]
org_ids = [str(i) for i in org_ids if i]
with tmp_to_root_org():
existing_groups = UserGroup.objects.filter(org_id__in=org_ids).values_list('org_id', 'name')
@@ -252,12 +255,19 @@ def bind_user_to_group(org_ids, group_names, user):
)
UserGroup.objects.bulk_create(groups_to_create)
user_groups = UserGroup.objects.filter(org_id__in=org_ids, name__in=group_names)
user_group_ids = set(user_groups.values_list('id', flat=True))
exist_group_ids = set(
User.groups.through.objects.filter(user_id=user.id)
.values_list('usergroup_id', flat=True)
)
need_add_group_ids = user_group_ids - exist_group_ids
user_group_links = [
User.groups.through(user_id=user.id, usergroup_id=group.id)
for group in user_groups
User.groups.through(user_id=user.id, usergroup_id=group_id)
for group_id in need_add_group_ids
]
if user_group_links:
User.groups.through.objects.bulk_create(user_group_links)
User.groups.through.objects.bulk_create(user_group_links, ignore_conflicts=True)