Merge pull request #12461 from jumpserver/master

v3.10.1
pull/12580/head
Bryan 2023-12-29 11:33:05 +05:00 committed by GitHub
commit a9620a3cbe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 105 additions and 65 deletions

View File

@ -94,7 +94,8 @@ JumpServer 堡垒机帮助企业以更安全的方式管控和登录各种类型
| [KoKo](https://github.com/jumpserver/koko) | <a href="https://github.com/jumpserver/koko/releases"><img alt="Koko release" src="https://img.shields.io/github/release/jumpserver/koko.svg" /></a> | JumpServer 字符协议 Connector 项目 |
| [Lion](https://github.com/jumpserver/lion-release) | <a href="https://github.com/jumpserver/lion-release/releases"><img alt="Lion release" src="https://img.shields.io/github/release/jumpserver/lion-release.svg" /></a> | JumpServer 图形协议 Connector 项目,依赖 [Apache Guacamole](https://guacamole.apache.org/) |
| [Razor](https://github.com/jumpserver/razor) | <img alt="Chen" src="https://img.shields.io/badge/release-私有发布-red" /> | JumpServer RDP 代理 Connector 项目 |
| [Tinker](https://github.com/jumpserver/tinker) | <img alt="Tinker" src="https://img.shields.io/badge/release-私有发布-red" /> | JumpServer 远程应用 Connector 项目 |
| [Tinker](https://github.com/jumpserver/tinker) | <img alt="Tinker" src="https://img.shields.io/badge/release-私有发布-red" /> | JumpServer 远程应用 Connector 项目 (Windows) |
| [Panda](https://github.com/jumpserver/Panda) | <img alt="Panda" src="https://img.shields.io/badge/release-私有发布-red" /> | JumpServer 远程应用 Connector 项目 (Linux) |
| [Magnus](https://github.com/jumpserver/magnus-release) | <a href="https://github.com/jumpserver/magnus-release/releases"><img alt="Magnus release" src="https://img.shields.io/github/release/jumpserver/magnus-release.svg" /> | JumpServer 数据库代理 Connector 项目 |
| [Chen](https://github.com/jumpserver/chen-release) | <a href="https://github.com/jumpserver/chen-release/releases"><img alt="Chen release" src="https://img.shields.io/github/release/jumpserver/chen-release.svg" /> | JumpServer Web DB 项目,替代原来的 OmniDB |
| [Kael](https://github.com/jumpserver/kael) | <a href="https://github.com/jumpserver/kael/releases"><img alt="Kael release" src="https://img.shields.io/github/release/jumpserver/kael.svg" /> | JumpServer 连接 GPT 资产的组件项目 |

View File

@ -3,13 +3,13 @@ import time
from collections import defaultdict, OrderedDict
from django.conf import settings
from openpyxl import Workbook
from rest_framework import serializers
from xlsxwriter import Workbook
from accounts.const.automation import AccountBackupType
from accounts.models.automations.backup_account import AccountBackupAutomation
from accounts.notifications import AccountBackupExecutionTaskMsg, AccountBackupByObjStorageExecutionTaskMsg
from accounts.serializers import AccountSecretSerializer
from accounts.models.automations.backup_account import AccountBackupAutomation
from assets.const import AllTypes
from common.utils.file import encrypt_and_compress_zip_file, zip_files
from common.utils.timezone import local_now_filename, local_now_display
@ -144,10 +144,11 @@ class AccountBackupHandler:
wb = Workbook(filename)
for sheet, data in data_map.items():
ws = wb.create_sheet(str(sheet))
ws = wb.add_worksheet(str(sheet))
for row in data:
ws.append(row)
wb.save(filename)
for col, _data in enumerate(row):
ws.write_string(0, col, _data)
wb.close()
files.append(filename)
timedelta = round((time.time() - time_start), 2)
print('创建备份文件完成: 用时 {}s'.format(timedelta))

View File

@ -4,7 +4,7 @@ from copy import deepcopy
from django.conf import settings
from django.utils import timezone
from openpyxl import Workbook
from xlsxwriter import Workbook
from accounts.const import AutomationTypes, SecretType, SSHKeyStrategy, SecretStrategy
from accounts.models import ChangeSecretRecord
@ -227,8 +227,9 @@ class ChangeSecretManager(AccountBasePlaybookManager):
rows.insert(0, header)
wb = Workbook(filename)
ws = wb.create_sheet('Sheet1')
ws = wb.add_worksheet('Sheet1')
for row in rows:
ws.append(row)
wb.save(filename)
for col, data in enumerate(row):
ws.write_string(0, col, data)
wb.close()
return True

View File

@ -72,7 +72,7 @@ class GatherAccountsManager(AccountBasePlaybookManager):
)
gathered_accounts.append(gathered_account)
if not self.is_sync_account:
return
continue
GatheredAccount.sync_accounts(gathered_accounts)
def run(self, *args, **kwargs):

View File

@ -16,10 +16,11 @@
- name: "Rename user home directory if it exists"
ansible.builtin.command:
cmd: "mv {{ user_home_dir.stdout }} {{ user_home_dir.stdout }}.bak"
when: home_dir.stat.exists and user_home_dir.stdout != ""
when: home_dir.stat | default(false) and user_home_dir.stdout != ""
- name: "Remove account"
ansible.builtin.user:
name: "{{ account.username }}"
state: absent
remove: "{{ home_dir.stat.exists }}"
when: home_dir.stat | default(false)

View File

@ -1,6 +1,7 @@
from django.template.loader import render_to_string
from django.utils.translation import gettext_lazy as _
from accounts.models import Account
from assets.models import Asset
from audits.models import UserLoginLog
from notifications.notifications import UserMessage
@ -16,12 +17,11 @@ class UserLoginReminderMsg(UserMessage):
def get_html_msg(self) -> dict:
user_log = self.user_log
context = {
'ip': user_log.ip,
'city': user_log.city,
'username': user_log.username,
'recipient': self.user.username,
'recipient': self.user,
'user_agent': user_log.user_agent,
}
message = render_to_string('acls/user_login_reminder.html', context)
@ -48,11 +48,14 @@ class AssetLoginReminderMsg(UserMessage):
super().__init__(user)
def get_html_msg(self) -> dict:
account = Account.objects.get(asset=self.asset, username=self.account_username)
context = {
'recipient': self.user.username,
'recipient': self.user,
'username': self.login_user.username,
'name': self.login_user.name,
'asset': str(self.asset),
'account': self.account_username,
'account_name': account.name,
}
message = render_to_string('acls/asset_login_reminder.html', context)

View File

@ -1,10 +1,10 @@
{% load i18n %}
<h3>{% trans 'Respectful' %}{{ recipient }}</h3>
<h3>{% trans 'Respectful' %}: {{ recipient.name }}[{{ recipient.username }}]</h3>
<hr>
<p><strong>{% trans 'Username' %}:</strong> [{{ username }}]</p>
<p><strong>{% trans 'User' %}:</strong> [{{ name }}({{ username }})]</p>
<p><strong>{% trans 'Assets' %}:</strong> [{{ asset }}]</p>
<p><strong>{% trans 'Account' %}:</strong> [{{ account }}]</p>
<p><strong>{% trans 'Account' %}:</strong> [{{ account_name }}({{ account }})]</p>
<hr>
<p>{% trans 'The user has just logged in to the asset. Please ensure that this is an authorized operation. If you suspect that this is an unauthorized access, please take appropriate measures immediately.' %}</p>

View File

@ -1,8 +1,8 @@
{% load i18n %}
<h3>{% trans 'Respectful' %}{{ recipient }}</h3>
<h3>{% trans 'Respectful' %}: {{ recipient.name }}[{{ recipient.username }}]</h3>
<hr>
<p><strong>{% trans 'Username' %}:</strong> [{{ username }}]</p>
<p><strong>{% trans 'User' %}:</strong> [{{ username }}]</p>
<p><strong>IP:</strong> [{{ ip }}]</p>
<p><strong>{% trans 'Login city' %}:</strong> [{{ city }}]</p>
<p><strong>{% trans 'User agent' %}:</strong> [{{ user_agent }}]</p>

View File

@ -93,7 +93,7 @@ class AssetViewSet(SuggestionMixin, NodeFilterMixin, OrgBulkModelViewSet):
model = Asset
filterset_class = AssetFilterSet
search_fields = ("name", "address", "comment")
ordering_fields = ('name', 'connectivity', 'platform', 'date_updated', 'date_created')
ordering_fields = ('name', 'address', 'connectivity', 'platform', 'date_updated', 'date_created')
serializer_classes = (
("default", serializers.AssetSerializer),
("platform", serializers.PlatformSerializer),

View File

@ -122,7 +122,8 @@ def send_login_info_to_reviewers(instance: UserLoginLog | str, auth_acl_id):
def on_user_auth_success(sender, user, request, login_type=None, **kwargs):
logger.debug('User login success: {}'.format(user.username))
check_different_city_login_if_need(user, request)
data = generate_data(user.username, request, login_type=login_type)
username = f"{user.name}({user.username})"
data = generate_data(username, request, login_type=login_type)
request.session['login_time'] = data['datetime'].strftime('%Y-%m-%d %H:%M:%S')
data.update({'mfa': int(user.mfa_enabled), 'status': True})
instance = write_login_log(**data)

View File

@ -152,6 +152,8 @@ class SessionCookieMiddleware(MiddlewareMixin):
value = 'close'
age = request.session.get_expiry_age()
expire_timestamp = request.session.get_expiry_date().timestamp()
response.set_cookie('jms_session_expire_timestamp', expire_timestamp)
response.set_cookie('jms_session_expire', value, max_age=age)
request.session.pop('auth_session_expiration_required', None)

View File

@ -1 +1 @@
from jumpserver.rewriting import db # noqa 采用猴子补丁的方式重写atomic ForeignKey OneToOneField

View File

@ -1,2 +1,2 @@
from . import db

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-12-21 16:12+0800\n"
"POT-Creation-Date: 2023-12-26 14:13+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"
@ -476,7 +476,7 @@ msgstr "終了日"
#: accounts/models/automations/change_secret.py:43
#: assets/models/automations/base.py:113 audits/models.py:208
#: audits/serializers.py:54 ops/models/base.py:49 ops/models/job.py:227
#: terminal/models/applet/applet.py:319 terminal/models/applet/host.py:140
#: terminal/models/applet/applet.py:320 terminal/models/applet/host.py:140
#: terminal/models/component/status.py:30
#: terminal/models/virtualapp/virtualapp.py:99
#: terminal/serializers/applet.py:18 terminal/serializers/applet_host.py:136
@ -742,7 +742,7 @@ msgstr "アカウントの存在ポリシー"
#: assets/models/label.py:21 assets/models/platform.py:96
#: assets/serializers/asset/common.py:122 assets/serializers/cagegory.py:12
#: assets/serializers/platform.py:140 assets/serializers/platform.py:236
#: perms/serializers/user_permission.py:25 settings/models.py:35
#: perms/serializers/user_permission.py:26 settings/models.py:35
#: tickets/models/ticket/apply_application.py:13 users/models/preference.py:12
msgid "Category"
msgstr "カテゴリ"
@ -756,7 +756,7 @@ msgstr "カテゴリ"
#: assets/serializers/platform.py:139 audits/serializers.py:53
#: audits/serializers.py:170
#: authentication/serializers/connect_token_secret.py:126 ops/models/job.py:144
#: perms/serializers/user_permission.py:26 terminal/models/applet/applet.py:39
#: perms/serializers/user_permission.py:27 terminal/models/applet/applet.py:39
#: terminal/models/component/storage.py:57
#: terminal/models/component/storage.py:146 terminal/serializers/applet.py:29
#: terminal/serializers/session.py:21 terminal/serializers/storage.py:264
@ -923,7 +923,7 @@ msgstr "关联平台,可以配置推送参数,如果不关联,则使用默
#: assets/models/group.py:20 common/db/models.py:36 ops/models/adhoc.py:26
#: ops/models/job.py:152 ops/models/playbook.py:31 rbac/models/role.py:37
#: settings/models.py:38 terminal/models/applet/applet.py:45
#: terminal/models/applet/applet.py:320 terminal/models/applet/host.py:143
#: terminal/models/applet/applet.py:321 terminal/models/applet/host.py:143
#: terminal/models/component/endpoint.py:25
#: terminal/models/component/endpoint.py:105
#: terminal/models/session/session.py:46
@ -1720,7 +1720,7 @@ msgstr "アドレス"
#: assets/models/asset/common.py:161 assets/models/platform.py:126
#: authentication/backends/passkey/models.py:12
#: authentication/serializers/connect_token_secret.py:118
#: perms/serializers/user_permission.py:24 xpack/plugins/cloud/models.py:329
#: perms/serializers/user_permission.py:25 xpack/plugins/cloud/models.py:329
msgid "Platform"
msgstr "プラットフォーム"
@ -1886,8 +1886,7 @@ msgstr "値"
#: assets/serializers/platform.py:119
#: authentication/serializers/connect_token_secret.py:124
#: common/serializers/common.py:85 labels/models.py:17 labels/models.py:33
#: labels/serializers.py:45 perms/serializers/user_permission.py:27
#: settings/serializers/msg.py:83
#: labels/serializers.py:45 settings/serializers/msg.py:83
msgid "Label"
msgstr "ラベル"
@ -3707,7 +3706,7 @@ msgid "Invalid ids for ids, should be a list"
msgstr "無効なID、リストでなければなりません"
#: common/db/fields.py:585 common/db/fields.py:590
#: common/serializers/fields.py:134 tickets/serializers/ticket/common.py:58
#: common/serializers/fields.py:133 tickets/serializers/ticket/common.py:58
#: xpack/plugins/cloud/serializers/account_attrs.py:56
#: xpack/plugins/cloud/serializers/account_attrs.py:79
#: xpack/plugins/cloud/serializers/account_attrs.py:150
@ -3880,21 +3879,21 @@ msgstr "{} 秒待ってから送信してください"
msgid "Children"
msgstr "ノード"
#: common/serializers/fields.py:135
#: common/serializers/fields.py:134
#, python-brace-format
msgid "Invalid pk \"{pk_value}\" - object does not exist."
msgstr "無効な pk \"{pk_value}\" - オブジェクトが存在しません"
#: common/serializers/fields.py:136
#: common/serializers/fields.py:135
#, python-brace-format
msgid "Incorrect type. Expected pk value, received {data_type}."
msgstr "エラータイプ。 予想される pk 値、受信 {data_type}。"
#: common/serializers/fields.py:210
#: common/serializers/fields.py:209
msgid "Invalid data type, should be list"
msgstr "間違ったデータ タイプです。リストにする必要があります"
#: common/serializers/fields.py:225
#: common/serializers/fields.py:224
msgid "Invalid choice: {}"
msgstr "無効なオプション: {}"
@ -4815,7 +4814,7 @@ msgid "My assets"
msgstr "私の資産"
#: rbac/tree.py:58 terminal/models/applet/applet.py:52
#: terminal/models/applet/applet.py:316 terminal/models/applet/host.py:30
#: terminal/models/applet/applet.py:317 terminal/models/applet/host.py:30
#: terminal/serializers/applet.py:15
msgid "Applet"
msgstr "リモートアプリケーション"
@ -6597,7 +6596,7 @@ msgstr "カスタムプラットフォームのみをサポート"
msgid "Missing type in platform.yml"
msgstr "platform.ymlにタイプがありません"
#: terminal/models/applet/applet.py:318 terminal/models/applet/host.py:36
#: terminal/models/applet/applet.py:319 terminal/models/applet/host.py:36
#: terminal/models/applet/host.py:138
msgid "Hosting"
msgstr "ホスト マシン"

View File

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:853320b42ac7795fa983c4216f89b3a776a889453d90e11dc425d1388ff9b803
oid sha256:80dd11dde678e4f9b64df18906175125218fd9f719bfe9aaa667ad6e2d055d40
size 139012

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: JumpServer 0.3.3\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-12-21 16:12+0800\n"
"POT-Creation-Date: 2023-12-26 14:13+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"
@ -475,7 +475,7 @@ msgstr "结束日期"
#: accounts/models/automations/change_secret.py:43
#: assets/models/automations/base.py:113 audits/models.py:208
#: audits/serializers.py:54 ops/models/base.py:49 ops/models/job.py:227
#: terminal/models/applet/applet.py:319 terminal/models/applet/host.py:140
#: terminal/models/applet/applet.py:320 terminal/models/applet/host.py:140
#: terminal/models/component/status.py:30
#: terminal/models/virtualapp/virtualapp.py:99
#: terminal/serializers/applet.py:18 terminal/serializers/applet_host.py:136
@ -740,7 +740,7 @@ msgstr "账号存在策略"
#: assets/models/label.py:21 assets/models/platform.py:96
#: assets/serializers/asset/common.py:122 assets/serializers/cagegory.py:12
#: assets/serializers/platform.py:140 assets/serializers/platform.py:236
#: perms/serializers/user_permission.py:25 settings/models.py:35
#: perms/serializers/user_permission.py:26 settings/models.py:35
#: tickets/models/ticket/apply_application.py:13 users/models/preference.py:12
msgid "Category"
msgstr "类别"
@ -754,7 +754,7 @@ msgstr "类别"
#: assets/serializers/platform.py:139 audits/serializers.py:53
#: audits/serializers.py:170
#: authentication/serializers/connect_token_secret.py:126 ops/models/job.py:144
#: perms/serializers/user_permission.py:26 terminal/models/applet/applet.py:39
#: perms/serializers/user_permission.py:27 terminal/models/applet/applet.py:39
#: terminal/models/component/storage.py:57
#: terminal/models/component/storage.py:146 terminal/serializers/applet.py:29
#: terminal/serializers/session.py:21 terminal/serializers/storage.py:264
@ -921,7 +921,7 @@ msgstr "关联平台,可配置推送参数,如果不关联,将使用默认
#: assets/models/group.py:20 common/db/models.py:36 ops/models/adhoc.py:26
#: ops/models/job.py:152 ops/models/playbook.py:31 rbac/models/role.py:37
#: settings/models.py:38 terminal/models/applet/applet.py:45
#: terminal/models/applet/applet.py:320 terminal/models/applet/host.py:143
#: terminal/models/applet/applet.py:321 terminal/models/applet/host.py:143
#: terminal/models/component/endpoint.py:25
#: terminal/models/component/endpoint.py:105
#: terminal/models/session/session.py:46
@ -1712,7 +1712,7 @@ msgstr "地址"
#: assets/models/asset/common.py:161 assets/models/platform.py:126
#: authentication/backends/passkey/models.py:12
#: authentication/serializers/connect_token_secret.py:118
#: perms/serializers/user_permission.py:24 xpack/plugins/cloud/models.py:329
#: perms/serializers/user_permission.py:25 xpack/plugins/cloud/models.py:329
msgid "Platform"
msgstr "系统平台"
@ -1878,8 +1878,7 @@ msgstr "值"
#: assets/serializers/platform.py:119
#: authentication/serializers/connect_token_secret.py:124
#: common/serializers/common.py:85 labels/models.py:17 labels/models.py:33
#: labels/serializers.py:45 perms/serializers/user_permission.py:27
#: settings/serializers/msg.py:83
#: labels/serializers.py:45 settings/serializers/msg.py:83
msgid "Label"
msgstr "标签"
@ -3663,7 +3662,7 @@ msgid "Invalid ids for ids, should be a list"
msgstr "无效的ID应为列表"
#: common/db/fields.py:585 common/db/fields.py:590
#: common/serializers/fields.py:134 tickets/serializers/ticket/common.py:58
#: common/serializers/fields.py:133 tickets/serializers/ticket/common.py:58
#: xpack/plugins/cloud/serializers/account_attrs.py:56
#: xpack/plugins/cloud/serializers/account_attrs.py:79
#: xpack/plugins/cloud/serializers/account_attrs.py:150
@ -3834,21 +3833,21 @@ msgstr "请在 {} 秒后发送"
msgid "Children"
msgstr "节点"
#: common/serializers/fields.py:135
#: common/serializers/fields.py:134
#, python-brace-format
msgid "Invalid pk \"{pk_value}\" - object does not exist."
msgstr "错误的 pk \"{pk_value}\" - 对象不存在"
#: common/serializers/fields.py:136
#: common/serializers/fields.py:135
#, python-brace-format
msgid "Incorrect type. Expected pk value, received {data_type}."
msgstr "错误类型。期望 pk 值,收到 {data_type}。"
#: common/serializers/fields.py:210
#: common/serializers/fields.py:209
msgid "Invalid data type, should be list"
msgstr "错误的数据类型,应该是列表"
#: common/serializers/fields.py:225
#: common/serializers/fields.py:224
msgid "Invalid choice: {}"
msgstr "无效选项: {}"
@ -4762,7 +4761,7 @@ msgid "My assets"
msgstr "我的资产"
#: rbac/tree.py:58 terminal/models/applet/applet.py:52
#: terminal/models/applet/applet.py:316 terminal/models/applet/host.py:30
#: terminal/models/applet/applet.py:317 terminal/models/applet/host.py:30
#: terminal/serializers/applet.py:15
msgid "Applet"
msgstr "远程应用"
@ -5464,7 +5463,7 @@ msgstr "启用 Vault"
#: settings/serializers/feature.py:55
msgid "Mount Point"
msgstr "挂点"
msgstr "挂点"
#: settings/serializers/feature.py:60
msgid "Chat AI"
@ -6504,7 +6503,7 @@ msgstr "只支持自定义平台"
msgid "Missing type in platform.yml"
msgstr "在 platform.yml 中缺少类型"
#: terminal/models/applet/applet.py:318 terminal/models/applet/host.py:36
#: terminal/models/applet/applet.py:319 terminal/models/applet/host.py:36
#: terminal/models/applet/host.py:138
msgid "Hosting"
msgstr "宿主机"

View File

@ -26,6 +26,7 @@ def common_argument_spec():
class SSHClient:
TIMEOUT = 20
SLEEP_INTERVAL = 2
COMPLETE_FLAG = 'complete'
@ -170,7 +171,12 @@ class SSHClient:
time.sleep(self.SLEEP_INTERVAL)
output += self._get_recv()
continue
start_time = time.time()
while self.COMPLETE_FLAG not in output:
if time.time() - start_time > self.TIMEOUT:
error_msg = output
print("切换用户操作超时,跳出循环。")
break
time.sleep(self.SLEEP_INTERVAL)
received_output = self._get_recv().replace(f'"{self.COMPLETE_FLAG}"', '')
output += received_output

View File

@ -217,6 +217,7 @@ class JobExecutionTaskDetail(APIView):
'is_success': execution.is_success,
'time_cost': execution.time_cost,
'job_id': execution.job.id,
'summary': execution.summary
})

View File

@ -10,6 +10,7 @@ from assets.const import Category, AllTypes
from assets.models import Node, Asset, Platform
from assets.serializers.asset.common import AssetLabelSerializer, AssetProtocolsPermsSerializer
from common.serializers.fields import ObjectRelatedField, LabeledChoiceField
from common.serializers import ResourceLabelsMixin
from orgs.mixins.serializers import OrgResourceModelSerializerMixin
from perms.serializers.permission import ActionChoicesField
@ -19,12 +20,11 @@ __all__ = [
]
class AssetPermedSerializer(OrgResourceModelSerializerMixin):
class AssetPermedSerializer(OrgResourceModelSerializerMixin, ResourceLabelsMixin):
""" 被授权资产的数据结构 """
platform = ObjectRelatedField(required=False, queryset=Platform.objects, label=_('Platform'))
category = LabeledChoiceField(choices=Category.choices, read_only=True, label=_('Category'))
type = LabeledChoiceField(choices=AllTypes.choices(), read_only=True, label=_('Type'))
labels = AssetLabelSerializer(many=True, required=False, label=_('Label'))
domain = ObjectRelatedField(required=False, queryset=Node.objects, label=_('Domain'))
class Meta:

View File

@ -30,6 +30,7 @@ exclude_permissions = (
('users', 'userpasswordhistory', '*', '*'),
('users', 'usersession', '*', '*'),
('assets', 'adminuser', '*', '*'),
('assets', 'label', '*', '*'),
('assets', 'assetgroup', '*', '*'),
('assets', 'cluster', '*', '*'),
('assets', 'systemuser', '*', '*'),

View File

@ -7,14 +7,14 @@ from ..models import Permission
__all__ = ['PermissionSerializer', 'UserPermsSerializer']
class ContentTypeSerializer(serializers.ModelSerializer):
class PermissionContentTypeSerializer(serializers.ModelSerializer):
class Meta:
model = ContentType
fields = ['id', 'app_label', 'model']
class PermissionSerializer(serializers.ModelSerializer):
content_type = ContentTypeSerializer(read_only=True)
content_type = PermissionContentTypeSerializer(read_only=True)
class Meta:
model = Permission

View File

@ -86,7 +86,7 @@ class ChatAISettingSerializer(serializers.Serializer):
return
gpt_api_model = Protocol.gpt_protocols()[Protocol.chatgpt]['setting']['api_mode']
choices = gpt_api_model['choices']
field_gpt_model._choices = choices
field_gpt_model.choices = choices
field_gpt_model.default = gpt_api_model['default']
cls = self.__class__
if cls.GPT_MODEL_CHOICES:

View File

@ -172,8 +172,9 @@ class Applet(JMSBaseModel):
return None
spec_label = asset.labels.filter(label__name__in=['AppletHost', '发布机']).first()
if spec_label:
matched = [host for host in hosts if host.name == spec_label.value]
if spec_label and spec_label.label:
label_value = spec_label.label.value
matched = [host for host in hosts if host.name == label_value]
if matched:
return matched[0]

View File

@ -16,6 +16,10 @@ class UserUserGroupRelationViewSet(JMSBulkRelationModelViewSet):
search_fields = filterset_fields
serializer_class = serializers.User2GroupRelationSerializer
m2m_field = User.groups.field
rbac_perms = {
'create': 'users.change_usergroup',
'bulk_destroy': 'users.change_usergroup',
}
def get_queryset(self):
return super().get_queryset().annotate(

View File

@ -867,6 +867,7 @@ class User(AuthMixin, TokenMixin, RoleMixin, MFAMixin, LabeledMixin, JSONFilterM
queryset = cls.objects.all()
if not current_org.is_root():
queryset = current_org.get_members()
queryset = queryset.exclude(is_service_account=True)
return queryset
@property

View File

@ -16,7 +16,8 @@ __all__ = [
class UserGroupSerializer(ResourceLabelsMixin, BulkOrgResourceModelSerializer):
users = ObjectRelatedField(
required=False, many=True, queryset=User.objects, label=_('User'),
required=False, many=True, queryset=User.objects,
attrs=("id", "name", "is_service_account"), label=_('User'),
)
class Meta:

18
poetry.lock generated
View File

@ -7540,6 +7540,22 @@ type = "legacy"
url = "https://pypi.tuna.tsinghua.edu.cn/simple"
reference = "tsinghua"
[[package]]
name = "xlsxwriter"
version = "3.1.9"
description = "A Python module for creating Excel XLSX files."
optional = false
python-versions = ">=3.6"
files = [
{file = "XlsxWriter-3.1.9-py3-none-any.whl", hash = "sha256:b61c1a0c786f82644936c0936ec96ee96cd3afb9440094232f7faef9b38689f0"},
{file = "XlsxWriter-3.1.9.tar.gz", hash = "sha256:de810bf328c6a4550f4ffd6b0b34972aeb7ffcf40f3d285a0413734f9b63a929"},
]
[package.source]
type = "legacy"
url = "https://pypi.tuna.tsinghua.edu.cn/simple"
reference = "tsinghua"
[[package]]
name = "xmlsec"
version = "1.3.13"
@ -7755,4 +7771,4 @@ reference = "tsinghua"
[metadata]
lock-version = "2.0"
python-versions = "^3.11"
content-hash = "397cb294c81da3ce74f1a1c3044bd778669284c0c280177162ed9d51e623a7c8"
content-hash = "19950a5300f8a4425e3e3c9a096fc3782cb544e02152e92ac1bc09d1d9b5274a"

View File

@ -145,6 +145,7 @@ user-agents = "^2.2.0"
django-cors-headers = "^4.3.0"
mistune = "0.8.4"
openai = "^1.3.7"
xlsxwriter = "^3.1.9"
[tool.poetry.group.xpack.dependencies]