From bf29158be9c3cdf597b6db9284f301155ab5e4ac Mon Sep 17 00:00:00 2001 From: ibuler Date: Wed, 28 Jun 2023 15:01:25 +0800 Subject: [PATCH 001/177] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=E6=94=AF?= =?UTF-8?q?=E6=8C=81=20tidb?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../migrations/0007_connectiontoken.py | 4 +-- .../migrations/0011_auto_20220705_1940.py | 33 ++++++++++--------- apps/jumpserver/rewriting/db.py | 10 +++--- .../migrations/0013_ticket_serial_num.py | 7 ++-- apps/tickets/models/ticket/general.py | 15 +++++---- .../migrations/0034_auto_20210506_1448.py | 5 ++- apps/users/migrations/0036_user_feishu_id.py | 7 ++-- apps/users/models/user.py | 11 +++++-- 8 files changed, 55 insertions(+), 37 deletions(-) diff --git a/apps/authentication/migrations/0007_connectiontoken.py b/apps/authentication/migrations/0007_connectiontoken.py index 86341ff5b..6c0b437da 100644 --- a/apps/authentication/migrations/0007_connectiontoken.py +++ b/apps/authentication/migrations/0007_connectiontoken.py @@ -1,10 +1,10 @@ # Generated by Django 3.1.12 on 2022-02-11 06:01 +import uuid from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ('authentication', '0006_auto_20211227_1059'), ] @@ -13,7 +13,7 @@ class Migration(migrations.Migration): migrations.CreateModel( name='ConnectionToken', fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('id', models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False),), ('created_by', models.CharField(blank=True, max_length=32, null=True, verbose_name='Created by')), ('updated_by', models.CharField(blank=True, max_length=32, null=True, verbose_name='Updated by')), ('date_created', models.DateTimeField(auto_now_add=True, null=True, verbose_name='Date created')), diff --git a/apps/authentication/migrations/0011_auto_20220705_1940.py b/apps/authentication/migrations/0011_auto_20220705_1940.py index 527003d9e..f965c9486 100644 --- a/apps/authentication/migrations/0011_auto_20220705_1940.py +++ b/apps/authentication/migrations/0011_auto_20220705_1940.py @@ -1,14 +1,13 @@ # Generated by Django 3.2.12 on 2022-07-05 11:40 -import authentication.models +import django.db.models.deletion from django.conf import settings from django.db import migrations, models -import django.db.models.deletion -import uuid + +import authentication.models class Migration(migrations.Migration): - dependencies = [ ('applications', '0021_auto_20220629_1826'), ('assets', '0091_auto_20220629_1826'), @@ -20,7 +19,9 @@ class Migration(migrations.Migration): migrations.AddField( model_name='connectiontoken', name='application', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='connection_tokens', to='applications.application', verbose_name='Application'), + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, + related_name='connection_tokens', to='applications.application', + verbose_name='Application'), ), migrations.AddField( model_name='connectiontoken', @@ -30,7 +31,8 @@ class Migration(migrations.Migration): migrations.AddField( model_name='connectiontoken', name='asset', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='connection_tokens', to='assets.asset', verbose_name='Asset'), + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, + related_name='connection_tokens', to='assets.asset', verbose_name='Asset'), ), migrations.AddField( model_name='connectiontoken', @@ -55,7 +57,9 @@ class Migration(migrations.Migration): migrations.AddField( model_name='connectiontoken', name='system_user', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='connection_tokens', to='assets.systemuser', verbose_name='System user'), + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, + related_name='connection_tokens', to='assets.systemuser', + verbose_name='System user'), ), migrations.AddField( model_name='connectiontoken', @@ -65,25 +69,24 @@ class Migration(migrations.Migration): migrations.AddField( model_name='connectiontoken', name='type', - field=models.CharField(choices=[('asset', 'Asset'), ('application', 'Application')], default='asset', max_length=16, verbose_name='Type'), + field=models.CharField(choices=[('asset', 'Asset'), ('application', 'Application')], default='asset', + max_length=16, verbose_name='Type'), ), migrations.AddField( model_name='connectiontoken', name='user', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='connection_tokens', to=settings.AUTH_USER_MODEL, verbose_name='User'), + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, + related_name='connection_tokens', to=settings.AUTH_USER_MODEL, verbose_name='User'), ), migrations.AddField( model_name='connectiontoken', name='user_display', field=models.CharField(default='', max_length=128, verbose_name='User display'), ), - migrations.AlterField( - model_name='connectiontoken', - name='id', - field=models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False), - ), migrations.AlterModelOptions( name='connectiontoken', - options={'ordering': ('-date_expired',), 'permissions': [('view_connectiontokensecret', 'Can view connection token secret')], 'verbose_name': 'Connection token'}, + options={'ordering': ('-date_expired',), + 'permissions': [('view_connectiontokensecret', 'Can view connection token secret')], + 'verbose_name': 'Connection token'}, ), ] diff --git a/apps/jumpserver/rewriting/db.py b/apps/jumpserver/rewriting/db.py index 6bc1b157b..1ccd49d8f 100644 --- a/apps/jumpserver/rewriting/db.py +++ b/apps/jumpserver/rewriting/db.py @@ -15,16 +15,18 @@ def atomic(using=None, savepoint=False): return db_atomic(using=using, savepoint=savepoint) -class OneToOneField(models.OneToOneField): +class OneToOneField(models.OneToOneField, ForeignKey): def __init__(self, *args, **kwargs): - kwargs['db_constraint'] = False - super().__init__(*args, **kwargs) + kwargs['unique'] = False + if os.getenv('DB_CONSTRAINT', '1') == '0': + kwargs['db_constraint'] = False + ForeignKey.__init__(self, *args, **kwargs) def set_db_constraint(): if os.getenv('DB_CONSTRAINT', '1') != '0': return - if sys.argv == 2 and sys.argv[1] == 'makemigrations': + if len(sys.argv) == 2 and sys.argv[1] == 'makemigrations': return print("Set foreignkey db constraint False") transaction.atomic = atomic diff --git a/apps/tickets/migrations/0013_ticket_serial_num.py b/apps/tickets/migrations/0013_ticket_serial_num.py index 96d0cbc0d..bad05a7f6 100644 --- a/apps/tickets/migrations/0013_ticket_serial_num.py +++ b/apps/tickets/migrations/0013_ticket_serial_num.py @@ -28,7 +28,6 @@ def fill_ticket_serial_number(apps, schema_editor): class Migration(migrations.Migration): - dependencies = [ ('tickets', '0012_ticketsession'), ] @@ -37,7 +36,11 @@ class Migration(migrations.Migration): migrations.AddField( model_name='ticket', name='serial_num', - field=models.CharField(max_length=128, null=True, unique=True, verbose_name='Serial number'), + field=models.CharField(max_length=128, null=True, verbose_name='Serial number'), ), migrations.RunPython(fill_ticket_serial_number), + migrations.AlterUniqueTogether( + name='ticket', + unique_together={('serial_num',)}, + ), ] diff --git a/apps/tickets/models/ticket/general.py b/apps/tickets/models/ticket/general.py index 4d6c29483..b419bb2bb 100644 --- a/apps/tickets/models/ticket/general.py +++ b/apps/tickets/models/ticket/general.py @@ -13,8 +13,8 @@ from django.utils.translation import ugettext_lazy as _ from common.db.encoder import ModelJSONFieldEncoder from common.db.models import JMSBaseModel from common.exceptions import JMSException -from common.utils.timezone import as_current_tz from common.utils import reverse +from common.utils.timezone import as_current_tz from orgs.models import Organization from orgs.utils import tmp_to_org from tickets.const import ( @@ -296,7 +296,7 @@ class Ticket(StatusMixin, JMSBaseModel): ) comment = models.TextField(default='', blank=True, verbose_name=_('Comment')) rel_snapshot = models.JSONField(verbose_name=_('Relation snapshot'), default=dict) - serial_num = models.CharField(_('Serial number'), max_length=128, unique=True, null=True) + serial_num = models.CharField(_('Serial number'), max_length=128, null=True) meta = models.JSONField(encoder=ModelJSONFieldEncoder, default=dict, verbose_name=_("Meta")) org_id = models.CharField( max_length=36, blank=True, default='', verbose_name=_('Organization'), db_index=True @@ -305,6 +305,9 @@ class Ticket(StatusMixin, JMSBaseModel): class Meta: ordering = ('-date_created',) verbose_name = _('Ticket') + unique_together = ( + ('serial_num',), + ) def __str__(self): return '{}({})'.format(self.title, self.applicant) @@ -328,10 +331,10 @@ class Ticket(StatusMixin, JMSBaseModel): queries = Q(applicant=user) | Q(ticket_steps__ticket_assignees__assignee=user) # TODO: 与 StatusMixin.process_map 内连表查询有部分重叠 有优化空间 待验证排除是否不影响其它调用 prefetch_ticket_assignee = Prefetch('ticket_steps__ticket_assignees', - queryset=TicketAssignee.objects.select_related('assignee'), ) - tickets = cls.objects.prefetch_related(prefetch_ticket_assignee)\ - .select_related('applicant')\ - .filter(queries)\ + queryset=TicketAssignee.objects.select_related('assignee'), ) + tickets = cls.objects.prefetch_related(prefetch_ticket_assignee) \ + .select_related('applicant') \ + .filter(queries) \ .distinct() return tickets diff --git a/apps/users/migrations/0034_auto_20210506_1448.py b/apps/users/migrations/0034_auto_20210506_1448.py index f08b34b3e..449f0ff6e 100644 --- a/apps/users/migrations/0034_auto_20210506_1448.py +++ b/apps/users/migrations/0034_auto_20210506_1448.py @@ -4,7 +4,6 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ('users', '0033_user_need_update_password'), ] @@ -13,11 +12,11 @@ class Migration(migrations.Migration): migrations.AddField( model_name='user', name='dingtalk_id', - field=models.CharField(default=None, max_length=128, null=True, unique=True, verbose_name='DingTalk'), + field=models.CharField(default=None, max_length=128, null=True, verbose_name='DingTalk'), ), migrations.AddField( model_name='user', name='wecom_id', - field=models.CharField(default=None, max_length=128, null=True, unique=True, verbose_name='WeCom'), + field=models.CharField(default=None, max_length=128, null=True, verbose_name='WeCom'), ), ] diff --git a/apps/users/migrations/0036_user_feishu_id.py b/apps/users/migrations/0036_user_feishu_id.py index 472bc0970..83c8c0d17 100644 --- a/apps/users/migrations/0036_user_feishu_id.py +++ b/apps/users/migrations/0036_user_feishu_id.py @@ -4,7 +4,6 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ('users', '0035_auto_20210526_1100'), ] @@ -13,6 +12,10 @@ class Migration(migrations.Migration): migrations.AddField( model_name='user', name='feishu_id', - field=models.CharField(default=None, max_length=128, null=True, unique=True, verbose_name='FeiShu'), + field=models.CharField(default=None, max_length=128, null=True, verbose_name='FeiShu'), + ), + migrations.AlterUniqueTogether( + name='user', + unique_together={('feishu_id',), ('wecom_id',), ('dingtalk_id',)}, ), ] diff --git a/apps/users/models/user.py b/apps/users/models/user.py index a156478bd..fcbc0b76e 100644 --- a/apps/users/models/user.py +++ b/apps/users/models/user.py @@ -811,9 +811,9 @@ class User(AuthMixin, TokenMixin, RoleMixin, MFAMixin, JSONFilterMixin, Abstract default=False, verbose_name=_('Need update password') ) date_updated = models.DateTimeField(auto_now=True, verbose_name=_('Date updated')) - wecom_id = models.CharField(null=True, default=None, unique=True, max_length=128, verbose_name=_('WeCom')) - dingtalk_id = models.CharField(null=True, default=None, unique=True, max_length=128, verbose_name=_('DingTalk')) - feishu_id = models.CharField(null=True, default=None, unique=True, max_length=128, verbose_name=_('FeiShu')) + wecom_id = models.CharField(null=True, default=None, max_length=128, verbose_name=_('WeCom')) + dingtalk_id = models.CharField(null=True, default=None, max_length=128, verbose_name=_('DingTalk')) + feishu_id = models.CharField(null=True, default=None, max_length=128, verbose_name=_('FeiShu')) DATE_EXPIRED_WARNING_DAYS = 5 @@ -945,6 +945,11 @@ class User(AuthMixin, TokenMixin, RoleMixin, MFAMixin, JSONFilterMixin, Abstract class Meta: ordering = ['username'] verbose_name = _("User") + unique_together = ( + ('dingtalk_id',), + ('wecom_id',), + ('feishu_id',), + ) permissions = [ ('invite_user', _('Can invite user')), ('remove_user', _('Can remove user')), From e2207cf8f15ee0e48d8221989445a1c8626661ed Mon Sep 17 00:00:00 2001 From: ibuler Date: Thu, 20 Jul 2023 19:41:42 +0800 Subject: [PATCH 002/177] =?UTF-8?q?chore:=20=E4=BF=AE=E6=94=B9=20readme?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 634a8e56a..2f0b02c62 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,7 @@ 9 年时间,倾情投入,用心做好一款开源堡垒机。

+------------------------------ JumpServer 是广受欢迎的开源堡垒机,是符合 4A 规范的专业运维安全审计系统。 JumpServer 堡垒机帮助企业以更安全的方式管控和登录各种类型的资产,包括: From 34e7671f65efc38a3c83fbba62f363875514ad65 Mon Sep 17 00:00:00 2001 From: ibuler Date: Fri, 21 Jul 2023 14:04:34 +0800 Subject: [PATCH 003/177] =?UTF-8?q?chore:=20=E4=BF=AE=E6=94=B9=20README?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 +--- requirements/requirements.txt | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 2f0b02c62..e83f8ee8f 100644 --- a/README.md +++ b/README.md @@ -84,9 +84,7 @@ JumpServer 堡垒机帮助企业以更安全的方式管控和登录各种类型 ### 参与贡献 -欢迎提交 PR 参与贡献。感谢以下贡献者,他们让 JumpServer 变的越来越好。 - - +欢迎提交 PR 参与贡献。 参考 [CONTRIBUTING.md](https://github.com/jumpserver/jumpserver/blob/dev/CONTRIBUTING.md) ## 组件项目 diff --git a/requirements/requirements.txt b/requirements/requirements.txt index 65004e605..d22d4972d 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -1,6 +1,6 @@ aiofiles==22.1.0 amqp==5.0.9 -git+https://github.com/jumpserver/ansible@master#egg=ansible-core +#git+https://github.com/jumpserver/ansible@master#egg=ansible-core ansible==7.1.0 ansible-runner==2.2.1 asn1crypto==0.24.0 From 0fb01bd7fb45ed788992735387ee9fd6248ee544 Mon Sep 17 00:00:00 2001 From: ibuler Date: Fri, 21 Jul 2023 14:10:21 +0800 Subject: [PATCH 004/177] =?UTF-8?q?chore:=20=E8=BF=98=E5=8E=9F=20requireme?= =?UTF-8?q?nts?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- requirements/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/requirements.txt b/requirements/requirements.txt index d22d4972d..65004e605 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -1,6 +1,6 @@ aiofiles==22.1.0 amqp==5.0.9 -#git+https://github.com/jumpserver/ansible@master#egg=ansible-core +git+https://github.com/jumpserver/ansible@master#egg=ansible-core ansible==7.1.0 ansible-runner==2.2.1 asn1crypto==0.24.0 From 54e6200ffef7f9f06815be15ff71c10f6435bdf7 Mon Sep 17 00:00:00 2001 From: Eric Date: Fri, 21 Jul 2023 18:21:24 +0800 Subject: [PATCH 005/177] =?UTF-8?q?feat:=20python=20=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E4=BD=BF=E7=94=A8=203.11=20=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/common/serializers/mixin.py | 7 ++++++- requirements/requirements.txt | 11 +++++++---- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/apps/common/serializers/mixin.py b/apps/common/serializers/mixin.py index 4d3e6ddc8..d665d6346 100644 --- a/apps/common/serializers/mixin.py +++ b/apps/common/serializers/mixin.py @@ -1,5 +1,10 @@ -from collections import Iterable, defaultdict, OrderedDict +import sys +from collections import defaultdict, OrderedDict +if sys.version_info.major >= 3 and sys.version_info.minor >= 10: + from collections.abc import Iterable +else: + from collections import Iterable from django.core.exceptions import ObjectDoesNotExist from django.db.models import NOT_PROVIDED from rest_framework import serializers diff --git a/requirements/requirements.txt b/requirements/requirements.txt index 65004e605..8f95d2d6c 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -1,10 +1,12 @@ +# 临时解决 cython 3.0 造成的错误 +cython==0.29.36 aiofiles==22.1.0 amqp==5.0.9 git+https://github.com/jumpserver/ansible@master#egg=ansible-core ansible==7.1.0 ansible-runner==2.2.1 asn1crypto==0.24.0 -bcrypt==3.1.4 +bcrypt==4.0.1 billiard==3.6.4.0 certifi==2022.12.7 cffi==1.15.1 @@ -94,7 +96,7 @@ django-proxy==1.2.1 channels-redis==4.0.0 python-daemon==2.3.0 eventlet==0.33.1 -greenlet==1.1.2 +greenlet==2.0.2 gunicorn==20.1.0 celery==5.2.7 flower==1.2.0 @@ -105,7 +107,8 @@ websockets==10.4 # Auth python-ldap==3.4.0 ldap3==2.9.1 -django-radius==1.5.0 +#django-radius==1.5.0 +git+https://github.com/robgolding/django-radius@develop#egg=django-radius jumpserver-django-oidc-rp==0.3.7.8 django-cas-ng==4.0.1 python-cas==1.5.0 @@ -118,7 +121,7 @@ kubernetes==21.7.0 # DB requirements mysqlclient==2.1.0 PyMySQL==1.0.2 -pymssql==2.2.5 +pymssql==2.2.7 django-mysql==3.9.0 django-redis==5.2.0 python-redis-lock==3.7.0 From 1f25eaf4130055dc6e299ea004a7d90ff83d8722 Mon Sep 17 00:00:00 2001 From: feng <1304903146@qq.com> Date: Fri, 21 Jul 2023 19:23:33 +0800 Subject: [PATCH 006/177] perf: update requirements.txt --- requirements/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/requirements.txt b/requirements/requirements.txt index 8f95d2d6c..839fccb11 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -119,7 +119,7 @@ botocore==1.27.12 s3transfer==0.6.0 kubernetes==21.7.0 # DB requirements -mysqlclient==2.1.0 +mysqlclient==2.2.0 PyMySQL==1.0.2 pymssql==2.2.7 django-mysql==3.9.0 From 78d8e410db156bc29170da2599b399ec7ba61ccd Mon Sep 17 00:00:00 2001 From: Huiser WANG Date: Sat, 22 Jul 2023 14:04:21 +0800 Subject: [PATCH 007/177] fix a latent bug when field_type belongs to int, bool and list. --- apps/common/serializers/dynamic.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/common/serializers/dynamic.py b/apps/common/serializers/dynamic.py index a42529b5a..4442fd139 100644 --- a/apps/common/serializers/dynamic.py +++ b/apps/common/serializers/dynamic.py @@ -62,6 +62,8 @@ def create_serializer_class(serializer_name, fields_info): data['required'] = False data = set_default_by_type(field_type, data, field_info) data = set_default_if_need(data, i) + if field_type in ['int', 'bool', 'list'] and "allow_blank" in data.keys(): + data.pop('allow_blank') field_name = data.pop('name') field_class = type_field_map.get(field_type, serializers.CharField) serializer_fields[field_name] = field_class(**data) From 2417a0930f2792de4bd2d8eef8b594f75c74dbb6 Mon Sep 17 00:00:00 2001 From: ibuler Date: Mon, 24 Jul 2023 10:07:32 +0800 Subject: [PATCH 008/177] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=E4=BE=9D?= =?UTF-8?q?=E8=B5=96=E5=BA=93=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- requirements/mac_pkg.sh | 2 +- requirements/requirements.txt | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/requirements/mac_pkg.sh b/requirements/mac_pkg.sh index 909282cf0..f78bad908 100644 --- a/requirements/mac_pkg.sh +++ b/requirements/mac_pkg.sh @@ -4,7 +4,7 @@ PROJECT_DIR=$(dirname "$BASE_DIR") echo "1. 安装依赖" brew install libtiff libjpeg webp little-cms2 openssl gettext git \ - git-lfs mysql libxml2 libxmlsec1 pkg-config postgresql freetds openssl \ + git-lfs libxml2 libxmlsec1 pkg-config postgresql freetds openssl \ libffi freerdp echo "2. 下载 IP 数据库" diff --git a/requirements/requirements.txt b/requirements/requirements.txt index 65004e605..3a1a78a4d 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -1,10 +1,10 @@ aiofiles==22.1.0 amqp==5.0.9 -git+https://github.com/jumpserver/ansible@master#egg=ansible-core +#git+https://github.com/jumpserver/ansible@master#egg=ansible-core ansible==7.1.0 ansible-runner==2.2.1 asn1crypto==0.24.0 -bcrypt==3.1.4 +bcrypt==4.0.1 billiard==3.6.4.0 certifi==2022.12.7 cffi==1.15.1 @@ -14,7 +14,7 @@ decorator==4.1.2 docutils==0.14 ecdsa==0.13.3 enum-compat==0.0.2 -ephem==3.7.6.0 +ephem==4.1.4 future==0.16.0 idna==2.8 itypes==1.2.0 @@ -27,15 +27,15 @@ passlib==1.7.4 pyasn1==0.4.8 pycparser==2.21 cryptography==38.0.4 -pycryptodome==3.15.0 -pycryptodomex==3.15.0 +pycryptodome==3.18.0 +pycryptodomex==3.18.0 phonenumbers==8.13.8 gmssl==3.2.1 itsdangerous==1.1.0 pyotp==2.6.0 PyNaCl==1.5.0 python-dateutil==2.8.2 -PyYAML==6.0 +PyYAML==6.0.1 requests==2.31.0 jms-storage==0.0.47 simplejson==3.17.6 @@ -60,7 +60,7 @@ pyvmomi==7.0.1 termcolor==1.1.0 html2text==2020.1.16 pyzipper==0.3.5 -python3-saml==1.12.0 +python3-saml==1.15.0 websocket-client==1.2.3 pyjwkest==1.4.2 jsonfield2==4.0.0.post0 @@ -94,7 +94,7 @@ django-proxy==1.2.1 channels-redis==4.0.0 python-daemon==2.3.0 eventlet==0.33.1 -greenlet==1.1.2 +greenlet==2.0.2 gunicorn==20.1.0 celery==5.2.7 flower==1.2.0 @@ -118,7 +118,7 @@ kubernetes==21.7.0 # DB requirements mysqlclient==2.1.0 PyMySQL==1.0.2 -pymssql==2.2.5 +#pymssql==2.2.5 django-mysql==3.9.0 django-redis==5.2.0 python-redis-lock==3.7.0 From ed492166254fbe3bd3bc5b6eeb604f321ba0b356 Mon Sep 17 00:00:00 2001 From: ibuler Date: Mon, 24 Jul 2023 10:14:26 +0800 Subject: [PATCH 009/177] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=20mssql?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- requirements/requirements.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements/requirements.txt b/requirements/requirements.txt index 3a1a78a4d..b3d289c51 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -1,6 +1,6 @@ aiofiles==22.1.0 amqp==5.0.9 -#git+https://github.com/jumpserver/ansible@master#egg=ansible-core +git+https://github.com/jumpserver/ansible@master#egg=ansible-core ansible==7.1.0 ansible-runner==2.2.1 asn1crypto==0.24.0 @@ -118,7 +118,7 @@ kubernetes==21.7.0 # DB requirements mysqlclient==2.1.0 PyMySQL==1.0.2 -#pymssql==2.2.5 +pymssql==2.2.5 django-mysql==3.9.0 django-redis==5.2.0 python-redis-lock==3.7.0 From b4b9c805ffa94750325011ed3cf22a85bc7d0e6f Mon Sep 17 00:00:00 2001 From: ibuler Date: Mon, 24 Jul 2023 11:52:25 +0800 Subject: [PATCH 010/177] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=E6=94=AF?= =?UTF-8?q?=E6=8C=81=20Django4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/accounts/api/automations/base.py | 2 +- apps/accounts/const/account.py | 2 +- apps/accounts/const/automation.py | 2 +- .../models/automations/backup_account.py | 2 +- .../models/automations/change_secret.py | 2 +- .../models/automations/gather_account.py | 2 +- .../models/automations/push_account.py | 2 +- .../models/automations/verify_account.py | 2 +- apps/accounts/models/base.py | 2 +- apps/accounts/notifications.py | 2 +- apps/accounts/serializers/account/account.py | 2 +- apps/accounts/serializers/account/backup.py | 2 +- apps/accounts/serializers/account/base.py | 2 +- .../serializers/account/gathered_account.py | 2 +- apps/accounts/serializers/account/template.py | 2 +- apps/accounts/serializers/automations/base.py | 2 +- .../serializers/automations/change_secret.py | 2 +- apps/accounts/tasks/push_account.py | 2 +- apps/accounts/utils.py | 2 +- apps/acls/apps.py | 2 +- apps/acls/models/command_acl.py | 2 +- apps/acls/models/login_acl.py | 2 +- apps/acls/models/login_asset_acl.py | 2 +- apps/acls/serializers/base.py | 2 +- apps/acls/serializers/command_acl.py | 2 +- apps/acls/serializers/login_acl.py | 2 +- apps/acls/serializers/rules/rules.py | 2 +- apps/applications/apps.py | 3 +- .../migrations/0006_application.py | 2 +- apps/applications/models.py | 2 +- apps/assets/api/domain.py | 3 +- apps/assets/api/node.py | 2 +- apps/assets/apps.py | 5 +- .../automations/ping_gateway/manager.py | 2 +- apps/assets/const/automation.py | 2 +- apps/assets/exceptions.py | 2 +- apps/assets/models/asset/common.py | 2 +- apps/assets/models/asset/host.py | 2 +- apps/assets/models/automations/base.py | 2 +- .../assets/models/automations/gather_facts.py | 2 +- apps/assets/models/automations/ping.py | 2 +- apps/assets/models/base.py | 2 +- apps/assets/models/cmd_filter.py | 2 +- apps/assets/models/domain.py | 2 +- apps/assets/models/favorite_asset.py | 2 +- apps/assets/models/gateway.py | 2 +- apps/assets/models/group.py | 2 +- apps/assets/models/label.py | 2 +- apps/assets/models/node.py | 5 +- apps/assets/models/utils.py | 2 +- apps/assets/notifications.py | 4 +- apps/assets/serializers/asset/common.py | 2 +- apps/assets/serializers/asset/database.py | 4 +- apps/assets/serializers/automations/base.py | 2 +- apps/assets/serializers/domain.py | 2 +- apps/assets/serializers/gateway.py | 2 +- apps/assets/serializers/label.py | 2 +- apps/assets/serializers/node.py | 2 +- apps/assets/tasks/ping_gateway.py | 2 +- apps/assets/tasks/utils.py | 3 +- apps/audits/apps.py | 3 +- apps/audits/backends/db.py | 2 +- apps/audits/const.py | 2 +- apps/audits/handler.py | 2 +- apps/audits/models.py | 4 +- apps/audits/serializers.py | 5 +- apps/audits/signal_handlers/login_log.py | 2 +- apps/authentication/api/confirm.py | 4 +- apps/authentication/api/connection_token.py | 2 +- apps/authentication/api/mfa.py | 12 +- apps/authentication/api/password.py | 26 +-- apps/authentication/apps.py | 7 +- apps/authentication/backends/custom.py | 8 +- apps/authentication/backends/drf.py | 15 +- .../authentication/backends/oauth2/signals.py | 6 +- apps/authentication/backends/oidc/signals.py | 6 +- apps/authentication/backends/oidc/views.py | 25 ++- apps/authentication/backends/saml2/signals.py | 3 +- apps/authentication/confirm/password.py | 2 +- apps/authentication/confirm/relogin.py | 2 +- apps/authentication/errors/failed.py | 4 +- apps/authentication/errors/mfa.py | 2 +- apps/authentication/errors/redirect.py | 2 +- apps/authentication/forms.py | 4 +- apps/authentication/mfa/base.py | 3 +- apps/authentication/mfa/custom.py | 2 +- apps/authentication/mfa/radius.py | 2 +- apps/authentication/mfa/sms.py | 4 +- apps/authentication/middleware.py | 2 +- apps/authentication/mixins.py | 2 +- apps/authentication/models/access_key.py | 2 +- .../authentication/models/connection_token.py | 2 +- apps/authentication/models/private_token.py | 2 +- apps/authentication/models/sso_token.py | 2 +- apps/authentication/models/temp_token.py | 6 +- apps/authentication/notifications.py | 4 +- .../serializers/connect_token_secret.py | 2 +- .../serializers/connection_token.py | 2 +- .../serializers/password_mfa.py | 2 +- apps/authentication/signals.py | 10 +- apps/authentication/utils.py | 8 +- apps/authentication/views/base.py | 13 +- apps/authentication/views/dingtalk.py | 5 +- apps/authentication/views/feishu.py | 6 +- apps/authentication/views/login.py | 2 +- apps/authentication/views/wecom.py | 40 ++--- apps/common/api/action.py | 2 +- apps/common/const/choices.py | 2 +- apps/common/const/common.py | 2 +- apps/common/db/encoder.py | 4 +- apps/common/db/fields.py | 8 +- apps/common/db/mixins.py | 2 +- apps/common/db/models.py | 2 +- apps/common/drf/metadata.py | 8 +- apps/common/drf/parsers/base.py | 2 +- apps/common/drf/renders/base.py | 2 +- apps/common/sdk/im/wecom/__init__.py | 23 ++- apps/common/sdk/sms/cmpp2.py | 16 +- apps/common/tasks.py | 6 +- apps/common/utils/encode.py | 2 +- apps/common/utils/ip/geoip/utils.py | 8 +- apps/common/validators.py | 7 +- apps/jumpserver/conf.py | 4 +- apps/jumpserver/context_processor.py | 2 +- apps/jumpserver/settings/base.py | 2 +- apps/jumpserver/views/celery_flower.py | 6 +- apps/jumpserver/views/other.py | 10 +- apps/locale/ja/LC_MESSAGES/django.po | 4 +- apps/locale/zh/LC_MESSAGES/django.po | 4 +- apps/notifications/apps.py | 4 +- apps/notifications/models/notification.py | 2 +- apps/ops/api/celery.py | 2 +- apps/ops/api/playbook.py | 2 +- apps/ops/const.py | 2 +- apps/ops/mixin.py | 2 +- apps/ops/models/adhoc.py | 3 +- apps/ops/tasks.py | 2 +- apps/orgs/api.py | 2 +- apps/orgs/apps.py | 5 +- apps/orgs/mixins/models.py | 2 +- apps/orgs/mixins/serializers.py | 2 +- apps/orgs/models.py | 2 +- apps/orgs/tasks.py | 2 +- apps/perms/api/user_permission/mixin.py | 9 +- apps/perms/apps.py | 5 +- apps/perms/const.py | 2 +- apps/perms/filters.py | 12 +- apps/perms/models/asset_permission.py | 2 +- apps/perms/models/perm_node.py | 2 +- apps/perms/notifications.py | 2 +- apps/perms/serializers/permission.py | 2 +- apps/perms/serializers/user_permission.py | 2 +- apps/rbac/api/role.py | 2 +- apps/rbac/api/rolebinding.py | 18 +- apps/rbac/apps.py | 3 +- apps/rbac/builtin.py | 16 +- apps/rbac/const.py | 2 +- apps/rbac/models/permission.py | 7 +- apps/rbac/models/role.py | 2 +- apps/rbac/serializers/permission.py | 5 +- apps/rbac/serializers/role.py | 2 +- apps/rbac/serializers/rolebinding.py | 9 +- apps/settings/api/email.py | 2 +- apps/settings/api/ldap.py | 2 +- apps/settings/apps.py | 5 +- apps/settings/models.py | 11 +- apps/settings/serializers/auth/base.py | 2 +- apps/settings/serializers/auth/cas.py | 2 +- apps/settings/serializers/auth/dingtalk.py | 2 +- apps/settings/serializers/auth/feishu.py | 2 +- apps/settings/serializers/auth/ldap.py | 2 +- apps/settings/serializers/auth/oauth2.py | 2 +- apps/settings/serializers/auth/oidc.py | 2 +- apps/settings/serializers/auth/radius.py | 2 +- apps/settings/serializers/auth/saml2.py | 3 +- apps/settings/serializers/auth/sms.py | 6 +- apps/settings/serializers/auth/sso.py | 2 +- apps/settings/serializers/auth/wecom.py | 2 +- apps/settings/serializers/basic.py | 3 +- apps/settings/serializers/cleaning.py | 5 +- apps/settings/serializers/email.py | 2 +- apps/settings/serializers/other.py | 2 +- apps/settings/serializers/security.py | 8 +- apps/settings/serializers/settings.py | 13 +- apps/settings/serializers/sms.py | 2 +- apps/settings/serializers/terminal.py | 2 +- apps/settings/signals.py | 2 +- apps/settings/tasks/ldap.py | 3 +- apps/settings/utils/ldap.py | 2 +- apps/terminal/api/component/endpoint.py | 2 +- apps/terminal/api/component/storage.py | 52 +++--- apps/terminal/api/session/session.py | 2 +- apps/terminal/api/session/sharing.py | 2 +- apps/terminal/backends/command/models.py | 3 +- apps/terminal/connect_methods.py | 2 +- apps/terminal/const.py | 2 +- apps/terminal/exceptions.py | 3 +- apps/terminal/models/component/endpoint.py | 2 +- apps/terminal/models/component/status.py | 2 +- apps/terminal/models/component/storage.py | 2 +- apps/terminal/models/component/task.py | 2 +- apps/terminal/models/component/terminal.py | 4 +- apps/terminal/models/session/command.py | 2 +- apps/terminal/models/session/replay.py | 2 +- apps/terminal/models/session/session.py | 2 +- apps/terminal/models/session/sharing.py | 2 +- apps/terminal/notifications.py | 4 +- apps/terminal/serializers/command.py | 7 +- apps/terminal/serializers/session.py | 2 +- apps/terminal/serializers/sharing.py | 2 +- apps/terminal/serializers/storage.py | 12 +- apps/terminal/serializers/terminal.py | 2 +- apps/terminal/utils/db_port_mapper.py | 2 +- apps/tickets/apps.py | 4 +- apps/tickets/const.py | 2 +- apps/tickets/errors.py | 2 +- apps/tickets/handlers/apply_asset.py | 2 +- apps/tickets/handlers/base.py | 2 +- apps/tickets/models/comment.py | 2 +- apps/tickets/models/flow.py | 2 +- apps/tickets/models/relation.py | 8 +- apps/tickets/models/ticket/general.py | 2 +- apps/tickets/notifications.py | 2 +- apps/tickets/serializers/flow.py | 10 +- .../tickets/serializers/ticket/apply_asset.py | 2 +- apps/tickets/serializers/ticket/common.py | 2 +- apps/tickets/serializers/ticket/ticket.py | 2 +- apps/tickets/views/approve.py | 5 +- apps/users/api/user.py | 3 +- apps/users/apps.py | 5 +- apps/users/const.py | 2 +- apps/users/models/group.py | 2 +- apps/users/models/user.py | 2 +- apps/users/notifications.py | 6 +- apps/users/serializers/group.py | 2 +- apps/users/serializers/profile.py | 2 +- apps/users/serializers/user.py | 2 +- apps/users/signal_handlers.py | 2 +- apps/users/signals.py | 9 +- apps/users/views/profile/otp.py | 16 +- apps/users/views/profile/password.py | 7 +- apps/users/views/profile/reset.py | 8 +- requirements/requirements.txt | 159 +++++++++--------- 243 files changed, 546 insertions(+), 614 deletions(-) diff --git a/apps/accounts/api/automations/base.py b/apps/accounts/api/automations/base.py index 7d5db0ac8..d5e588c04 100644 --- a/apps/accounts/api/automations/base.py +++ b/apps/accounts/api/automations/base.py @@ -1,5 +1,5 @@ from django.shortcuts import get_object_or_404 -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from rest_framework import status, mixins, viewsets from rest_framework.response import Response diff --git a/apps/accounts/const/account.py b/apps/accounts/const/account.py index 9a3541001..44caa2889 100644 --- a/apps/accounts/const/account.py +++ b/apps/accounts/const/account.py @@ -1,5 +1,5 @@ from django.db.models import TextChoices -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ class SecretType(TextChoices): diff --git a/apps/accounts/const/automation.py b/apps/accounts/const/automation.py index 791527078..cb39703e0 100644 --- a/apps/accounts/const/automation.py +++ b/apps/accounts/const/automation.py @@ -1,5 +1,5 @@ from django.db import models -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from assets.const import Connectivity from common.db.fields import TreeChoices diff --git a/apps/accounts/models/automations/backup_account.py b/apps/accounts/models/automations/backup_account.py index fba3b3149..c72e0daef 100644 --- a/apps/accounts/models/automations/backup_account.py +++ b/apps/accounts/models/automations/backup_account.py @@ -6,7 +6,7 @@ import uuid from celery import current_task from django.db import models from django.db.models import F -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from common.const.choices import Trigger from common.db.encoder import ModelJSONFieldEncoder diff --git a/apps/accounts/models/automations/change_secret.py b/apps/accounts/models/automations/change_secret.py index 2226040a2..a2a1d42a2 100644 --- a/apps/accounts/models/automations/change_secret.py +++ b/apps/accounts/models/automations/change_secret.py @@ -1,5 +1,5 @@ from django.db import models -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from accounts.const import ( AutomationTypes, SecretType, SecretStrategy, SSHKeyStrategy diff --git a/apps/accounts/models/automations/gather_account.py b/apps/accounts/models/automations/gather_account.py index dd9b5c862..9ea5dcc3b 100644 --- a/apps/accounts/models/automations/gather_account.py +++ b/apps/accounts/models/automations/gather_account.py @@ -1,6 +1,6 @@ from django.db import models from django.db.models import Q -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from accounts.const import AutomationTypes, Source from accounts.models import Account diff --git a/apps/accounts/models/automations/push_account.py b/apps/accounts/models/automations/push_account.py index d3a14411f..fe628f4cb 100644 --- a/apps/accounts/models/automations/push_account.py +++ b/apps/accounts/models/automations/push_account.py @@ -1,5 +1,5 @@ from django.db import models -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from accounts.const import AutomationTypes from accounts.models import Account diff --git a/apps/accounts/models/automations/verify_account.py b/apps/accounts/models/automations/verify_account.py index 03ec4f8c9..ae9beb9a6 100644 --- a/apps/accounts/models/automations/verify_account.py +++ b/apps/accounts/models/automations/verify_account.py @@ -1,4 +1,4 @@ -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from accounts.const import AutomationTypes from .base import AccountBaseAutomation diff --git a/apps/accounts/models/base.py b/apps/accounts/models/base.py index e4bd780ac..3f9f70883 100644 --- a/apps/accounts/models/base.py +++ b/apps/accounts/models/base.py @@ -6,7 +6,7 @@ from hashlib import md5 import sshpubkeys from django.conf import settings from django.db import models -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from accounts.const import SecretType from common.db import fields diff --git a/apps/accounts/notifications.py b/apps/accounts/notifications.py index 3c4897df1..190eb8fb6 100644 --- a/apps/accounts/notifications.py +++ b/apps/accounts/notifications.py @@ -1,4 +1,4 @@ -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from common.tasks import send_mail_attachment_async from users.models import User diff --git a/apps/accounts/serializers/account/account.py b/apps/accounts/serializers/account/account.py index cc1952a1c..54035e4be 100644 --- a/apps/accounts/serializers/account/account.py +++ b/apps/accounts/serializers/account/account.py @@ -3,7 +3,7 @@ from copy import deepcopy from django.db import IntegrityError from django.db.models import Q -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from rest_framework import serializers from rest_framework.generics import get_object_or_404 from rest_framework.validators import UniqueTogetherValidator diff --git a/apps/accounts/serializers/account/backup.py b/apps/accounts/serializers/account/backup.py index 712bdd095..b6ec22203 100644 --- a/apps/accounts/serializers/account/backup.py +++ b/apps/accounts/serializers/account/backup.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from rest_framework import serializers from accounts.models import AccountBackupAutomation, AccountBackupExecution diff --git a/apps/accounts/serializers/account/base.py b/apps/accounts/serializers/account/base.py index 2f9660bd5..e2a837b03 100644 --- a/apps/accounts/serializers/account/base.py +++ b/apps/accounts/serializers/account/base.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from rest_framework import serializers from accounts.const import SecretType diff --git a/apps/accounts/serializers/account/gathered_account.py b/apps/accounts/serializers/account/gathered_account.py index b382fda4c..a36bddc5e 100644 --- a/apps/accounts/serializers/account/gathered_account.py +++ b/apps/accounts/serializers/account/gathered_account.py @@ -1,4 +1,4 @@ -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from accounts.models import GatheredAccount from orgs.mixins.serializers import BulkOrgResourceModelSerializer diff --git a/apps/accounts/serializers/account/template.py b/apps/accounts/serializers/account/template.py index ffe8c7564..9642c36b0 100644 --- a/apps/accounts/serializers/account/template.py +++ b/apps/accounts/serializers/account/template.py @@ -1,4 +1,4 @@ -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from rest_framework import serializers from accounts.models import AccountTemplate, Account diff --git a/apps/accounts/serializers/automations/base.py b/apps/accounts/serializers/automations/base.py index 8e7f11f23..c2cd21be3 100644 --- a/apps/accounts/serializers/automations/base.py +++ b/apps/accounts/serializers/automations/base.py @@ -1,4 +1,4 @@ -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from rest_framework import serializers from accounts.models import AutomationExecution diff --git a/apps/accounts/serializers/automations/change_secret.py b/apps/accounts/serializers/automations/change_secret.py index 3c6e11205..da8a1585c 100644 --- a/apps/accounts/serializers/automations/change_secret.py +++ b/apps/accounts/serializers/automations/change_secret.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from rest_framework import serializers from accounts.const import ( diff --git a/apps/accounts/tasks/push_account.py b/apps/accounts/tasks/push_account.py index 623481be9..0e0608999 100644 --- a/apps/accounts/tasks/push_account.py +++ b/apps/accounts/tasks/push_account.py @@ -1,5 +1,5 @@ from celery import shared_task -from django.utils.translation import gettext_noop, ugettext_lazy as _ +from django.utils.translation import gettext_noop, gettext_lazy as _ from accounts.const import AutomationTypes from accounts.tasks.common import quickstart_automation_by_snapshot diff --git a/apps/accounts/utils.py b/apps/accounts/utils.py index ef0d61fe1..1a24008fc 100644 --- a/apps/accounts/utils.py +++ b/apps/accounts/utils.py @@ -1,4 +1,4 @@ -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from rest_framework import serializers from accounts.const import ( diff --git a/apps/acls/apps.py b/apps/acls/apps.py index 0a93fe495..291ce855e 100644 --- a/apps/acls/apps.py +++ b/apps/acls/apps.py @@ -1,5 +1,5 @@ from django.apps import AppConfig -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ class AclsConfig(AppConfig): diff --git a/apps/acls/models/command_acl.py b/apps/acls/models/command_acl.py index 9029142f2..4fbfd0829 100644 --- a/apps/acls/models/command_acl.py +++ b/apps/acls/models/command_acl.py @@ -3,7 +3,7 @@ import re from django.db import models -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from common.utils import lazyproperty, get_logger from orgs.mixins.models import JMSOrgBaseModel diff --git a/apps/acls/models/login_acl.py b/apps/acls/models/login_acl.py index 7191fe4b6..6f2e21b34 100644 --- a/apps/acls/models/login_acl.py +++ b/apps/acls/models/login_acl.py @@ -1,5 +1,5 @@ from django.db import models -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from common.utils import get_request_ip, get_ip_city from common.utils.timezone import local_now_display diff --git a/apps/acls/models/login_asset_acl.py b/apps/acls/models/login_asset_acl.py index 5d2293a18..7669152b4 100644 --- a/apps/acls/models/login_asset_acl.py +++ b/apps/acls/models/login_asset_acl.py @@ -1,5 +1,5 @@ from django.db import models -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from .base import UserAssetAccountBaseACL diff --git a/apps/acls/serializers/base.py b/apps/acls/serializers/base.py index 94c4d9fa1..4c2d80bfc 100644 --- a/apps/acls/serializers/base.py +++ b/apps/acls/serializers/base.py @@ -1,4 +1,4 @@ -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from rest_framework import serializers from acls.models.base import BaseACL diff --git a/apps/acls/serializers/command_acl.py b/apps/acls/serializers/command_acl.py index 672164012..dde953277 100644 --- a/apps/acls/serializers/command_acl.py +++ b/apps/acls/serializers/command_acl.py @@ -1,4 +1,4 @@ -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from rest_framework import serializers from acls.models import CommandGroup, CommandFilterACL diff --git a/apps/acls/serializers/login_acl.py b/apps/acls/serializers/login_acl.py index c86424986..737e5269d 100644 --- a/apps/acls/serializers/login_acl.py +++ b/apps/acls/serializers/login_acl.py @@ -1,4 +1,4 @@ -from django.utils.translation import ugettext as _ +from django.utils.translation import gettext as _ from common.serializers import MethodSerializer from orgs.mixins.serializers import BulkOrgResourceModelSerializer diff --git a/apps/acls/serializers/rules/rules.py b/apps/acls/serializers/rules/rules.py index 85b865cd6..4c88d0ac7 100644 --- a/apps/acls/serializers/rules/rules.py +++ b/apps/acls/serializers/rules/rules.py @@ -1,7 +1,7 @@ # coding: utf-8 # +from django.utils.translation import gettext_lazy as _ from rest_framework import serializers -from django.utils.translation import ugettext_lazy as _ from common.utils import get_logger from common.utils.ip import is_ip_address, is_ip_network, is_ip_segment diff --git a/apps/applications/apps.py b/apps/applications/apps.py index a025a0517..c672bf36e 100644 --- a/apps/applications/apps.py +++ b/apps/applications/apps.py @@ -1,7 +1,7 @@ from __future__ import unicode_literals -from django.utils.translation import ugettext_lazy as _ from django.apps import AppConfig +from django.utils.translation import gettext_lazy as _ class ApplicationsConfig(AppConfig): @@ -9,5 +9,4 @@ class ApplicationsConfig(AppConfig): verbose_name = _('Applications') def ready(self): - from . import signal_handlers super().ready() diff --git a/apps/applications/migrations/0006_application.py b/apps/applications/migrations/0006_application.py index fbe629873..0333b860d 100644 --- a/apps/applications/migrations/0006_application.py +++ b/apps/applications/migrations/0006_application.py @@ -127,7 +127,7 @@ class Migration(migrations.Migration): ('name', models.CharField(max_length=128, verbose_name='Name')), ('category', models.CharField(choices=[('db', 'Database'), ('remote_app', 'Remote app'), ('cloud', 'Cloud')], max_length=16, verbose_name='Category')), ('type', models.CharField(choices=[('mysql', 'MySQL'), ('oracle', 'Oracle'), ('postgresql', 'PostgreSQL'), ('mariadb', 'MariaDB'), ('chrome', 'Chrome'), ('mysql_workbench', 'MySQL Workbench'), ('vmware_client', 'vSphere Client'), ('custom', 'Custom'), ('k8s', 'Kubernetes')], max_length=16, verbose_name='Type')), - ('attrs', django_mysql.models.JSONField(default=dict)), + ('attrs', models.JSONField(default=dict)), ('comment', models.TextField(blank=True, default='', max_length=128, verbose_name='Comment')), ('domain', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='applications', to='assets.Domain', verbose_name='Domain')), ], diff --git a/apps/applications/models.py b/apps/applications/models.py index 60efc8aab..c13ddc092 100644 --- a/apps/applications/models.py +++ b/apps/applications/models.py @@ -1,5 +1,5 @@ from django.db import models -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from common.db.models import JMSBaseModel from orgs.mixins.models import OrgModelMixin diff --git a/apps/assets/api/domain.py b/apps/assets/api/domain.py index 40d676d78..86097247c 100644 --- a/apps/assets/api/domain.py +++ b/apps/assets/api/domain.py @@ -1,5 +1,5 @@ # ~*~ coding: utf-8 ~*~ -from django.utils.translation import ugettext as _ +from django.utils.translation import gettext as _ from django.views.generic.detail import SingleObjectMixin from rest_framework.serializers import ValidationError from rest_framework.views import APIView, Response @@ -29,6 +29,7 @@ class DomainViewSet(OrgBulkModelViewSet): def get_queryset(self): return super().get_queryset().prefetch_related('assets') + class GatewayViewSet(HostViewSet): perm_model = Gateway filterset_fields = ("domain__name", "name", "domain") diff --git a/apps/assets/api/node.py b/apps/assets/api/node.py index 47ac0b4e6..30c533179 100644 --- a/apps/assets/api/node.py +++ b/apps/assets/api/node.py @@ -3,7 +3,7 @@ from collections import namedtuple, defaultdict from functools import partial from django.db.models.signals import m2m_changed -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from rest_framework import status from rest_framework.decorators import action from rest_framework.generics import get_object_or_404 diff --git a/apps/assets/apps.py b/apps/assets/apps.py index a91b10ffc..2966894d6 100644 --- a/apps/assets/apps.py +++ b/apps/assets/apps.py @@ -1,7 +1,7 @@ from __future__ import unicode_literals -from django.utils.translation import ugettext_lazy as _ from django.apps import AppConfig +from django.utils.translation import gettext_lazy as _ class AssetsConfig(AppConfig): @@ -13,6 +13,3 @@ class AssetsConfig(AppConfig): def ready(self): super().ready() - from . import signal_handlers - from . import tasks - diff --git a/apps/assets/automations/ping_gateway/manager.py b/apps/assets/automations/ping_gateway/manager.py index b3f243fdb..c272570d3 100644 --- a/apps/assets/automations/ping_gateway/manager.py +++ b/apps/assets/automations/ping_gateway/manager.py @@ -2,7 +2,7 @@ import socket import paramiko from django.utils import timezone -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from assets.const import AutomationTypes, Connectivity from assets.models import Gateway diff --git a/apps/assets/const/automation.py b/apps/assets/const/automation.py index 831b11b66..4a2054db1 100644 --- a/apps/assets/const/automation.py +++ b/apps/assets/const/automation.py @@ -1,5 +1,5 @@ from django.db.models import TextChoices -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ class Connectivity(TextChoices): diff --git a/apps/assets/exceptions.py b/apps/assets/exceptions.py index ad22b6339..07e4de0a2 100644 --- a/apps/assets/exceptions.py +++ b/apps/assets/exceptions.py @@ -1,4 +1,4 @@ -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from rest_framework import status from common.exceptions import JMSException diff --git a/apps/assets/models/asset/common.py b/apps/assets/models/asset/common.py index 7a564f787..b7425b870 100644 --- a/apps/assets/models/asset/common.py +++ b/apps/assets/models/asset/common.py @@ -8,7 +8,7 @@ from collections import defaultdict from django.db import models from django.db.models import Q from django.forms import model_to_dict -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from assets import const from common.db.fields import EncryptMixin diff --git a/apps/assets/models/asset/host.py b/apps/assets/models/asset/host.py index 69187c828..a424cfcec 100644 --- a/apps/assets/models/asset/host.py +++ b/apps/assets/models/asset/host.py @@ -1,4 +1,4 @@ -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from .common import Asset diff --git a/apps/assets/models/automations/base.py b/apps/assets/models/automations/base.py index ba9c3ffcb..27e5ed74a 100644 --- a/apps/assets/models/automations/base.py +++ b/apps/assets/models/automations/base.py @@ -2,7 +2,7 @@ import uuid from celery import current_task from django.db import models -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from assets.models.asset import Asset from assets.models.node import Node diff --git a/apps/assets/models/automations/gather_facts.py b/apps/assets/models/automations/gather_facts.py index cf11ea41b..5e179cd83 100644 --- a/apps/assets/models/automations/gather_facts.py +++ b/apps/assets/models/automations/gather_facts.py @@ -1,4 +1,4 @@ -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from assets.const import AutomationTypes from .base import AssetBaseAutomation diff --git a/apps/assets/models/automations/ping.py b/apps/assets/models/automations/ping.py index a8df4e7c8..98aee079e 100644 --- a/apps/assets/models/automations/ping.py +++ b/apps/assets/models/automations/ping.py @@ -1,4 +1,4 @@ -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from assets.const import AutomationTypes from .base import AssetBaseAutomation diff --git a/apps/assets/models/base.py b/apps/assets/models/base.py index 8f5ed713f..c4866c22b 100644 --- a/apps/assets/models/base.py +++ b/apps/assets/models/base.py @@ -3,7 +3,7 @@ from django.db import models from django.utils import timezone -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from assets.const import Connectivity from common.utils import ( diff --git a/apps/assets/models/cmd_filter.py b/apps/assets/models/cmd_filter.py index dd0d7b0d1..ec6f1be3e 100644 --- a/apps/assets/models/cmd_filter.py +++ b/apps/assets/models/cmd_filter.py @@ -4,7 +4,7 @@ import uuid from django.core.validators import MinValueValidator, MaxValueValidator from django.db import models -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from common.utils import get_logger from orgs.mixins.models import OrgModelMixin diff --git a/apps/assets/models/domain.py b/apps/assets/models/domain.py index 6dd5e3c4f..587f41d7c 100644 --- a/apps/assets/models/domain.py +++ b/apps/assets/models/domain.py @@ -3,7 +3,7 @@ import random from django.db import models -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from common.utils import get_logger from orgs.mixins.models import JMSOrgBaseModel diff --git a/apps/assets/models/favorite_asset.py b/apps/assets/models/favorite_asset.py index 92d52fe7f..052551402 100644 --- a/apps/assets/models/favorite_asset.py +++ b/apps/assets/models/favorite_asset.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # from django.db import models -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from common.db.models import JMSBaseModel diff --git a/apps/assets/models/gateway.py b/apps/assets/models/gateway.py index 0fc6626df..c474da26d 100644 --- a/apps/assets/models/gateway.py +++ b/apps/assets/models/gateway.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from assets.const import GATEWAY_NAME from assets.models.platform import Platform diff --git a/apps/assets/models/group.py b/apps/assets/models/group.py index 02db7f41f..ad3545a1e 100644 --- a/apps/assets/models/group.py +++ b/apps/assets/models/group.py @@ -7,7 +7,7 @@ from __future__ import unicode_literals import uuid from django.db import models -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ __all__ = ['AssetGroup'] diff --git a/apps/assets/models/label.py b/apps/assets/models/label.py index 3aff63385..5dbd50361 100644 --- a/apps/assets/models/label.py +++ b/apps/assets/models/label.py @@ -2,7 +2,7 @@ # from django.db import models -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from common.utils import lazyproperty from orgs.mixins.models import JMSOrgBaseModel diff --git a/apps/assets/models/node.py b/apps/assets/models/node.py index 94ff9aba5..139295f69 100644 --- a/apps/assets/models/node.py +++ b/apps/assets/models/node.py @@ -10,8 +10,7 @@ from django.core.cache import cache from django.db import models, transaction from django.db.models import Q, Manager from django.db.transaction import atomic -from django.utils.translation import ugettext -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _, gettext from common.db.models import output_as_string from common.utils import get_logger @@ -163,7 +162,7 @@ class FamilyMixin: return key def get_next_child_preset_name(self): - name = ugettext("New node") + name = gettext("New node") values = [ child.value[child.value.rfind(' '):] for child in self.get_children() diff --git a/apps/assets/models/utils.py b/apps/assets/models/utils.py index a5e4da1da..ee3de1043 100644 --- a/apps/assets/models/utils.py +++ b/apps/assets/models/utils.py @@ -3,7 +3,7 @@ # from django.core.exceptions import ValidationError -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from common.utils import validate_ssh_private_key diff --git a/apps/assets/notifications.py b/apps/assets/notifications.py index 14e84768e..8f6577b8a 100644 --- a/apps/assets/notifications.py +++ b/apps/assets/notifications.py @@ -1,4 +1,4 @@ -from django.utils.translation import ugettext as _ +from django.utils.translation import gettext as _ from notifications.notifications import UserMessage @@ -22,4 +22,4 @@ class BulkUpdatePlatformSkipAssetUserMsg(UserMessage): from assets.models import Asset user = User.objects.first() assets = Asset.objects.all()[:10] - return cls(user, assets) \ No newline at end of file + return cls(user, assets) diff --git a/apps/assets/serializers/asset/common.py b/apps/assets/serializers/asset/common.py index 69ccf8e21..718efbb0d 100644 --- a/apps/assets/serializers/asset/common.py +++ b/apps/assets/serializers/asset/common.py @@ -3,7 +3,7 @@ from django.db.models import F from django.db.transaction import atomic -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from rest_framework import serializers from accounts.models import Account diff --git a/apps/assets/serializers/asset/database.py b/apps/assets/serializers/asset/database.py index 386cb87e9..17a122fd6 100644 --- a/apps/assets/serializers/asset/database.py +++ b/apps/assets/serializers/asset/database.py @@ -1,6 +1,6 @@ -from django.utils.translation import ugettext_lazy as _ -from rest_framework.serializers import ValidationError +from django.utils.translation import gettext_lazy as _ from rest_framework import serializers +from rest_framework.serializers import ValidationError from assets.models import Database from assets.serializers.gateway import GatewayWithAccountSecretSerializer diff --git a/apps/assets/serializers/automations/base.py b/apps/assets/serializers/automations/base.py index d930fd1dc..f720ed077 100644 --- a/apps/assets/serializers/automations/base.py +++ b/apps/assets/serializers/automations/base.py @@ -1,4 +1,4 @@ -from django.utils.translation import ugettext as _ +from django.utils.translation import gettext as _ from rest_framework import serializers from assets.models import Asset, Node, BaseAutomation, AutomationExecution diff --git a/apps/assets/serializers/domain.py b/apps/assets/serializers/domain.py index 74eb1117a..a22d1a9ad 100644 --- a/apps/assets/serializers/domain.py +++ b/apps/assets/serializers/domain.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from rest_framework import serializers from common.serializers.fields import ObjectRelatedField diff --git a/apps/assets/serializers/gateway.py b/apps/assets/serializers/gateway.py index 259bc13f8..e596ef5a3 100644 --- a/apps/assets/serializers/gateway.py +++ b/apps/assets/serializers/gateway.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from rest_framework import serializers from .asset.common import AccountSecretSerializer diff --git a/apps/assets/serializers/label.py b/apps/assets/serializers/label.py index 48bc0885f..3d913aeea 100644 --- a/apps/assets/serializers/label.py +++ b/apps/assets/serializers/label.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # from django.db.models import Count -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from rest_framework import serializers from orgs.mixins.serializers import BulkOrgResourceModelSerializer diff --git a/apps/assets/serializers/node.py b/apps/assets/serializers/node.py index fb4c12d67..ac161318b 100644 --- a/apps/assets/serializers/node.py +++ b/apps/assets/serializers/node.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- +from django.utils.translation import gettext as _ from rest_framework import serializers -from django.utils.translation import ugettext as _ from orgs.mixins.serializers import BulkOrgResourceModelSerializer from ..models import Asset, Node diff --git a/apps/assets/tasks/ping_gateway.py b/apps/assets/tasks/ping_gateway.py index 789a81c87..05ab7fb0c 100644 --- a/apps/assets/tasks/ping_gateway.py +++ b/apps/assets/tasks/ping_gateway.py @@ -1,6 +1,6 @@ # ~*~ coding: utf-8 ~*~ from celery import shared_task -from django.utils.translation import gettext_noop, ugettext_lazy as _ +from django.utils.translation import gettext_noop, gettext_lazy as _ from assets.const import AutomationTypes from common.utils import get_logger diff --git a/apps/assets/tasks/utils.py b/apps/assets/tasks/utils.py index a60f1b494..d65351eaa 100644 --- a/apps/assets/tasks/utils.py +++ b/apps/assets/tasks/utils.py @@ -1,10 +1,9 @@ # -*- coding: utf-8 -*- # -from django.utils.translation import ugettext as _ +from django.utils.translation import gettext as _ from common.utils import get_logger - logger = get_logger(__file__) __all__ = [ 'check_asset_can_run_ansible', 'clean_ansible_task_hosts', diff --git a/apps/audits/apps.py b/apps/audits/apps.py index 6e198176b..40de7ddaa 100644 --- a/apps/audits/apps.py +++ b/apps/audits/apps.py @@ -1,7 +1,7 @@ from django.apps import AppConfig from django.conf import settings -from django.utils.translation import ugettext_lazy as _ from django.db.models.signals import post_save +from django.utils.translation import gettext_lazy as _ class AuditsConfig(AppConfig): @@ -10,7 +10,6 @@ class AuditsConfig(AppConfig): def ready(self): from . import signal_handlers - from . import tasks if settings.SYSLOG_ENABLE: post_save.connect(signal_handlers.on_audits_log_create) diff --git a/apps/audits/backends/db.py b/apps/audits/backends/db.py index 0c0f46a4a..ac589931d 100644 --- a/apps/audits/backends/db.py +++ b/apps/audits/backends/db.py @@ -1,5 +1,5 @@ # ~*~ coding: utf-8 ~*~ -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from audits.models import OperateLog diff --git a/apps/audits/const.py b/apps/audits/const.py index ae8679f01..a2832ef9d 100644 --- a/apps/audits/const.py +++ b/apps/audits/const.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # -from django.utils.translation import ugettext_lazy as _ from django.db.models import TextChoices, IntegerChoices +from django.utils.translation import gettext_lazy as _ DEFAULT_CITY = _("Unknown") diff --git a/apps/audits/handler.py b/apps/audits/handler.py index 6ac055778..7d9e331cb 100644 --- a/apps/audits/handler.py +++ b/apps/audits/handler.py @@ -3,7 +3,7 @@ from datetime import datetime from django.core.cache import cache from django.db import transaction -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from common.local import encrypted_field_set from common.utils import get_request_ip, get_logger diff --git a/apps/audits/models.py b/apps/audits/models.py index a0de58d05..42e712dbd 100644 --- a/apps/audits/models.py +++ b/apps/audits/models.py @@ -1,11 +1,11 @@ import os import uuid +from django.conf import settings from django.db import models from django.db.models import Q -from django.conf import settings from django.utils import timezone -from django.utils.translation import gettext, ugettext_lazy as _ +from django.utils.translation import gettext, gettext_lazy as _ from common.db.encoder import ModelJSONFieldEncoder from common.utils import lazyproperty diff --git a/apps/audits/serializers.py b/apps/audits/serializers.py index 7b7573232..a90651bc9 100644 --- a/apps/audits/serializers.py +++ b/apps/audits/serializers.py @@ -1,13 +1,14 @@ # -*- coding: utf-8 -*- # -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from rest_framework import serializers -from orgs.mixins.serializers import BulkOrgResourceModelSerializer + from audits.backends.db import OperateLogStore from common.serializers.fields import LabeledChoiceField from common.utils import reverse, i18n_trans from common.utils.timezone import as_current_tz from ops.serializers.job import JobExecutionSerializer +from orgs.mixins.serializers import BulkOrgResourceModelSerializer from terminal.models import Session from . import models from .const import ( diff --git a/apps/audits/signal_handlers/login_log.py b/apps/audits/signal_handlers/login_log.py index a73482b20..f74d55e8e 100644 --- a/apps/audits/signal_handlers/login_log.py +++ b/apps/audits/signal_handlers/login_log.py @@ -5,7 +5,7 @@ from django.contrib.auth import BACKEND_SESSION_KEY from django.dispatch import receiver from django.utils import timezone, translation from django.utils.functional import LazyObject -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from rest_framework.request import Request from authentication.signals import post_auth_failed, post_auth_success diff --git a/apps/authentication/api/confirm.py b/apps/authentication/api/confirm.py index d3a32a7c8..0923875a0 100644 --- a/apps/authentication/api/confirm.py +++ b/apps/authentication/api/confirm.py @@ -2,10 +2,10 @@ # import time -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ +from rest_framework import status from rest_framework.generics import RetrieveAPIView, CreateAPIView from rest_framework.response import Response -from rest_framework import status from common.permissions import IsValidUser, UserConfirmation from ..const import ConfirmType diff --git a/apps/authentication/api/connection_token.py b/apps/authentication/api/connection_token.py index a98855f85..5ad3f81db 100644 --- a/apps/authentication/api/connection_token.py +++ b/apps/authentication/api/connection_token.py @@ -7,7 +7,7 @@ from django.conf import settings from django.http import HttpResponse from django.shortcuts import get_object_or_404 from django.utils import timezone -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from rest_framework import status, serializers from rest_framework.decorators import action from rest_framework.exceptions import PermissionDenied, ValidationError diff --git a/apps/authentication/api/mfa.py b/apps/authentication/api/mfa.py index fe81149e3..3436c2eeb 100644 --- a/apps/authentication/api/mfa.py +++ b/apps/authentication/api/mfa.py @@ -1,20 +1,18 @@ # -*- coding: utf-8 -*- # -import time -from django.utils.translation import ugettext as _ -from django.conf import settings from django.shortcuts import get_object_or_404 -from rest_framework.permissions import AllowAny +from django.utils.translation import gettext as _ from rest_framework.generics import CreateAPIView -from rest_framework.serializers import ValidationError +from rest_framework.permissions import AllowAny from rest_framework.response import Response +from rest_framework.serializers import ValidationError -from common.utils import get_logger from common.exceptions import UnexpectError +from common.utils import get_logger from users.models.user import User -from .. import serializers from .. import errors +from .. import serializers from ..mixins import AuthMixin logger = get_logger(__name__) diff --git a/apps/authentication/api/password.py b/apps/authentication/api/password.py index 53f47c03c..f1b245a46 100644 --- a/apps/authentication/api/password.py +++ b/apps/authentication/api/password.py @@ -1,24 +1,24 @@ -from django.http import HttpResponseRedirect -from rest_framework.generics import CreateAPIView -from rest_framework.response import Response -from rest_framework.permissions import AllowAny -from django.utils.translation import ugettext as _ -from django.template.loader import render_to_string from django.core.cache import cache +from django.http import HttpResponseRedirect from django.shortcuts import reverse +from django.template.loader import render_to_string +from django.utils.translation import gettext as _ +from rest_framework.generics import CreateAPIView +from rest_framework.permissions import AllowAny +from rest_framework.response import Response -from common.utils.verify_code import SendAndVerifyCodeUtil -from common.permissions import IsValidUser -from common.utils.random import random_string -from common.utils import get_object_or_none +from authentication.errors import PasswordInvalid +from authentication.mixins import AuthMixin +from authentication.mixins import authenticate from authentication.serializers import ( PasswordVerifySerializer, ResetPasswordCodeSerializer ) +from common.permissions import IsValidUser +from common.utils import get_object_or_none +from common.utils.random import random_string +from common.utils.verify_code import SendAndVerifyCodeUtil from settings.utils import get_login_title from users.models import User -from authentication.mixins import authenticate -from authentication.errors import PasswordInvalid -from authentication.mixins import AuthMixin class UserResetPasswordSendCodeApi(CreateAPIView): diff --git a/apps/authentication/apps.py b/apps/authentication/apps.py index 615bb255e..4ee3ffce0 100644 --- a/apps/authentication/apps.py +++ b/apps/authentication/apps.py @@ -1,5 +1,5 @@ from django.apps import AppConfig -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ class AuthenticationConfig(AppConfig): @@ -7,9 +7,4 @@ class AuthenticationConfig(AppConfig): verbose_name = _('Authentication') def ready(self): - from . import signal_handlers - from . import notifications - from . import tasks - super().ready() - diff --git a/apps/authentication/backends/custom.py b/apps/authentication/backends/custom.py index d05e097d5..3f2b05940 100644 --- a/apps/authentication/backends/custom.py +++ b/apps/authentication/backends/custom.py @@ -1,10 +1,10 @@ from django.conf import settings -from django.utils.module_loading import import_string -from django.utils.translation import ugettext_lazy as _ -from common.utils import get_logger from django.contrib.auth import get_user_model -from authentication.signals import user_auth_failed, user_auth_success +from django.utils.module_loading import import_string +from django.utils.translation import gettext_lazy as _ +from authentication.signals import user_auth_failed, user_auth_success +from common.utils import get_logger from .base import JMSModelBackend logger = get_logger(__file__) diff --git a/apps/authentication/backends/drf.py b/apps/authentication/backends/drf.py index 10c191b1b..8d7d60e99 100644 --- a/apps/authentication/backends/drf.py +++ b/apps/authentication/backends/drf.py @@ -1,22 +1,20 @@ # -*- coding: utf-8 -*- # -import uuid import time +import uuid -from django.core.cache import cache -from django.utils.translation import ugettext as _ -from six import text_type from django.contrib.auth import get_user_model - +from django.core.cache import cache +from django.utils.translation import gettext as _ from rest_framework import HTTP_HEADER_ENCODING from rest_framework import authentication, exceptions +from six import text_type + from common.auth import signature - from common.utils import get_object_or_none, make_signature, http_to_unixtime +from .base import JMSBaseAuthBackend from ..models import AccessKey, PrivateToken -from .base import JMSBaseAuthBackend, JMSModelBackend - UserModel = get_user_model() @@ -200,4 +198,3 @@ class SignatureAuthentication(signature.SignatureAuthentication): return user, secret except (AccessKey.DoesNotExist, exceptions.ValidationError): return None, None - diff --git a/apps/authentication/backends/oauth2/signals.py b/apps/authentication/backends/oauth2/signals.py index b82ae90d7..4f192a9ad 100644 --- a/apps/authentication/backends/oauth2/signals.py +++ b/apps/authentication/backends/oauth2/signals.py @@ -1,7 +1,3 @@ from django.dispatch import Signal - -oauth2_create_or_update_user = Signal( - providing_args=['request', 'user', 'created', 'name', 'username', 'email'] -) - +oauth2_create_or_update_user = Signal() diff --git a/apps/authentication/backends/oidc/signals.py b/apps/authentication/backends/oidc/signals.py index 2f4c071e4..5346dba03 100644 --- a/apps/authentication/backends/oidc/signals.py +++ b/apps/authentication/backends/oidc/signals.py @@ -9,8 +9,4 @@ from django.dispatch import Signal - -openid_create_or_update_user = Signal( - providing_args=['request', 'user', 'created', 'name', 'username', 'email'] -) - +openid_create_or_update_user = Signal() diff --git a/apps/authentication/backends/oidc/views.py b/apps/authentication/backends/oidc/views.py index 88088245d..c638aeef6 100644 --- a/apps/authentication/backends/oidc/views.py +++ b/apps/authentication/backends/oidc/views.py @@ -11,8 +11,8 @@ import base64 import hashlib -import time import secrets +import time from django.conf import settings from django.contrib import auth @@ -20,13 +20,12 @@ from django.core.exceptions import SuspiciousOperation from django.http import HttpResponseRedirect, QueryDict from django.urls import reverse from django.utils.crypto import get_random_string -from django.utils.http import is_safe_url, urlencode +from django.utils.http import url_has_allowed_host_and_scheme, urlencode from django.views.generic import View from authentication.utils import build_absolute_uri_for_oidc from .utils import get_logger - logger = get_logger(__file__) @@ -102,7 +101,7 @@ class OIDCAuthRequestView(View): logger.debug(log_prompt.format('Stores next url in the session')) next_url = request.GET.get('next') request.session['oidc_auth_next_url'] = next_url \ - if is_safe_url(url=next_url, allowed_hosts=(request.get_host(), )) else None + if url_has_allowed_host_and_scheme(url=next_url, allowed_hosts=(request.get_host(),)) else None # Redirects the user to authorization endpoint. logger.debug(log_prompt.format('Construct redirect url')) @@ -145,15 +144,15 @@ class OIDCAuthCallbackView(View): # missing or if no state can be retrieved from the current session. if ( - ((nonce and settings.AUTH_OPENID_USE_NONCE) or not settings.AUTH_OPENID_USE_NONCE) - and - ( - (state and settings.AUTH_OPENID_USE_STATE and 'state' in callback_params) - or - (not settings.AUTH_OPENID_USE_STATE) - ) - and - ('code' in callback_params) + ((nonce and settings.AUTH_OPENID_USE_NONCE) or not settings.AUTH_OPENID_USE_NONCE) + and + ( + (state and settings.AUTH_OPENID_USE_STATE and 'state' in callback_params) + or + (not settings.AUTH_OPENID_USE_STATE) + ) + and + ('code' in callback_params) ): # Ensures that the passed state values is the same as the one that was previously # generated when forging the authorization request. This is necessary to mitigate diff --git a/apps/authentication/backends/saml2/signals.py b/apps/authentication/backends/saml2/signals.py index 3dcdd9d35..72feddbbe 100644 --- a/apps/authentication/backends/saml2/signals.py +++ b/apps/authentication/backends/saml2/signals.py @@ -1,4 +1,3 @@ from django.dispatch import Signal - -saml2_create_or_update_user = Signal(providing_args=('user', 'created', 'request', 'attrs')) +saml2_create_or_update_user = Signal() diff --git a/apps/authentication/confirm/password.py b/apps/authentication/confirm/password.py index 944ab8f24..dc49576a3 100644 --- a/apps/authentication/confirm/password.py +++ b/apps/authentication/confirm/password.py @@ -1,4 +1,4 @@ -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from authentication.mixins import authenticate from .base import BaseConfirm diff --git a/apps/authentication/confirm/relogin.py b/apps/authentication/confirm/relogin.py index 447a17ab0..2b27ef5fe 100644 --- a/apps/authentication/confirm/relogin.py +++ b/apps/authentication/confirm/relogin.py @@ -1,7 +1,7 @@ from datetime import datetime from django.utils import timezone -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from .base import BaseConfirm diff --git a/apps/authentication/errors/failed.py b/apps/authentication/errors/failed.py index 3e0848524..f6d8004c6 100644 --- a/apps/authentication/errors/failed.py +++ b/apps/authentication/errors/failed.py @@ -1,11 +1,11 @@ # -*- coding: utf-8 -*- # -from django.utils.translation import ugettext_lazy as _ from django.conf import settings +from django.utils.translation import gettext_lazy as _ from users.utils import LoginBlockUtil, MFABlockUtils, LoginIpBlockUtil -from ..signals import post_auth_failed from . import const +from ..signals import post_auth_failed class AuthFailedNeedLogMixin: diff --git a/apps/authentication/errors/mfa.py b/apps/authentication/errors/mfa.py index 288c2060e..40b97df92 100644 --- a/apps/authentication/errors/mfa.py +++ b/apps/authentication/errors/mfa.py @@ -1,4 +1,4 @@ -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from common.exceptions import JMSException diff --git a/apps/authentication/errors/redirect.py b/apps/authentication/errors/redirect.py index 466ec708d..5e7c5412d 100644 --- a/apps/authentication/errors/redirect.py +++ b/apps/authentication/errors/redirect.py @@ -1,5 +1,5 @@ -from django.utils.translation import ugettext_lazy as _ from django.urls import reverse +from django.utils.translation import gettext_lazy as _ from common.exceptions import JMSException from . import const diff --git a/apps/authentication/forms.py b/apps/authentication/forms.py index 747b821ea..90429bc82 100644 --- a/apps/authentication/forms.py +++ b/apps/authentication/forms.py @@ -1,9 +1,9 @@ # -*- coding: utf-8 -*- # +from captcha.fields import CaptchaField, CaptchaTextInput from django import forms from django.conf import settings -from django.utils.translation import ugettext_lazy as _ -from captcha.fields import CaptchaField, CaptchaTextInput +from django.utils.translation import gettext_lazy as _ from common.utils import get_logger, decrypt_password diff --git a/apps/authentication/mfa/base.py b/apps/authentication/mfa/base.py index 2158b8fe1..8bcaaf3a0 100644 --- a/apps/authentication/mfa/base.py +++ b/apps/authentication/mfa/base.py @@ -1,6 +1,6 @@ import abc -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ class BaseMFA(abc.ABC): @@ -69,4 +69,3 @@ class BaseMFA(abc.ABC): @staticmethod def help_text_of_disable(): return '' - diff --git a/apps/authentication/mfa/custom.py b/apps/authentication/mfa/custom.py index 3b671f709..0819dcfaa 100644 --- a/apps/authentication/mfa/custom.py +++ b/apps/authentication/mfa/custom.py @@ -1,6 +1,6 @@ from django.conf import settings from django.utils.module_loading import import_string -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from common.utils import get_logger from .base import BaseMFA diff --git a/apps/authentication/mfa/radius.py b/apps/authentication/mfa/radius.py index 9f1250234..2055e9776 100644 --- a/apps/authentication/mfa/radius.py +++ b/apps/authentication/mfa/radius.py @@ -1,5 +1,5 @@ -from django.utils.translation import ugettext_lazy as _ from django.conf import settings +from django.utils.translation import gettext_lazy as _ from .base import BaseMFA from ..backends.radius import RadiusBackend diff --git a/apps/authentication/mfa/sms.py b/apps/authentication/mfa/sms.py index aa426bf57..d114b648e 100644 --- a/apps/authentication/mfa/sms.py +++ b/apps/authentication/mfa/sms.py @@ -1,8 +1,8 @@ -from django.utils.translation import ugettext_lazy as _ from django.conf import settings +from django.utils.translation import gettext_lazy as _ -from .base import BaseMFA from common.utils.verify_code import SendAndVerifyCodeUtil +from .base import BaseMFA sms_failed_msg = _("SMS verify code invalid") diff --git a/apps/authentication/middleware.py b/apps/authentication/middleware.py index 43f7bdc14..b4ee86ed4 100644 --- a/apps/authentication/middleware.py +++ b/apps/authentication/middleware.py @@ -5,7 +5,7 @@ from django.contrib.auth import logout as auth_logout from django.http import HttpResponse from django.shortcuts import redirect, reverse, render from django.utils.deprecation import MiddlewareMixin -from django.utils.translation import ugettext as _ +from django.utils.translation import gettext as _ from apps.authentication import mixins from authentication.signals import post_auth_failed diff --git a/apps/authentication/mixins.py b/apps/authentication/mixins.py index e859fe4de..518e4aeb4 100644 --- a/apps/authentication/mixins.py +++ b/apps/authentication/mixins.py @@ -15,7 +15,7 @@ from django.core.cache import cache from django.core.exceptions import ImproperlyConfigured from django.shortcuts import reverse, redirect, get_object_or_404 from django.utils.http import urlencode -from django.utils.translation import ugettext as _ +from django.utils.translation import gettext as _ from rest_framework.request import Request from acls.models import LoginACL diff --git a/apps/authentication/models/access_key.py b/apps/authentication/models/access_key.py index d0e6fb0ef..77fa67c74 100644 --- a/apps/authentication/models/access_key.py +++ b/apps/authentication/models/access_key.py @@ -2,7 +2,7 @@ import uuid from django.conf import settings from django.db import models -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ import common.db.models diff --git a/apps/authentication/models/connection_token.py b/apps/authentication/models/connection_token.py index ce5b4829f..7bc8afcc7 100644 --- a/apps/authentication/models/connection_token.py +++ b/apps/authentication/models/connection_token.py @@ -6,7 +6,7 @@ from django.conf import settings from django.core.cache import cache from django.db import models from django.utils import timezone -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from rest_framework.exceptions import PermissionDenied from accounts.const import AliasAccount diff --git a/apps/authentication/models/private_token.py b/apps/authentication/models/private_token.py index 8d83d1e0a..bb5f1da87 100644 --- a/apps/authentication/models/private_token.py +++ b/apps/authentication/models/private_token.py @@ -1,4 +1,4 @@ -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from rest_framework.authtoken.models import Token diff --git a/apps/authentication/models/sso_token.py b/apps/authentication/models/sso_token.py index c8ec1e9eb..61002a1a8 100644 --- a/apps/authentication/models/sso_token.py +++ b/apps/authentication/models/sso_token.py @@ -1,7 +1,7 @@ import uuid from django.db import models -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from common.db.models import BaseCreateUpdateModel, CASCADE_SIGNAL_SKIP diff --git a/apps/authentication/models/temp_token.py b/apps/authentication/models/temp_token.py index d76a30a42..33d86cbc1 100644 --- a/apps/authentication/models/temp_token.py +++ b/apps/authentication/models/temp_token.py @@ -1,7 +1,7 @@ -from django.utils import timezone -from django.utils.translation import ugettext_lazy as _ - from django.db import models +from django.utils import timezone +from django.utils.translation import gettext_lazy as _ + from common.db.models import JMSBaseModel diff --git a/apps/authentication/notifications.py b/apps/authentication/notifications.py index 364ac20dd..e52f29a94 100644 --- a/apps/authentication/notifications.py +++ b/apps/authentication/notifications.py @@ -1,9 +1,9 @@ -from django.utils.translation import ugettext as _ from django.template.loader import render_to_string +from django.utils.translation import gettext as _ -from notifications.notifications import UserMessage from common.utils import get_logger from common.utils.timezone import local_now_display +from notifications.notifications import UserMessage logger = get_logger(__file__) diff --git a/apps/authentication/serializers/connect_token_secret.py b/apps/authentication/serializers/connect_token_secret.py index a3d56b90c..33fbe842e 100644 --- a/apps/authentication/serializers/connect_token_secret.py +++ b/apps/authentication/serializers/connect_token_secret.py @@ -1,4 +1,4 @@ -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from rest_framework import serializers from accounts.const import SecretType diff --git a/apps/authentication/serializers/connection_token.py b/apps/authentication/serializers/connection_token.py index bc3d051e1..4579e73ee 100644 --- a/apps/authentication/serializers/connection_token.py +++ b/apps/authentication/serializers/connection_token.py @@ -1,4 +1,4 @@ -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from rest_framework import serializers from common.serializers import CommonModelSerializer diff --git a/apps/authentication/serializers/password_mfa.py b/apps/authentication/serializers/password_mfa.py index d83260748..3e733b6ec 100644 --- a/apps/authentication/serializers/password_mfa.py +++ b/apps/authentication/serializers/password_mfa.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from rest_framework import serializers from common.serializers.fields import EncryptedField diff --git a/apps/authentication/signals.py b/apps/authentication/signals.py index 556bba614..7c8b8e229 100644 --- a/apps/authentication/signals.py +++ b/apps/authentication/signals.py @@ -1,9 +1,7 @@ from django.dispatch import Signal +post_auth_success = Signal() +post_auth_failed = Signal() -post_auth_success = Signal(providing_args=('user', 'request')) -post_auth_failed = Signal(providing_args=('username', 'request', 'reason')) - - -user_auth_success = Signal(providing_args=('user', 'request', 'backend', 'create')) -user_auth_failed = Signal(providing_args=('username', 'request', 'reason', 'backend')) +user_auth_success = Signal() +user_auth_failed = Signal() diff --git a/apps/authentication/utils.py b/apps/authentication/utils.py index a0db9061c..b53afa423 100644 --- a/apps/authentication/utils.py +++ b/apps/authentication/utils.py @@ -4,12 +4,12 @@ import ipaddress from urllib.parse import urljoin, urlparse from django.conf import settings -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ -from common.utils import validate_ip, get_ip_city, get_request_ip -from common.utils import get_logger -from audits.models import UserLoginLog from audits.const import DEFAULT_CITY +from audits.models import UserLoginLog +from common.utils import get_logger +from common.utils import validate_ip, get_ip_city, get_request_ip from .notifications import DifferentCityLoginMessage logger = get_logger(__file__) diff --git a/apps/authentication/views/base.py b/apps/authentication/views/base.py index e98e41e70..7969502c0 100644 --- a/apps/authentication/views/base.py +++ b/apps/authentication/views/base.py @@ -1,26 +1,23 @@ from functools import lru_cache -from rest_framework.request import Request -from django.utils.translation import ugettext_lazy as _ -from django.utils.module_loading import import_string from django.conf import settings from django.db.utils import IntegrityError +from django.utils.module_loading import import_string +from django.utils.translation import gettext_lazy as _ from django.views import View +from rest_framework.request import Request from authentication import errors from authentication.mixins import AuthMixin -from users.models import User -from common.utils.django import reverse, get_object_or_none from common.utils import get_logger - +from common.utils.django import reverse, get_object_or_none +from users.models import User from .mixins import FlashMessageMixin - logger = get_logger(__file__) class BaseLoginCallbackView(AuthMixin, FlashMessageMixin, View): - client_type_path = '' client_auth_params = {} user_type = '' diff --git a/apps/authentication/views/dingtalk.py b/apps/authentication/views/dingtalk.py index 77cec63fd..819f1d055 100644 --- a/apps/authentication/views/dingtalk.py +++ b/apps/authentication/views/dingtalk.py @@ -4,7 +4,7 @@ from django.conf import settings from django.db.utils import IntegrityError from django.http.request import HttpRequest from django.http.response import HttpResponseRedirect -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from django.views import View from rest_framework.exceptions import APIException from rest_framework.permissions import AllowAny, IsAuthenticated @@ -13,16 +13,15 @@ from authentication import errors from authentication.const import ConfirmType from authentication.mixins import AuthMixin from authentication.notifications import OAuthBindMessage -from common.views.mixins import PermissionsMixin, UserConfirmRequiredExceptionMixin from common.permissions import UserConfirmation from common.sdk.im.dingtalk import URL, DingTalk from common.utils import get_logger from common.utils.common import get_request_ip from common.utils.django import get_object_or_none, reverse from common.utils.random import random_string +from common.views.mixins import PermissionsMixin, UserConfirmRequiredExceptionMixin from users.models import User from users.views import UserVerifyPasswordView - from .base import BaseLoginCallbackView from .mixins import METAMixin, FlashMessageMixin diff --git a/apps/authentication/views/feishu.py b/apps/authentication/views/feishu.py index 62660764a..0f62ef75d 100644 --- a/apps/authentication/views/feishu.py +++ b/apps/authentication/views/feishu.py @@ -4,22 +4,21 @@ from django.conf import settings from django.db.utils import IntegrityError from django.http.request import HttpRequest from django.http.response import HttpResponseRedirect -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from django.views import View from rest_framework.exceptions import APIException from rest_framework.permissions import AllowAny, IsAuthenticated from authentication.const import ConfirmType from authentication.notifications import OAuthBindMessage -from common.views.mixins import PermissionsMixin, UserConfirmRequiredExceptionMixin from common.permissions import UserConfirmation from common.sdk.im.feishu import URL, FeiShu from common.utils import get_logger from common.utils.common import get_request_ip from common.utils.django import reverse from common.utils.random import random_string +from common.views.mixins import PermissionsMixin, UserConfirmRequiredExceptionMixin from users.views import UserVerifyPasswordView - from .base import BaseLoginCallbackView from .mixins import FlashMessageMixin @@ -166,4 +165,3 @@ class FeiShuQRLoginCallbackView(FeiShuQRMixin, BaseLoginCallbackView): msg_client_err = _('FeiShu Error') msg_user_not_bound_err = _('FeiShu is not bound') msg_not_found_user_from_client_err = _('Failed to get user from FeiShu') - diff --git a/apps/authentication/views/login.py b/apps/authentication/views/login.py index 8b5696dc9..459abb3cf 100644 --- a/apps/authentication/views/login.py +++ b/apps/authentication/views/login.py @@ -16,7 +16,7 @@ from django.shortcuts import reverse, redirect from django.templatetags.static import static from django.urls import reverse_lazy from django.utils.decorators import method_decorator -from django.utils.translation import ugettext as _, get_language +from django.utils.translation import gettext as _, get_language from django.views.decorators.cache import never_cache from django.views.decorators.csrf import csrf_protect from django.views.decorators.debug import sensitive_post_parameters diff --git a/apps/authentication/views/wecom.py b/apps/authentication/views/wecom.py index e127dbeee..238d0b3e6 100644 --- a/apps/authentication/views/wecom.py +++ b/apps/authentication/views/wecom.py @@ -1,28 +1,28 @@ -from django.http.response import HttpResponseRedirect -from django.utils.translation import ugettext_lazy as _ from urllib.parse import urlencode -from django.views import View -from django.conf import settings -from django.http.request import HttpRequest -from django.db.utils import IntegrityError -from rest_framework.permissions import IsAuthenticated, AllowAny -from rest_framework.exceptions import APIException -from users.models import User -from users.views import UserVerifyPasswordView -from common.utils import get_logger -from common.utils.random import random_string -from common.utils.django import reverse, get_object_or_none +from django.conf import settings +from django.db.utils import IntegrityError +from django.http.request import HttpRequest +from django.http.response import HttpResponseRedirect +from django.utils.translation import gettext_lazy as _ +from django.views import View +from rest_framework.exceptions import APIException +from rest_framework.permissions import IsAuthenticated, AllowAny + +from authentication import errors +from authentication.const import ConfirmType +from authentication.mixins import AuthMixin +from authentication.notifications import OAuthBindMessage +from common.permissions import UserConfirmation from common.sdk.im.wecom import URL from common.sdk.im.wecom import WeCom -from common.views.mixins import UserConfirmRequiredExceptionMixin, PermissionsMixin +from common.utils import get_logger from common.utils.common import get_request_ip -from common.permissions import UserConfirmation -from authentication import errors -from authentication.mixins import AuthMixin -from authentication.const import ConfirmType -from authentication.notifications import OAuthBindMessage - +from common.utils.django import reverse, get_object_or_none +from common.utils.random import random_string +from common.views.mixins import UserConfirmRequiredExceptionMixin, PermissionsMixin +from users.models import User +from users.views import UserVerifyPasswordView from .base import BaseLoginCallbackView from .mixins import METAMixin, FlashMessageMixin diff --git a/apps/common/api/action.py b/apps/common/api/action.py index 8d7829d9e..738ad3db4 100644 --- a/apps/common/api/action.py +++ b/apps/common/api/action.py @@ -2,7 +2,7 @@ # from typing import Callable -from django.utils.translation import ugettext as _ +from django.utils.translation import gettext as _ from rest_framework.decorators import action from rest_framework.request import Request from rest_framework.response import Response diff --git a/apps/common/const/choices.py b/apps/common/const/choices.py index 9b6c817f3..6db9254b3 100644 --- a/apps/common/const/choices.py +++ b/apps/common/const/choices.py @@ -1,5 +1,5 @@ from django.db import models -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ ADMIN = 'Admin' USER = 'User' diff --git a/apps/common/const/common.py b/apps/common/const/common.py index 33a889ecb..ab149fef5 100644 --- a/apps/common/const/common.py +++ b/apps/common/const/common.py @@ -1,6 +1,6 @@ import re -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ create_success_msg = _("%(name)s was created successfully") update_success_msg = _("%(name)s was updated successfully") diff --git a/apps/common/db/encoder.py b/apps/common/db/encoder.py index d773491a1..2bc9332f3 100644 --- a/apps/common/db/encoder.py +++ b/apps/common/db/encoder.py @@ -6,9 +6,9 @@ from datetime import datetime from django.conf import settings from django.db import models from django.utils import timezone as dj_timezone -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ -lazy_type = type(_('ugettext_lazy')) +lazy_type = type(_('gettext_lazy')) class ModelJSONFieldEncoder(json.JSONEncoder): diff --git a/apps/common/db/fields.py b/apps/common/db/fields.py index dee051da5..f9f2d9f43 100644 --- a/apps/common/db/fields.py +++ b/apps/common/db/fields.py @@ -11,8 +11,8 @@ from django.core.exceptions import ValidationError from django.core.validators import MinValueValidator, MaxValueValidator from django.db import models from django.db.models import Q, Manager, QuerySet -from django.utils.encoding import force_text -from django.utils.translation import ugettext_lazy as _ +from django.utils.encoding import force_str +from django.utils.translation import gettext_lazy as _ from rest_framework.utils.encoders import JSONEncoder from common.local import add_encrypted_field_set @@ -146,7 +146,7 @@ class EncryptMixin: if value is None: return value - value = force_text(value) + value = force_str(value) plain_value = crypto.decrypt(value) # 如果没有解开,使用原来的signer解密 @@ -167,7 +167,7 @@ class EncryptMixin: sp = super() if hasattr(sp, "get_prep_value"): value = sp.get_prep_value(value) - value = force_text(value) + value = force_str(value) # 替换新的加密方式 return crypto.encrypt(value) diff --git a/apps/common/db/mixins.py b/apps/common/db/mixins.py index 43c5f8a65..0d4e1c9bc 100644 --- a/apps/common/db/mixins.py +++ b/apps/common/db/mixins.py @@ -3,7 +3,7 @@ from django.db import models from django.utils import timezone -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ __all__ = [ "NoDeleteManager", "NoDeleteModelMixin", "NoDeleteQuerySet", diff --git a/apps/common/db/models.py b/apps/common/db/models.py index d01a37266..a3d51bcb7 100644 --- a/apps/common/db/models.py +++ b/apps/common/db/models.py @@ -15,7 +15,7 @@ from django.db import models from django.db import transaction from django.db.models import F, ExpressionWrapper, CASCADE from django.db.models import QuerySet -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from ..const.signals import SKIP_SIGNAL diff --git a/apps/common/drf/metadata.py b/apps/common/drf/metadata.py index 731daf878..9caa84c28 100644 --- a/apps/common/drf/metadata.py +++ b/apps/common/drf/metadata.py @@ -7,8 +7,8 @@ from collections import OrderedDict from django.core.exceptions import PermissionDenied from django.http import Http404 -from django.utils.encoding import force_text -from django.utils.translation import ugettext_lazy as _ +from django.utils.encoding import force_str +from django.utils.translation import gettext_lazy as _ from rest_framework import exceptions, serializers from rest_framework.fields import empty from rest_framework.metadata import SimpleMetadata @@ -81,7 +81,7 @@ class SimpleMetadataWithFilters(SimpleMetadata): field_info["choices"] = [ { "value": choice_value, - "label": force_text(choice_label, strings_only=True), + "label": force_str(choice_label, strings_only=True), } for choice_value, choice_label in dict(field.choices).items() ] @@ -109,7 +109,7 @@ class SimpleMetadataWithFilters(SimpleMetadata): for attr in self.attrs: value = getattr(field, attr, None) if value is not None and value != "": - field_info[attr] = force_text(value, strings_only=True) + field_info[attr] = force_str(value, strings_only=True) if getattr(field, "child", None): field_info["child"] = self.get_field_info(field.child) diff --git a/apps/common/drf/parsers/base.py b/apps/common/drf/parsers/base.py index 43d736f21..6d4b70788 100644 --- a/apps/common/drf/parsers/base.py +++ b/apps/common/drf/parsers/base.py @@ -3,7 +3,7 @@ import codecs import json import re -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from rest_framework import serializers from rest_framework import status from rest_framework.exceptions import ParseError, APIException diff --git a/apps/common/drf/renders/base.py b/apps/common/drf/renders/base.py index a9b3b5c8a..cdc1626ff 100644 --- a/apps/common/drf/renders/base.py +++ b/apps/common/drf/renders/base.py @@ -4,7 +4,7 @@ import re from datetime import datetime import pyzipper -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from rest_framework import serializers from rest_framework.renderers import BaseRenderer from rest_framework.utils import encoders, json diff --git a/apps/common/sdk/im/wecom/__init__.py b/apps/common/sdk/im/wecom/__init__.py index b58e4ab3b..8262cbeb5 100644 --- a/apps/common/sdk/im/wecom/__init__.py +++ b/apps/common/sdk/im/wecom/__init__.py @@ -1,12 +1,12 @@ from typing import Iterable, AnyStr -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from rest_framework.exceptions import APIException -from users.utils import construct_user_email -from common.utils.common import get_logger -from common.sdk.im.utils import digest, update_values from common.sdk.im.mixin import RequestMixin, BaseRequest +from common.sdk.im.utils import digest, update_values +from common.utils.common import get_logger +from users.utils import construct_user_email logger = get_logger(__name__) @@ -112,13 +112,13 @@ class WeCom(RequestMixin): update_values(extra_params, kwargs) body = { - "touser": '|'.join(users), - "msgtype": "text", - "agentid": self._agentid, - "text": { - "content": msg - }, - **extra_params + "touser": '|'.join(users), + "msgtype": "text", + "agentid": self._agentid, + "text": { + "content": msg + }, + **extra_params } if markdown: body['msgtype'] = 'markdown' @@ -184,4 +184,3 @@ class WeCom(RequestMixin): return { 'username': username, 'name': name, 'email': email } - diff --git a/apps/common/sdk/sms/cmpp2.py b/apps/common/sdk/sms/cmpp2.py index 4d81ee1a0..344cf829f 100644 --- a/apps/common/sdk/sms/cmpp2.py +++ b/apps/common/sdk/sms/cmpp2.py @@ -4,16 +4,14 @@ import struct import time from django.conf import settings -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ -from common.utils import get_logger from common.exceptions import JMSException +from common.utils import get_logger from .base import BaseSMSClient - logger = get_logger(__file__) - CMPP_CONNECT = 0x00000001 # 请求连接 CMPP_CONNECT_RESP = 0x80000001 # 请求连接应答 CMPP_TERMINATE = 0x00000002 # 终止连接 @@ -99,10 +97,10 @@ class CMPPSubmitRequestInstance(CMPPBaseRequestInstance): self.length = 126 + 21 * dest_usr_tl + len(_msg_content) self.command_id = CMPP_SUBMIT self.body = msg_id + pk_total + pk_number + registered_delivery \ - + msg_level + service_id + fee_user_type + fee_terminal_id \ - + tp_pid + tp_udhi + msg_fmt + _msg_src + fee_type + fee_code \ - + valid_time + at_time + src_id + _dest_usr_tl + _dest_terminal_id \ - + _msg_length + _msg_content + reserve + + msg_level + service_id + fee_user_type + fee_terminal_id \ + + tp_pid + tp_udhi + msg_fmt + _msg_src + fee_type + fee_code \ + + valid_time + at_time + src_id + _dest_usr_tl + _dest_terminal_id \ + + _msg_length + _msg_content + reserve class CMPPTerminateRequestInstance(CMPPBaseRequestInstance): @@ -161,7 +159,7 @@ class CMPPResponseInstance(object): src_terminal_id = body[42:63] registered_delivery = struct.unpack('!B', body[63:64]) msg_length = struct.unpack('!B', body[64:65]) - msg_content = body[65:msg_length[0]+65] + msg_content = body[65:msg_length[0] + 65] return { 'Msg_Id': msg_id, 'Dest_Id': dest_id, 'Service_Id': service_id, 'TP_pid': tp_pid, 'TP_udhi': tp_udhi, 'Msg_Fmt': msg_fmt, diff --git a/apps/common/tasks.py b/apps/common/tasks.py index a3130ead6..a7d9aacdd 100644 --- a/apps/common/tasks.py +++ b/apps/common/tasks.py @@ -1,9 +1,9 @@ import os -from django.utils.translation import ugettext_lazy as _ -from django.core.mail import send_mail, EmailMultiAlternatives -from django.conf import settings from celery import shared_task +from django.conf import settings +from django.core.mail import send_mail, EmailMultiAlternatives +from django.utils.translation import gettext_lazy as _ from .utils import get_logger diff --git a/apps/common/utils/encode.py b/apps/common/utils/encode.py index 767645c88..6f1fc079e 100644 --- a/apps/common/utils/encode.py +++ b/apps/common/utils/encode.py @@ -45,7 +45,7 @@ class Signer(metaclass=Singleton): def sign(self, value): s = JSONWebSignatureSerializer(self.secret_key, algorithm_name='HS256') - return s.dumps(value).decode() + return self.json_serializer.dumps(value).decode() def unsign(self, value): if value is None: diff --git a/apps/common/utils/ip/geoip/utils.py b/apps/common/utils/ip/geoip/utils.py index 64752a3a1..693a0305c 100644 --- a/apps/common/utils/ip/geoip/utils.py +++ b/apps/common/utils/ip/geoip/utils.py @@ -1,12 +1,12 @@ # -*- coding: utf-8 -*- # -import os import ipaddress +import os import geoip2.database -from geoip2.errors import GeoIP2Error -from django.utils.translation import ugettext_lazy as _ from django.conf import settings +from django.utils.translation import gettext_lazy as _ +from geoip2.errors import GeoIP2Error __all__ = ['get_ip_city_by_geoip'] reader = None @@ -36,5 +36,3 @@ def get_ip_city_by_geoip(ip): lang = 'zh-CN' city = city_names.get(lang, _("Unknown")) return city - - diff --git a/apps/common/validators.py b/apps/common/validators.py index 5bb3e4bdb..7e33d7d76 100644 --- a/apps/common/validators.py +++ b/apps/common/validators.py @@ -3,14 +3,13 @@ import re import phonenumbers - from django.core.validators import RegexValidator -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ +from phonenumbers.phonenumberutil import NumberParseException +from rest_framework import serializers from rest_framework.validators import ( UniqueTogetherValidator, ValidationError ) -from rest_framework import serializers -from phonenumbers.phonenumberutil import NumberParseException from common.utils.strings import no_special_chars diff --git a/apps/jumpserver/conf.py b/apps/jumpserver/conf.py index 33f0dbaf4..d9b15943f 100644 --- a/apps/jumpserver/conf.py +++ b/apps/jumpserver/conf.py @@ -21,7 +21,7 @@ from urllib.parse import urljoin, urlparse import yaml from django.urls import reverse_lazy -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from gmssl.sm4 import CryptSM4, SM4_ENCRYPT, SM4_DECRYPT BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) @@ -234,7 +234,7 @@ class Config(dict): 'LOGIN_URL': reverse_lazy('authentication:login'), 'CONNECTION_TOKEN_ONETIME_EXPIRATION': 5 * 60, # 默认(new) - 'CONNECTION_TOKEN_EXPIRATION': 5 * 60, # 默认(old) + 'CONNECTION_TOKEN_EXPIRATION': 5 * 60, # 默认(old) 'CONNECTION_TOKEN_REUSABLE_EXPIRATION': 60 * 60 * 24 * 30, # 最大(new) 'CONNECTION_TOKEN_EXPIRATION_MAX': 60 * 60 * 24 * 30, # 最大(old) diff --git a/apps/jumpserver/context_processor.py b/apps/jumpserver/context_processor.py index 9966228dc..7b92674bb 100644 --- a/apps/jumpserver/context_processor.py +++ b/apps/jumpserver/context_processor.py @@ -2,7 +2,7 @@ # from django.conf import settings from django.templatetags.static import static -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ default_interface = dict(( ('logo_logout', static('img/logo.png')), diff --git a/apps/jumpserver/settings/base.py b/apps/jumpserver/settings/base.py index 2bc547e57..9d60aa9a9 100644 --- a/apps/jumpserver/settings/base.py +++ b/apps/jumpserver/settings/base.py @@ -6,7 +6,7 @@ from redis.sentinel import SentinelManagedSSLConnection if platform.system() == 'Darwin' and platform.machine() == 'arm64': import pymysql - pymysql.version_info = (1, 4, 2, "final", 0) + # pymysql.version_info = (1, 4, 2, "final", 0) pymysql.install_as_MySQLdb() from django.urls import reverse_lazy diff --git a/apps/jumpserver/views/celery_flower.py b/apps/jumpserver/views/celery_flower.py index 3d98d3bef..fd6d3fac6 100644 --- a/apps/jumpserver/views/celery_flower.py +++ b/apps/jumpserver/views/celery_flower.py @@ -1,10 +1,9 @@ # -*- coding: utf-8 -*- # -from django.http import HttpResponse from django.conf import settings -from django.utils.translation import ugettext as _ +from django.http import HttpResponse +from django.utils.translation import gettext as _ from django.views.decorators.csrf import csrf_exempt - from proxy.views import proxy_view flower_url = settings.FLOWER_URL @@ -24,4 +23,3 @@ def celery_flower_view(request, path): '

{}
'.format(e) response = HttpResponse(msg) return response - diff --git a/apps/jumpserver/views/other.py b/apps/jumpserver/views/other.py index 984898158..038a6fb06 100644 --- a/apps/jumpserver/views/other.py +++ b/apps/jumpserver/views/other.py @@ -2,13 +2,13 @@ # import re -from django.http import HttpResponseRedirect, JsonResponse, Http404 from django.conf import settings -from django.views.generic import View, TemplateView -from django.shortcuts import redirect -from django.utils.translation import ugettext_lazy as _ -from django.views.decorators.csrf import csrf_exempt from django.http import HttpResponse +from django.http import HttpResponseRedirect, JsonResponse, Http404 +from django.shortcuts import redirect +from django.utils.translation import gettext_lazy as _ +from django.views.decorators.csrf import csrf_exempt +from django.views.generic import View, TemplateView from rest_framework.views import APIView from common.views.http import HttpResponseTemporaryRedirect diff --git a/apps/locale/ja/LC_MESSAGES/django.po b/apps/locale/ja/LC_MESSAGES/django.po index 5797de8e5..b44d97a34 100644 --- a/apps/locale/ja/LC_MESSAGES/django.po +++ b/apps/locale/ja/LC_MESSAGES/django.po @@ -3209,8 +3209,8 @@ msgid "%(name)s was updated successfully" msgstr "%(name)s は正常に更新されました" #: common/db/encoder.py:11 -msgid "ugettext_lazy" -msgstr "ugettext_lazy" +msgid "gettext_lazy" +msgstr "gettext_lazy" #: common/db/fields.py:106 msgid "Marshal dict data to char field" diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po index 8db571768..58edc7f08 100644 --- a/apps/locale/zh/LC_MESSAGES/django.po +++ b/apps/locale/zh/LC_MESSAGES/django.po @@ -3169,8 +3169,8 @@ msgid "%(name)s was updated successfully" msgstr "%(name)s 更新成功" #: common/db/encoder.py:11 -msgid "ugettext_lazy" -msgstr "ugettext_lazy" +msgid "gettext_lazy" +msgstr "gettext_lazy" #: common/db/fields.py:106 msgid "Marshal dict data to char field" diff --git a/apps/notifications/apps.py b/apps/notifications/apps.py index 306f2b55b..6147197c9 100644 --- a/apps/notifications/apps.py +++ b/apps/notifications/apps.py @@ -1,5 +1,5 @@ from django.apps import AppConfig -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ class NotificationsConfig(AppConfig): @@ -7,6 +7,4 @@ class NotificationsConfig(AppConfig): verbose_name = _('Notifications') def ready(self): - from . import signal_handlers - from . import notifications super().ready() diff --git a/apps/notifications/models/notification.py b/apps/notifications/models/notification.py index 410d07a28..fe639c7e8 100644 --- a/apps/notifications/models/notification.py +++ b/apps/notifications/models/notification.py @@ -1,5 +1,5 @@ from django.db import models -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from common.db.models import JMSBaseModel, CASCADE_SIGNAL_SKIP diff --git a/apps/ops/api/celery.py b/apps/ops/api/celery.py index d4540269c..67f4d4dda 100644 --- a/apps/ops/api/celery.py +++ b/apps/ops/api/celery.py @@ -5,7 +5,7 @@ import re from celery.result import AsyncResult from django.shortcuts import get_object_or_404 -from django.utils.translation import ugettext as _ +from django.utils.translation import gettext as _ from django_celery_beat.models import PeriodicTask from rest_framework import generics, viewsets, mixins, status from rest_framework.response import Response diff --git a/apps/ops/api/playbook.py b/apps/ops/api/playbook.py index 9d74aa565..72e62cb82 100644 --- a/apps/ops/api/playbook.py +++ b/apps/ops/api/playbook.py @@ -4,7 +4,7 @@ import zipfile from django.conf import settings from django.shortcuts import get_object_or_404 -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from rest_framework import status from common.exceptions import JMSException diff --git a/apps/ops/const.py b/apps/ops/const.py index 5f31bb00d..6bb8ee750 100644 --- a/apps/ops/const.py +++ b/apps/ops/const.py @@ -1,5 +1,5 @@ from django.db import models -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ class StrategyChoice(models.TextChoices): diff --git a/apps/ops/mixin.py b/apps/ops/mixin.py index 487f677a0..05d1e297d 100644 --- a/apps/ops/mixin.py +++ b/apps/ops/mixin.py @@ -3,7 +3,7 @@ import abc from django.db import models -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from rest_framework import serializers from .celery.utils import ( diff --git a/apps/ops/models/adhoc.py b/apps/ops/models/adhoc.py index 254453a90..18b1e5cba 100644 --- a/apps/ops/models/adhoc.py +++ b/apps/ops/models/adhoc.py @@ -2,9 +2,8 @@ import uuid from django.db import models -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ -from common.db.models import JMSBaseModel from common.utils import get_logger __all__ = ["AdHoc"] diff --git a/apps/ops/tasks.py b/apps/ops/tasks.py index 1fe0fbe7c..045c8f1b9 100644 --- a/apps/ops/tasks.py +++ b/apps/ops/tasks.py @@ -2,7 +2,7 @@ from celery import shared_task from celery.exceptions import SoftTimeLimitExceeded -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from django_celery_beat.models import PeriodicTask from common.utils import get_logger, get_object_or_none diff --git a/apps/orgs/api.py b/apps/orgs/api.py index b0d8386e8..b10c3454e 100644 --- a/apps/orgs/api.py +++ b/apps/orgs/api.py @@ -2,7 +2,7 @@ # from django.conf import settings -from django.utils.translation import ugettext as _ +from django.utils.translation import gettext as _ from rest_framework.exceptions import PermissionDenied from rest_framework.generics import RetrieveAPIView diff --git a/apps/orgs/apps.py b/apps/orgs/apps.py index 70505d0f0..c835af0a5 100644 --- a/apps/orgs/apps.py +++ b/apps/orgs/apps.py @@ -1,5 +1,5 @@ from django.apps import AppConfig -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ class OrgsConfig(AppConfig): @@ -7,5 +7,4 @@ class OrgsConfig(AppConfig): verbose_name = _('App organizations') def ready(self): - from . import tasks - from . import signal_handlers + pass diff --git a/apps/orgs/mixins/models.py b/apps/orgs/mixins/models.py index d9eef1e2f..a9494ad1a 100644 --- a/apps/orgs/mixins/models.py +++ b/apps/orgs/mixins/models.py @@ -3,7 +3,7 @@ from django.core.exceptions import ValidationError from django.db import models -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from common.db.models import JMSBaseModel from common.utils import get_logger, lazyproperty diff --git a/apps/orgs/mixins/serializers.py b/apps/orgs/mixins/serializers.py index e2e5a48a8..558dac282 100644 --- a/apps/orgs/mixins/serializers.py +++ b/apps/orgs/mixins/serializers.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from rest_framework import serializers from rest_framework.validators import UniqueTogetherValidator diff --git a/apps/orgs/models.py b/apps/orgs/models.py index 647c37cb9..66286e38e 100644 --- a/apps/orgs/models.py +++ b/apps/orgs/models.py @@ -1,5 +1,5 @@ from django.db import models -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from common.db.models import JMSBaseModel from common.tree import TreeNode diff --git a/apps/orgs/tasks.py b/apps/orgs/tasks.py index 04992f52a..7e02a64a2 100644 --- a/apps/orgs/tasks.py +++ b/apps/orgs/tasks.py @@ -1,5 +1,5 @@ from celery import shared_task -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from common.utils import get_logger diff --git a/apps/perms/api/user_permission/mixin.py b/apps/perms/api/user_permission/mixin.py index 4f4d48181..24ed7fbc1 100644 --- a/apps/perms/api/user_permission/mixin.py +++ b/apps/perms/api/user_permission/mixin.py @@ -1,13 +1,13 @@ # -*- coding: utf-8 -*- # from django.shortcuts import get_object_or_404 -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from rest_framework.request import Request -from users.models import User -from rbac.permissions import RBACPermission -from common.utils import is_uuid from common.exceptions import JMSObjectDoesNotExist +from common.utils import is_uuid +from rbac.permissions import RBACPermission +from users.models import User __all__ = ['SelfOrPKUserMixin'] @@ -57,4 +57,3 @@ class SelfOrPKUserMixin: def request_user_is_self(self): return self.kwargs.get('user') in ['my', 'self'] - diff --git a/apps/perms/apps.py b/apps/perms/apps.py index 7bb606080..c0f2aba38 100644 --- a/apps/perms/apps.py +++ b/apps/perms/apps.py @@ -1,7 +1,7 @@ from __future__ import unicode_literals from django.apps import AppConfig -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ class PermsConfig(AppConfig): @@ -10,6 +10,3 @@ class PermsConfig(AppConfig): def ready(self): super().ready() - from . import signal_handlers - from . import notifications - from . import tasks diff --git a/apps/perms/const.py b/apps/perms/const.py index 60e1ae493..373723a4b 100644 --- a/apps/perms/const.py +++ b/apps/perms/const.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from common.db.fields import BitChoices from common.utils.integer import bit diff --git a/apps/perms/filters.py b/apps/perms/filters.py index 202720480..55a72cf68 100644 --- a/apps/perms/filters.py +++ b/apps/perms/filters.py @@ -1,12 +1,11 @@ -from django_filters import rest_framework as filters -from django.utils.translation import ugettext_lazy as _ from django.db.models import QuerySet, Q +from django_filters import rest_framework as filters -from common.drf.filters import BaseFilterSet -from common.utils import get_object_or_none, is_uuid -from users.models import User, UserGroup from assets.models import Node, Asset +from common.drf.filters import BaseFilterSet +from common.utils import get_object_or_none from perms.models import AssetPermission, AssetPermissionQuerySet +from users.models import User, UserGroup class PermissionBaseFilter(BaseFilterSet): @@ -64,7 +63,8 @@ class PermissionBaseFilter(BaseFilterSet): groups = list(user.groups.all().values_list('id', flat=True)) user_asset_perm_ids = AssetPermission.objects.filter(users=user).distinct().values_list('id', flat=True) - group_asset_perm_ids = AssetPermission.objects.filter(user_groups__in=groups).distinct().values_list('id', flat=True) + group_asset_perm_ids = AssetPermission.objects.filter(user_groups__in=groups).distinct().values_list('id', + flat=True) asset_perm_ids = {*user_asset_perm_ids, *group_asset_perm_ids} diff --git a/apps/perms/models/asset_permission.py b/apps/perms/models/asset_permission.py index 08484e88e..2d5fa6ea5 100644 --- a/apps/perms/models/asset_permission.py +++ b/apps/perms/models/asset_permission.py @@ -3,7 +3,7 @@ import logging from django.db import models from django.db.models import Q from django.utils import timezone -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from accounts.const import AliasAccount from accounts.models import Account diff --git a/apps/perms/models/perm_node.py b/apps/perms/models/perm_node.py index f5dc52be3..b3c209e3d 100644 --- a/apps/perms/models/perm_node.py +++ b/apps/perms/models/perm_node.py @@ -1,6 +1,6 @@ from django.db import models from django.db.models import F, TextChoices -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from accounts.models import Account from assets.models import Asset, Node, FamilyMixin diff --git a/apps/perms/notifications.py b/apps/perms/notifications.py index 9e074cd03..2a8aa0c2d 100644 --- a/apps/perms/notifications.py +++ b/apps/perms/notifications.py @@ -1,5 +1,5 @@ -from django.utils.translation import ugettext as _ from django.template.loader import render_to_string +from django.utils.translation import gettext as _ from common.utils import reverse as js_reverse from notifications.notifications import UserMessage diff --git a/apps/perms/serializers/permission.py b/apps/perms/serializers/permission.py index 4d037e4d3..976fc1f31 100644 --- a/apps/perms/serializers/permission.py +++ b/apps/perms/serializers/permission.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # from django.db.models import Q -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from rest_framework import serializers from accounts.models import AccountTemplate, Account diff --git a/apps/perms/serializers/user_permission.py b/apps/perms/serializers/user_permission.py index 7d054c0d7..44904e82e 100644 --- a/apps/perms/serializers/user_permission.py +++ b/apps/perms/serializers/user_permission.py @@ -2,7 +2,7 @@ # from django.db.models import F -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from rest_framework import serializers from accounts.models import Account diff --git a/apps/rbac/api/role.py b/apps/rbac/api/role.py index d59c42192..387d0bc9c 100644 --- a/apps/rbac/api/role.py +++ b/apps/rbac/api/role.py @@ -1,5 +1,5 @@ from django.db.models import Q, Count -from django.utils.translation import ugettext as _ +from django.utils.translation import gettext as _ from rest_framework.decorators import action from rest_framework.exceptions import PermissionDenied diff --git a/apps/rbac/api/rolebinding.py b/apps/rbac/api/rolebinding.py index f7ad47351..4f3354e5b 100644 --- a/apps/rbac/api/rolebinding.py +++ b/apps/rbac/api/rolebinding.py @@ -1,10 +1,10 @@ -from django.utils.translation import ugettext as _ from django.db.models import F, Value from django.db.models.functions import Concat +from django.utils.translation import gettext as _ +from common.exceptions import JMSException from orgs.mixins.api import OrgBulkModelViewSet from orgs.utils import current_org -from common.exceptions import JMSException from .. import serializers from ..models import RoleBinding, SystemRoleBinding, OrgRoleBinding @@ -26,15 +26,15 @@ class RoleBindingViewSet(OrgBulkModelViewSet): ] def get_queryset(self): - queryset = self._get_queryset()\ + queryset = self._get_queryset() \ .prefetch_related('user', 'role', 'org') \ .annotate( - user_display=Concat( - F('user__name'), Value('('), - F('user__username'), Value(')') - ), - role_display=F('role__name') - ) + user_display=Concat( + F('user__name'), Value('('), + F('user__username'), Value(')') + ), + role_display=F('role__name') + ) return queryset def _get_queryset(self): diff --git a/apps/rbac/apps.py b/apps/rbac/apps.py index f22c7cf0a..646521870 100644 --- a/apps/rbac/apps.py +++ b/apps/rbac/apps.py @@ -1,5 +1,5 @@ from django.apps import AppConfig -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ class RBACConfig(AppConfig): @@ -7,5 +7,4 @@ class RBACConfig(AppConfig): verbose_name = _('RBAC') def ready(self): - from . import signal_handlers super().ready() diff --git a/apps/rbac/builtin.py b/apps/rbac/builtin.py index 508883446..a16944d47 100644 --- a/apps/rbac/builtin.py +++ b/apps/rbac/builtin.py @@ -1,4 +1,4 @@ -from django.utils.translation import ugettext_noop +from django.utils.translation import gettext_noop from .const import Scope, system_exclude_permissions, org_exclude_permissions @@ -111,25 +111,25 @@ class PredefineRole: class BuiltinRole: system_admin = PredefineRole( - '1', ugettext_noop('SystemAdmin'), Scope.system, [] + '1', gettext_noop('SystemAdmin'), Scope.system, [] ) system_auditor = PredefineRole( - '2', ugettext_noop('SystemAuditor'), Scope.system, system_auditor_perms + '2', gettext_noop('SystemAuditor'), Scope.system, system_auditor_perms ) system_component = PredefineRole( - '4', ugettext_noop('SystemComponent'), Scope.system, app_exclude_perms, 'exclude' + '4', gettext_noop('SystemComponent'), Scope.system, app_exclude_perms, 'exclude' ) system_user = PredefineRole( - '3', ugettext_noop('User'), Scope.system, system_user_perms + '3', gettext_noop('User'), Scope.system, system_user_perms ) org_admin = PredefineRole( - '5', ugettext_noop('OrgAdmin'), Scope.org, [] + '5', gettext_noop('OrgAdmin'), Scope.org, [] ) org_auditor = PredefineRole( - '6', ugettext_noop('OrgAuditor'), Scope.org, auditor_perms + '6', gettext_noop('OrgAuditor'), Scope.org, auditor_perms ) org_user = PredefineRole( - '7', ugettext_noop('OrgUser'), Scope.org, user_perms + '7', gettext_noop('OrgUser'), Scope.org, user_perms ) system_role_mapper = None org_role_mapper = None diff --git a/apps/rbac/const.py b/apps/rbac/const.py index cd7fd642a..c484b747f 100644 --- a/apps/rbac/const.py +++ b/apps/rbac/const.py @@ -1,5 +1,5 @@ from django.db import models -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ class Scope(models.TextChoices): diff --git a/apps/rbac/models/permission.py b/apps/rbac/models/permission.py index 0cb29f73a..17653f151 100644 --- a/apps/rbac/models/permission.py +++ b/apps/rbac/models/permission.py @@ -1,7 +1,7 @@ -from django.db.models import Q -from django.utils.translation import ugettext_lazy as _ -from django.contrib.auth.models import Permission as DjangoPermission from django.contrib.auth.models import ContentType as DjangoContentType +from django.contrib.auth.models import Permission as DjangoPermission +from django.db.models import Q +from django.utils.translation import gettext_lazy as _ from .. import const @@ -21,6 +21,7 @@ class ContentType(DjangoContentType): class Permission(DjangoPermission): """ 权限类 """ + class Meta: proxy = True verbose_name = _('Permissions') diff --git a/apps/rbac/models/role.py b/apps/rbac/models/role.py index 1eff7c15c..4f18f67f8 100644 --- a/apps/rbac/models/role.py +++ b/apps/rbac/models/role.py @@ -1,5 +1,5 @@ from django.db import models -from django.utils.translation import ugettext_lazy as _, gettext +from django.utils.translation import gettext_lazy as _, gettext from common.db.models import JMSBaseModel from common.utils import lazyproperty diff --git a/apps/rbac/serializers/permission.py b/apps/rbac/serializers/permission.py index 809b86636..cc97b6c8a 100644 --- a/apps/rbac/serializers/permission.py +++ b/apps/rbac/serializers/permission.py @@ -1,10 +1,9 @@ -from django.utils.translation import ugettext_lazy as _ -from rest_framework import serializers from django.contrib.auth.models import ContentType +from django.utils.translation import gettext_lazy as _ +from rest_framework import serializers from ..models import Permission - __all__ = ['PermissionSerializer', 'UserPermsSerializer'] diff --git a/apps/rbac/serializers/role.py b/apps/rbac/serializers/role.py index 78724c18a..84c597396 100644 --- a/apps/rbac/serializers/role.py +++ b/apps/rbac/serializers/role.py @@ -1,4 +1,4 @@ -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from rest_framework import serializers from common.serializers.fields import LabeledChoiceField diff --git a/apps/rbac/serializers/rolebinding.py b/apps/rbac/serializers/rolebinding.py index cfbf248b8..5e26cdf42 100644 --- a/apps/rbac/serializers/rolebinding.py +++ b/apps/rbac/serializers/rolebinding.py @@ -1,11 +1,11 @@ +from django.utils.translation import gettext_lazy as _ from rest_framework import serializers -from django.utils.translation import ugettext_lazy as _ from orgs.serializers import CurrentOrgDefault from ..models import RoleBinding, SystemRoleBinding, OrgRoleBinding __all__ = [ - 'RoleBindingSerializer', 'OrgRoleBindingSerializer', 'SystemRoleBindingSerializer' + 'RoleBindingSerializer', 'OrgRoleBindingSerializer', 'SystemRoleBindingSerializer' ] @@ -13,7 +13,7 @@ class RoleBindingSerializer(serializers.ModelSerializer): class Meta: model = RoleBinding fields = [ - 'id', 'user', 'user_display', 'role', 'role_display', + 'id', 'user', 'user_display', 'role', 'role_display', 'scope', 'org', 'org_name', ] read_only_fields = ['scope'] @@ -55,6 +55,3 @@ class OrgRoleBindingSerializer(RoleBindingSerializer): if not self.instance and role_bindings.exists(): raise serializers.ValidationError({'role': _('Has bound this role')}) return attrs - - - diff --git a/apps/settings/api/email.py b/apps/settings/api/email.py index 45bec7514..1e8ef2286 100644 --- a/apps/settings/api/email.py +++ b/apps/settings/api/email.py @@ -5,7 +5,7 @@ from smtplib import SMTPSenderRefused from django.conf import settings from django.core.mail import send_mail, get_connection -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from rest_framework.views import Response, APIView from common.utils import get_logger diff --git a/apps/settings/api/ldap.py b/apps/settings/api/ldap.py index 8c98f821f..486da3562 100644 --- a/apps/settings/api/ldap.py +++ b/apps/settings/api/ldap.py @@ -4,7 +4,7 @@ import threading from django.conf import settings -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from rest_framework import generics from rest_framework.generics import CreateAPIView from rest_framework.views import Response, APIView diff --git a/apps/settings/apps.py b/apps/settings/apps.py index 2f96498cc..b96893da1 100644 --- a/apps/settings/apps.py +++ b/apps/settings/apps.py @@ -1,5 +1,5 @@ from django.apps import AppConfig -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ class SettingsConfig(AppConfig): @@ -7,5 +7,4 @@ class SettingsConfig(AppConfig): verbose_name = _('Settings') def ready(self): - from . import tasks - from . import signal_handlers + pass diff --git a/apps/settings/models.py b/apps/settings/models.py index 170d032a4..ab570d07d 100644 --- a/apps/settings/models.py +++ b/apps/settings/models.py @@ -1,13 +1,12 @@ -import os import json +from django.conf import settings +from django.core.files.base import ContentFile +from django.core.files.storage import default_storage +from django.core.files.uploadedfile import InMemoryUploadedFile from django.db import models from django.db.utils import ProgrammingError, OperationalError -from django.utils.translation import ugettext_lazy as _ -from django.conf import settings -from django.core.files.storage import default_storage -from django.core.files.base import ContentFile -from django.core.files.uploadedfile import InMemoryUploadedFile +from django.utils.translation import gettext_lazy as _ from common.utils import signer, get_logger diff --git a/apps/settings/serializers/auth/base.py b/apps/settings/serializers/auth/base.py index abc1ab8b0..ffc6acf1d 100644 --- a/apps/settings/serializers/auth/base.py +++ b/apps/settings/serializers/auth/base.py @@ -1,4 +1,4 @@ -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from rest_framework import serializers __all__ = [ diff --git a/apps/settings/serializers/auth/cas.py b/apps/settings/serializers/auth/cas.py index 4fc964529..c85497b00 100644 --- a/apps/settings/serializers/auth/cas.py +++ b/apps/settings/serializers/auth/cas.py @@ -1,4 +1,4 @@ -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from rest_framework import serializers __all__ = [ diff --git a/apps/settings/serializers/auth/dingtalk.py b/apps/settings/serializers/auth/dingtalk.py index 4ec7814a1..418693bb8 100644 --- a/apps/settings/serializers/auth/dingtalk.py +++ b/apps/settings/serializers/auth/dingtalk.py @@ -1,4 +1,4 @@ -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from rest_framework import serializers from common.serializers.fields import EncryptedField diff --git a/apps/settings/serializers/auth/feishu.py b/apps/settings/serializers/auth/feishu.py index a06d41b23..d3c1edcad 100644 --- a/apps/settings/serializers/auth/feishu.py +++ b/apps/settings/serializers/auth/feishu.py @@ -1,4 +1,4 @@ -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from rest_framework import serializers from common.serializers.fields import EncryptedField diff --git a/apps/settings/serializers/auth/ldap.py b/apps/settings/serializers/auth/ldap.py index cc1976884..054fe6144 100644 --- a/apps/settings/serializers/auth/ldap.py +++ b/apps/settings/serializers/auth/ldap.py @@ -1,4 +1,4 @@ -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from rest_framework import serializers from common.serializers.fields import EncryptedField diff --git a/apps/settings/serializers/auth/oauth2.py b/apps/settings/serializers/auth/oauth2.py index d7f1f4407..56ddd6a66 100644 --- a/apps/settings/serializers/auth/oauth2.py +++ b/apps/settings/serializers/auth/oauth2.py @@ -1,4 +1,4 @@ -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from rest_framework import serializers from common.serializers.fields import EncryptedField diff --git a/apps/settings/serializers/auth/oidc.py b/apps/settings/serializers/auth/oidc.py index 2daf02ff5..0738de49a 100644 --- a/apps/settings/serializers/auth/oidc.py +++ b/apps/settings/serializers/auth/oidc.py @@ -1,4 +1,4 @@ -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from rest_framework import serializers from common.serializers.fields import EncryptedField diff --git a/apps/settings/serializers/auth/radius.py b/apps/settings/serializers/auth/radius.py index 54098c3d0..b4085c352 100644 --- a/apps/settings/serializers/auth/radius.py +++ b/apps/settings/serializers/auth/radius.py @@ -1,7 +1,7 @@ # coding: utf-8 # -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from rest_framework import serializers from common.serializers.fields import EncryptedField diff --git a/apps/settings/serializers/auth/saml2.py b/apps/settings/serializers/auth/saml2.py index 9e0001218..35a4ef5d5 100644 --- a/apps/settings/serializers/auth/saml2.py +++ b/apps/settings/serializers/auth/saml2.py @@ -1,5 +1,4 @@ - -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from rest_framework import serializers __all__ = [ diff --git a/apps/settings/serializers/auth/sms.py b/apps/settings/serializers/auth/sms.py index 0b8138137..40881e52a 100644 --- a/apps/settings/serializers/auth/sms.py +++ b/apps/settings/serializers/auth/sms.py @@ -1,10 +1,10 @@ -from django.utils.translation import ugettext_lazy as _ from django.db import models +from django.utils.translation import gettext_lazy as _ from rest_framework import serializers +from common.sdk.sms import BACKENDS from common.serializers.fields import EncryptedField, PhoneField from common.validators import PhoneValidator -from common.sdk.sms import BACKENDS __all__ = [ 'SMSSettingSerializer', 'AlibabaSMSSettingSerializer', 'TencentSMSSettingSerializer', @@ -26,7 +26,7 @@ class SignTmplPairSerializer(serializers.Serializer): class BaseSMSSettingSerializer(serializers.Serializer): PREFIX_TITLE = _('SMS') - + SMS_TEST_PHONE = PhoneField( validators=[PhoneValidator()], required=False, allow_blank=True, allow_null=True, label=_('Test phone') ) diff --git a/apps/settings/serializers/auth/sso.py b/apps/settings/serializers/auth/sso.py index 0f7a7cef7..74549c72f 100644 --- a/apps/settings/serializers/auth/sso.py +++ b/apps/settings/serializers/auth/sso.py @@ -1,4 +1,4 @@ -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from rest_framework import serializers __all__ = [ diff --git a/apps/settings/serializers/auth/wecom.py b/apps/settings/serializers/auth/wecom.py index 462b17db6..b296eb691 100644 --- a/apps/settings/serializers/auth/wecom.py +++ b/apps/settings/serializers/auth/wecom.py @@ -1,4 +1,4 @@ -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from rest_framework import serializers from common.serializers.fields import EncryptedField diff --git a/apps/settings/serializers/basic.py b/apps/settings/serializers/basic.py index d7d7f7ed9..91a81d45b 100644 --- a/apps/settings/serializers/basic.py +++ b/apps/settings/serializers/basic.py @@ -1,6 +1,6 @@ import uuid -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from rest_framework import serializers @@ -52,4 +52,3 @@ class BasicSettingSerializer(serializers.Serializer): if not s: return 'http://127.0.0.1' return s.strip('/') - diff --git a/apps/settings/serializers/cleaning.py b/apps/settings/serializers/cleaning.py index dfc568c99..eb1841561 100644 --- a/apps/settings/serializers/cleaning.py +++ b/apps/settings/serializers/cleaning.py @@ -1,4 +1,4 @@ -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from rest_framework import serializers __all__ = ['CleaningSerializer'] @@ -29,7 +29,8 @@ class CleaningSerializer(serializers.Serializer): ) TERMINAL_SESSION_KEEP_DURATION = serializers.IntegerField( min_value=1, max_value=99999, required=True, label=_('Session keep duration (day)'), - help_text=_('Session, record, command will be delete if more than duration, only in database, OSS will not be affected.') + help_text=_( + 'Session, record, command will be delete if more than duration, only in database, OSS will not be affected.') ) ACTIVITY_LOG_KEEP_DAYS = serializers.IntegerField( min_value=1, max_value=9999, diff --git a/apps/settings/serializers/email.py b/apps/settings/serializers/email.py index ab8b10415..ce4568b62 100644 --- a/apps/settings/serializers/email.py +++ b/apps/settings/serializers/email.py @@ -1,7 +1,7 @@ # coding: utf-8 # -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from rest_framework import serializers from common.serializers.fields import EncryptedField diff --git a/apps/settings/serializers/other.py b/apps/settings/serializers/other.py index 42df32496..7cf447ef0 100644 --- a/apps/settings/serializers/other.py +++ b/apps/settings/serializers/other.py @@ -1,4 +1,4 @@ -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from rest_framework import serializers diff --git a/apps/settings/serializers/security.py b/apps/settings/serializers/security.py index c9f02d591..329cc8ebe 100644 --- a/apps/settings/serializers/security.py +++ b/apps/settings/serializers/security.py @@ -1,4 +1,4 @@ -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from rest_framework import serializers from acls.serializers.rules import ip_group_help_text, ip_group_child_validator @@ -98,11 +98,13 @@ class SecurityAuthSerializer(serializers.Serializer): ) ONLY_ALLOW_EXIST_USER_AUTH = serializers.BooleanField( required=False, default=False, label=_("Only exist user login"), - help_text=_("If enabled, non-existent users will not be allowed to log in; if disabled, users of other authentication methods except local authentication methods are allowed to log in and automatically create users (if the user does not exist)") + help_text=_( + "If enabled, non-existent users will not be allowed to log in; if disabled, users of other authentication methods except local authentication methods are allowed to log in and automatically create users (if the user does not exist)") ) ONLY_ALLOW_AUTH_FROM_SOURCE = serializers.BooleanField( required=False, default=False, label=_("Only from source login"), - help_text=_("If it is enabled, the user will only authenticate to the source when logging in; if it is disabled, the user will authenticate all the enabled authentication methods in a certain order when logging in, and as long as one of the authentication methods is successful, they can log in directly") + help_text=_( + "If it is enabled, the user will only authenticate to the source when logging in; if it is disabled, the user will authenticate all the enabled authentication methods in a certain order when logging in, and as long as one of the authentication methods is successful, they can log in directly") ) SECURITY_MFA_VERIFY_TTL = serializers.IntegerField( min_value=5, max_value=60 * 60 * 10, diff --git a/apps/settings/serializers/settings.py b/apps/settings/serializers/settings.py index 2fb15b0af..c0ff911a7 100644 --- a/apps/settings/serializers/settings.py +++ b/apps/settings/serializers/settings.py @@ -1,12 +1,9 @@ # coding: utf-8 from django.core.cache import cache from django.utils import translation -from django.utils.translation import gettext_noop, ugettext_lazy as _ +from django.utils.translation import gettext_noop, gettext_lazy as _ from common.utils import i18n_fmt -from .basic import BasicSettingSerializer -from .other import OtherSettingSerializer -from .email import EmailSettingSerializer, EmailContentSettingSerializer from .auth import ( LDAPSettingSerializer, OIDCSettingSerializer, KeycloakSettingSerializer, CASSettingSerializer, RadiusSettingSerializer, FeiShuSettingSerializer, @@ -15,10 +12,12 @@ from .auth import ( SAML2SettingSerializer, OAuth2SettingSerializer, SSOSettingSerializer, CustomSMSSettingSerializer, ) -from .terminal import TerminalSettingSerializer -from .security import SecuritySettingSerializer +from .basic import BasicSettingSerializer from .cleaning import CleaningSerializer - +from .email import EmailSettingSerializer, EmailContentSettingSerializer +from .other import OtherSettingSerializer +from .security import SecuritySettingSerializer +from .terminal import TerminalSettingSerializer __all__ = [ 'SettingsSerializer', diff --git a/apps/settings/serializers/sms.py b/apps/settings/serializers/sms.py index fa274a52a..ec78993a6 100644 --- a/apps/settings/serializers/sms.py +++ b/apps/settings/serializers/sms.py @@ -1,4 +1,4 @@ -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from rest_framework import serializers diff --git a/apps/settings/serializers/terminal.py b/apps/settings/serializers/terminal.py index 87ce12fb7..86465009e 100644 --- a/apps/settings/serializers/terminal.py +++ b/apps/settings/serializers/terminal.py @@ -1,4 +1,4 @@ -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from rest_framework import serializers diff --git a/apps/settings/signals.py b/apps/settings/signals.py index 859378a83..ccc9cd2d5 100644 --- a/apps/settings/signals.py +++ b/apps/settings/signals.py @@ -1,3 +1,3 @@ from django.dispatch import Signal -category_setting_updated = Signal(providing_args=('category', 'serializer')) +category_setting_updated = Signal() diff --git a/apps/settings/tasks/ldap.py b/apps/settings/tasks/ldap.py index b931efb48..0530680e8 100644 --- a/apps/settings/tasks/ldap.py +++ b/apps/settings/tasks/ldap.py @@ -2,8 +2,7 @@ # from celery import shared_task from django.conf import settings -from django.db import transaction -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from common.utils import get_logger from ops.celery.decorator import after_app_ready_start diff --git a/apps/settings/utils/ldap.py b/apps/settings/utils/ldap.py index e8ff0ab79..d130ac41a 100644 --- a/apps/settings/utils/ldap.py +++ b/apps/settings/utils/ldap.py @@ -7,7 +7,7 @@ from copy import deepcopy from django.conf import settings from django.core.cache import cache -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from ldap3 import Server, Connection, SIMPLE from ldap3.core.exceptions import ( LDAPSocketOpenError, diff --git a/apps/terminal/api/component/endpoint.py b/apps/terminal/api/component/endpoint.py index c7518932f..e2eeaf548 100644 --- a/apps/terminal/api/component/endpoint.py +++ b/apps/terminal/api/component/endpoint.py @@ -1,5 +1,5 @@ from django.shortcuts import get_object_or_404 -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from rest_framework import status from rest_framework.decorators import action from rest_framework.request import Request diff --git a/apps/terminal/api/component/storage.py b/apps/terminal/api/component/storage.py index c912e3131..04e0db9ad 100644 --- a/apps/terminal/api/component/storage.py +++ b/apps/terminal/api/component/storage.py @@ -1,15 +1,15 @@ # coding: utf-8 # -from rest_framework import viewsets, generics, status -from rest_framework.response import Response -from rest_framework.request import Request -from rest_framework.decorators import action -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from django_filters import utils +from rest_framework import viewsets, generics, status +from rest_framework.decorators import action +from rest_framework.request import Request +from rest_framework.response import Response -from terminal import const from common.const.http import GET +from terminal import const from terminal.filters import CommandStorageFilter, CommandFilter, CommandFilterForStorageTree from terminal.models import CommandStorage, ReplayStorage from terminal.serializers import CommandStorageSerializer, ReplayStorageSerializer @@ -78,26 +78,26 @@ class CommandStorageViewSet(BaseStorageViewSetMixin, viewsets.ModelViewSet): invalid = _('Invalid') nodes = [ - { - 'id': storage.id, - 'name': f'{storage.name}({storage.type})({command_count})', - 'title': f'{storage.name}({storage.type})', - 'pId': 'root', - 'isParent': False, - 'open': False, - 'valid': True, - } for storage, command_count in storages_with_count - ] + [ - { - 'id': storage.id, - 'name': f'{storage.name}({storage.type}) *{invalid}', - 'title': f'{storage.name}({storage.type})', - 'pId': 'root', - 'isParent': False, - 'open': False, - 'valid': False, - } for storage in invalid_storages - ] + { + 'id': storage.id, + 'name': f'{storage.name}({storage.type})({command_count})', + 'title': f'{storage.name}({storage.type})', + 'pId': 'root', + 'isParent': False, + 'open': False, + 'valid': True, + } for storage, command_count in storages_with_count + ] + [ + { + 'id': storage.id, + 'name': f'{storage.name}({storage.type}) *{invalid}', + 'title': f'{storage.name}({storage.type})', + 'pId': 'root', + 'isParent': False, + 'open': False, + 'valid': False, + } for storage in invalid_storages + ] nodes.append(root) return Response(data=nodes) diff --git a/apps/terminal/api/session/session.py b/apps/terminal/api/session/session.py index 47432b60b..730fc99eb 100644 --- a/apps/terminal/api/session/session.py +++ b/apps/terminal/api/session/session.py @@ -8,7 +8,7 @@ from django.db.models import F from django.http import FileResponse from django.shortcuts import get_object_or_404, reverse from django.utils.encoding import escape_uri_path -from django.utils.translation import ugettext as _ +from django.utils.translation import gettext as _ from django_filters import rest_framework as filters from rest_framework import generics from rest_framework import viewsets, views diff --git a/apps/terminal/api/session/sharing.py b/apps/terminal/api/session/sharing.py index 9a60734fa..1675ee294 100644 --- a/apps/terminal/api/session/sharing.py +++ b/apps/terminal/api/session/sharing.py @@ -1,5 +1,5 @@ from django.conf import settings -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from rest_framework.decorators import action from rest_framework.exceptions import MethodNotAllowed, ValidationError from rest_framework.response import Response diff --git a/apps/terminal/backends/command/models.py b/apps/terminal/backends/command/models.py index 801b3cdf1..cb30efddd 100644 --- a/apps/terminal/backends/command/models.py +++ b/apps/terminal/backends/command/models.py @@ -4,7 +4,7 @@ import uuid from datetime import datetime from django.db import models -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from common.utils.common import lazyproperty from orgs.mixins.models import OrgModelMixin @@ -12,7 +12,6 @@ from terminal.const import RiskLevelChoices class AbstractSessionCommand(OrgModelMixin): - id = models.UUIDField(default=uuid.uuid4, primary_key=True) user = models.CharField(max_length=64, db_index=True, verbose_name=_("User")) asset = models.CharField(max_length=128, db_index=True, verbose_name=_("Asset")) diff --git a/apps/terminal/connect_methods.py b/apps/terminal/connect_methods.py index f6870344d..ed49d722e 100644 --- a/apps/terminal/connect_methods.py +++ b/apps/terminal/connect_methods.py @@ -5,7 +5,7 @@ from collections import defaultdict from django.conf import settings from django.db.models import TextChoices -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from assets.const import Protocol from .const import TerminalType diff --git a/apps/terminal/const.py b/apps/terminal/const.py index f34233e3a..8b04c74cc 100644 --- a/apps/terminal/const.py +++ b/apps/terminal/const.py @@ -2,7 +2,7 @@ # from django.db.models import TextChoices, IntegerChoices -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ class RiskLevelChoices(IntegerChoices): diff --git a/apps/terminal/exceptions.py b/apps/terminal/exceptions.py index bb3e43591..7dab48300 100644 --- a/apps/terminal/exceptions.py +++ b/apps/terminal/exceptions.py @@ -1,4 +1,4 @@ -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from common.exceptions import JMSException @@ -11,4 +11,3 @@ class BulkCreateNotSupport(JMSException): class StorageInvalid(JMSException): default_code = 'storage_invalid' default_detail = _('Storage is invalid') - diff --git a/apps/terminal/models/component/endpoint.py b/apps/terminal/models/component/endpoint.py index c68c06307..8daf75a57 100644 --- a/apps/terminal/models/component/endpoint.py +++ b/apps/terminal/models/component/endpoint.py @@ -1,6 +1,6 @@ from django.core.validators import MinValueValidator, MaxValueValidator from django.db import models -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from assets.models import Asset from common.db.fields import PortField diff --git a/apps/terminal/models/component/status.py b/apps/terminal/models/component/status.py index d273b9dac..2f74ae18d 100644 --- a/apps/terminal/models/component/status.py +++ b/apps/terminal/models/component/status.py @@ -3,7 +3,7 @@ import uuid from django.core.cache import cache from django.db import models from django.forms.models import model_to_dict -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from common.utils import get_logger diff --git a/apps/terminal/models/component/storage.py b/apps/terminal/models/component/storage.py index 0d4a5347f..6a34f3f5a 100644 --- a/apps/terminal/models/component/storage.py +++ b/apps/terminal/models/component/storage.py @@ -7,7 +7,7 @@ from importlib import import_module import jms_storage from django.conf import settings from django.db import models -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from common.db.fields import EncryptJsonDictTextField from common.db.models import JMSBaseModel diff --git a/apps/terminal/models/component/task.py b/apps/terminal/models/component/task.py index 1c081da53..b1694dcb8 100644 --- a/apps/terminal/models/component/task.py +++ b/apps/terminal/models/component/task.py @@ -1,7 +1,7 @@ from __future__ import unicode_literals from django.db import models -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from common.db.models import JMSBaseModel from .terminal import Terminal diff --git a/apps/terminal/models/component/terminal.py b/apps/terminal/models/component/terminal.py index cc79212db..f2b0f9148 100644 --- a/apps/terminal/models/component/terminal.py +++ b/apps/terminal/models/component/terminal.py @@ -1,9 +1,9 @@ -import time import uuid + from django.conf import settings from django.core.cache import cache from django.db import models -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from common.const.signals import SKIP_SIGNAL from common.db.models import JMSBaseModel diff --git a/apps/terminal/models/session/command.py b/apps/terminal/models/session/command.py index 3d377523b..9978f9911 100644 --- a/apps/terminal/models/session/command.py +++ b/apps/terminal/models/session/command.py @@ -2,7 +2,7 @@ from __future__ import unicode_literals from django.db import models from django.db.models.signals import post_save -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from terminal.backends.command.models import AbstractSessionCommand diff --git a/apps/terminal/models/session/replay.py b/apps/terminal/models/session/replay.py index 9fd210f48..29d55cd9c 100644 --- a/apps/terminal/models/session/replay.py +++ b/apps/terminal/models/session/replay.py @@ -1,5 +1,5 @@ from django.db import models -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from common.db.models import JMSBaseModel from .session import Session diff --git a/apps/terminal/models/session/session.py b/apps/terminal/models/session/session.py index ccf5936b8..35c11727e 100644 --- a/apps/terminal/models/session/session.py +++ b/apps/terminal/models/session/session.py @@ -8,7 +8,7 @@ from django.core.cache import cache from django.core.files.storage import default_storage from django.db import models from django.utils import timezone -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from assets.models import Asset from common.utils import get_object_or_none, lazyproperty diff --git a/apps/terminal/models/session/sharing.py b/apps/terminal/models/session/sharing.py index c0e83dfda..e5187a3b8 100644 --- a/apps/terminal/models/session/sharing.py +++ b/apps/terminal/models/session/sharing.py @@ -2,7 +2,7 @@ import datetime from django.db import models from django.utils import timezone -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from common.db.models import JMSBaseModel from orgs.mixins.models import OrgModelMixin diff --git a/apps/terminal/notifications.py b/apps/terminal/notifications.py index cfcac4396..f200650a6 100644 --- a/apps/terminal/notifications.py +++ b/apps/terminal/notifications.py @@ -2,7 +2,7 @@ from typing import Callable from django.conf import settings from django.template.loader import render_to_string -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from common.utils import get_logger, reverse from common.utils import lazyproperty @@ -10,9 +10,9 @@ from common.utils.timezone import local_now_display from notifications.backends import BACKEND from notifications.models import SystemMsgSubscription from notifications.notifications import SystemMessage, UserMessage +from terminal.const import RiskLevelChoices from terminal.models import Session, Command from users.models import User -from terminal.const import RiskLevelChoices logger = get_logger(__name__) diff --git a/apps/terminal/serializers/command.py b/apps/terminal/serializers/command.py index b8983a59c..11b16f5ad 100644 --- a/apps/terminal/serializers/command.py +++ b/apps/terminal/serializers/command.py @@ -1,18 +1,17 @@ # ~*~ coding: utf-8 ~*~ -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from rest_framework import serializers -from common.utils import pretty_string, is_uuid, get_logger from common.serializers.fields import LabeledChoiceField -from terminal.models import Command +from common.utils import pretty_string, is_uuid, get_logger from terminal.const import RiskLevelChoices +from terminal.models import Command logger = get_logger(__name__) __all__ = ['SessionCommandSerializer', 'InsecureCommandAlertSerializer'] class SimpleSessionCommandSerializer(serializers.ModelSerializer): - """ 简单Session命令序列类, 用来提取公共字段 """ user = serializers.CharField(label=_("User")) # 限制 64 字符,见 validate_user asset = serializers.CharField(max_length=128, label=_("Asset")) diff --git a/apps/terminal/serializers/session.py b/apps/terminal/serializers/session.py index dc736a522..999028133 100644 --- a/apps/terminal/serializers/session.py +++ b/apps/terminal/serializers/session.py @@ -1,4 +1,4 @@ -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from rest_framework import serializers from common.serializers.fields import LabeledChoiceField diff --git a/apps/terminal/serializers/sharing.py b/apps/terminal/serializers/sharing.py index c7b8f2e4e..abc2dbdd3 100644 --- a/apps/terminal/serializers/sharing.py +++ b/apps/terminal/serializers/sharing.py @@ -1,4 +1,4 @@ -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from rest_framework import serializers from common.serializers.fields import LabeledChoiceField diff --git a/apps/terminal/serializers/storage.py b/apps/terminal/serializers/storage.py index dd0f7f677..2c9a1b1c2 100644 --- a/apps/terminal/serializers/storage.py +++ b/apps/terminal/serializers/storage.py @@ -1,15 +1,17 @@ # -*- coding: utf-8 -*- # +from urllib.parse import urlparse + +from django.db.models import TextChoices +from django.utils.translation import gettext_lazy as _ from rest_framework import serializers from rest_framework.validators import UniqueValidator -from urllib.parse import urlparse -from django.utils.translation import ugettext_lazy as _ -from django.db.models import TextChoices -from common.serializers.fields import LabeledChoiceField + from common.serializers import MethodSerializer +from common.serializers.fields import LabeledChoiceField from common.serializers.fields import ReadableHiddenField, EncryptedField -from ..models import ReplayStorage, CommandStorage from .. import const +from ..models import ReplayStorage, CommandStorage # Replay storage serializers diff --git a/apps/terminal/serializers/terminal.py b/apps/terminal/serializers/terminal.py index 2904c7938..a65249551 100644 --- a/apps/terminal/serializers/terminal.py +++ b/apps/terminal/serializers/terminal.py @@ -1,4 +1,4 @@ -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from rest_framework import serializers from common.serializers import BulkModelSerializer diff --git a/apps/terminal/utils/db_port_mapper.py b/apps/terminal/utils/db_port_mapper.py index 9d335859a..9878fa9ef 100644 --- a/apps/terminal/utils/db_port_mapper.py +++ b/apps/terminal/utils/db_port_mapper.py @@ -1,6 +1,6 @@ from django.conf import settings from django.core.cache import cache -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from assets.const import DatabaseTypes from assets.models import Database diff --git a/apps/tickets/apps.py b/apps/tickets/apps.py index 317ac592e..563bb9048 100644 --- a/apps/tickets/apps.py +++ b/apps/tickets/apps.py @@ -1,5 +1,5 @@ from django.apps import AppConfig -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ class TicketsConfig(AppConfig): @@ -7,6 +7,4 @@ class TicketsConfig(AppConfig): verbose_name = _('Tickets') def ready(self): - from . import signal_handlers - from . import notifications return super().ready() diff --git a/apps/tickets/const.py b/apps/tickets/const.py index ccd044bbe..a2a5ec981 100644 --- a/apps/tickets/const.py +++ b/apps/tickets/const.py @@ -1,5 +1,5 @@ from django.db.models import TextChoices, IntegerChoices -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ TICKET_DETAIL_URL = '/ui/#/tickets/tickets/{id}?type={type}' diff --git a/apps/tickets/errors.py b/apps/tickets/errors.py index 716eeca94..5bd73a95f 100644 --- a/apps/tickets/errors.py +++ b/apps/tickets/errors.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from common.exceptions import JMSException diff --git a/apps/tickets/handlers/apply_asset.py b/apps/tickets/handlers/apply_asset.py index f2b2ee842..3b4c70729 100644 --- a/apps/tickets/handlers/apply_asset.py +++ b/apps/tickets/handlers/apply_asset.py @@ -1,4 +1,4 @@ -from django.utils.translation import ugettext as _ +from django.utils.translation import gettext as _ from orgs.utils import tmp_to_org from perms.models import AssetPermission diff --git a/apps/tickets/handlers/base.py b/apps/tickets/handlers/base.py index 6548bfa8f..fbf6a8e46 100644 --- a/apps/tickets/handlers/base.py +++ b/apps/tickets/handlers/base.py @@ -1,6 +1,6 @@ import html2text from django.template.loader import render_to_string -from django.utils.translation import ugettext as _ +from django.utils.translation import gettext as _ from common.utils import get_logger from tickets.const import TicketState, TicketType diff --git a/apps/tickets/models/comment.py b/apps/tickets/models/comment.py index 6577b65e2..20d427497 100644 --- a/apps/tickets/models/comment.py +++ b/apps/tickets/models/comment.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # from django.db import models -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from common.db.models import JMSBaseModel diff --git a/apps/tickets/models/flow.py b/apps/tickets/models/flow.py index 0b7518fc6..c339e4685 100644 --- a/apps/tickets/models/flow.py +++ b/apps/tickets/models/flow.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # from django.db import models -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from common.db.models import JMSBaseModel from orgs.mixins.models import OrgModelMixin diff --git a/apps/tickets/models/relation.py b/apps/tickets/models/relation.py index ca159804d..98bb1dc87 100644 --- a/apps/tickets/models/relation.py +++ b/apps/tickets/models/relation.py @@ -1,10 +1,12 @@ from django.db import models -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ class TicketSession(models.Model): - ticket = models.ForeignKey('tickets.Ticket', related_name='session_relation', on_delete=models.CASCADE, db_constraint=False) - session = models.ForeignKey('terminal.Session', related_name='ticket_relation', on_delete=models.CASCADE, db_constraint=False) + ticket = models.ForeignKey('tickets.Ticket', related_name='session_relation', on_delete=models.CASCADE, + db_constraint=False) + session = models.ForeignKey('terminal.Session', related_name='ticket_relation', on_delete=models.CASCADE, + db_constraint=False) class Meta: verbose_name = _("Ticket session relation") diff --git a/apps/tickets/models/ticket/general.py b/apps/tickets/models/ticket/general.py index b419bb2bb..f7c78a4a1 100644 --- a/apps/tickets/models/ticket/general.py +++ b/apps/tickets/models/ticket/general.py @@ -8,7 +8,7 @@ from django.db.models import Prefetch, Q from django.db.models.fields import related from django.db.utils import IntegrityError from django.forms import model_to_dict -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from common.db.encoder import ModelJSONFieldEncoder from common.db.models import JMSBaseModel diff --git a/apps/tickets/notifications.py b/apps/tickets/notifications.py index 5da077496..91c0a047d 100644 --- a/apps/tickets/notifications.py +++ b/apps/tickets/notifications.py @@ -6,7 +6,7 @@ from django.core.cache import cache from django.forms import model_to_dict from django.shortcuts import reverse from django.template.loader import render_to_string -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from common.db.encoder import ModelJSONFieldEncoder from common.utils import get_logger, random_string diff --git a/apps/tickets/serializers/flow.py b/apps/tickets/serializers/flow.py index f3b9c0215..01951c1ae 100644 --- a/apps/tickets/serializers/flow.py +++ b/apps/tickets/serializers/flow.py @@ -1,13 +1,13 @@ -from rest_framework import serializers from django.db.transaction import atomic -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ +from rest_framework import serializers +from common.serializers.fields import LabeledChoiceField +from orgs.mixins.serializers import OrgResourceModelSerializerMixin from orgs.models import Organization from orgs.utils import get_current_org_id -from orgs.mixins.serializers import OrgResourceModelSerializerMixin -from common.serializers.fields import LabeledChoiceField -from tickets.models import TicketFlow, ApprovalRule from tickets.const import TicketApprovalStrategy, TicketType +from tickets.models import TicketFlow, ApprovalRule __all__ = ['TicketFlowSerializer'] diff --git a/apps/tickets/serializers/ticket/apply_asset.py b/apps/tickets/serializers/ticket/apply_asset.py index 98587f266..49dcc09a0 100644 --- a/apps/tickets/serializers/ticket/apply_asset.py +++ b/apps/tickets/serializers/ticket/apply_asset.py @@ -1,4 +1,4 @@ -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from rest_framework import serializers from assets.models import Asset, Node diff --git a/apps/tickets/serializers/ticket/common.py b/apps/tickets/serializers/ticket/common.py index 8ec463337..90204c18a 100644 --- a/apps/tickets/serializers/ticket/common.py +++ b/apps/tickets/serializers/ticket/common.py @@ -1,6 +1,6 @@ from django.db.models import Model from django.db.transaction import atomic -from django.utils.translation import ugettext as _ +from django.utils.translation import gettext as _ from rest_framework import serializers from orgs.utils import tmp_to_org diff --git a/apps/tickets/serializers/ticket/ticket.py b/apps/tickets/serializers/ticket/ticket.py index ff76ee9eb..edeb97ad2 100644 --- a/apps/tickets/serializers/ticket/ticket.py +++ b/apps/tickets/serializers/ticket/ticket.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from rest_framework import serializers from common.serializers.fields import LabeledChoiceField diff --git a/apps/tickets/views/approve.py b/apps/tickets/views/approve.py index a3a265005..21e5b4af6 100644 --- a/apps/tickets/views/approve.py +++ b/apps/tickets/views/approve.py @@ -2,11 +2,13 @@ # from __future__ import unicode_literals + from django.core.cache import cache from django.shortcuts import redirect, reverse +from django.utils.translation import gettext as _ from django.views.generic.base import TemplateView -from django.utils.translation import ugettext as _ +from common.utils import get_logger, FlashMessageUtil from orgs.utils import tmp_to_root_org from tickets.const import TicketType from tickets.errors import AlreadyClosed @@ -14,7 +16,6 @@ from tickets.models import ( Ticket, ApplyAssetTicket, ApplyLoginTicket, ApplyLoginAssetTicket, ApplyCommandTicket ) -from common.utils import get_logger, FlashMessageUtil logger = get_logger(__name__) diff --git a/apps/users/api/user.py b/apps/users/api/user.py index 7bb8a7d8f..e0bc288c8 100644 --- a/apps/users/api/user.py +++ b/apps/users/api/user.py @@ -1,7 +1,7 @@ # ~*~ coding: utf-8 ~*~ from collections import defaultdict -from django.utils.translation import ugettext as _ +from django.utils.translation import gettext as _ from rest_framework import generics from rest_framework.decorators import action from rest_framework.response import Response @@ -118,7 +118,6 @@ class UserViewSet(CommonApiMixin, UserQuerysetMixin, SuggestionMixin, BulkModelV self.check_object_permissions(self.request, user) return super().perform_bulk_update(serializer) - def perform_bulk_destroy(self, objects): for obj in objects: self.check_object_permissions(self.request, obj) diff --git a/apps/users/apps.py b/apps/users/apps.py index ead9987be..9c00a68f9 100644 --- a/apps/users/apps.py +++ b/apps/users/apps.py @@ -1,7 +1,7 @@ from __future__ import unicode_literals -from django.utils.translation import ugettext_lazy as _ from django.apps import AppConfig +from django.utils.translation import gettext_lazy as _ class UsersConfig(AppConfig): @@ -9,7 +9,4 @@ class UsersConfig(AppConfig): verbose_name = _('Users') def ready(self): - from . import signal_handlers - from . import notifications - from . import tasks super().ready() diff --git a/apps/users/const.py b/apps/users/const.py index 41f350a28..0de518098 100644 --- a/apps/users/const.py +++ b/apps/users/const.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # from django.db.models import TextChoices -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ TICKET_DETAIL_URL = '/ui/#/tickets/tickets/{id}' diff --git a/apps/users/models/group.py b/apps/users/models/group.py index e92e65c81..914c22f75 100644 --- a/apps/users/models/group.py +++ b/apps/users/models/group.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- from django.db import models -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from common.utils import lazyproperty from orgs.mixins.models import JMSOrgBaseModel diff --git a/apps/users/models/user.py b/apps/users/models/user.py index fcbc0b76e..4a7dccd05 100644 --- a/apps/users/models/user.py +++ b/apps/users/models/user.py @@ -16,7 +16,7 @@ from django.db import models from django.shortcuts import reverse from django.utils import timezone from django.utils.module_loading import import_string -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from common.db import fields, models as jms_models from common.utils import ( diff --git a/apps/users/notifications.py b/apps/users/notifications.py index cbc6e1976..95af2386e 100644 --- a/apps/users/notifications.py +++ b/apps/users/notifications.py @@ -1,10 +1,10 @@ -from urllib.parse import urljoin from collections import defaultdict +from urllib.parse import urljoin -from django.utils import timezone -from django.utils.translation import ugettext as _ from django.conf import settings from django.template.loader import render_to_string +from django.utils import timezone +from django.utils.translation import gettext as _ from common.utils import reverse, get_request_ip_or_data, get_request_user_agent from notifications.notifications import UserMessage diff --git a/apps/users/serializers/group.py b/apps/users/serializers/group.py index dc61eee21..af4e349e0 100644 --- a/apps/users/serializers/group.py +++ b/apps/users/serializers/group.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # from django.db.models import Count -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from common.serializers.mixin import ObjectRelatedField from orgs.mixins.serializers import BulkOrgResourceModelSerializer diff --git a/apps/users/serializers/profile.py b/apps/users/serializers/profile.py index 7502a7525..f03bb133b 100644 --- a/apps/users/serializers/profile.py +++ b/apps/users/serializers/profile.py @@ -1,5 +1,5 @@ from django.conf import settings -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from rest_framework import serializers from common.serializers.fields import EncryptedField, LabeledChoiceField diff --git a/apps/users/serializers/user.py b/apps/users/serializers/user.py index 099bddd1d..ee10ddf74 100644 --- a/apps/users/serializers/user.py +++ b/apps/users/serializers/user.py @@ -3,7 +3,7 @@ from functools import partial -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from rest_framework import serializers from common.serializers import CommonBulkSerializerMixin diff --git a/apps/users/signal_handlers.py b/apps/users/signal_handlers.py index 2b2054ea3..7db379d4a 100644 --- a/apps/users/signal_handlers.py +++ b/apps/users/signal_handlers.py @@ -3,7 +3,7 @@ from django.conf import settings from django.db.models.signals import post_save from django.dispatch import receiver -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from django_auth_ldap.backend import populate_user from django_cas_ng.signals import cas_user_authenticated diff --git a/apps/users/signals.py b/apps/users/signals.py index 739379d93..d85139c62 100644 --- a/apps/users/signals.py +++ b/apps/users/signals.py @@ -1,7 +1,6 @@ from django.dispatch import Signal - -post_user_create = Signal(providing_args=('user',)) -post_user_change_password = Signal(providing_args=('user',)) -pre_user_leave_org = Signal(providing_args=('user', 'org')) -post_user_leave_org = Signal(providing_args=('user', 'org')) +post_user_create = Signal() +post_user_change_password = Signal() +pre_user_leave_org = Signal() +post_user_leave_org = Signal() diff --git a/apps/users/views/profile/otp.py b/apps/users/views/profile/otp.py index 5b4333d37..a42a7a513 100644 --- a/apps/users/views/profile/otp.py +++ b/apps/users/views/profile/otp.py @@ -1,21 +1,19 @@ # ~*~ coding: utf-8 ~*~ -import time +from django.contrib.auth import logout as auth_logout +from django.http.response import HttpResponseRedirect +from django.shortcuts import redirect from django.urls import reverse -from django.utils.translation import ugettext as _ +from django.utils.translation import gettext as _ from django.views.generic.base import TemplateView from django.views.generic.edit import FormView -from django.contrib.auth import logout as auth_logout -from django.shortcuts import redirect -from django.http.response import HttpResponseRedirect -from authentication.mixins import AuthMixin -from authentication.mfa import MFAOtp, otp_failed_msg from authentication.errors import SessionEmptyError +from authentication.mfa import MFAOtp, otp_failed_msg +from authentication.mixins import AuthMixin +from common.permissions import IsValidUser from common.utils import get_logger, FlashMessageUtil from common.views.mixins import PermissionsMixin -from common.permissions import IsValidUser -from .password import UserVerifyPasswordView from ... import forms from ...utils import ( generate_otp_uri, check_otp_code, diff --git a/apps/users/views/profile/password.py b/apps/users/views/profile/password.py index bb51b8aa4..87d0bf6e7 100644 --- a/apps/users/views/profile/password.py +++ b/apps/users/views/profile/password.py @@ -1,15 +1,12 @@ # ~*~ coding: utf-8 ~*~ -import time -from django.conf import settings from django.contrib.auth import authenticate from django.shortcuts import redirect -from django.utils.translation import ugettext as _ +from django.utils.translation import gettext as _ from django.views.generic.edit import FormView -from authentication.mixins import AuthMixin from authentication import errors - +from authentication.mixins import AuthMixin from common.utils import get_logger from ... import forms from ...utils import ( diff --git a/apps/users/views/profile/reset.py b/apps/users/views/profile/reset.py index 2972225ef..b8e18a647 100644 --- a/apps/users/views/profile/reset.py +++ b/apps/users/views/profile/reset.py @@ -2,16 +2,16 @@ from __future__ import unicode_literals -from common.utils import FlashMessageUtil, get_object_or_none, random_string -from common.utils.verify_code import SendAndVerifyCodeUtil from django.conf import settings from django.core.cache import cache from django.shortcuts import redirect, reverse from django.urls import reverse_lazy -from django.utils.translation import ugettext as _ +from django.utils.translation import gettext as _ from django.views.generic import FormView, RedirectView -from users.notifications import ResetPasswordSuccessMsg +from common.utils import FlashMessageUtil, get_object_or_none, random_string +from common.utils.verify_code import SendAndVerifyCodeUtil +from users.notifications import ResetPasswordSuccessMsg from ... import forms from ...models import User from ...utils import check_password_rules, get_password_check_rules diff --git a/requirements/requirements.txt b/requirements/requirements.txt index da47a1c31..71c08477c 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -1,137 +1,136 @@ # 临时解决 cython 3.0 造成的错误 -cython==0.29.36 -aiofiles==22.1.0 -amqp==5.0.9 -git+https://github.com/jumpserver/ansible@master#egg=ansible-core +cython==3.0.0 +aiofiles==23.1.0 +amqp==5.1.1 +#git+https://github.com/jumpserver/ansible@master#egg=ansible-core ansible==7.1.0 -ansible-runner==2.2.1 -asn1crypto==0.24.0 +ansible-runner==2.3.3 +asn1crypto==1.5.1 bcrypt==4.0.1 -billiard==3.6.4.0 -certifi==2022.12.7 +billiard==4.1.0 +certifi==2023.7.22 cffi==1.15.1 -chardet==3.0.4 -configparser==3.5.0 -decorator==4.1.2 -docutils==0.14 -ecdsa==0.13.3 -enum-compat==0.0.2 +chardet==5.1.0 +configparser==6.0.0 +decorator==5.1.1 +docutils==0.20.1 +ecdsa==0.18.0 +enum-compat==0.0.3 ephem==4.1.4 -future==0.16.0 -idna==2.8 +future==0.18.3 +idna==3.4 itypes==1.2.0 Jinja2==3.1.2 -jmespath==1.0.1 -MarkupSafe==2.1.1 +#jmespath==0.9.3 +MarkupSafe==2.1.3 olefile==0.46 -paramiko==2.11.0 +paramiko==3.2.0 passlib==1.7.4 -pyasn1==0.4.8 +pyasn1==0.5.0 pycparser==2.21 -cryptography==38.0.4 +cryptography==41.0.2 pycryptodome==3.18.0 pycryptodomex==3.18.0 -phonenumbers==8.13.8 -gmssl==3.2.1 +phonenumbers==8.13.17 +gmssl==3.2.2 itsdangerous==1.1.0 -pyotp==2.6.0 +pyotp==2.8.0 PyNaCl==1.5.0 python-dateutil==2.8.2 PyYAML==6.0.1 requests==2.31.0 -jms-storage==0.0.47 -simplejson==3.17.6 +jms-storage==0.0.49 +simplejson==3.19.1 six==1.16.0 sshtunnel==0.4.0 sshpubkeys==3.3.1 uritemplate==4.1.1 -urllib3==1.26.9 +urllib3==1.26.16 vine==5.0.0 -Werkzeug==2.1.2 +Werkzeug==2.3.6 unicodecsv==0.14.1 httpsig==1.3.0 -treelib==1.6.1 -psutil==5.9.1 +treelib==1.6.4 +psutil==5.9.5 msrestazure==0.6.4 -adal==1.2.5 +adal==1.2.7 openpyxl==3.0.10 pyexcel==0.7.0 pyexcel-xlsx==0.6.0 data-tree==0.0.1 -pyvmomi==7.0.1 -termcolor==1.1.0 +pyvmomi==8.0.1.0.2 +termcolor==2.3.0 html2text==2020.1.16 -pyzipper==0.3.5 +pyzipper==0.3.6 python3-saml==1.15.0 -websocket-client==1.2.3 +websocket-client==1.6.1 pyjwkest==1.4.2 jsonfield2==4.0.0.post0 -geoip2==4.5.0 +geoip2==4.7.0 ipip-ipdb==1.6.1 pywinrm==0.4.3 # Django environment -Django==3.2.20 -django-bootstrap3==14.2.0 -django-filter==2.4.0 -django-formtools==2.2 +Django==4.2.3 +django-bootstrap3==23.4 +django-filter==23.2 +django-formtools==2.4.1 django-ranged-response==0.2.0 django-rest-swagger==2.2.0 -django-simple-captcha==0.5.17 -django-timezone-field==5.0 -djangorestframework==3.13.1 +django-simple-captcha==0.5.18 +django-timezone-field==5.1 +djangorestframework==3.14.0 djangorestframework-bulk==0.2.1 -django-simple-history==3.1.1 -django-private-storage==3.0 +django-simple-history==3.3.0 +django-private-storage==3.1 drf-nested-routers==0.93.4 -drf-writable-nested==0.6.4 +drf-writable-nested==0.7.0 rest_condition==1.0.3 -drf-yasg==1.20.0 +drf-yasg==1.21.7 coreapi==2.3.3 coreschema==0.0.4 openapi-codec==1.3.2 -Pillow==9.3.0 -pytz==2022.1 +Pillow==10.0.0 +pytz==2023.3 # Runtime -django-proxy==1.2.1 -channels-redis==4.0.0 -python-daemon==2.3.0 -eventlet==0.33.1 +django-proxy==1.2.2 +channels-redis==4.1.0 +python-daemon==3.0.1 +eventlet==0.33.3 greenlet==2.0.2 -gunicorn==20.1.0 -celery==5.2.7 -flower==1.2.0 -django-celery-beat==2.3.0 -kombu==5.2.4 -uvicorn==0.20.0 -websockets==10.4 +gunicorn==21.2.0 +celery==5.3.1 +flower==2.0.0 +django-celery-beat==2.5.0 +kombu==5.3.1 +uvicorn==0.23.1 +websockets==11.0.3 # Auth -python-ldap==3.4.0 +python-ldap==3.4.3 ldap3==2.9.1 #django-radius==1.5.0 -git+https://github.com/robgolding/django-radius@develop#egg=django-radius -jumpserver-django-oidc-rp==0.3.7.8 -django-cas-ng==4.0.1 -python-cas==1.5.0 -django-auth-ldap==2.2.0 +#git+https://github.com/robgolding/django-radius@develop#egg=django-radius +django-cas-ng==4.3.0 +python-cas==1.6.0 +django-auth-ldap==4.4.0 # Cloud req -boto3==1.24.12 -botocore==1.27.12 -s3transfer==0.6.0 -kubernetes==21.7.0 +boto3==1.28.9 +botocore==1.31.9 +s3transfer==0.6.1 +kubernetes==27.2.0 # DB requirements mysqlclient==2.2.0 -PyMySQL==1.0.2 +PyMySQL==1.1.0 pymssql==2.2.7 -django-mysql==3.9.0 -django-redis==5.2.0 -python-redis-lock==3.7.0 -pyOpenSSL==22.0.0 -redis==4.5.4 -pyOpenSSL==22.0.0 -pymongo==4.2.0 +django-mysql==4.11.0 +django-redis==5.3.0 +python-redis-lock==4.0.0 +pyOpenSSL==23.2.0 +redis==4.6.0 +pyOpenSSL==23.2.0 +pymongo==4.4.1 pyfreerdp==0.0.1 # Debug -ipython==8.10.0 +ipython==8.14.0 ForgeryPy3==0.3.1 -django-debug-toolbar==3.5 +django-debug-toolbar==4.1.0 Pympler==1.0.1 From 7ae52eb941471c9639924bdc719777322367a050 Mon Sep 17 00:00:00 2001 From: ibuler Date: Mon, 24 Jul 2023 14:09:22 +0800 Subject: [PATCH 011/177] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=20gettext?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/accounts/apps.py | 5 ++--- apps/assets/apps.py | 2 ++ apps/audits/apps.py | 3 ++- apps/authentication/apps.py | 3 +++ apps/authentication/signal_handlers.py | 4 +++- apps/common/apps.py | 5 +++-- apps/common/utils/timezone.py | 6 ++++-- apps/jumpserver/routing.py | 12 +++++++++--- apps/jumpserver/settings/base.py | 3 ++- apps/notifications/apps.py | 2 ++ apps/ops/apps.py | 10 +++++----- apps/orgs/apps.py | 4 +++- apps/perms/apps.py | 3 +++ apps/rbac/apps.py | 1 + apps/settings/apps.py | 3 ++- apps/terminal/apps.py | 8 ++++---- apps/tickets/apps.py | 2 ++ apps/users/apps.py | 3 +++ requirements/mac_pkg.sh | 1 + requirements/requirements.txt | 4 ++-- 20 files changed, 58 insertions(+), 26 deletions(-) diff --git a/apps/accounts/apps.py b/apps/accounts/apps.py index 89ad972a9..56ca232f7 100644 --- a/apps/accounts/apps.py +++ b/apps/accounts/apps.py @@ -6,6 +6,5 @@ class AccountsConfig(AppConfig): name = 'accounts' def ready(self): - from . import signal_handlers - from . import tasks - __all__ = signal_handlers + from . import signal_handlers # noqa + from . import tasks # noqa diff --git a/apps/assets/apps.py b/apps/assets/apps.py index 2966894d6..9ebd7a93d 100644 --- a/apps/assets/apps.py +++ b/apps/assets/apps.py @@ -12,4 +12,6 @@ class AssetsConfig(AppConfig): super().__init__(*args, **kwargs) def ready(self): + from . import signal_handlers # noqa + from . import tasks # noqa super().ready() diff --git a/apps/audits/apps.py b/apps/audits/apps.py index 40de7ddaa..ddaa535a7 100644 --- a/apps/audits/apps.py +++ b/apps/audits/apps.py @@ -9,7 +9,8 @@ class AuditsConfig(AppConfig): verbose_name = _('Audits') def ready(self): - from . import signal_handlers + from . import signal_handlers # noqa + from . import tasks # noqa if settings.SYSLOG_ENABLE: post_save.connect(signal_handlers.on_audits_log_create) diff --git a/apps/authentication/apps.py b/apps/authentication/apps.py index 4ee3ffce0..5a1c1966a 100644 --- a/apps/authentication/apps.py +++ b/apps/authentication/apps.py @@ -7,4 +7,7 @@ class AuthenticationConfig(AppConfig): verbose_name = _('Authentication') def ready(self): + from . import signal_handlers # noqa + from . import tasks # noqa + from . import notifications # noqa super().ready() diff --git a/apps/authentication/signal_handlers.py b/apps/authentication/signal_handlers.py index b1f55f689..e9de006fe 100644 --- a/apps/authentication/signal_handlers.py +++ b/apps/authentication/signal_handlers.py @@ -10,7 +10,6 @@ from apps.jumpserver.settings.auth import AUTHENTICATION_BACKENDS_THIRD_PARTY from .signals import post_auth_success, post_auth_failed, user_auth_failed, user_auth_success -@receiver(user_logged_in) def on_user_auth_login_success(sender, user, request, **kwargs): # 失效 perms 缓存 user.expire_rbac_perms_cache() @@ -52,3 +51,6 @@ def on_user_login_success(sender, request, user, backend, create=False, **kwargs def on_user_login_failed(sender, username, request, reason, backend, **kwargs): request.session['auth_backend'] = backend post_auth_failed.send(sender, username=username, request=request, reason=reason) + + +user_logged_in.connect(on_user_auth_login_success) diff --git a/apps/common/apps.py b/apps/common/apps.py index 89e735a09..5fb85992a 100644 --- a/apps/common/apps.py +++ b/apps/common/apps.py @@ -1,6 +1,7 @@ from __future__ import unicode_literals import sys + from django.apps import AppConfig @@ -8,8 +9,8 @@ class CommonConfig(AppConfig): name = 'common' def ready(self): - from . import signal_handlers - from . import tasks + from . import signal_handlers # noqa + from . import tasks # noqa from .signals import django_ready excludes = ['migrate', 'compilemessages', 'makemigrations'] for i in excludes: diff --git a/apps/common/utils/timezone.py b/apps/common/utils/timezone.py index 17e44b7bf..b7dfd595f 100644 --- a/apps/common/utils/timezone.py +++ b/apps/common/utils/timezone.py @@ -1,5 +1,6 @@ -import pytz from datetime import datetime, timedelta, timezone + +import pytz from django.utils import timezone as dj_timezone from rest_framework.fields import DateTimeField @@ -8,6 +9,7 @@ max = datetime.max.replace(tzinfo=timezone.utc) def astimezone(dt: datetime, tzinfo: pytz.tzinfo.DstTzInfo): assert dj_timezone.is_aware(dt) + print("dt.tzinfo: ", tzinfo, type(tzinfo)) return tzinfo.normalize(dt.astimezone(tzinfo)) @@ -16,7 +18,7 @@ def as_china_cst(dt: datetime): def as_current_tz(dt: datetime): - return astimezone(dt, dj_timezone.get_current_timezone()) + return dt.astimezone(dj_timezone.get_current_timezone()) def utc_now(): diff --git a/apps/jumpserver/routing.py b/apps/jumpserver/routing.py index 965a2b71b..ee3885b9e 100644 --- a/apps/jumpserver/routing.py +++ b/apps/jumpserver/routing.py @@ -1,12 +1,12 @@ from channels.auth import AuthMiddlewareStack from channels.routing import ProtocolTypeRouter, URLRouter +from channels.security.websocket import AllowedHostsOriginValidator from django.core.asgi import get_asgi_application -from ops.urls.ws_urls import urlpatterns as ops_urlpatterns from notifications.urls.ws_urls import urlpatterns as notifications_urlpatterns +from ops.urls.ws_urls import urlpatterns as ops_urlpatterns from settings.urls.ws_urls import urlpatterns as setting_urlpatterns from terminal.urls.ws_urls import urlpatterns as terminal_urlpatterns - from .middleware import WsSignatureAuthMiddleware urlpatterns = [] @@ -16,6 +16,12 @@ urlpatterns += ops_urlpatterns + \ terminal_urlpatterns application = ProtocolTypeRouter({ - 'websocket': WsSignatureAuthMiddleware(AuthMiddlewareStack(URLRouter(urlpatterns))), "http": get_asgi_application(), + 'websocket': AllowedHostsOriginValidator( + WsSignatureAuthMiddleware( + AuthMiddlewareStack( + URLRouter(urlpatterns) + ) + ) + ), }) diff --git a/apps/jumpserver/settings/base.py b/apps/jumpserver/settings/base.py index 9d60aa9a9..e70156b3b 100644 --- a/apps/jumpserver/settings/base.py +++ b/apps/jumpserver/settings/base.py @@ -66,7 +66,8 @@ APPLET_DOWNLOAD_HOST = CONFIG.APPLET_DOWNLOAD_HOST SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https') # https://docs.djangoproject.com/en/4.1/ref/settings/#std-setting-CSRF_TRUSTED_ORIGINS -CSRF_TRUSTED_ORIGINS = CONFIG.CSRF_TRUSTED_ORIGINS.split(',') if CONFIG.CSRF_TRUSTED_ORIGINS else [] +CSRF_TRUSTED_ORIGINS = CONFIG.CSRF_TRUSTED_ORIGINS.split(',') if CONFIG.CSRF_TRUSTED_ORIGINS \ + else ['https://*', 'https://.*', 'http://localhost:9528'] # LOG LEVEL LOG_LEVEL = CONFIG.LOG_LEVEL diff --git a/apps/notifications/apps.py b/apps/notifications/apps.py index 6147197c9..07ce8ff48 100644 --- a/apps/notifications/apps.py +++ b/apps/notifications/apps.py @@ -7,4 +7,6 @@ class NotificationsConfig(AppConfig): verbose_name = _('Notifications') def ready(self): + from . import signal_handlers # noqa + from . import notifications # noqa super().ready() diff --git a/apps/ops/apps.py b/apps/ops/apps.py index 7956a5dc1..a29a03749 100644 --- a/apps/ops/apps.py +++ b/apps/ops/apps.py @@ -1,7 +1,7 @@ from __future__ import unicode_literals -from django.utils.translation import gettext_lazy as _ from django.apps import AppConfig +from django.utils.translation import gettext_lazy as _ class OpsConfig(AppConfig): @@ -12,8 +12,8 @@ class OpsConfig(AppConfig): from orgs.models import Organization from orgs.utils import set_current_org set_current_org(Organization.root()) - from .celery import signal_handler - from . import signal_handlers - from . import notifications - from . import tasks + from .celery import signal_handler # noqa + from . import signal_handlers # noqa + from . import notifications # noqa + from . import tasks # noqa super().ready() diff --git a/apps/orgs/apps.py b/apps/orgs/apps.py index c835af0a5..150f346ec 100644 --- a/apps/orgs/apps.py +++ b/apps/orgs/apps.py @@ -7,4 +7,6 @@ class OrgsConfig(AppConfig): verbose_name = _('App organizations') def ready(self): - pass + from . import signal_handlers # noqa + from . import tasks # noqa + super().ready() diff --git a/apps/perms/apps.py b/apps/perms/apps.py index c0f2aba38..ee9e9c0e3 100644 --- a/apps/perms/apps.py +++ b/apps/perms/apps.py @@ -9,4 +9,7 @@ class PermsConfig(AppConfig): verbose_name = _('App permissions') def ready(self): + from . import signal_handlers # noqa + from . import tasks # noqa + from . import notifications # noqa super().ready() diff --git a/apps/rbac/apps.py b/apps/rbac/apps.py index 646521870..e233185d5 100644 --- a/apps/rbac/apps.py +++ b/apps/rbac/apps.py @@ -7,4 +7,5 @@ class RBACConfig(AppConfig): verbose_name = _('RBAC') def ready(self): + from . import signal_handlers # noqa super().ready() diff --git a/apps/settings/apps.py b/apps/settings/apps.py index b96893da1..e18608331 100644 --- a/apps/settings/apps.py +++ b/apps/settings/apps.py @@ -7,4 +7,5 @@ class SettingsConfig(AppConfig): verbose_name = _('Settings') def ready(self): - pass + from . import signal_handlers # noqa + from . import tasks # noqa diff --git a/apps/terminal/apps.py b/apps/terminal/apps.py index d383d01cd..b1b9538d3 100644 --- a/apps/terminal/apps.py +++ b/apps/terminal/apps.py @@ -1,7 +1,7 @@ from __future__ import unicode_literals -from django.utils.translation import gettext_lazy as _ from django.apps import AppConfig +from django.utils.translation import gettext_lazy as _ class TerminalConfig(AppConfig): @@ -9,7 +9,7 @@ class TerminalConfig(AppConfig): verbose_name = _('Terminals') def ready(self): - from . import signal_handlers - from . import notifications - from . import tasks + from . import signal_handlers # noqa + from . import notifications # noqa + from . import tasks # noqa return super().ready() diff --git a/apps/tickets/apps.py b/apps/tickets/apps.py index 563bb9048..49f818b7e 100644 --- a/apps/tickets/apps.py +++ b/apps/tickets/apps.py @@ -7,4 +7,6 @@ class TicketsConfig(AppConfig): verbose_name = _('Tickets') def ready(self): + from . import signal_handlers # noqa + from . import notifications # noqa return super().ready() diff --git a/apps/users/apps.py b/apps/users/apps.py index 9c00a68f9..f5aa7e269 100644 --- a/apps/users/apps.py +++ b/apps/users/apps.py @@ -9,4 +9,7 @@ class UsersConfig(AppConfig): verbose_name = _('Users') def ready(self): + from . import signal_handlers # noqa + from . import tasks # noqa + from . import notifications # noqa super().ready() diff --git a/requirements/mac_pkg.sh b/requirements/mac_pkg.sh index f78bad908..05033572a 100644 --- a/requirements/mac_pkg.sh +++ b/requirements/mac_pkg.sh @@ -6,6 +6,7 @@ echo "1. 安装依赖" brew install libtiff libjpeg webp little-cms2 openssl gettext git \ git-lfs libxml2 libxmlsec1 pkg-config postgresql freetds openssl \ libffi freerdp +pip install daphne channels channel-redis echo "2. 下载 IP 数据库" ip_db_path="${PROJECT_DIR}/apps/common/utils/geoip/GeoLite2-City.mmdb" diff --git a/requirements/requirements.txt b/requirements/requirements.txt index 71c08477c..8bbcbff77 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -2,7 +2,7 @@ cython==3.0.0 aiofiles==23.1.0 amqp==5.1.1 -#git+https://github.com/jumpserver/ansible@master#egg=ansible-core +git+https://github.com/jumpserver/ansible@master#egg=ansible-core ansible==7.1.0 ansible-runner==2.3.3 asn1crypto==1.5.1 @@ -108,7 +108,7 @@ websockets==11.0.3 python-ldap==3.4.3 ldap3==2.9.1 #django-radius==1.5.0 -#git+https://github.com/robgolding/django-radius@develop#egg=django-radius +git+https://github.com/robgolding/django-radius@develop#egg=django-radius django-cas-ng==4.3.0 python-cas==1.6.0 django-auth-ldap==4.4.0 From 86a17b9955fc09ba3ad1281e620179b65f7427bf Mon Sep 17 00:00:00 2001 From: ibuler Date: Mon, 24 Jul 2023 14:32:13 +0800 Subject: [PATCH 012/177] =?UTF-8?q?perf:=20=E6=94=AF=E6=8C=81=20ws?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/jumpserver/asgi.py | 22 ++++++++++++++++++---- apps/jumpserver/routing.py | 26 ++++---------------------- apps/jumpserver/settings/base.py | 3 +++ apps/jumpserver/settings/libs.py | 2 +- 4 files changed, 26 insertions(+), 27 deletions(-) diff --git a/apps/jumpserver/asgi.py b/apps/jumpserver/asgi.py index a71974685..428781225 100644 --- a/apps/jumpserver/asgi.py +++ b/apps/jumpserver/asgi.py @@ -1,7 +1,21 @@ import os -import django -from channels.routing import get_default_application + +from channels.auth import AuthMiddlewareStack +from channels.routing import ProtocolTypeRouter, URLRouter +from channels.security.websocket import AllowedHostsOriginValidator +from django.core.asgi import get_asgi_application + +from .routing import urlpatterns os.environ.setdefault("DJANGO_SETTINGS_MODULE", "jumpserver.settings") -django.setup() -application = get_default_application() +application = ProtocolTypeRouter({ + # Django's ASGI application to handle traditional HTTP requests + "http": get_asgi_application(), + + # WebSocket chat handler + "websocket": AllowedHostsOriginValidator( + AuthMiddlewareStack( + URLRouter(urlpatterns) + ) + ), +}) diff --git a/apps/jumpserver/routing.py b/apps/jumpserver/routing.py index ee3885b9e..c89da7f39 100644 --- a/apps/jumpserver/routing.py +++ b/apps/jumpserver/routing.py @@ -1,27 +1,9 @@ -from channels.auth import AuthMiddlewareStack -from channels.routing import ProtocolTypeRouter, URLRouter -from channels.security.websocket import AllowedHostsOriginValidator -from django.core.asgi import get_asgi_application - from notifications.urls.ws_urls import urlpatterns as notifications_urlpatterns from ops.urls.ws_urls import urlpatterns as ops_urlpatterns from settings.urls.ws_urls import urlpatterns as setting_urlpatterns from terminal.urls.ws_urls import urlpatterns as terminal_urlpatterns -from .middleware import WsSignatureAuthMiddleware -urlpatterns = [] -urlpatterns += ops_urlpatterns + \ - notifications_urlpatterns + \ - setting_urlpatterns + \ - terminal_urlpatterns - -application = ProtocolTypeRouter({ - "http": get_asgi_application(), - 'websocket': AllowedHostsOriginValidator( - WsSignatureAuthMiddleware( - AuthMiddlewareStack( - URLRouter(urlpatterns) - ) - ) - ), -}) +urlpatterns = ops_urlpatterns + \ + notifications_urlpatterns + \ + setting_urlpatterns + \ + terminal_urlpatterns diff --git a/apps/jumpserver/settings/base.py b/apps/jumpserver/settings/base.py index e70156b3b..179fe77af 100644 --- a/apps/jumpserver/settings/base.py +++ b/apps/jumpserver/settings/base.py @@ -142,6 +142,9 @@ MIDDLEWARE = [ 'jumpserver.middleware.EndMiddleware', ] +if DEBUG or DEBUG_DEV: + INSTALLED_APPS.insert(0, 'daphne') + ROOT_URLCONF = 'jumpserver.urls' TEMPLATES = [ diff --git a/apps/jumpserver/settings/libs.py b/apps/jumpserver/settings/libs.py index 0c35ba322..8fe71f343 100644 --- a/apps/jumpserver/settings/libs.py +++ b/apps/jumpserver/settings/libs.py @@ -127,7 +127,7 @@ CHANNEL_LAYERS = { }, } -ASGI_APPLICATION = 'jumpserver.routing.application' +ASGI_APPLICATION = 'jumpserver.asgi.application' # Dump all celery log to here CELERY_LOG_DIR = os.path.join(PROJECT_DIR, 'data', 'celery') From 95e92a45d51a97a530bc62b3a0c704b18cc66881 Mon Sep 17 00:00:00 2001 From: ibuler Date: Mon, 24 Jul 2023 14:46:48 +0800 Subject: [PATCH 013/177] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=20xpack=20re?= =?UTF-8?q?quirements?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- requirements/requirements_xpack.txt | 38 ++++++++++++++--------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/requirements/requirements_xpack.txt b/requirements/requirements_xpack.txt index 8f1930fad..0c62395e7 100644 --- a/requirements/requirements_xpack.txt +++ b/requirements/requirements_xpack.txt @@ -1,26 +1,26 @@ # Cloud req -qingcloud-sdk==1.2.12 -azure-mgmt-subscription==1.0.0 -azure-identity==1.5.0 -azure-mgmt-compute==4.6.2 -azure-mgmt-network==2.7.0 -google-cloud-compute==0.5.0 -grpcio==1.54.2 -alibabacloud_dysmsapi20170525==2.0.2 +qingcloud-sdk==1.2.15 +azure-mgmt-subscription==3.1.1 +azure-identity==1.13.0 +azure-mgmt-compute==30.0.0 +azure-mgmt-network==23.1.0 +google-cloud-compute==1.13.0 +grpcio==1.56.2 +alibabacloud_dysmsapi20170525==2.0.24 python-novaclient==11.0.1 -python-keystoneclient==4.3.0 -bce-python-sdk==0.8.64 -tencentcloud-sdk-python==3.0.662 -aliyun-python-sdk-core-v3==2.9.1 -aliyun-python-sdk-ecs==4.10.1 -huaweicloud-sdk-python==1.0.21 +python-keystoneclient==5.1.0 +bce-python-sdk==0.8.87 +tencentcloud-sdk-python==3.0.941 +aliyun-python-sdk-core-v3==2.13.33 +aliyun-python-sdk-ecs==4.24.64 +huaweicloud-sdk-python==1.0.28 # python-keystoneclient need keystoneauth1>=3.4.0 # huaweicloud-sdk-python need keystoneauth1<=3.4.0 keystoneauth1==3.4.0 # DB requirements -oracledb==1.0.1 -psycopg2-binary==2.9.1 -pymssql==2.2.5 +oracledb==1.3.2 +psycopg2-binary==2.9.6 +pymssql==2.2.7 IPy==1.1 -psycopg2==2.9.4 -ucloud-sdk-python3==0.11.47 +psycopg2==2.9.6 +ucloud-sdk-python3==0.11.50 From e3aaba479855a78976b3608dac3485728ea1c564 Mon Sep 17 00:00:00 2001 From: ibuler Date: Mon, 24 Jul 2023 14:57:49 +0800 Subject: [PATCH 014/177] =?UTF-8?q?perf:=20=E5=8E=BB=E6=8E=89=E4=B8=8D?= =?UTF-8?q?=E7=94=A8=E7=9A=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/applications/migrations/0006_application.py | 1 - apps/authentication/signal_handlers.py | 4 +--- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/apps/applications/migrations/0006_application.py b/apps/applications/migrations/0006_application.py index 0333b860d..423e9468a 100644 --- a/apps/applications/migrations/0006_application.py +++ b/apps/applications/migrations/0006_application.py @@ -2,7 +2,6 @@ from django.db import migrations, models import django.db.models.deletion -import django_mysql.models import uuid diff --git a/apps/authentication/signal_handlers.py b/apps/authentication/signal_handlers.py index e9de006fe..b1f55f689 100644 --- a/apps/authentication/signal_handlers.py +++ b/apps/authentication/signal_handlers.py @@ -10,6 +10,7 @@ from apps.jumpserver.settings.auth import AUTHENTICATION_BACKENDS_THIRD_PARTY from .signals import post_auth_success, post_auth_failed, user_auth_failed, user_auth_success +@receiver(user_logged_in) def on_user_auth_login_success(sender, user, request, **kwargs): # 失效 perms 缓存 user.expire_rbac_perms_cache() @@ -51,6 +52,3 @@ def on_user_login_success(sender, request, user, backend, create=False, **kwargs def on_user_login_failed(sender, username, request, reason, backend, **kwargs): request.session['auth_backend'] = backend post_auth_failed.send(sender, username=username, request=request, reason=reason) - - -user_logged_in.connect(on_user_auth_login_success) From d8d487f770c65da67267b3c7128a9e347169d9ab Mon Sep 17 00:00:00 2001 From: ibuler Date: Mon, 24 Jul 2023 15:32:30 +0800 Subject: [PATCH 015/177] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=20ALLOW=5FHO?= =?UTF-8?q?STS?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/common/utils/encode.py | 2 +- apps/common/utils/timezone.py | 15 +-------------- apps/jumpserver/asgi.py | 4 ++-- apps/jumpserver/conf.py | 1 + apps/jumpserver/settings/base.py | 18 +++++++++++++----- 5 files changed, 18 insertions(+), 22 deletions(-) diff --git a/apps/common/utils/encode.py b/apps/common/utils/encode.py index 6f1fc079e..767645c88 100644 --- a/apps/common/utils/encode.py +++ b/apps/common/utils/encode.py @@ -45,7 +45,7 @@ class Signer(metaclass=Singleton): def sign(self, value): s = JSONWebSignatureSerializer(self.secret_key, algorithm_name='HS256') - return self.json_serializer.dumps(value).decode() + return s.dumps(value).decode() def unsign(self, value): if value is None: diff --git a/apps/common/utils/timezone.py b/apps/common/utils/timezone.py index b7dfd595f..a74ebe73a 100644 --- a/apps/common/utils/timezone.py +++ b/apps/common/utils/timezone.py @@ -1,21 +1,8 @@ -from datetime import datetime, timedelta, timezone +from datetime import datetime, timedelta -import pytz from django.utils import timezone as dj_timezone from rest_framework.fields import DateTimeField -max = datetime.max.replace(tzinfo=timezone.utc) - - -def astimezone(dt: datetime, tzinfo: pytz.tzinfo.DstTzInfo): - assert dj_timezone.is_aware(dt) - print("dt.tzinfo: ", tzinfo, type(tzinfo)) - return tzinfo.normalize(dt.astimezone(tzinfo)) - - -def as_china_cst(dt: datetime): - return astimezone(dt, pytz.timezone('Asia/Shanghai')) - def as_current_tz(dt: datetime): return dt.astimezone(dj_timezone.get_current_timezone()) diff --git a/apps/jumpserver/asgi.py b/apps/jumpserver/asgi.py index 428781225..dc7760efe 100644 --- a/apps/jumpserver/asgi.py +++ b/apps/jumpserver/asgi.py @@ -2,9 +2,9 @@ import os from channels.auth import AuthMiddlewareStack from channels.routing import ProtocolTypeRouter, URLRouter -from channels.security.websocket import AllowedHostsOriginValidator from django.core.asgi import get_asgi_application +from .middleware import WsSignatureAuthMiddleware from .routing import urlpatterns os.environ.setdefault("DJANGO_SETTINGS_MODULE", "jumpserver.settings") @@ -13,7 +13,7 @@ application = ProtocolTypeRouter({ "http": get_asgi_application(), # WebSocket chat handler - "websocket": AllowedHostsOriginValidator( + "websocket": WsSignatureAuthMiddleware( AuthMiddlewareStack( URLRouter(urlpatterns) ) diff --git a/apps/jumpserver/conf.py b/apps/jumpserver/conf.py index d9b15943f..711edf657 100644 --- a/apps/jumpserver/conf.py +++ b/apps/jumpserver/conf.py @@ -514,6 +514,7 @@ class Config(dict): 'TIME_ZONE': 'Asia/Shanghai', 'FORCE_SCRIPT_NAME': '', 'SESSION_COOKIE_SECURE': False, + 'ALLOWED_HOSTS': '', 'CSRF_COOKIE_SECURE': False, 'REFERER_CHECK_ENABLED': False, 'CSRF_TRUSTED_ORIGINS': '', diff --git a/apps/jumpserver/settings/base.py b/apps/jumpserver/settings/base.py index 179fe77af..551e4ae8a 100644 --- a/apps/jumpserver/settings/base.py +++ b/apps/jumpserver/settings/base.py @@ -65,14 +65,22 @@ APPLET_DOWNLOAD_HOST = CONFIG.APPLET_DOWNLOAD_HOST # https://docs.djangoproject.com/en/4.1/ref/settings/ SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https') -# https://docs.djangoproject.com/en/4.1/ref/settings/#std-setting-CSRF_TRUSTED_ORIGINS -CSRF_TRUSTED_ORIGINS = CONFIG.CSRF_TRUSTED_ORIGINS.split(',') if CONFIG.CSRF_TRUSTED_ORIGINS \ - else ['https://*', 'https://.*', 'http://localhost:9528'] - # LOG LEVEL LOG_LEVEL = CONFIG.LOG_LEVEL -ALLOWED_HOSTS = ['*'] +ALLOWED_HOSTS = CONFIG.ALLOWED_HOSTS.split(',') if CONFIG.ALLOWED_HOSTS else ['localhost', '127.0.0.1'] + +# https://docs.djangoproject.com/en/4.1/ref/settings/#std-setting-CSRF_TRUSTED_ORIGINS +CSRF_TRUSTED_ORIGINS = [] +for origin in ALLOWED_HOSTS: + # 避免错误 先判断一下吧 + if origin.startswith('http'): + CSRF_TRUSTED_ORIGINS.append(origin) + continue + if origin.startswith('.'): + origin = '*.' + for schema in ['https', 'http']: + CSRF_TRUSTED_ORIGINS.append('{}://{}'.format(schema, origin)) # Max post update field num DATA_UPLOAD_MAX_NUMBER_FIELDS = 10000 From 38e8e8734d79d1ed8609476db51b9f8b40afd9df Mon Sep 17 00:00:00 2001 From: ibuler Date: Mon, 24 Jul 2023 17:49:32 +0800 Subject: [PATCH 016/177] =?UTF-8?q?perf:=20=E6=B7=BB=E5=8A=A0=20DEBUG=20?= =?UTF-8?q?=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/jumpserver/conf.py | 3 +-- apps/jumpserver/settings/base.py | 37 +++++++++++++++++++++-------- requirements/requirements_xpack.txt | 8 +++---- 3 files changed, 31 insertions(+), 17 deletions(-) diff --git a/apps/jumpserver/conf.py b/apps/jumpserver/conf.py index 711edf657..1de30cd86 100644 --- a/apps/jumpserver/conf.py +++ b/apps/jumpserver/conf.py @@ -514,10 +514,9 @@ class Config(dict): 'TIME_ZONE': 'Asia/Shanghai', 'FORCE_SCRIPT_NAME': '', 'SESSION_COOKIE_SECURE': False, - 'ALLOWED_HOSTS': '', + 'TRUST_SITES': '', 'CSRF_COOKIE_SECURE': False, 'REFERER_CHECK_ENABLED': False, - 'CSRF_TRUSTED_ORIGINS': '', 'SESSION_ENGINE': 'cache', 'SESSION_SAVE_EVERY_REQUEST': True, 'SESSION_EXPIRE_AT_BROWSER_CLOSE_FORCE': False, diff --git a/apps/jumpserver/settings/base.py b/apps/jumpserver/settings/base.py index 551e4ae8a..fc3ba19ad 100644 --- a/apps/jumpserver/settings/base.py +++ b/apps/jumpserver/settings/base.py @@ -67,21 +67,38 @@ SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https') # LOG LEVEL LOG_LEVEL = CONFIG.LOG_LEVEL +DOMAINS = CONFIG.DOMAINS or CONFIG.SITE_URL +ALLOWED_DOMAINS = DOMAINS.split(',') if DOMAINS else ['localhost:8080'] +ALLOWED_DOMAINS = [host.strip() for host in ALLOWED_DOMAINS] +ALLOWED_DOMAINS = [host.replace('http://', '').replace('https://', '') for host in ALLOWED_DOMAINS if host] +ALLOWED_DOMAINS = [host.split('/')[0] for host in ALLOWED_DOMAINS if host] -ALLOWED_HOSTS = CONFIG.ALLOWED_HOSTS.split(',') if CONFIG.ALLOWED_HOSTS else ['localhost', '127.0.0.1'] +DEBUG_HOSTS = ['127.0.0.1', 'localhost'] +DEBUG_PORT = ['8080', '80', '443', '4200', '9528'] +if DEBUG: + for host in DEBUG_HOSTS: + for port in DEBUG_PORT: + ALLOWED_DOMAINS.append('{}:{}'.format(host, port)) + +ALLOWED_HOSTS = list(set(['.' + host.split(':')[0] for host in ALLOWED_DOMAINS])) + +print("ALLOWED_HOSTS: ", ALLOWED_HOSTS) # https://docs.djangoproject.com/en/4.1/ref/settings/#std-setting-CSRF_TRUSTED_ORIGINS CSRF_TRUSTED_ORIGINS = [] -for origin in ALLOWED_HOSTS: - # 避免错误 先判断一下吧 - if origin.startswith('http'): - CSRF_TRUSTED_ORIGINS.append(origin) - continue - if origin.startswith('.'): - origin = '*.' - for schema in ['https', 'http']: - CSRF_TRUSTED_ORIGINS.append('{}://{}'.format(schema, origin)) +for host in ALLOWED_DOMAINS: + host = host.strip('.') + if host.startswith('http'): + CSRF_TRUSTED_ORIGINS.append(host) + continue + for schema in ['https', 'http']: + # CSRF_TRUSTED_ORIGINS.append('{}://{}'.format(schema, host)) + CSRF_TRUSTED_ORIGINS.append('{}://*.{}'.format(schema, host)) + +print("CSRF_TRUSTED_ORIGINS: ") +for origin in CSRF_TRUSTED_ORIGINS: + print(' - ' + origin) # Max post update field num DATA_UPLOAD_MAX_NUMBER_FIELDS = 10000 diff --git a/requirements/requirements_xpack.txt b/requirements/requirements_xpack.txt index 0c62395e7..f7644fb05 100644 --- a/requirements/requirements_xpack.txt +++ b/requirements/requirements_xpack.txt @@ -7,16 +7,14 @@ azure-mgmt-network==23.1.0 google-cloud-compute==1.13.0 grpcio==1.56.2 alibabacloud_dysmsapi20170525==2.0.24 -python-novaclient==11.0.1 +python-novaclient==18.3.0 python-keystoneclient==5.1.0 bce-python-sdk==0.8.87 tencentcloud-sdk-python==3.0.941 aliyun-python-sdk-core-v3==2.13.33 aliyun-python-sdk-ecs==4.24.64 -huaweicloud-sdk-python==1.0.28 -# python-keystoneclient need keystoneauth1>=3.4.0 -# huaweicloud-sdk-python need keystoneauth1<=3.4.0 -keystoneauth1==3.4.0 +#huaweicloud-sdk-python==1.0.28 +keystoneauth1==5.2.1 # DB requirements oracledb==1.3.2 psycopg2-binary==2.9.6 From 148bf3b89472eabb19fa7c57e56a19305e34e25b Mon Sep 17 00:00:00 2001 From: ibuler Date: Mon, 24 Jul 2023 17:55:17 +0800 Subject: [PATCH 017/177] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=E5=86=99?= =?UTF-8?q?=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/jumpserver/settings/base.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/apps/jumpserver/settings/base.py b/apps/jumpserver/settings/base.py index fc3ba19ad..4a89e4234 100644 --- a/apps/jumpserver/settings/base.py +++ b/apps/jumpserver/settings/base.py @@ -76,12 +76,10 @@ ALLOWED_DOMAINS = [host.split('/')[0] for host in ALLOWED_DOMAINS if host] DEBUG_HOSTS = ['127.0.0.1', 'localhost'] DEBUG_PORT = ['8080', '80', '443', '4200', '9528'] if DEBUG: - for host in DEBUG_HOSTS: - for port in DEBUG_PORT: - ALLOWED_DOMAINS.append('{}:{}'.format(host, port)) + DEBUG_HOST_PORTS = ['{}:{}'.format(host, port) for host in DEBUG_HOSTS for port in DEBUG_PORT] + ALLOWED_DOMAINS.extend(DEBUG_HOST_PORTS) ALLOWED_HOSTS = list(set(['.' + host.split(':')[0] for host in ALLOWED_DOMAINS])) - print("ALLOWED_HOSTS: ", ALLOWED_HOSTS) # https://docs.djangoproject.com/en/4.1/ref/settings/#std-setting-CSRF_TRUSTED_ORIGINS From 7af769f7d36ecd9a928c811a5b55012a69b67ec7 Mon Sep 17 00:00:00 2001 From: ibuler Date: Mon, 24 Jul 2023 18:05:28 +0800 Subject: [PATCH 018/177] =?UTF-8?q?perf:=20es=20=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E5=AF=BC=E5=85=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/common/plugins/es.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/apps/common/plugins/es.py b/apps/common/plugins/es.py index a5e027c90..06b85cb00 100644 --- a/apps/common/plugins/es.py +++ b/apps/common/plugins/es.py @@ -2,8 +2,12 @@ # import datetime import inspect +import sys -from collections.abc import Iterable +if sys.version_info.major == 3 and sys.version_info.minor >= 10: + from collections.abc import Iterable +else: + from collections import Iterable from functools import reduce, partial from itertools import groupby from uuid import UUID @@ -19,7 +23,6 @@ from common.utils import get_logger from common.utils.timezone import local_now_date_display from common.exceptions import JMSException - logger = get_logger(__file__) From 98fd2094984a864505d76dd0e98c9e6e6794e978 Mon Sep 17 00:00:00 2001 From: ibuler Date: Mon, 24 Jul 2023 18:09:10 +0800 Subject: [PATCH 019/177] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=E4=B8=BA=20D?= =?UTF-8?q?omain?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/jumpserver/conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/jumpserver/conf.py b/apps/jumpserver/conf.py index 1de30cd86..067e3f7ee 100644 --- a/apps/jumpserver/conf.py +++ b/apps/jumpserver/conf.py @@ -514,7 +514,7 @@ class Config(dict): 'TIME_ZONE': 'Asia/Shanghai', 'FORCE_SCRIPT_NAME': '', 'SESSION_COOKIE_SECURE': False, - 'TRUST_SITES': '', + 'DOMAINS': '', 'CSRF_COOKIE_SECURE': False, 'REFERER_CHECK_ENABLED': False, 'SESSION_ENGINE': 'cache', From b443a89cb54804ef60181974ef858aa5b43e7507 Mon Sep 17 00:00:00 2001 From: ibuler Date: Mon, 24 Jul 2023 18:22:48 +0800 Subject: [PATCH 020/177] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=20Python=20?= =?UTF-8?q?=E7=9A=84=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index d8fd27492..7b71a8927 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM jumpserver/python:3.9-slim-buster as stage-build +FROM python:3.11.4-slim-bullseye as stage-build ARG TARGETARCH ARG VERSION @@ -8,7 +8,7 @@ WORKDIR /opt/jumpserver ADD . . RUN cd utils && bash -ixeu build.sh -FROM jumpserver/python:3.9-slim-buster +FROM python:3.11.4-slim-bullseye ARG TARGETARCH MAINTAINER JumpServer Team From 554c1da38bbff98e9fe0820e4bf5e8027994fb98 Mon Sep 17 00:00:00 2001 From: ibuler Date: Mon, 24 Jul 2023 19:30:27 +0800 Subject: [PATCH 021/177] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=E7=89=88?= =?UTF-8?q?=E6=9C=AC=E4=BB=A5=E6=9D=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- requirements/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/requirements.txt b/requirements/requirements.txt index 8bbcbff77..065a18fba 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -39,7 +39,7 @@ PyNaCl==1.5.0 python-dateutil==2.8.2 PyYAML==6.0.1 requests==2.31.0 -jms-storage==0.0.49 +jms-storage==0.0.50 simplejson==3.19.1 six==1.16.0 sshtunnel==0.4.0 From d5461fe66f936674c9f4e3c1161a6c5d6eeb515e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=90=B4=E5=B0=8F=E7=99=BD?= <296015668@qq.com> Date: Mon, 24 Jul 2023 21:09:02 +0800 Subject: [PATCH 022/177] =?UTF-8?q?perf:=20=E6=8B=86=E5=88=86=20loong64=20?= =?UTF-8?q?=E6=9E=B6=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/Dockerfile b/Dockerfile index 7b71a8927..992c9fca8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -83,21 +83,10 @@ WORKDIR /tmp/build COPY ./requirements ./requirements ARG PIP_MIRROR=https://pypi.douban.com/simple -ARG PIP_JMS_MIRROR=https://pypi.douban.com/simple RUN --mount=type=cache,target=/root/.cache/pip \ set -ex \ && pip config set global.index-url ${PIP_MIRROR} \ - && pip install --upgrade pip \ - && pip install --upgrade setuptools wheel \ - && \ - if [ "${TARGETARCH}" == "loong64" ]; then \ - pip install https://download.jumpserver.org/pypi/simple/cryptography/cryptography-38.0.4-cp39-cp39-linux_loongarch64.whl; \ - pip install https://download.jumpserver.org/pypi/simple/greenlet/greenlet-1.1.2-cp39-cp39-linux_loongarch64.whl; \ - pip install https://download.jumpserver.org/pypi/simple/PyNaCl/PyNaCl-1.5.0-cp39-cp39-linux_loongarch64.whl; \ - pip install https://download.jumpserver.org/pypi/simple/grpcio/grpcio-1.54.2-cp39-cp39-linux_loongarch64.whl; \ - fi \ - && pip install $(grep -E 'jms|jumpserver' requirements/requirements.txt) -i ${PIP_JMS_MIRROR} \ && pip install -r requirements/requirements.txt COPY --from=stage-build /opt/jumpserver/release/jumpserver /opt/jumpserver From 94d40efcada50a6fe5ed9ea1c92f2394b777c4e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=90=B4=E5=B0=8F=E7=99=BD?= <296015668@qq.com> Date: Mon, 24 Jul 2023 21:16:01 +0800 Subject: [PATCH 023/177] =?UTF-8?q?perf:=20=E9=A2=84=E6=9E=84=E5=BB=BA=20a?= =?UTF-8?q?nsible-core?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 2 ++ requirements/requirements.txt | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 992c9fca8..14756e408 100644 --- a/Dockerfile +++ b/Dockerfile @@ -82,11 +82,13 @@ RUN set -ex \ WORKDIR /tmp/build COPY ./requirements ./requirements +ARG ANSIBLE_CORE_VERSION=2.14.1 ARG PIP_MIRROR=https://pypi.douban.com/simple RUN --mount=type=cache,target=/root/.cache/pip \ set -ex \ && pip config set global.index-url ${PIP_MIRROR} \ + && pip install https://github.com/jumpserver/ansible/releases/download/v${ANSIBLE_CORE_VERSION}/ansible_core-${ANSIBLE_CORE_VERSION}-py3-none-any.whl \ && pip install -r requirements/requirements.txt COPY --from=stage-build /opt/jumpserver/release/jumpserver /opt/jumpserver diff --git a/requirements/requirements.txt b/requirements/requirements.txt index 065a18fba..30a5d66cf 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -2,7 +2,7 @@ cython==3.0.0 aiofiles==23.1.0 amqp==5.1.1 -git+https://github.com/jumpserver/ansible@master#egg=ansible-core +#git+https://github.com/jumpserver/ansible@master#egg=ansible-core ansible==7.1.0 ansible-runner==2.3.3 asn1crypto==1.5.1 From f1d984898b25341e4c6bedb09ea44cf190400348 Mon Sep 17 00:00:00 2001 From: ibuler Date: Mon, 24 Jul 2023 22:53:10 +0800 Subject: [PATCH 024/177] =?UTF-8?q?perf:=20=E5=8E=BB=E6=8E=89=E4=B8=8D?= =?UTF-8?q?=E7=94=A8=E7=9A=84=20app?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/jumpserver/settings/base.py | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/jumpserver/settings/base.py b/apps/jumpserver/settings/base.py index 4a89e4234..ba8429c19 100644 --- a/apps/jumpserver/settings/base.py +++ b/apps/jumpserver/settings/base.py @@ -118,7 +118,6 @@ INSTALLED_APPS = [ 'acls.apps.AclsConfig', 'notifications.apps.NotificationsConfig', 'rbac.apps.RBACConfig', - 'jms_oidc_rp', 'rest_framework', 'rest_framework_swagger', 'drf_yasg', From 089d769eb01bcd1f4870b66a6aaba9c45fad5967 Mon Sep 17 00:00:00 2001 From: ibuler Date: Mon, 24 Jul 2023 23:20:05 +0800 Subject: [PATCH 025/177] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=20asgi=20?= =?UTF-8?q?=E7=9A=84=E4=BD=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/jumpserver/asgi.py | 21 +++--------- apps/jumpserver/middleware.py | 36 -------------------- apps/jumpserver/routing.py | 57 ++++++++++++++++++++++++++++++++ apps/jumpserver/settings/libs.py | 5 +-- 4 files changed, 64 insertions(+), 55 deletions(-) diff --git a/apps/jumpserver/asgi.py b/apps/jumpserver/asgi.py index dc7760efe..c2db9fdf6 100644 --- a/apps/jumpserver/asgi.py +++ b/apps/jumpserver/asgi.py @@ -1,21 +1,8 @@ import os -from channels.auth import AuthMiddlewareStack -from channels.routing import ProtocolTypeRouter, URLRouter -from django.core.asgi import get_asgi_application - -from .middleware import WsSignatureAuthMiddleware -from .routing import urlpatterns +import django +from channels.routing import get_default_application os.environ.setdefault("DJANGO_SETTINGS_MODULE", "jumpserver.settings") -application = ProtocolTypeRouter({ - # Django's ASGI application to handle traditional HTTP requests - "http": get_asgi_application(), - - # WebSocket chat handler - "websocket": WsSignatureAuthMiddleware( - AuthMiddlewareStack( - URLRouter(urlpatterns) - ) - ), -}) +django.setup() +application = get_default_application() diff --git a/apps/jumpserver/middleware.py b/apps/jumpserver/middleware.py index a4738649f..9a49189c8 100644 --- a/apps/jumpserver/middleware.py +++ b/apps/jumpserver/middleware.py @@ -6,16 +6,12 @@ import re import time import pytz -from channels.db import database_sync_to_async from django.conf import settings from django.core.exceptions import MiddlewareNotUsed -from django.core.handlers.asgi import ASGIRequest from django.http.response import HttpResponseForbidden from django.shortcuts import HttpResponse from django.utils import timezone -from authentication.backends.drf import (SignatureAuthentication, - AccessTokenAuthentication) from .utils import set_current_request @@ -146,35 +142,3 @@ class EndMiddleware: response = self.get_response(request) request._e_time_end = time.time() return response - - -@database_sync_to_async -def get_signature_user(scope): - headers = dict(scope["headers"]) - if not headers.get(b'authorization'): - return - if scope['type'] == 'websocket': - scope['method'] = 'GET' - try: - # 因为 ws 使用的是 scope,所以需要转换成 request 对象,用于认证校验 - request = ASGIRequest(scope, None) - backends = [SignatureAuthentication(), - AccessTokenAuthentication()] - for backend in backends: - user, _ = backend.authenticate(request) - if user: - return user - except Exception as e: - print(e) - return None - - -class WsSignatureAuthMiddleware: - def __init__(self, app): - self.app = app - - async def __call__(self, scope, receive, send): - user = await get_signature_user(scope) - if user: - scope['user'] = user - return await self.app(scope, receive, send) diff --git a/apps/jumpserver/routing.py b/apps/jumpserver/routing.py index c89da7f39..68a28bb97 100644 --- a/apps/jumpserver/routing.py +++ b/apps/jumpserver/routing.py @@ -1,9 +1,66 @@ +from channels.auth import AuthMiddlewareStack +from channels.db import database_sync_to_async +from channels.routing import ProtocolTypeRouter, URLRouter +from django.core.asgi import get_asgi_application +from django.core.handlers.asgi import ASGIRequest + +from authentication.backends.drf import ( + SignatureAuthentication, + AccessTokenAuthentication +) from notifications.urls.ws_urls import urlpatterns as notifications_urlpatterns from ops.urls.ws_urls import urlpatterns as ops_urlpatterns from settings.urls.ws_urls import urlpatterns as setting_urlpatterns from terminal.urls.ws_urls import urlpatterns as terminal_urlpatterns +__all__ = ['urlpatterns'] + urlpatterns = ops_urlpatterns + \ notifications_urlpatterns + \ setting_urlpatterns + \ terminal_urlpatterns + + +@database_sync_to_async +def get_signature_user(scope): + headers = dict(scope["headers"]) + if not headers.get(b'authorization'): + return + if scope['type'] == 'websocket': + scope['method'] = 'GET' + try: + # 因为 ws 使用的是 scope,所以需要转换成 request 对象,用于认证校验 + request = ASGIRequest(scope, None) + backends = [SignatureAuthentication(), + AccessTokenAuthentication()] + for backend in backends: + user, _ = backend.authenticate(request) + if user: + return user + except Exception as e: + print(e) + return None + + +class WsSignatureAuthMiddleware: + def __init__(self, app): + self.app = app + + async def __call__(self, scope, receive, send): + user = await get_signature_user(scope) + if user: + scope['user'] = user + return await self.app(scope, receive, send) + + +application = ProtocolTypeRouter({ + # Django's ASGI application to handle traditional HTTP requests + "http": get_asgi_application(), + + # WebSocket chat handler + "websocket": WsSignatureAuthMiddleware( + AuthMiddlewareStack( + URLRouter(urlpatterns) + ) + ), +}) diff --git a/apps/jumpserver/settings/libs.py b/apps/jumpserver/settings/libs.py index 8fe71f343..3679320c4 100644 --- a/apps/jumpserver/settings/libs.py +++ b/apps/jumpserver/settings/libs.py @@ -116,7 +116,8 @@ else: host=CONFIG.REDIS_HOST, port=CONFIG.REDIS_PORT, db=CONFIG.REDIS_DB_WS ) REDIS_LAYERS_SSL_PARAMS.pop('ssl', None) - REDIS_LAYERS_HOST['address'] = '{}?{}'.format(REDIS_LAYERS_ADDRESS, urlencode(REDIS_LAYERS_SSL_PARAMS)) + REDIS_LAYERS_HOST['address'] = '{}?{}'.format(REDIS_LAYERS_ADDRESS, + urlencode(REDIS_LAYERS_SSL_PARAMS)) CHANNEL_LAYERS = { 'default': { @@ -127,7 +128,7 @@ CHANNEL_LAYERS = { }, } -ASGI_APPLICATION = 'jumpserver.asgi.application' +ASGI_APPLICATION = 'jumpserver.routing.application' # Dump all celery log to here CELERY_LOG_DIR = os.path.join(PROJECT_DIR, 'data', 'celery') From 160c99a01a614f8c20bdb2a289b8d77e37e3e087 Mon Sep 17 00:00:00 2001 From: ibuler Date: Mon, 24 Jul 2023 23:21:30 +0800 Subject: [PATCH 026/177] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=20requiremen?= =?UTF-8?q?ts?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- requirements/requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements/requirements.txt b/requirements/requirements.txt index 30a5d66cf..5823e72c2 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -103,6 +103,7 @@ flower==2.0.0 django-celery-beat==2.5.0 kombu==5.3.1 uvicorn==0.23.1 +uvicorn[standard]==0.22.0 websockets==11.0.3 # Auth python-ldap==3.4.3 From 5fedb5440ce6c20fe76756c927f7c46e2ea3401a Mon Sep 17 00:00:00 2001 From: ibuler Date: Mon, 24 Jul 2023 23:23:04 +0800 Subject: [PATCH 027/177] =?UTF-8?q?perf:=20=E8=AE=BE=E7=BD=AE=20applicatio?= =?UTF-8?q?n=20=E5=88=B0=20=5F=5Fall=5F=5F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/jumpserver/routing.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/jumpserver/routing.py b/apps/jumpserver/routing.py index 68a28bb97..a23e2978b 100644 --- a/apps/jumpserver/routing.py +++ b/apps/jumpserver/routing.py @@ -13,7 +13,7 @@ from ops.urls.ws_urls import urlpatterns as ops_urlpatterns from settings.urls.ws_urls import urlpatterns as setting_urlpatterns from terminal.urls.ws_urls import urlpatterns as terminal_urlpatterns -__all__ = ['urlpatterns'] +__all__ = ['urlpatterns', 'application'] urlpatterns = ops_urlpatterns + \ notifications_urlpatterns + \ From 366693783cbb8323abe2455ef4ec2331c908e366 Mon Sep 17 00:00:00 2001 From: ibuler Date: Mon, 24 Jul 2023 23:27:25 +0800 Subject: [PATCH 028/177] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=20uvicon=20?= =?UTF-8?q?=20=E7=9A=84=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- requirements/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/requirements.txt b/requirements/requirements.txt index 5823e72c2..2e233bba1 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -102,7 +102,7 @@ celery==5.3.1 flower==2.0.0 django-celery-beat==2.5.0 kombu==5.3.1 -uvicorn==0.23.1 +uvicorn==0.22.0 uvicorn[standard]==0.22.0 websockets==11.0.3 # Auth From 4d2c4a9602aad4c647e44a0c073a8f0eded74189 Mon Sep 17 00:00:00 2001 From: ibuler Date: Tue, 25 Jul 2023 10:11:57 +0800 Subject: [PATCH 029/177] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=20domains=20?= =?UTF-8?q?=E8=8E=B7=E5=8F=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/jumpserver/settings/base.py | 35 ++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/apps/jumpserver/settings/base.py b/apps/jumpserver/settings/base.py index ba8429c19..7498b1a33 100644 --- a/apps/jumpserver/settings/base.py +++ b/apps/jumpserver/settings/base.py @@ -67,32 +67,41 @@ SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https') # LOG LEVEL LOG_LEVEL = CONFIG.LOG_LEVEL -DOMAINS = CONFIG.DOMAINS or CONFIG.SITE_URL +DOMAINS = CONFIG.DOMAINS or 'localhost' +if os.environ.get('SERVER_NAME'): + DOMAINS += ',{}'.format(os.environ.get('SERVER_NAME')) +if CONFIG.SITE_URL: + DOMAINS += ',{}'.format(CONFIG.SITE_URL) + ALLOWED_DOMAINS = DOMAINS.split(',') if DOMAINS else ['localhost:8080'] ALLOWED_DOMAINS = [host.strip() for host in ALLOWED_DOMAINS] ALLOWED_DOMAINS = [host.replace('http://', '').replace('https://', '') for host in ALLOWED_DOMAINS if host] ALLOWED_DOMAINS = [host.split('/')[0] for host in ALLOWED_DOMAINS if host] -DEBUG_HOSTS = ['127.0.0.1', 'localhost'] -DEBUG_PORT = ['8080', '80', '443', '4200', '9528'] +DEBUG_HOSTS = ('127.0.0.1', 'localhost') +DEBUG_PORT = ['8080', '80', ] if DEBUG: - DEBUG_HOST_PORTS = ['{}:{}'.format(host, port) for host in DEBUG_HOSTS for port in DEBUG_PORT] - ALLOWED_DOMAINS.extend(DEBUG_HOST_PORTS) + DEBUG_PORT.extend(['4200', '9528']) +DEBUG_HOST_PORTS = ['{}:{}'.format(host, port) for host in DEBUG_HOSTS for port in DEBUG_PORT] +ALLOWED_DOMAINS.extend(DEBUG_HOST_PORTS) ALLOWED_HOSTS = list(set(['.' + host.split(':')[0] for host in ALLOWED_DOMAINS])) -print("ALLOWED_HOSTS: ", ALLOWED_HOSTS) +print("ALLOWED_HOSTS: ", ) +for host in ALLOWED_HOSTS: + print(' - ' + host) # https://docs.djangoproject.com/en/4.1/ref/settings/#std-setting-CSRF_TRUSTED_ORIGINS CSRF_TRUSTED_ORIGINS = [] - -for host in ALLOWED_DOMAINS: - host = host.strip('.') - if host.startswith('http'): - CSRF_TRUSTED_ORIGINS.append(host) +for host_port in ALLOWED_DOMAINS: + origin = host_port.strip('.') + if origin.startswith('http'): + CSRF_TRUSTED_ORIGINS.append(origin) continue + is_local_origin = origin.split(':')[0] in DEBUG_HOSTS for schema in ['https', 'http']: - # CSRF_TRUSTED_ORIGINS.append('{}://{}'.format(schema, host)) - CSRF_TRUSTED_ORIGINS.append('{}://*.{}'.format(schema, host)) + if is_local_origin and schema == 'https': + continue + CSRF_TRUSTED_ORIGINS.append('{}://*.{}'.format(schema, origin)) print("CSRF_TRUSTED_ORIGINS: ") for origin in CSRF_TRUSTED_ORIGINS: From a20b210514f690d7158dd3cc0e9f3d6ddeb736e3 Mon Sep 17 00:00:00 2001 From: ibuler Date: Tue, 25 Jul 2023 10:41:16 +0800 Subject: [PATCH 030/177] =?UTF-8?q?perf:=20=E9=99=8D=E7=BA=A7=20Django=20?= =?UTF-8?q?=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- requirements/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/requirements.txt b/requirements/requirements.txt index 2e233bba1..c76b5360e 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -70,7 +70,7 @@ geoip2==4.7.0 ipip-ipdb==1.6.1 pywinrm==0.4.3 # Django environment -Django==4.2.3 +Django==4.1.10 django-bootstrap3==23.4 django-filter==23.2 django-formtools==2.4.1 From 6478727cd269d90034dba0c01a35ac6b138405eb Mon Sep 17 00:00:00 2001 From: ibuler Date: Tue, 25 Jul 2023 10:53:14 +0800 Subject: [PATCH 031/177] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=E4=BE=9D?= =?UTF-8?q?=E8=B5=96=E5=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 2 -- requirements/requirements.txt | 7 ++----- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/Dockerfile b/Dockerfile index 14756e408..992c9fca8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -82,13 +82,11 @@ RUN set -ex \ WORKDIR /tmp/build COPY ./requirements ./requirements -ARG ANSIBLE_CORE_VERSION=2.14.1 ARG PIP_MIRROR=https://pypi.douban.com/simple RUN --mount=type=cache,target=/root/.cache/pip \ set -ex \ && pip config set global.index-url ${PIP_MIRROR} \ - && pip install https://github.com/jumpserver/ansible/releases/download/v${ANSIBLE_CORE_VERSION}/ansible_core-${ANSIBLE_CORE_VERSION}-py3-none-any.whl \ && pip install -r requirements/requirements.txt COPY --from=stage-build /opt/jumpserver/release/jumpserver /opt/jumpserver diff --git a/requirements/requirements.txt b/requirements/requirements.txt index c76b5360e..d5b3aba09 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -2,7 +2,7 @@ cython==3.0.0 aiofiles==23.1.0 amqp==5.1.1 -#git+https://github.com/jumpserver/ansible@master#egg=ansible-core +ansible-core@https://github.com/jumpserver/ansible/archive/refs/tags/v2.14.1.zip ansible==7.1.0 ansible-runner==2.3.3 asn1crypto==1.5.1 @@ -108,8 +108,7 @@ websockets==11.0.3 # Auth python-ldap==3.4.3 ldap3==2.9.1 -#django-radius==1.5.0 -git+https://github.com/robgolding/django-radius@develop#egg=django-radius +django-radius@https://github.com/ibuler/django-radius/archive/refs/tags/1.5.0.zip django-cas-ng==4.3.0 python-cas==1.6.0 django-auth-ldap==4.4.0 @@ -121,8 +120,6 @@ kubernetes==27.2.0 # DB requirements mysqlclient==2.2.0 PyMySQL==1.1.0 -pymssql==2.2.7 -django-mysql==4.11.0 django-redis==5.3.0 python-redis-lock==4.0.0 pyOpenSSL==23.2.0 From 76903977eb93d573fdbaa29292b723c6bb5dec2d Mon Sep 17 00:00:00 2001 From: ibuler Date: Tue, 25 Jul 2023 11:21:01 +0800 Subject: [PATCH 032/177] =?UTF-8?q?perf:=20=E4=BD=BF=E7=94=A8=E7=98=A6?= =?UTF-8?q?=E8=BA=AB=E5=90=8E=E7=9A=84=20ansible?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- requirements/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/requirements.txt b/requirements/requirements.txt index d5b3aba09..619d9aa70 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -2,7 +2,7 @@ cython==3.0.0 aiofiles==23.1.0 amqp==5.1.1 -ansible-core@https://github.com/jumpserver/ansible/archive/refs/tags/v2.14.1.zip +ansible-core@https://github.com/jumpserver/ansible/releases/download/v2.14.1/ansible-2.14.1.zip ansible==7.1.0 ansible-runner==2.3.3 asn1crypto==1.5.1 From 806baeb13601884c8f5c2aed59ce5840eb7380ca Mon Sep 17 00:00:00 2001 From: ibuler Date: Tue, 25 Jul 2023 14:45:24 +0800 Subject: [PATCH 033/177] =?UTF-8?q?perf:=20=E4=BF=AE=E5=A4=8D=E6=89=B9?= =?UTF-8?q?=E9=87=8F=E6=9B=B4=E6=96=B0=E8=B5=84=E4=BA=A7=E5=AF=BC=E8=87=B4?= =?UTF-8?q?=E7=9A=84=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/assets/serializers/asset/common.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/assets/serializers/asset/common.py b/apps/assets/serializers/asset/common.py index 718efbb0d..7d7eb4ec9 100644 --- a/apps/assets/serializers/asset/common.py +++ b/apps/assets/serializers/asset/common.py @@ -157,6 +157,8 @@ class AssetSerializer(BulkOrgResourceModelSerializer, WritableNestedModelSeriali def _extract_accounts(self): if not getattr(self, 'initial_data', None): return + if isinstance(self.initial_data, list): + return accounts = self.initial_data.pop('accounts', None) self._accounts = accounts From 539a6161e6a048c95a6ceb0e04e8ae5967ecaaf7 Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Tue, 25 Jul 2023 15:40:57 +0800 Subject: [PATCH 034/177] =?UTF-8?q?perf:=20=E7=BF=BB=E8=AF=91=20(#11082)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: feng <1304903146@qq.com> --- apps/locale/ja/LC_MESSAGES/django.mo | 4 +- apps/locale/ja/LC_MESSAGES/django.po | 542 +++++++++++++------------- apps/locale/zh/LC_MESSAGES/django.mo | 4 +- apps/locale/zh/LC_MESSAGES/django.po | 544 +++++++++++++-------------- 4 files changed, 547 insertions(+), 547 deletions(-) diff --git a/apps/locale/ja/LC_MESSAGES/django.mo b/apps/locale/ja/LC_MESSAGES/django.mo index 4a4ff2f0b..62fb28861 100644 --- a/apps/locale/ja/LC_MESSAGES/django.mo +++ b/apps/locale/ja/LC_MESSAGES/django.mo @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2d100b8957a5be7b3819b1f47bbd0e0f358c4d77112afb2aa8072f034372a412 -size 148962 +oid sha256:bd82a00953513f7ddd38f6f1d45f770e3a02d1c4a2467bfd791218c10c8d717c +size 148960 diff --git a/apps/locale/ja/LC_MESSAGES/django.po b/apps/locale/ja/LC_MESSAGES/django.po index b44d97a34..424fbf22b 100644 --- a/apps/locale/ja/LC_MESSAGES/django.po +++ b/apps/locale/ja/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-07-20 18:40+0800\n" +"POT-Creation-Date: 2023-07-25 15:37+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -199,8 +199,8 @@ msgstr "作成のみ" #: assets/serializers/domain.py:19 assets/serializers/label.py:27 #: audits/models.py:53 authentication/models/connection_token.py:36 #: perms/models/asset_permission.py:64 perms/serializers/permission.py:34 -#: terminal/backends/command/models.py:18 terminal/models/session/session.py:31 -#: terminal/notifications.py:155 terminal/serializers/command.py:18 +#: terminal/backends/command/models.py:17 terminal/models/session/session.py:31 +#: terminal/notifications.py:155 terminal/serializers/command.py:17 #: terminal/templates/terminal/_msg_command_warning.html:4 #: tickets/models/ticket/apply_asset.py:16 xpack/plugins/cloud/models.py:212 msgid "Asset" @@ -234,7 +234,7 @@ msgstr "ソース ID" #: acls/serializers/base.py:124 assets/serializers/asset/common.py:125 #: assets/serializers/gateway.py:28 audits/models.py:54 ops/models/base.py:18 #: perms/models/asset_permission.py:70 perms/serializers/permission.py:39 -#: terminal/backends/command/models.py:19 terminal/models/session/session.py:33 +#: terminal/backends/command/models.py:18 terminal/models/session/session.py:33 #: terminal/templates/terminal/_msg_command_warning.html:8 #: tickets/models/ticket/command_confirm.py:13 xpack/plugins/cloud/models.py:85 msgid "Account" @@ -417,8 +417,8 @@ msgstr "終了日" #: accounts/models/automations/change_secret.py:93 #: accounts/serializers/account/account.py:239 assets/const/automation.py:8 -#: authentication/views/base.py:29 authentication/views/base.py:30 -#: authentication/views/base.py:31 common/const/choices.py:20 +#: authentication/views/base.py:26 authentication/views/base.py:27 +#: authentication/views/base.py:28 common/const/choices.py:20 msgid "Error" msgstr "間違い" @@ -470,7 +470,7 @@ msgstr "トリガー方式" #: accounts/models/automations/push_account.py:16 acls/models/base.py:41 #: acls/serializers/base.py:57 assets/models/cmd_filter.py:81 -#: audits/models.py:87 audits/serializers.py:82 +#: audits/models.py:87 audits/serializers.py:83 #: authentication/serializers/connect_token_secret.py:116 #: authentication/templates/authentication/_access_key_modal.html:34 msgid "Action" @@ -494,10 +494,10 @@ msgstr "アカウントの確認" #: assets/serializers/asset/common.py:146 assets/serializers/platform.py:110 #: assets/serializers/platform.py:223 #: authentication/serializers/connect_token_secret.py:110 ops/mixin.py:21 -#: ops/models/adhoc.py:21 ops/models/celery.py:15 ops/models/celery.py:57 +#: ops/models/adhoc.py:20 ops/models/celery.py:15 ops/models/celery.py:57 #: ops/models/job.py:94 ops/models/playbook.py:23 ops/serializers/job.py:20 #: orgs/models.py:80 perms/models/asset_permission.py:56 rbac/models/role.py:29 -#: settings/models.py:33 settings/serializers/sms.py:6 +#: settings/models.py:32 settings/serializers/sms.py:6 #: terminal/models/applet/applet.py:32 terminal/models/component/endpoint.py:12 #: terminal/models/component/endpoint.py:92 #: terminal/models/component/storage.py:26 terminal/models/component/task.py:15 @@ -573,7 +573,7 @@ msgstr "アカウントの存在ポリシー" #: assets/models/label.py:21 assets/models/platform.py:89 #: assets/serializers/asset/common.py:121 assets/serializers/cagegory.py:8 #: assets/serializers/platform.py:128 assets/serializers/platform.py:224 -#: perms/serializers/user_permission.py:26 settings/models.py:35 +#: perms/serializers/user_permission.py:26 settings/models.py:34 #: tickets/models/ticket/apply_application.py:13 msgid "Category" msgstr "カテゴリ" @@ -584,13 +584,13 @@ msgstr "カテゴリ" #: assets/models/_user.py:50 assets/models/automations/base.py:20 #: assets/models/cmd_filter.py:74 assets/models/platform.py:90 #: assets/serializers/asset/common.py:122 assets/serializers/platform.py:112 -#: assets/serializers/platform.py:127 audits/serializers.py:48 +#: assets/serializers/platform.py:127 audits/serializers.py:49 #: authentication/serializers/connect_token_secret.py:123 ops/models/job.py:105 #: perms/serializers/user_permission.py:27 terminal/models/applet/applet.py:38 #: terminal/models/component/storage.py:57 #: terminal/models/component/storage.py:146 terminal/serializers/applet.py:29 -#: terminal/serializers/session.py:20 terminal/serializers/storage.py:224 -#: terminal/serializers/storage.py:236 tickets/models/comment.py:26 +#: terminal/serializers/session.py:20 terminal/serializers/storage.py:226 +#: terminal/serializers/storage.py:238 tickets/models/comment.py:26 #: tickets/models/flow.py:56 tickets/models/ticket/apply_application.py:16 #: tickets/models/ticket/general.py:275 tickets/serializers/flow.py:53 #: tickets/serializers/ticket/ticket.py:19 @@ -654,13 +654,13 @@ msgstr "ID" #: notifications/models/notification.py:12 #: perms/api/user_permission/mixin.py:55 perms/models/asset_permission.py:58 #: perms/serializers/permission.py:30 rbac/builtin.py:123 -#: rbac/models/rolebinding.py:49 terminal/backends/command/models.py:17 +#: rbac/models/rolebinding.py:49 terminal/backends/command/models.py:16 #: terminal/models/session/session.py:29 terminal/models/session/sharing.py:32 #: terminal/notifications.py:156 terminal/notifications.py:205 -#: terminal/serializers/command.py:17 +#: terminal/serializers/command.py:16 #: terminal/templates/terminal/_msg_command_warning.html:6 #: tickets/models/comment.py:21 users/const.py:14 users/models/user.py:947 -#: users/models/user.py:978 users/serializers/group.py:18 +#: users/models/user.py:983 users/serializers/group.py:18 msgid "User" msgstr "ユーザー" @@ -746,7 +746,7 @@ msgstr "自動タスク実行履歴" #: audits/models.py:59 audits/signal_handlers/activity_log.py:33 #: common/const/choices.py:18 ops/const.py:56 ops/serializers/celery.py:40 #: terminal/const.py:76 terminal/models/session/sharing.py:107 -#: tickets/views/approve.py:114 +#: tickets/views/approve.py:115 msgid "Success" msgstr "成功" @@ -846,7 +846,7 @@ msgstr "アカウント" #: acls/models/command_acl.py:16 assets/models/cmd_filter.py:60 #: ops/serializers/job.py:55 terminal/const.py:84 -#: terminal/models/session/session.py:42 terminal/serializers/command.py:19 +#: terminal/models/session/session.py:42 terminal/serializers/command.py:18 #: terminal/templates/terminal/_msg_command_alert.html:12 #: terminal/templates/terminal/_msg_command_execute_alert.html:10 #: terminal/templates/terminal/_msg_command_warning.html:23 @@ -997,7 +997,7 @@ msgstr "" "資産を直接作成することはできません。ホストまたはその他を作成する必要がありま" "す" -#: assets/api/domain.py:62 +#: assets/api/domain.py:63 msgid "Number required" msgstr "必要な数" @@ -1040,7 +1040,7 @@ msgid "Unable to connect to port {port} on {address}" msgstr "{port} のポート {address} に接続できません" #: assets/automations/ping_gateway/manager.py:58 -#: authentication/middleware.py:92 xpack/plugins/cloud/providers/fc.py:48 +#: authentication/middleware.py:92 xpack/plugins/cloud/providers/fc.py:47 msgid "Authentication failed" msgstr "認証に失敗しました" @@ -1172,7 +1172,7 @@ msgstr "コンソールセッションに接続" msgid "Any" msgstr "任意" -#: assets/const/protocol.py:66 settings/serializers/security.py:151 +#: assets/const/protocol.py:66 settings/serializers/security.py:153 msgid "Security" msgstr "セキュリティ" @@ -1236,8 +1236,8 @@ msgstr "SSHパブリックキー" #: assets/models/_user.py:27 assets/models/cmd_filter.py:40 #: assets/models/cmd_filter.py:88 assets/models/group.py:20 -#: common/db/models.py:36 ops/models/adhoc.py:27 ops/models/job.py:113 -#: ops/models/playbook.py:26 rbac/models/role.py:37 settings/models.py:38 +#: common/db/models.py:36 ops/models/adhoc.py:26 ops/models/job.py:113 +#: ops/models/playbook.py:26 rbac/models/role.py:37 settings/models.py:37 #: terminal/models/applet/applet.py:44 terminal/models/applet/applet.py:248 #: terminal/models/applet/host.py:139 terminal/models/component/endpoint.py:24 #: terminal/models/component/endpoint.py:102 @@ -1250,7 +1250,7 @@ msgstr "コメント" #: assets/models/_user.py:28 assets/models/automations/base.py:114 #: assets/models/cmd_filter.py:41 assets/models/group.py:19 #: common/db/models.py:34 ops/models/base.py:54 ops/models/job.py:193 -#: users/models/user.py:979 +#: users/models/user.py:984 msgid "Date created" msgstr "作成された日付" @@ -1289,7 +1289,7 @@ msgstr "ユーザーと同じユーザー名" #: assets/models/_user.py:52 authentication/models/connection_token.py:41 #: authentication/serializers/connect_token_secret.py:111 #: terminal/models/applet/applet.py:41 terminal/serializers/session.py:18 -#: terminal/serializers/session.py:39 terminal/serializers/storage.py:68 +#: terminal/serializers/session.py:39 terminal/serializers/storage.py:70 msgid "Protocol" msgstr "プロトコル" @@ -1431,7 +1431,7 @@ msgid "Asset automation task" msgstr "アセットの自動化タスク" #: assets/models/automations/base.py:113 audits/models.py:199 -#: audits/serializers.py:49 ops/models/base.py:49 ops/models/job.py:186 +#: audits/serializers.py:50 ops/models/base.py:49 ops/models/job.py:186 #: terminal/models/applet/applet.py:247 terminal/models/applet/host.py:136 #: terminal/models/component/status.py:30 terminal/serializers/applet.py:18 #: terminal/serializers/applet_host.py:107 tickets/models/ticket/general.py:283 @@ -1501,7 +1501,7 @@ msgstr "資産グループ" #: assets/models/group.py:31 assets/models/platform.py:19 #: assets/serializers/platform.py:113 -#: xpack/plugins/cloud/providers/nutanix.py:30 +#: xpack/plugins/cloud/providers/nutanix.py:32 msgid "Default" msgstr "デフォルト" @@ -1509,15 +1509,15 @@ msgstr "デフォルト" msgid "Default asset group" msgstr "デフォルトアセットグループ" -#: assets/models/label.py:15 rbac/const.py:6 users/models/user.py:964 +#: assets/models/label.py:15 rbac/const.py:6 users/models/user.py:969 msgid "System" msgstr "システム" -#: assets/models/label.py:19 assets/models/node.py:545 +#: assets/models/label.py:19 assets/models/node.py:544 #: assets/serializers/cagegory.py:7 assets/serializers/cagegory.py:14 #: authentication/models/connection_token.py:29 #: authentication/serializers/connect_token_secret.py:122 -#: common/serializers/common.py:86 settings/models.py:34 +#: common/serializers/common.py:86 settings/models.py:33 msgid "Value" msgstr "値" @@ -1530,32 +1530,32 @@ msgstr "値" msgid "Label" msgstr "ラベル" -#: assets/models/node.py:166 +#: assets/models/node.py:165 msgid "New node" msgstr "新しいノード" -#: assets/models/node.py:473 audits/backends/db.py:55 audits/backends/db.py:56 +#: assets/models/node.py:472 audits/backends/db.py:55 audits/backends/db.py:56 msgid "empty" msgstr "空" -#: assets/models/node.py:544 perms/models/perm_node.py:28 +#: assets/models/node.py:543 perms/models/perm_node.py:28 msgid "Key" msgstr "キー" -#: assets/models/node.py:546 assets/serializers/node.py:20 +#: assets/models/node.py:545 assets/serializers/node.py:20 msgid "Full value" msgstr "フルバリュー" -#: assets/models/node.py:550 perms/models/perm_node.py:30 +#: assets/models/node.py:549 perms/models/perm_node.py:30 msgid "Parent key" msgstr "親キー" -#: assets/models/node.py:559 perms/serializers/permission.py:35 +#: assets/models/node.py:558 perms/serializers/permission.py:35 #: tickets/models/ticket/apply_asset.py:14 xpack/plugins/cloud/models.py:96 msgid "Node" msgstr "ノード" -#: assets/models/node.py:562 +#: assets/models/node.py:561 msgid "Can match node" msgstr "ノードを一致させることができます" @@ -1572,12 +1572,12 @@ msgid "Public" msgstr "開ける" #: assets/models/platform.py:21 assets/serializers/platform.py:48 -#: settings/serializers/settings.py:67 +#: settings/serializers/settings.py:66 #: users/templates/users/reset_password.html:29 msgid "Setting" msgstr "設定" -#: assets/models/platform.py:38 audits/const.py:48 settings/models.py:37 +#: assets/models/platform.py:38 audits/const.py:48 settings/models.py:36 #: terminal/serializers/applet_host.py:33 msgid "Enabled" msgstr "有効化" @@ -1805,7 +1805,7 @@ msgstr "制約" msgid "Types" msgstr "タイプ" -#: assets/serializers/gateway.py:23 common/validators.py:35 +#: assets/serializers/gateway.py:23 common/validators.py:34 msgid "This field must be unique." msgstr "このフィールドは一意である必要があります。" @@ -1934,19 +1934,19 @@ msgstr "ノード配下のアセットが接続できるかテストする" msgid "Test gateways connectivity" msgstr "ゲートウェイ接続のテスト。" -#: assets/tasks/utils.py:17 +#: assets/tasks/utils.py:16 msgid "Asset has been disabled, skipped: {}" msgstr "資産が無効化されました。スキップ: {}" -#: assets/tasks/utils.py:21 +#: assets/tasks/utils.py:20 msgid "Asset may not be support ansible, skipped: {}" msgstr "資産はサポートできない場合があります。スキップ: {}" -#: assets/tasks/utils.py:39 +#: assets/tasks/utils.py:38 msgid "For security, do not push user {}" msgstr "セキュリティのために、ユーザー {} をプッシュしないでください" -#: assets/tasks/utils.py:55 +#: assets/tasks/utils.py:54 msgid "No assets matched, stop task" msgstr "一致する資産がない、タスクを停止" @@ -2065,7 +2065,7 @@ msgstr "ジョブ監査ログ" msgid "Remote addr" msgstr "リモートaddr" -#: audits/models.py:56 audits/serializers.py:33 +#: audits/models.py:56 audits/serializers.py:34 msgid "Operate" msgstr "操作" @@ -2077,7 +2077,7 @@ msgstr "ファイル名" msgid "File" msgstr "書類" -#: audits/models.py:62 terminal/backends/command/models.py:22 +#: audits/models.py:62 terminal/backends/command/models.py:21 #: terminal/models/session/replay.py:9 terminal/models/session/sharing.py:18 #: terminal/models/session/sharing.py:81 #: terminal/templates/terminal/_msg_command_alert.html:10 @@ -2090,17 +2090,17 @@ msgstr "セッション" msgid "File transfer log" msgstr "ファイル転送ログ" -#: audits/models.py:89 audits/serializers.py:84 +#: audits/models.py:89 audits/serializers.py:85 msgid "Resource Type" msgstr "リソースタイプ" #: audits/models.py:90 audits/models.py:93 audits/models.py:139 -#: audits/serializers.py:83 +#: audits/serializers.py:84 msgid "Resource" msgstr "リソース" #: audits/models.py:96 audits/models.py:142 audits/models.py:168 -#: terminal/serializers/command.py:76 +#: terminal/serializers/command.py:75 msgid "Datetime" msgstr "時間" @@ -2142,11 +2142,11 @@ msgstr "ログインIP" msgid "Login city" msgstr "ログイン都市" -#: audits/models.py:188 audits/serializers.py:63 +#: audits/models.py:188 audits/serializers.py:64 msgid "User agent" msgstr "ユーザーエージェント" -#: audits/models.py:191 audits/serializers.py:47 +#: audits/models.py:191 audits/serializers.py:48 #: authentication/templates/authentication/_mfa_confirm_modal.html:14 #: users/forms/profile.py:65 users/models/user.py:776 #: users/serializers/profile.py:126 @@ -2157,7 +2157,7 @@ msgstr "MFA" msgid "Date login" msgstr "日付ログイン" -#: audits/models.py:203 audits/serializers.py:65 +#: audits/models.py:203 audits/serializers.py:66 msgid "Authentication backend" msgstr "認証バックエンド" @@ -2165,11 +2165,11 @@ msgstr "認証バックエンド" msgid "User login log" msgstr "ユーザーログインログ" -#: audits/serializers.py:64 +#: audits/serializers.py:65 msgid "Reason display" msgstr "理由表示" -#: audits/serializers.py:132 +#: audits/serializers.py:133 #, python-format msgid "User %s %s this resource" msgstr "ユーザー %s %s が現在のリソースをサブスクライブしました。" @@ -2208,7 +2208,7 @@ msgstr "認証トークン" msgid "WeCom" msgstr "企業微信" -#: audits/signal_handlers/login_log.py:32 authentication/views/feishu.py:123 +#: audits/signal_handlers/login_log.py:32 authentication/views/feishu.py:122 #: authentication/views/login.py:87 notifications/backends/__init__.py:14 #: settings/serializers/auth/feishu.py:10 #: settings/serializers/auth/feishu.py:13 users/models/user.py:708 @@ -2216,7 +2216,7 @@ msgstr "企業微信" msgid "FeiShu" msgstr "本を飛ばす" -#: audits/signal_handlers/login_log.py:33 authentication/views/dingtalk.py:160 +#: audits/signal_handlers/login_log.py:33 authentication/views/dingtalk.py:159 #: authentication/views/login.py:81 notifications/backends/__init__.py:12 #: settings/serializers/auth/dingtalk.py:10 users/models/user.py:707 #: users/models/user.py:815 @@ -2266,7 +2266,7 @@ msgstr "ACL アクションは拒否です: {}({})" msgid "ACL action is review" msgstr "ACL アクションはレビューです" -#: authentication/api/mfa.py:59 +#: authentication/api/mfa.py:57 msgid "Current user not support mfa type: {}" msgstr "現在のユーザーはmfaタイプをサポートしていません: {}" @@ -2305,56 +2305,56 @@ msgstr "認証" msgid "User invalid, disabled or expired" msgstr "ユーザーが無効、無効、または期限切れです" -#: authentication/backends/drf.py:56 +#: authentication/backends/drf.py:54 msgid "Invalid signature header. No credentials provided." msgstr "署名ヘッダーが無効です。資格情報は提供されていません。" -#: authentication/backends/drf.py:59 +#: authentication/backends/drf.py:57 msgid "Invalid signature header. Signature string should not contain spaces." msgstr "署名ヘッダーが無効です。署名文字列にはスペースを含まないでください。" -#: authentication/backends/drf.py:66 +#: authentication/backends/drf.py:64 msgid "Invalid signature header. Format like AccessKeyId:Signature" msgstr "署名ヘッダーが無効です。AccessKeyIdのような形式: Signature" -#: authentication/backends/drf.py:70 +#: authentication/backends/drf.py:68 msgid "" "Invalid signature header. Signature string should not contain invalid " "characters." msgstr "" "署名ヘッダーが無効です。署名文字列に無効な文字を含めることはできません。" -#: authentication/backends/drf.py:90 authentication/backends/drf.py:106 +#: authentication/backends/drf.py:88 authentication/backends/drf.py:104 msgid "Invalid signature." msgstr "署名が無効です。" -#: authentication/backends/drf.py:97 +#: authentication/backends/drf.py:95 msgid "HTTP header: Date not provide or not %a, %d %b %Y %H:%M:%S GMT" msgstr "HTTP header: Date not provide or not" -#: authentication/backends/drf.py:102 +#: authentication/backends/drf.py:100 msgid "Expired, more than 15 minutes" msgstr "期限切れ、15分以上" -#: authentication/backends/drf.py:109 +#: authentication/backends/drf.py:107 msgid "User disabled." msgstr "ユーザーが無効になりました。" -#: authentication/backends/drf.py:127 +#: authentication/backends/drf.py:125 msgid "Invalid token header. No credentials provided." msgstr "無効なトークンヘッダー。資格情報は提供されていません。" -#: authentication/backends/drf.py:130 +#: authentication/backends/drf.py:128 msgid "Invalid token header. Sign string should not contain spaces." msgstr "無効なトークンヘッダー。記号文字列にはスペースを含めないでください。" -#: authentication/backends/drf.py:137 +#: authentication/backends/drf.py:135 msgid "" "Invalid token header. Sign string should not contain invalid characters." msgstr "" "無効なトークンヘッダー。署名文字列に無効な文字を含めることはできません。" -#: authentication/backends/drf.py:148 +#: authentication/backends/drf.py:146 msgid "Invalid token or cache refreshed." msgstr "無効なトークンまたはキャッシュの更新。" @@ -2503,12 +2503,12 @@ msgstr "企業の微信はすでにバインドされています" msgid "WeCom is not bound" msgstr "企業の微信をバインドしていません" -#: authentication/errors/mfa.py:28 authentication/views/dingtalk.py:210 -#: authentication/views/dingtalk.py:252 +#: authentication/errors/mfa.py:28 authentication/views/dingtalk.py:209 +#: authentication/views/dingtalk.py:251 msgid "DingTalk is not bound" msgstr "DingTalkはバインドされていません" -#: authentication/errors/mfa.py:33 authentication/views/feishu.py:167 +#: authentication/errors/mfa.py:33 authentication/views/feishu.py:166 msgid "FeiShu is not bound" msgstr "本を飛ばすは拘束されていません" @@ -2644,7 +2644,7 @@ msgid "Please change your password" msgstr "パスワードを変更してください" #: authentication/models/connection_token.py:38 -#: terminal/serializers/storage.py:111 +#: terminal/serializers/storage.py:113 msgid "Account name" msgstr "アカウント名" @@ -3034,74 +3034,74 @@ msgstr "コピー成功" msgid "LAN" msgstr "ローカルエリアネットワーク" -#: authentication/views/base.py:64 +#: authentication/views/base.py:61 #: perms/templates/perms/_msg_permed_items_expire.html:21 msgid "If you have any question, please contact the administrator" msgstr "質問があったら、管理者に連絡して下さい" -#: authentication/views/dingtalk.py:42 +#: authentication/views/dingtalk.py:41 msgid "DingTalk Error, Please contact your system administrator" msgstr "DingTalkエラー、システム管理者に連絡してください" -#: authentication/views/dingtalk.py:45 authentication/views/dingtalk.py:209 +#: authentication/views/dingtalk.py:44 authentication/views/dingtalk.py:208 msgid "DingTalk Error" msgstr "DingTalkエラー" -#: authentication/views/dingtalk.py:57 authentication/views/feishu.py:51 +#: authentication/views/dingtalk.py:56 authentication/views/feishu.py:50 #: authentication/views/wecom.py:57 msgid "" "The system configuration is incorrect. Please contact your administrator" msgstr "システム設定が正しくありません。管理者に連絡してください" -#: authentication/views/dingtalk.py:61 +#: authentication/views/dingtalk.py:60 msgid "DingTalk is already bound" msgstr "DingTalkはすでにバインドされています" -#: authentication/views/dingtalk.py:129 authentication/views/wecom.py:129 +#: authentication/views/dingtalk.py:128 authentication/views/wecom.py:129 msgid "Invalid user_id" msgstr "無効なuser_id" -#: authentication/views/dingtalk.py:145 +#: authentication/views/dingtalk.py:144 msgid "DingTalk query user failed" msgstr "DingTalkクエリユーザーが失敗しました" -#: authentication/views/dingtalk.py:154 +#: authentication/views/dingtalk.py:153 msgid "The DingTalk is already bound to another user" msgstr "DingTalkはすでに別のユーザーにバインドされています" -#: authentication/views/dingtalk.py:161 +#: authentication/views/dingtalk.py:160 msgid "Binding DingTalk successfully" msgstr "DingTalkのバインドに成功" -#: authentication/views/dingtalk.py:211 authentication/views/dingtalk.py:246 +#: authentication/views/dingtalk.py:210 authentication/views/dingtalk.py:245 msgid "Failed to get user from DingTalk" msgstr "DingTalkからユーザーを取得できませんでした" -#: authentication/views/dingtalk.py:253 +#: authentication/views/dingtalk.py:252 msgid "Please login with a password and then bind the DingTalk" msgstr "パスワードでログインし、DingTalkをバインドしてください" -#: authentication/views/feishu.py:39 authentication/views/feishu.py:166 +#: authentication/views/feishu.py:38 authentication/views/feishu.py:165 msgid "FeiShu Error" msgstr "FeiShuエラー" -#: authentication/views/feishu.py:67 +#: authentication/views/feishu.py:66 msgid "FeiShu is already bound" msgstr "FeiShuはすでにバインドされています" -#: authentication/views/feishu.py:108 +#: authentication/views/feishu.py:107 msgid "FeiShu query user failed" msgstr "FeiShuクエリユーザーが失敗しました" -#: authentication/views/feishu.py:117 +#: authentication/views/feishu.py:116 msgid "The FeiShu is already bound to another user" msgstr "FeiShuはすでに別のユーザーにバインドされています" -#: authentication/views/feishu.py:124 +#: authentication/views/feishu.py:123 msgid "Binding FeiShu successfully" msgstr "本を飛ばすのバインドに成功" -#: authentication/views/feishu.py:168 +#: authentication/views/feishu.py:167 msgid "Failed to get user from FeiShu" msgstr "本を飛ばすからユーザーを取得できませんでした" @@ -3339,11 +3339,11 @@ msgstr "このアクションでは、MFAの確認が必要です。" msgid "Unexpect error occur" msgstr "予期しないエラーが発生します" -#: common/plugins/es.py:28 +#: common/plugins/es.py:31 msgid "Invalid elasticsearch config" msgstr "無効なElasticsearch構成" -#: common/plugins/es.py:33 +#: common/plugins/es.py:36 msgid "Not Support Elasticsearch8" msgstr "サポートされていません Elasticsearch8" @@ -3359,11 +3359,11 @@ msgstr "企業微信エラー、システム管理者に連絡してください msgid "Signature does not match" msgstr "署名が一致しない" -#: common/sdk/sms/cmpp2.py:46 +#: common/sdk/sms/cmpp2.py:44 msgid "sp_id is 6 bits" msgstr "SP idは6ビット" -#: common/sdk/sms/cmpp2.py:216 +#: common/sdk/sms/cmpp2.py:214 msgid "Failed to connect to the CMPP gateway server, err: {}" msgstr "接続ゲートウェイサーバエラー, 非: {}" @@ -3446,15 +3446,15 @@ msgstr "無効なアドレス。" msgid "Hello %s" msgstr "こんにちは %s" -#: common/validators.py:17 +#: common/validators.py:16 msgid "Special char not allowed" msgstr "特別なcharは許可されていません" -#: common/validators.py:43 +#: common/validators.py:42 msgid "Should not contains special characters" msgstr "特殊文字を含むべきではない" -#: common/validators.py:48 +#: common/validators.py:47 msgid "The mobile phone number format is incorrect" msgstr "携帯電話番号の形式が正しくありません" @@ -3488,7 +3488,7 @@ msgstr "アカウントが正常に作成されました" msgid "JumpServer Open Source Bastion Host" msgstr "JumpServer オープンソースの要塞ホスト" -#: jumpserver/views/celery_flower.py:23 +#: jumpserver/views/celery_flower.py:22 msgid "

Flower service unavailable, check it

" msgstr "

フラワーサービス利用不可、チェック

" @@ -3616,7 +3616,7 @@ msgstr "空欄" msgid "VCS" msgstr "VCS" -#: ops/const.py:38 ops/models/adhoc.py:45 +#: ops/const.py:38 ops/models/adhoc.py:44 msgid "Adhoc" msgstr "コマンド#コマンド#" @@ -3673,20 +3673,20 @@ msgstr "{} から {} までの範囲" msgid "Require periodic or regularly perform setting" msgstr "定期的または定期的に設定を行う必要があります" -#: ops/models/adhoc.py:22 +#: ops/models/adhoc.py:21 msgid "Pattern" msgstr "パターン" -#: ops/models/adhoc.py:24 ops/models/job.py:98 +#: ops/models/adhoc.py:23 ops/models/job.py:98 msgid "Module" msgstr "モジュール" -#: ops/models/adhoc.py:25 ops/models/celery.py:58 ops/models/job.py:97 +#: ops/models/adhoc.py:24 ops/models/celery.py:58 ops/models/job.py:97 #: terminal/models/component/task.py:16 msgid "Args" msgstr "アルグ" -#: ops/models/adhoc.py:26 ops/models/base.py:16 ops/models/base.py:53 +#: ops/models/adhoc.py:25 ops/models/base.py:16 ops/models/base.py:53 #: ops/models/job.py:106 ops/models/job.py:192 ops/models/playbook.py:25 #: terminal/models/session/sharing.py:23 msgid "Creator" @@ -4125,7 +4125,7 @@ msgstr "Webターミナルを表示できます" msgid "Can view file manager" msgstr "ファイルマネージャを表示できます" -#: rbac/models/permission.py:26 rbac/models/role.py:34 +#: rbac/models/permission.py:27 rbac/models/role.py:34 msgid "Permissions" msgstr "権限" @@ -4170,7 +4170,7 @@ msgstr "組織の役割バインディング" msgid "System role binding" msgstr "システムロールバインディング" -#: rbac/serializers/permission.py:26 users/serializers/profile.py:132 +#: rbac/serializers/permission.py:25 users/serializers/profile.py:132 msgid "Perms" msgstr "パーマ" @@ -4206,7 +4206,7 @@ msgstr "ワークスペースビュー" msgid "Audit view" msgstr "監査ビュー" -#: rbac/tree.py:27 settings/models.py:159 +#: rbac/tree.py:27 settings/models.py:158 msgid "System setting" msgstr "システム設定" @@ -4305,47 +4305,47 @@ msgstr "携帯番号をテストこのフィールドは必須です" msgid "Settings" msgstr "設定" -#: settings/models.py:36 +#: settings/models.py:35 msgid "Encrypted" msgstr "暗号化された" -#: settings/models.py:161 +#: settings/models.py:160 msgid "Can change email setting" msgstr "メール設定を変更できます" -#: settings/models.py:162 +#: settings/models.py:161 msgid "Can change auth setting" msgstr "資格認定の設定" -#: settings/models.py:163 +#: settings/models.py:162 msgid "Can change system msg sub setting" msgstr "システムmsgサブ设定を変更できます" -#: settings/models.py:164 +#: settings/models.py:163 msgid "Can change sms setting" msgstr "Smsの設定を変えることができます" -#: settings/models.py:165 +#: settings/models.py:164 msgid "Can change security setting" msgstr "セキュリティ設定を変更できます" -#: settings/models.py:166 +#: settings/models.py:165 msgid "Can change clean setting" msgstr "きれいな設定を変えることができます" -#: settings/models.py:167 +#: settings/models.py:166 msgid "Can change interface setting" msgstr "インターフェイスの設定を変えることができます" -#: settings/models.py:168 +#: settings/models.py:167 msgid "Can change license setting" msgstr "ライセンス設定を変更できます" -#: settings/models.py:169 +#: settings/models.py:168 msgid "Can change terminal setting" msgstr "ターミナルの設定を変えることができます" -#: settings/models.py:170 +#: settings/models.py:169 msgid "Can change other setting" msgstr "他の設定を変えることができます" @@ -4406,7 +4406,7 @@ msgid "Proxy server url" msgstr "コールバックアドレス" #: settings/serializers/auth/cas.py:18 settings/serializers/auth/oauth2.py:54 -#: settings/serializers/auth/saml2.py:34 +#: settings/serializers/auth/saml2.py:33 msgid "Logout completely" msgstr "同期ログアウト" @@ -4418,7 +4418,7 @@ msgstr "ユーザー名のプロパティ" msgid "Enable attributes map" msgstr "属性マップの有効化" -#: settings/serializers/auth/cas.py:28 settings/serializers/auth/saml2.py:33 +#: settings/serializers/auth/cas.py:28 settings/serializers/auth/saml2.py:32 msgid "Rename attr" msgstr "マッピングのプロパティ" @@ -4538,7 +4538,7 @@ msgid "Provider end session endpoint" msgstr "プロバイダーのセッション終了エンドポイント" #: settings/serializers/auth/oauth2.py:59 settings/serializers/auth/oidc.py:98 -#: settings/serializers/auth/saml2.py:35 +#: settings/serializers/auth/saml2.py:34 msgid "Always update user" msgstr "常にユーザーを更新" @@ -4634,31 +4634,31 @@ msgstr "Radius認証の有効化" msgid "OTP in Radius" msgstr "Radius のOTP" -#: settings/serializers/auth/saml2.py:11 +#: settings/serializers/auth/saml2.py:10 msgid "SAML2" msgstr "SAML2" -#: settings/serializers/auth/saml2.py:14 +#: settings/serializers/auth/saml2.py:13 msgid "Enable SAML2 Auth" msgstr "SAML2認証の有効化" -#: settings/serializers/auth/saml2.py:17 +#: settings/serializers/auth/saml2.py:16 msgid "IDP metadata URL" msgstr "IDP metadata アドレス" -#: settings/serializers/auth/saml2.py:20 +#: settings/serializers/auth/saml2.py:19 msgid "IDP metadata XML" msgstr "IDP metadata XML" -#: settings/serializers/auth/saml2.py:23 +#: settings/serializers/auth/saml2.py:22 msgid "SP advanced settings" msgstr "詳細設定" -#: settings/serializers/auth/saml2.py:27 +#: settings/serializers/auth/saml2.py:26 msgid "SP private key" msgstr "SP プライベートキー" -#: settings/serializers/auth/saml2.py:31 +#: settings/serializers/auth/saml2.py:30 msgid "SP cert" msgstr "SP 証明書" @@ -4844,7 +4844,7 @@ msgstr "クラウド同期レコードは日数を保持します(天)" msgid "Session keep duration (day)" msgstr "セッション維持期間(天)" -#: settings/serializers/cleaning.py:32 +#: settings/serializers/cleaning.py:33 msgid "" "Session, record, command will be delete if more than duration, only in " "database, OSS will not be affected." @@ -4852,7 +4852,7 @@ msgstr "" "この期間を超えるセッション、録音、およびコマンド レコードは削除されます (デー" "タベースのバックアップに影響し、OSS などには影響しません)" -#: settings/serializers/cleaning.py:36 +#: settings/serializers/cleaning.py:37 msgid "Activity log keep days (day)" msgstr "活動ログは日数を保持します(天)" @@ -5131,7 +5131,7 @@ msgstr "" msgid "Only exist user login" msgstr "ユーザーログインのみ存在" -#: settings/serializers/security.py:101 +#: settings/serializers/security.py:102 msgid "" "If enabled, non-existent users will not be allowed to log in; if disabled, " "users of other authentication methods except local authentication methods " @@ -5142,11 +5142,11 @@ msgstr "" "ローカル認証方法を除く他の認証方法のユーザーはログインでき、ユーザーが自動的" "に作成されます (ユーザーが存在しない場合)。" -#: settings/serializers/security.py:104 +#: settings/serializers/security.py:105 msgid "Only from source login" msgstr "ソースログインからのみ" -#: settings/serializers/security.py:105 +#: settings/serializers/security.py:107 msgid "" "If it is enabled, the user will only authenticate to the source when logging " "in; if it is disabled, the user will authenticate all the enabled " @@ -5157,28 +5157,28 @@ msgstr "" "な場合、ユーザーはログイン時に、いずれかの認証方法が成功する限り、有効なすべ" "ての認証方法を特定の順序で認証します。 、直接ログインできます" -#: settings/serializers/security.py:109 +#: settings/serializers/security.py:111 msgid "MFA verify TTL (secend)" msgstr "MFAはTTLを確認します(秒)" -#: settings/serializers/security.py:111 +#: settings/serializers/security.py:113 msgid "" "The verification MFA takes effect only when you view the account password" msgstr "検証MFAはアカウントのパスワードを表示したときにのみ有効になります。" -#: settings/serializers/security.py:116 +#: settings/serializers/security.py:118 msgid "Verify code TTL" msgstr "認証コード有効時間" -#: settings/serializers/security.py:117 +#: settings/serializers/security.py:119 msgid "Unit: second, reset password and send SMS code expiration time" msgstr "パスワードをリセットしてSMSコードの有効期限を送信します" -#: settings/serializers/security.py:121 +#: settings/serializers/security.py:123 msgid "Enable Login dynamic code" msgstr "ログイン動的コードの有効化" -#: settings/serializers/security.py:122 +#: settings/serializers/security.py:124 msgid "" "The password and additional code are sent to a third party authentication " "system for verification" @@ -5186,28 +5186,28 @@ msgstr "" "パスワードと追加コードは、検証のためにサードパーティの認証システムに送信され" "ます" -#: settings/serializers/security.py:127 +#: settings/serializers/security.py:129 msgid "MFA in login page" msgstr "ログインページのMFA" -#: settings/serializers/security.py:128 +#: settings/serializers/security.py:130 msgid "Eu security regulations(GDPR) require MFA to be on the login page" msgstr "" "Euセキュリティ規制 (GDPR) では、MFAがログインページにある必要があります" -#: settings/serializers/security.py:131 +#: settings/serializers/security.py:133 msgid "Enable Login captcha" msgstr "ログインcaptchaの有効化" -#: settings/serializers/security.py:132 +#: settings/serializers/security.py:134 msgid "Enable captcha to prevent robot authentication" msgstr "Captchaを有効にしてロボット認証を防止する" -#: settings/serializers/security.py:154 +#: settings/serializers/security.py:156 msgid "Enable terminal register" msgstr "ターミナルレジスタの有効化" -#: settings/serializers/security.py:156 +#: settings/serializers/security.py:158 msgid "" "Allow terminal register, after all terminal setup, you should disable this " "for security" @@ -5215,68 +5215,68 @@ msgstr "" "ターミナルレジスタを許可し、すべてのターミナルセットアップの後、セキュリティ" "のためにこれを無効にする必要があります" -#: settings/serializers/security.py:160 +#: settings/serializers/security.py:162 msgid "Enable watermark" msgstr "透かしの有効化" -#: settings/serializers/security.py:161 +#: settings/serializers/security.py:163 msgid "Enabled, the web session and replay contains watermark information" msgstr "Webセッションとリプレイには透かし情報が含まれています。" -#: settings/serializers/security.py:165 +#: settings/serializers/security.py:167 msgid "Connection max idle time (minute)" msgstr "接続最大アイドル時間(分)" -#: settings/serializers/security.py:166 +#: settings/serializers/security.py:168 msgid "If idle time more than it, disconnect connection." msgstr "この設定以上の操作がない場合、接続は切断されます" -#: settings/serializers/security.py:169 +#: settings/serializers/security.py:171 msgid "Remember manual auth" msgstr "手動入力パスワードの保存" -#: settings/serializers/security.py:172 +#: settings/serializers/security.py:174 msgid "Insecure command alert" msgstr "安全でないコマンドアラート" -#: settings/serializers/security.py:175 +#: settings/serializers/security.py:177 msgid "Email recipient" msgstr "メール受信者" -#: settings/serializers/security.py:176 +#: settings/serializers/security.py:178 msgid "Multiple user using , split" msgstr "複数のユーザーを使用して、分割" -#: settings/serializers/security.py:179 +#: settings/serializers/security.py:181 msgid "Operation center" msgstr "職業センター" -#: settings/serializers/security.py:180 +#: settings/serializers/security.py:182 msgid "Allow user run batch command or not using ansible" msgstr "ユーザー実行バッチコマンドを許可するか、ansibleを使用しない" -#: settings/serializers/security.py:184 +#: settings/serializers/security.py:186 msgid "Operation center command blacklist" msgstr "オペレーション センター コマンド ブラックリスト" -#: settings/serializers/security.py:185 +#: settings/serializers/security.py:187 msgid "Commands that are not allowed execute." msgstr "実行が許可されていないコマンド" -#: settings/serializers/security.py:188 +#: settings/serializers/security.py:190 msgid "Session share" msgstr "セッション共有" -#: settings/serializers/security.py:189 +#: settings/serializers/security.py:191 msgid "Enabled, Allows user active session to be shared with other users" msgstr "" "ユーザーのアクティブなセッションを他のユーザーと共有できるようにします。" -#: settings/serializers/security.py:192 +#: settings/serializers/security.py:194 msgid "Remote Login Protection" msgstr "リモートログイン保護" -#: settings/serializers/security.py:194 +#: settings/serializers/security.py:196 msgid "" "The system determines whether the login IP address belongs to a common login " "city. If the account is logged in from a common login city, the system sends " @@ -5286,7 +5286,7 @@ msgstr "" "します。アカウントが共通のログイン都市からログインしている場合、システムはリ" "モートログインリマインダーを送信します" -#: settings/serializers/settings.py:71 +#: settings/serializers/settings.py:70 #, python-format msgid "[%s] %s" msgstr "[%s] %s" @@ -5358,11 +5358,11 @@ msgstr "" "ヒント: Luna ページでグラフィック アセットを接続するときに使用するデフォルト" "の解像度" -#: settings/tasks/ldap.py:25 +#: settings/tasks/ldap.py:24 msgid "Periodic import ldap user" msgstr "LDAP ユーザーを定期的にインポートする" -#: settings/tasks/ldap.py:46 +#: settings/tasks/ldap.py:45 msgid "Registration periodic import ldap user task" msgstr "登録サイクルLDAPユーザータスクのインポート" @@ -5729,15 +5729,15 @@ msgstr "安全なセッション共有設定が無効になっています" msgid "Terminals" msgstr "ターミナル管理" -#: terminal/backends/command/models.py:20 +#: terminal/backends/command/models.py:19 msgid "Input" msgstr "入力" -#: terminal/backends/command/models.py:21 terminal/serializers/command.py:74 +#: terminal/backends/command/models.py:20 terminal/serializers/command.py:73 msgid "Output" msgstr "出力" -#: terminal/backends/command/models.py:25 terminal/serializers/command.py:23 +#: terminal/backends/command/models.py:24 terminal/serializers/command.py:22 #: terminal/templates/terminal/_msg_command_warning.html:10 msgid "Risk level" msgstr "リスクレベル" @@ -5827,7 +5827,7 @@ msgstr "同時実行可能" msgid "Tags" msgstr "ラベル" -#: terminal/models/applet/applet.py:47 terminal/serializers/storage.py:157 +#: terminal/models/applet/applet.py:47 terminal/serializers/storage.py:159 msgid "Hosts" msgstr "ホスト" @@ -5906,9 +5906,9 @@ msgstr "Redis ポート" #: terminal/models/component/endpoint.py:29 #: terminal/models/component/endpoint.py:100 -#: terminal/serializers/endpoint.py:73 terminal/serializers/storage.py:38 -#: terminal/serializers/storage.py:50 terminal/serializers/storage.py:80 -#: terminal/serializers/storage.py:90 terminal/serializers/storage.py:98 +#: terminal/serializers/endpoint.py:73 terminal/serializers/storage.py:40 +#: terminal/serializers/storage.py:52 terminal/serializers/storage.py:82 +#: terminal/serializers/storage.py:92 terminal/serializers/storage.py:100 msgid "Endpoint" msgstr "エンドポイント" @@ -5966,7 +5966,7 @@ msgstr "再生ストレージ" msgid "type" msgstr "タイプ" -#: terminal/models/component/terminal.py:89 terminal/serializers/command.py:77 +#: terminal/models/component/terminal.py:89 terminal/serializers/command.py:76 msgid "Remote Address" msgstr "リモートアドレス" @@ -6151,7 +6151,7 @@ msgstr "" "URL を入力します。
例: https://172.16.10.110 または https://dev." "jumpserver.com" -#: terminal/serializers/applet_host.py:46 terminal/serializers/storage.py:168 +#: terminal/serializers/applet_host.py:46 terminal/serializers/storage.py:170 msgid "Ignore Certificate Verification" msgstr "証明書の検証を無視する" @@ -6183,35 +6183,35 @@ msgstr "RDS 远程应用注销时间限制" msgid "Load status" msgstr "ロードステータス" -#: terminal/serializers/command.py:20 +#: terminal/serializers/command.py:19 msgid "Session ID" msgstr "セッションID" -#: terminal/serializers/command.py:42 +#: terminal/serializers/command.py:41 msgid "Command Filter ACL" msgstr "コマンドフィルター" -#: terminal/serializers/command.py:45 +#: terminal/serializers/command.py:44 msgid "Command Group" msgstr "コマンドグループ" -#: terminal/serializers/command.py:56 +#: terminal/serializers/command.py:55 msgid "Invalid command filter ACL id" msgstr "無効なコマンドフィルターID" -#: terminal/serializers/command.py:60 +#: terminal/serializers/command.py:59 msgid "Invalid command group id" msgstr "無効なコマンドグループID" -#: terminal/serializers/command.py:64 +#: terminal/serializers/command.py:63 msgid "Invalid session id" msgstr "無効なセッションID" -#: terminal/serializers/command.py:73 +#: terminal/serializers/command.py:72 msgid "Account " msgstr "アカウント" -#: terminal/serializers/command.py:75 +#: terminal/serializers/command.py:74 msgid "Timestamp" msgstr "タイムスタンプ" @@ -6290,65 +6290,65 @@ msgstr "ターミナルディスプレイ" msgid "Command amount" msgstr "コマンド量" -#: terminal/serializers/storage.py:20 +#: terminal/serializers/storage.py:22 msgid "Endpoint invalid: remove path `{}`" msgstr "エンドポイントが無効: パス '{}' を削除" -#: terminal/serializers/storage.py:26 +#: terminal/serializers/storage.py:28 msgid "Bucket" msgstr "バケット" -#: terminal/serializers/storage.py:30 +#: terminal/serializers/storage.py:32 #: xpack/plugins/cloud/serializers/account_attrs.py:17 msgid "Access key id" msgstr "アクセスキー" -#: terminal/serializers/storage.py:34 +#: terminal/serializers/storage.py:36 #: xpack/plugins/cloud/serializers/account_attrs.py:20 msgid "Access key secret" msgstr "アクセスキーシークレット" -#: terminal/serializers/storage.py:65 xpack/plugins/cloud/models.py:209 +#: terminal/serializers/storage.py:67 xpack/plugins/cloud/models.py:209 msgid "Region" msgstr "リージョン" -#: terminal/serializers/storage.py:109 +#: terminal/serializers/storage.py:111 msgid "Container name" msgstr "コンテナー名" -#: terminal/serializers/storage.py:112 +#: terminal/serializers/storage.py:114 msgid "Account key" msgstr "アカウントキー" -#: terminal/serializers/storage.py:115 +#: terminal/serializers/storage.py:117 msgid "Endpoint suffix" msgstr "エンドポイントサフィックス" -#: terminal/serializers/storage.py:135 +#: terminal/serializers/storage.py:137 msgid "The address format is incorrect" msgstr "アドレス形式が正しくありません" -#: terminal/serializers/storage.py:142 +#: terminal/serializers/storage.py:144 msgid "Host invalid" msgstr "ホスト無効" -#: terminal/serializers/storage.py:145 +#: terminal/serializers/storage.py:147 msgid "Port invalid" msgstr "ポートが無効" -#: terminal/serializers/storage.py:160 +#: terminal/serializers/storage.py:162 msgid "Index by date" msgstr "日付による索引付け" -#: terminal/serializers/storage.py:161 +#: terminal/serializers/storage.py:163 msgid "Whether to create an index by date" msgstr "現在の日付に基づいてインデックスを動的に作成するかどうか" -#: terminal/serializers/storage.py:164 +#: terminal/serializers/storage.py:166 msgid "Index" msgstr "インデックス" -#: terminal/serializers/storage.py:166 +#: terminal/serializers/storage.py:168 msgid "Doc type" msgstr "Docタイプ" @@ -6527,7 +6527,7 @@ msgstr "チケットフロー承認ルール" msgid "Ticket flow" msgstr "チケットの流れ" -#: tickets/models/relation.py:10 +#: tickets/models/relation.py:12 msgid "Ticket session relation" msgstr "チケットセッションの関係" @@ -6601,11 +6601,11 @@ msgstr "承認ステップ" msgid "Relation snapshot" msgstr "製造オーダスナップショット" -#: tickets/models/ticket/general.py:398 +#: tickets/models/ticket/general.py:401 msgid "Please try again" msgstr "もう一度お試しください" -#: tickets/models/ticket/general.py:467 +#: tickets/models/ticket/general.py:470 msgid "Super ticket" msgstr "スーパーチケット" @@ -6711,7 +6711,7 @@ msgid "Ticket information" msgstr "作業指示情報" #: tickets/templates/tickets/approve_check_password.html:29 -#: tickets/views/approve.py:38 +#: tickets/views/approve.py:39 msgid "Ticket approval" msgstr "作業指示の承認" @@ -6723,30 +6723,30 @@ msgstr "承認" msgid "Go Login" msgstr "ログイン" -#: tickets/views/approve.py:39 +#: tickets/views/approve.py:40 msgid "" "This ticket does not exist, the process has ended, or this link has expired" msgstr "" "このワークシートが存在しないか、ワークシートが終了したか、このリンクが無効に" "なっています" -#: tickets/views/approve.py:68 +#: tickets/views/approve.py:69 msgid "Click the button below to approve or reject" msgstr "下のボタンをクリックして同意または拒否。" -#: tickets/views/approve.py:70 +#: tickets/views/approve.py:71 msgid "After successful authentication, this ticket can be approved directly" msgstr "認証に成功した後、作業指示書は直接承認することができる。" -#: tickets/views/approve.py:92 +#: tickets/views/approve.py:93 msgid "Illegal approval action" msgstr "無効な承認アクション" -#: tickets/views/approve.py:105 +#: tickets/views/approve.py:106 msgid "This user is not authorized to approve this ticket" msgstr "このユーザーはこの作業指示を承認する権限がありません" -#: users/api/user.py:191 +#: users/api/user.py:190 msgid "Could not reset self otp, use profile reset instead" msgstr "自己otpをリセットできませんでした、代わりにプロファイルリセットを使用" @@ -6908,27 +6908,27 @@ msgstr "最終更新日パスワード" msgid "Need update password" msgstr "更新パスワードが必要" -#: users/models/user.py:949 +#: users/models/user.py:954 msgid "Can invite user" msgstr "ユーザーを招待できます" -#: users/models/user.py:950 +#: users/models/user.py:955 msgid "Can remove user" msgstr "ユーザーを削除できます" -#: users/models/user.py:951 +#: users/models/user.py:956 msgid "Can match user" msgstr "ユーザーに一致できます" -#: users/models/user.py:960 +#: users/models/user.py:965 msgid "Administrator" msgstr "管理者" -#: users/models/user.py:963 +#: users/models/user.py:968 msgid "Administrator is the super user of system" msgstr "管理者はシステムのスーパーユーザーです" -#: users/models/user.py:988 +#: users/models/user.py:993 msgid "User password history" msgstr "ユーザーパスワード履歴" @@ -7253,36 +7253,36 @@ msgstr "" msgid "Open MFA Authenticator and enter the 6-bit dynamic code" msgstr "MFA Authenticatorを開き、6ビットの動的コードを入力します" -#: users/views/profile/otp.py:87 +#: users/views/profile/otp.py:85 msgid "Already bound" msgstr "すでにバインド済み" -#: users/views/profile/otp.py:88 +#: users/views/profile/otp.py:86 msgid "MFA already bound, disable first, then bound" msgstr "" "MFAはすでにバインドされており、最初に無効にしてからバインドされています。" -#: users/views/profile/otp.py:115 +#: users/views/profile/otp.py:113 msgid "OTP enable success" msgstr "OTP有効化成功" -#: users/views/profile/otp.py:116 +#: users/views/profile/otp.py:114 msgid "OTP enable success, return login page" msgstr "OTP有効化成功、ログインページを返す" -#: users/views/profile/otp.py:158 +#: users/views/profile/otp.py:156 msgid "Disable OTP" msgstr "OTPの無効化" -#: users/views/profile/otp.py:164 +#: users/views/profile/otp.py:162 msgid "OTP disable success" msgstr "OTP無効化成功" -#: users/views/profile/otp.py:165 +#: users/views/profile/otp.py:163 msgid "OTP disable success, return login page" msgstr "OTP無効化成功、ログインページを返す" -#: users/views/profile/password.py:36 users/views/profile/password.py:41 +#: users/views/profile/password.py:33 users/views/profile/password.py:38 msgid "Password invalid" msgstr "パスワード無効" @@ -7318,11 +7318,11 @@ msgstr "パスワードの成功をリセットし、ログインページに戻 msgid "XPACK" msgstr "XPack" -#: xpack/plugins/cloud/api.py:40 +#: xpack/plugins/cloud/api.py:38 msgid "Test connection successful" msgstr "テスト接続成功" -#: xpack/plugins/cloud/api.py:42 +#: xpack/plugins/cloud/api.py:40 msgid "Test connection failed: {}" msgstr "テスト接続に失敗しました: {}" @@ -7378,7 +7378,7 @@ msgstr "ucloud" msgid "VMware" msgstr "VMware" -#: xpack/plugins/cloud/const.py:23 xpack/plugins/cloud/providers/nutanix.py:13 +#: xpack/plugins/cloud/const.py:23 xpack/plugins/cloud/providers/nutanix.py:15 msgid "Nutanix" msgstr "Nutanix" @@ -7510,106 +7510,106 @@ msgstr "インスタンス" msgid "Sync instance detail" msgstr "同期インスタンスの詳細" -#: xpack/plugins/cloud/providers/aws_international.py:17 +#: xpack/plugins/cloud/providers/aws_international.py:18 msgid "China (Beijing)" msgstr "中国 (北京)" -#: xpack/plugins/cloud/providers/aws_international.py:18 +#: xpack/plugins/cloud/providers/aws_international.py:19 msgid "China (Ningxia)" msgstr "中国 (寧夏)" -#: xpack/plugins/cloud/providers/aws_international.py:21 +#: xpack/plugins/cloud/providers/aws_international.py:22 msgid "US East (Ohio)" msgstr "米国東部 (オハイオ州)" -#: xpack/plugins/cloud/providers/aws_international.py:22 +#: xpack/plugins/cloud/providers/aws_international.py:23 msgid "US East (N. Virginia)" msgstr "米国東部 (N. バージニア州)" -#: xpack/plugins/cloud/providers/aws_international.py:23 +#: xpack/plugins/cloud/providers/aws_international.py:24 msgid "US West (N. California)" msgstr "米国西部 (N. カリフォルニア州)" -#: xpack/plugins/cloud/providers/aws_international.py:24 +#: xpack/plugins/cloud/providers/aws_international.py:25 msgid "US West (Oregon)" msgstr "米国西部 (オレゴン州)" -#: xpack/plugins/cloud/providers/aws_international.py:25 +#: xpack/plugins/cloud/providers/aws_international.py:26 msgid "Africa (Cape Town)" msgstr "アフリカ (ケープタウン)" -#: xpack/plugins/cloud/providers/aws_international.py:26 +#: xpack/plugins/cloud/providers/aws_international.py:27 msgid "Asia Pacific (Hong Kong)" msgstr "アジアパシフィック (香港)" -#: xpack/plugins/cloud/providers/aws_international.py:27 +#: xpack/plugins/cloud/providers/aws_international.py:28 msgid "Asia Pacific (Mumbai)" msgstr "アジア太平洋 (ムンバイ)" -#: xpack/plugins/cloud/providers/aws_international.py:28 +#: xpack/plugins/cloud/providers/aws_international.py:29 msgid "Asia Pacific (Osaka-Local)" msgstr "アジアパシフィック (大阪-ローカル)" -#: xpack/plugins/cloud/providers/aws_international.py:29 +#: xpack/plugins/cloud/providers/aws_international.py:30 msgid "Asia Pacific (Seoul)" msgstr "アジア太平洋地域 (ソウル)" -#: xpack/plugins/cloud/providers/aws_international.py:30 +#: xpack/plugins/cloud/providers/aws_international.py:31 msgid "Asia Pacific (Singapore)" msgstr "アジア太平洋 (シンガポール)" -#: xpack/plugins/cloud/providers/aws_international.py:31 +#: xpack/plugins/cloud/providers/aws_international.py:32 msgid "Asia Pacific (Sydney)" msgstr "アジア太平洋 (シドニー)" -#: xpack/plugins/cloud/providers/aws_international.py:32 +#: xpack/plugins/cloud/providers/aws_international.py:33 msgid "Asia Pacific (Tokyo)" msgstr "アジアパシフィック (東京)" -#: xpack/plugins/cloud/providers/aws_international.py:33 +#: xpack/plugins/cloud/providers/aws_international.py:34 msgid "Canada (Central)" msgstr "カナダ (中央)" -#: xpack/plugins/cloud/providers/aws_international.py:34 +#: xpack/plugins/cloud/providers/aws_international.py:35 msgid "Europe (Frankfurt)" msgstr "ヨーロッパ (フランクフルト)" -#: xpack/plugins/cloud/providers/aws_international.py:35 +#: xpack/plugins/cloud/providers/aws_international.py:36 msgid "Europe (Ireland)" msgstr "ヨーロッパ (アイルランド)" -#: xpack/plugins/cloud/providers/aws_international.py:36 +#: xpack/plugins/cloud/providers/aws_international.py:37 msgid "Europe (London)" msgstr "ヨーロッパ (ロンドン)" -#: xpack/plugins/cloud/providers/aws_international.py:37 +#: xpack/plugins/cloud/providers/aws_international.py:38 msgid "Europe (Milan)" msgstr "ヨーロッパ (ミラノ)" -#: xpack/plugins/cloud/providers/aws_international.py:38 +#: xpack/plugins/cloud/providers/aws_international.py:39 msgid "Europe (Paris)" msgstr "ヨーロッパ (パリ)" -#: xpack/plugins/cloud/providers/aws_international.py:39 +#: xpack/plugins/cloud/providers/aws_international.py:40 msgid "Europe (Stockholm)" msgstr "ヨーロッパ (ストックホルム)" -#: xpack/plugins/cloud/providers/aws_international.py:40 +#: xpack/plugins/cloud/providers/aws_international.py:41 msgid "Middle East (Bahrain)" msgstr "中东 (バーレーン)" -#: xpack/plugins/cloud/providers/aws_international.py:41 +#: xpack/plugins/cloud/providers/aws_international.py:42 msgid "South America (São Paulo)" msgstr "南米 (サンパウロ)" #: xpack/plugins/cloud/providers/baiducloud.py:54 -#: xpack/plugins/cloud/providers/jdcloud.py:127 +#: xpack/plugins/cloud/providers/jdcloud.py:125 msgid "CN North-Beijing" msgstr "華北-北京" #: xpack/plugins/cloud/providers/baiducloud.py:55 -#: xpack/plugins/cloud/providers/huaweicloud.py:40 -#: xpack/plugins/cloud/providers/jdcloud.py:130 +#: xpack/plugins/cloud/providers/huaweicloud.py:42 +#: xpack/plugins/cloud/providers/jdcloud.py:128 msgid "CN South-Guangzhou" msgstr "華南-広州" @@ -7618,7 +7618,7 @@ msgid "CN East-Suzhou" msgstr "華東-蘇州" #: xpack/plugins/cloud/providers/baiducloud.py:57 -#: xpack/plugins/cloud/providers/huaweicloud.py:48 +#: xpack/plugins/cloud/providers/huaweicloud.py:50 msgid "CN-Hong Kong" msgstr "中国-香港" @@ -7631,72 +7631,72 @@ msgid "CN North-Baoding" msgstr "華北-保定" #: xpack/plugins/cloud/providers/baiducloud.py:60 -#: xpack/plugins/cloud/providers/jdcloud.py:129 +#: xpack/plugins/cloud/providers/jdcloud.py:127 msgid "CN East-Shanghai" msgstr "華東-上海" #: xpack/plugins/cloud/providers/baiducloud.py:61 -#: xpack/plugins/cloud/providers/huaweicloud.py:47 +#: xpack/plugins/cloud/providers/huaweicloud.py:49 msgid "AP-Singapore" msgstr "アジア太平洋-シンガポール" -#: xpack/plugins/cloud/providers/huaweicloud.py:35 +#: xpack/plugins/cloud/providers/huaweicloud.py:37 msgid "AF-Johannesburg" msgstr "アフリカ-ヨハネスブルク" -#: xpack/plugins/cloud/providers/huaweicloud.py:36 +#: xpack/plugins/cloud/providers/huaweicloud.py:38 msgid "CN North-Beijing4" msgstr "華北-北京4" -#: xpack/plugins/cloud/providers/huaweicloud.py:37 +#: xpack/plugins/cloud/providers/huaweicloud.py:39 msgid "CN North-Beijing1" msgstr "華北-北京1" -#: xpack/plugins/cloud/providers/huaweicloud.py:38 +#: xpack/plugins/cloud/providers/huaweicloud.py:40 msgid "CN East-Shanghai2" msgstr "華東-上海2" -#: xpack/plugins/cloud/providers/huaweicloud.py:39 +#: xpack/plugins/cloud/providers/huaweicloud.py:41 msgid "CN East-Shanghai1" msgstr "華東-上海1" -#: xpack/plugins/cloud/providers/huaweicloud.py:41 +#: xpack/plugins/cloud/providers/huaweicloud.py:43 msgid "LA-Mexico City1" msgstr "LA-メキシコCity1" -#: xpack/plugins/cloud/providers/huaweicloud.py:42 +#: xpack/plugins/cloud/providers/huaweicloud.py:44 msgid "LA-Santiago" msgstr "ラテンアメリカ-サンディエゴ" -#: xpack/plugins/cloud/providers/huaweicloud.py:43 +#: xpack/plugins/cloud/providers/huaweicloud.py:45 msgid "LA-Sao Paulo1" msgstr "ラミー・サンパウロ1" -#: xpack/plugins/cloud/providers/huaweicloud.py:44 +#: xpack/plugins/cloud/providers/huaweicloud.py:46 msgid "EU-Paris" msgstr "ヨーロッパ-パリ" -#: xpack/plugins/cloud/providers/huaweicloud.py:45 +#: xpack/plugins/cloud/providers/huaweicloud.py:47 msgid "CN Southwest-Guiyang1" msgstr "南西-貴陽1" -#: xpack/plugins/cloud/providers/huaweicloud.py:46 +#: xpack/plugins/cloud/providers/huaweicloud.py:48 msgid "AP-Bangkok" msgstr "アジア太平洋-バンコク" -#: xpack/plugins/cloud/providers/huaweicloud.py:50 +#: xpack/plugins/cloud/providers/huaweicloud.py:52 msgid "CN Northeast-Dalian" msgstr "华北-大连" -#: xpack/plugins/cloud/providers/huaweicloud.py:51 +#: xpack/plugins/cloud/providers/huaweicloud.py:53 msgid "CN North-Ulanqab1" msgstr "華北-ウランチャブ一" -#: xpack/plugins/cloud/providers/huaweicloud.py:52 +#: xpack/plugins/cloud/providers/huaweicloud.py:54 msgid "CN South-Guangzhou-InvitationOnly" msgstr "華南-広州-友好ユーザー環境" -#: xpack/plugins/cloud/providers/jdcloud.py:128 +#: xpack/plugins/cloud/providers/jdcloud.py:126 msgid "CN East-Suqian" msgstr "華東-宿遷" @@ -7824,7 +7824,7 @@ msgstr "同期インスタンス タスクを実行する" msgid "Period clean sync instance task execution" msgstr "同期インスタンス タスクの実行記録を定期的にクリアする" -#: xpack/plugins/cloud/utils.py:69 +#: xpack/plugins/cloud/utils.py:68 msgid "Account unavailable" msgstr "利用できないアカウント" @@ -7832,7 +7832,7 @@ msgstr "利用できないアカウント" msgid "Restore default successfully." msgstr "デフォルトの復元に成功しました。" -#: xpack/plugins/interface/meta.py:10 +#: xpack/plugins/interface/meta.py:9 msgid "Interface settings" msgstr "インターフェイスの設定" @@ -7864,15 +7864,15 @@ msgstr "テーマ" msgid "Interface setting" msgstr "インターフェイスの設定" -#: xpack/plugins/license/api.py:50 +#: xpack/plugins/license/api.py:52 msgid "License import successfully" msgstr "ライセンスのインポートに成功" -#: xpack/plugins/license/api.py:51 +#: xpack/plugins/license/api.py:53 msgid "License is invalid" msgstr "ライセンスが無効です" -#: xpack/plugins/license/meta.py:11 xpack/plugins/license/models.py:138 +#: xpack/plugins/license/meta.py:10 xpack/plugins/license/models.py:138 msgid "License" msgstr "ライセンス" diff --git a/apps/locale/zh/LC_MESSAGES/django.mo b/apps/locale/zh/LC_MESSAGES/django.mo index 14979766a..145af8511 100644 --- a/apps/locale/zh/LC_MESSAGES/django.mo +++ b/apps/locale/zh/LC_MESSAGES/django.mo @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1b88bc1c5216d7cfc2b0a72d889198bcab84ddd40dd3f5a13a5662dfcf8170ee -size 121846 +oid sha256:859c812ee67cc9b5f79da96d5e72445a60bdd19af7db4a8b71196a065adefeab +size 121844 diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po index 58edc7f08..10fd864cc 100644 --- a/apps/locale/zh/LC_MESSAGES/django.po +++ b/apps/locale/zh/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: JumpServer 0.3.3\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-07-20 18:40+0800\n" +"POT-Creation-Date: 2023-07-25 15:37+0800\n" "PO-Revision-Date: 2021-05-20 10:54+0800\n" "Last-Translator: ibuler \n" "Language-Team: JumpServer team\n" @@ -198,8 +198,8 @@ msgstr "仅创建" #: assets/serializers/domain.py:19 assets/serializers/label.py:27 #: audits/models.py:53 authentication/models/connection_token.py:36 #: perms/models/asset_permission.py:64 perms/serializers/permission.py:34 -#: terminal/backends/command/models.py:18 terminal/models/session/session.py:31 -#: terminal/notifications.py:155 terminal/serializers/command.py:18 +#: terminal/backends/command/models.py:17 terminal/models/session/session.py:31 +#: terminal/notifications.py:155 terminal/serializers/command.py:17 #: terminal/templates/terminal/_msg_command_warning.html:4 #: tickets/models/ticket/apply_asset.py:16 xpack/plugins/cloud/models.py:212 msgid "Asset" @@ -233,7 +233,7 @@ msgstr "来源 ID" #: acls/serializers/base.py:124 assets/serializers/asset/common.py:125 #: assets/serializers/gateway.py:28 audits/models.py:54 ops/models/base.py:18 #: perms/models/asset_permission.py:70 perms/serializers/permission.py:39 -#: terminal/backends/command/models.py:19 terminal/models/session/session.py:33 +#: terminal/backends/command/models.py:18 terminal/models/session/session.py:33 #: terminal/templates/terminal/_msg_command_warning.html:8 #: tickets/models/ticket/command_confirm.py:13 xpack/plugins/cloud/models.py:85 msgid "Account" @@ -416,8 +416,8 @@ msgstr "结束日期" #: accounts/models/automations/change_secret.py:93 #: accounts/serializers/account/account.py:239 assets/const/automation.py:8 -#: authentication/views/base.py:29 authentication/views/base.py:30 -#: authentication/views/base.py:31 common/const/choices.py:20 +#: authentication/views/base.py:26 authentication/views/base.py:27 +#: authentication/views/base.py:28 common/const/choices.py:20 msgid "Error" msgstr "错误" @@ -469,7 +469,7 @@ msgstr "触发方式" #: accounts/models/automations/push_account.py:16 acls/models/base.py:41 #: acls/serializers/base.py:57 assets/models/cmd_filter.py:81 -#: audits/models.py:87 audits/serializers.py:82 +#: audits/models.py:87 audits/serializers.py:83 #: authentication/serializers/connect_token_secret.py:116 #: authentication/templates/authentication/_access_key_modal.html:34 msgid "Action" @@ -493,10 +493,10 @@ msgstr "账号验证" #: assets/serializers/asset/common.py:146 assets/serializers/platform.py:110 #: assets/serializers/platform.py:223 #: authentication/serializers/connect_token_secret.py:110 ops/mixin.py:21 -#: ops/models/adhoc.py:21 ops/models/celery.py:15 ops/models/celery.py:57 +#: ops/models/adhoc.py:20 ops/models/celery.py:15 ops/models/celery.py:57 #: ops/models/job.py:94 ops/models/playbook.py:23 ops/serializers/job.py:20 #: orgs/models.py:80 perms/models/asset_permission.py:56 rbac/models/role.py:29 -#: settings/models.py:33 settings/serializers/sms.py:6 +#: settings/models.py:32 settings/serializers/sms.py:6 #: terminal/models/applet/applet.py:32 terminal/models/component/endpoint.py:12 #: terminal/models/component/endpoint.py:92 #: terminal/models/component/storage.py:26 terminal/models/component/task.py:15 @@ -569,7 +569,7 @@ msgstr "账号存在策略" #: assets/models/label.py:21 assets/models/platform.py:89 #: assets/serializers/asset/common.py:121 assets/serializers/cagegory.py:8 #: assets/serializers/platform.py:128 assets/serializers/platform.py:224 -#: perms/serializers/user_permission.py:26 settings/models.py:35 +#: perms/serializers/user_permission.py:26 settings/models.py:34 #: tickets/models/ticket/apply_application.py:13 msgid "Category" msgstr "类别" @@ -580,13 +580,13 @@ msgstr "类别" #: assets/models/_user.py:50 assets/models/automations/base.py:20 #: assets/models/cmd_filter.py:74 assets/models/platform.py:90 #: assets/serializers/asset/common.py:122 assets/serializers/platform.py:112 -#: assets/serializers/platform.py:127 audits/serializers.py:48 +#: assets/serializers/platform.py:127 audits/serializers.py:49 #: authentication/serializers/connect_token_secret.py:123 ops/models/job.py:105 #: perms/serializers/user_permission.py:27 terminal/models/applet/applet.py:38 #: terminal/models/component/storage.py:57 #: terminal/models/component/storage.py:146 terminal/serializers/applet.py:29 -#: terminal/serializers/session.py:20 terminal/serializers/storage.py:224 -#: terminal/serializers/storage.py:236 tickets/models/comment.py:26 +#: terminal/serializers/session.py:20 terminal/serializers/storage.py:226 +#: terminal/serializers/storage.py:238 tickets/models/comment.py:26 #: tickets/models/flow.py:56 tickets/models/ticket/apply_application.py:16 #: tickets/models/ticket/general.py:275 tickets/serializers/flow.py:53 #: tickets/serializers/ticket/ticket.py:19 @@ -650,13 +650,13 @@ msgstr "ID" #: notifications/models/notification.py:12 #: perms/api/user_permission/mixin.py:55 perms/models/asset_permission.py:58 #: perms/serializers/permission.py:30 rbac/builtin.py:123 -#: rbac/models/rolebinding.py:49 terminal/backends/command/models.py:17 +#: rbac/models/rolebinding.py:49 terminal/backends/command/models.py:16 #: terminal/models/session/session.py:29 terminal/models/session/sharing.py:32 #: terminal/notifications.py:156 terminal/notifications.py:205 -#: terminal/serializers/command.py:17 +#: terminal/serializers/command.py:16 #: terminal/templates/terminal/_msg_command_warning.html:6 #: tickets/models/comment.py:21 users/const.py:14 users/models/user.py:947 -#: users/models/user.py:978 users/serializers/group.py:18 +#: users/models/user.py:983 users/serializers/group.py:18 msgid "User" msgstr "用户" @@ -742,7 +742,7 @@ msgstr "自动化任务执行历史" #: audits/models.py:59 audits/signal_handlers/activity_log.py:33 #: common/const/choices.py:18 ops/const.py:56 ops/serializers/celery.py:40 #: terminal/const.py:76 terminal/models/session/sharing.py:107 -#: tickets/views/approve.py:114 +#: tickets/views/approve.py:115 msgid "Success" msgstr "成功" @@ -842,7 +842,7 @@ msgstr "账号管理" #: acls/models/command_acl.py:16 assets/models/cmd_filter.py:60 #: ops/serializers/job.py:55 terminal/const.py:84 -#: terminal/models/session/session.py:42 terminal/serializers/command.py:19 +#: terminal/models/session/session.py:42 terminal/serializers/command.py:18 #: terminal/templates/terminal/_msg_command_alert.html:12 #: terminal/templates/terminal/_msg_command_execute_alert.html:10 #: terminal/templates/terminal/_msg_command_warning.html:23 @@ -990,7 +990,7 @@ msgstr "匹配应用" msgid "Cannot create asset directly, you should create a host or other" msgstr "不能直接创建资产, 你应该创建主机或其他资产" -#: assets/api/domain.py:62 +#: assets/api/domain.py:63 msgid "Number required" msgstr "需要为数字" @@ -1033,7 +1033,7 @@ msgid "Unable to connect to port {port} on {address}" msgstr "无法连接到 {port} 上的端口 {address}" #: assets/automations/ping_gateway/manager.py:58 -#: authentication/middleware.py:92 xpack/plugins/cloud/providers/fc.py:48 +#: authentication/middleware.py:92 xpack/plugins/cloud/providers/fc.py:47 msgid "Authentication failed" msgstr "认证失败" @@ -1165,7 +1165,7 @@ msgstr "连接到控制台会话" msgid "Any" msgstr "任意" -#: assets/const/protocol.py:66 settings/serializers/security.py:151 +#: assets/const/protocol.py:66 settings/serializers/security.py:153 msgid "Security" msgstr "安全" @@ -1229,8 +1229,8 @@ msgstr "SSH公钥" #: assets/models/_user.py:27 assets/models/cmd_filter.py:40 #: assets/models/cmd_filter.py:88 assets/models/group.py:20 -#: common/db/models.py:36 ops/models/adhoc.py:27 ops/models/job.py:113 -#: ops/models/playbook.py:26 rbac/models/role.py:37 settings/models.py:38 +#: common/db/models.py:36 ops/models/adhoc.py:26 ops/models/job.py:113 +#: ops/models/playbook.py:26 rbac/models/role.py:37 settings/models.py:37 #: terminal/models/applet/applet.py:44 terminal/models/applet/applet.py:248 #: terminal/models/applet/host.py:139 terminal/models/component/endpoint.py:24 #: terminal/models/component/endpoint.py:102 @@ -1243,7 +1243,7 @@ msgstr "备注" #: assets/models/_user.py:28 assets/models/automations/base.py:114 #: assets/models/cmd_filter.py:41 assets/models/group.py:19 #: common/db/models.py:34 ops/models/base.py:54 ops/models/job.py:193 -#: users/models/user.py:979 +#: users/models/user.py:984 msgid "Date created" msgstr "创建日期" @@ -1282,7 +1282,7 @@ msgstr "用户名与用户相同" #: assets/models/_user.py:52 authentication/models/connection_token.py:41 #: authentication/serializers/connect_token_secret.py:111 #: terminal/models/applet/applet.py:41 terminal/serializers/session.py:18 -#: terminal/serializers/session.py:39 terminal/serializers/storage.py:68 +#: terminal/serializers/session.py:39 terminal/serializers/storage.py:70 msgid "Protocol" msgstr "协议" @@ -1424,7 +1424,7 @@ msgid "Asset automation task" msgstr "资产自动化任务" #: assets/models/automations/base.py:113 audits/models.py:199 -#: audits/serializers.py:49 ops/models/base.py:49 ops/models/job.py:186 +#: audits/serializers.py:50 ops/models/base.py:49 ops/models/job.py:186 #: terminal/models/applet/applet.py:247 terminal/models/applet/host.py:136 #: terminal/models/component/status.py:30 terminal/serializers/applet.py:18 #: terminal/serializers/applet_host.py:107 tickets/models/ticket/general.py:283 @@ -1494,7 +1494,7 @@ msgstr "资产组" #: assets/models/group.py:31 assets/models/platform.py:19 #: assets/serializers/platform.py:113 -#: xpack/plugins/cloud/providers/nutanix.py:30 +#: xpack/plugins/cloud/providers/nutanix.py:32 msgid "Default" msgstr "默认" @@ -1502,15 +1502,15 @@ msgstr "默认" msgid "Default asset group" msgstr "默认资产组" -#: assets/models/label.py:15 rbac/const.py:6 users/models/user.py:964 +#: assets/models/label.py:15 rbac/const.py:6 users/models/user.py:969 msgid "System" msgstr "系统" -#: assets/models/label.py:19 assets/models/node.py:545 +#: assets/models/label.py:19 assets/models/node.py:544 #: assets/serializers/cagegory.py:7 assets/serializers/cagegory.py:14 #: authentication/models/connection_token.py:29 #: authentication/serializers/connect_token_secret.py:122 -#: common/serializers/common.py:86 settings/models.py:34 +#: common/serializers/common.py:86 settings/models.py:33 msgid "Value" msgstr "值" @@ -1523,32 +1523,32 @@ msgstr "值" msgid "Label" msgstr "标签" -#: assets/models/node.py:166 +#: assets/models/node.py:165 msgid "New node" msgstr "新节点" -#: assets/models/node.py:473 audits/backends/db.py:55 audits/backends/db.py:56 +#: assets/models/node.py:472 audits/backends/db.py:55 audits/backends/db.py:56 msgid "empty" msgstr "空" -#: assets/models/node.py:544 perms/models/perm_node.py:28 +#: assets/models/node.py:543 perms/models/perm_node.py:28 msgid "Key" msgstr "键" -#: assets/models/node.py:546 assets/serializers/node.py:20 +#: assets/models/node.py:545 assets/serializers/node.py:20 msgid "Full value" msgstr "全称" -#: assets/models/node.py:550 perms/models/perm_node.py:30 +#: assets/models/node.py:549 perms/models/perm_node.py:30 msgid "Parent key" msgstr "ssh私钥" -#: assets/models/node.py:559 perms/serializers/permission.py:35 +#: assets/models/node.py:558 perms/serializers/permission.py:35 #: tickets/models/ticket/apply_asset.py:14 xpack/plugins/cloud/models.py:96 msgid "Node" msgstr "节点" -#: assets/models/node.py:562 +#: assets/models/node.py:561 msgid "Can match node" msgstr "可以匹配节点" @@ -1565,12 +1565,12 @@ msgid "Public" msgstr "开放的" #: assets/models/platform.py:21 assets/serializers/platform.py:48 -#: settings/serializers/settings.py:67 +#: settings/serializers/settings.py:66 #: users/templates/users/reset_password.html:29 msgid "Setting" msgstr "设置" -#: assets/models/platform.py:38 audits/const.py:48 settings/models.py:37 +#: assets/models/platform.py:38 audits/const.py:48 settings/models.py:36 #: terminal/serializers/applet_host.py:33 msgid "Enabled" msgstr "启用" @@ -1796,7 +1796,7 @@ msgstr "约束" msgid "Types" msgstr "类型" -#: assets/serializers/gateway.py:23 common/validators.py:35 +#: assets/serializers/gateway.py:23 common/validators.py:34 msgid "This field must be unique." msgstr "字段必须唯一" @@ -1918,19 +1918,19 @@ msgstr "测试节点下资产是否可连接" msgid "Test gateways connectivity" msgstr "测试网关可连接性" -#: assets/tasks/utils.py:17 +#: assets/tasks/utils.py:16 msgid "Asset has been disabled, skipped: {}" msgstr "资产已经被禁用, 跳过: {}" -#: assets/tasks/utils.py:21 +#: assets/tasks/utils.py:20 msgid "Asset may not be support ansible, skipped: {}" msgstr "资产或许不支持ansible, 跳过: {}" -#: assets/tasks/utils.py:39 +#: assets/tasks/utils.py:38 msgid "For security, do not push user {}" msgstr "为了安全,禁止推送用户 {}" -#: assets/tasks/utils.py:55 +#: assets/tasks/utils.py:54 msgid "No assets matched, stop task" msgstr "没有匹配到资产,结束任务" @@ -2049,7 +2049,7 @@ msgstr "作业审计日志" msgid "Remote addr" msgstr "远端地址" -#: audits/models.py:56 audits/serializers.py:33 +#: audits/models.py:56 audits/serializers.py:34 msgid "Operate" msgstr "操作" @@ -2061,7 +2061,7 @@ msgstr "文件名" msgid "File" msgstr "文件" -#: audits/models.py:62 terminal/backends/command/models.py:22 +#: audits/models.py:62 terminal/backends/command/models.py:21 #: terminal/models/session/replay.py:9 terminal/models/session/sharing.py:18 #: terminal/models/session/sharing.py:81 #: terminal/templates/terminal/_msg_command_alert.html:10 @@ -2074,17 +2074,17 @@ msgstr "会话" msgid "File transfer log" msgstr "文件管理" -#: audits/models.py:89 audits/serializers.py:84 +#: audits/models.py:89 audits/serializers.py:85 msgid "Resource Type" msgstr "资源类型" #: audits/models.py:90 audits/models.py:93 audits/models.py:139 -#: audits/serializers.py:83 +#: audits/serializers.py:84 msgid "Resource" msgstr "资源" #: audits/models.py:96 audits/models.py:142 audits/models.py:168 -#: terminal/serializers/command.py:76 +#: terminal/serializers/command.py:75 msgid "Datetime" msgstr "日期" @@ -2126,11 +2126,11 @@ msgstr "登录 IP" msgid "Login city" msgstr "登录城市" -#: audits/models.py:188 audits/serializers.py:63 +#: audits/models.py:188 audits/serializers.py:64 msgid "User agent" msgstr "用户代理" -#: audits/models.py:191 audits/serializers.py:47 +#: audits/models.py:191 audits/serializers.py:48 #: authentication/templates/authentication/_mfa_confirm_modal.html:14 #: users/forms/profile.py:65 users/models/user.py:776 #: users/serializers/profile.py:126 @@ -2141,7 +2141,7 @@ msgstr "MFA" msgid "Date login" msgstr "登录日期" -#: audits/models.py:203 audits/serializers.py:65 +#: audits/models.py:203 audits/serializers.py:66 msgid "Authentication backend" msgstr "认证方式" @@ -2149,11 +2149,11 @@ msgstr "认证方式" msgid "User login log" msgstr "用户登录日志" -#: audits/serializers.py:64 +#: audits/serializers.py:65 msgid "Reason display" msgstr "原因描述" -#: audits/serializers.py:132 +#: audits/serializers.py:133 #, python-format msgid "User %s %s this resource" msgstr "用户 %s %s 了当前资源" @@ -2192,7 +2192,7 @@ msgstr "认证令牌" msgid "WeCom" msgstr "企业微信" -#: audits/signal_handlers/login_log.py:32 authentication/views/feishu.py:123 +#: audits/signal_handlers/login_log.py:32 authentication/views/feishu.py:122 #: authentication/views/login.py:87 notifications/backends/__init__.py:14 #: settings/serializers/auth/feishu.py:10 #: settings/serializers/auth/feishu.py:13 users/models/user.py:708 @@ -2200,7 +2200,7 @@ msgstr "企业微信" msgid "FeiShu" msgstr "飞书" -#: audits/signal_handlers/login_log.py:33 authentication/views/dingtalk.py:160 +#: audits/signal_handlers/login_log.py:33 authentication/views/dingtalk.py:159 #: authentication/views/login.py:81 notifications/backends/__init__.py:12 #: settings/serializers/auth/dingtalk.py:10 users/models/user.py:707 #: users/models/user.py:815 @@ -2248,7 +2248,7 @@ msgstr "ACL 动作是拒绝: {}({})" msgid "ACL action is review" msgstr "ACL 动作是复核" -#: authentication/api/mfa.py:59 +#: authentication/api/mfa.py:57 msgid "Current user not support mfa type: {}" msgstr "当前用户不支持 MFA 类型: {}" @@ -2285,54 +2285,54 @@ msgstr "认证" msgid "User invalid, disabled or expired" msgstr "用户无效,已禁用或已过期" -#: authentication/backends/drf.py:56 +#: authentication/backends/drf.py:54 msgid "Invalid signature header. No credentials provided." msgstr "不合法的签名头" -#: authentication/backends/drf.py:59 +#: authentication/backends/drf.py:57 msgid "Invalid signature header. Signature string should not contain spaces." msgstr "不合法的签名头" -#: authentication/backends/drf.py:66 +#: authentication/backends/drf.py:64 msgid "Invalid signature header. Format like AccessKeyId:Signature" msgstr "不合法的签名头" -#: authentication/backends/drf.py:70 +#: authentication/backends/drf.py:68 msgid "" "Invalid signature header. Signature string should not contain invalid " "characters." msgstr "不合法的签名头" -#: authentication/backends/drf.py:90 authentication/backends/drf.py:106 +#: authentication/backends/drf.py:88 authentication/backends/drf.py:104 msgid "Invalid signature." msgstr "签名无效" -#: authentication/backends/drf.py:97 +#: authentication/backends/drf.py:95 msgid "HTTP header: Date not provide or not %a, %d %b %Y %H:%M:%S GMT" msgstr "HTTP header not valid" -#: authentication/backends/drf.py:102 +#: authentication/backends/drf.py:100 msgid "Expired, more than 15 minutes" msgstr "已过期,超过15分钟" -#: authentication/backends/drf.py:109 +#: authentication/backends/drf.py:107 msgid "User disabled." msgstr "用户已禁用" -#: authentication/backends/drf.py:127 +#: authentication/backends/drf.py:125 msgid "Invalid token header. No credentials provided." msgstr "无效的令牌头。没有提供任何凭据。" -#: authentication/backends/drf.py:130 +#: authentication/backends/drf.py:128 msgid "Invalid token header. Sign string should not contain spaces." msgstr "无效的令牌头。符号字符串不应包含空格。" -#: authentication/backends/drf.py:137 +#: authentication/backends/drf.py:135 msgid "" "Invalid token header. Sign string should not contain invalid characters." msgstr "无效的令牌头。符号字符串不应包含无效字符。" -#: authentication/backends/drf.py:148 +#: authentication/backends/drf.py:146 msgid "Invalid token or cache refreshed." msgstr "刷新的令牌或缓存无效。" @@ -2475,12 +2475,12 @@ msgstr "企业微信已经绑定" msgid "WeCom is not bound" msgstr "没有绑定企业微信" -#: authentication/errors/mfa.py:28 authentication/views/dingtalk.py:210 -#: authentication/views/dingtalk.py:252 +#: authentication/errors/mfa.py:28 authentication/views/dingtalk.py:209 +#: authentication/views/dingtalk.py:251 msgid "DingTalk is not bound" msgstr "钉钉没有绑定" -#: authentication/errors/mfa.py:33 authentication/views/feishu.py:167 +#: authentication/errors/mfa.py:33 authentication/views/feishu.py:166 msgid "FeiShu is not bound" msgstr "没有绑定飞书" @@ -2612,7 +2612,7 @@ msgid "Please change your password" msgstr "请修改密码" #: authentication/models/connection_token.py:38 -#: terminal/serializers/storage.py:111 +#: terminal/serializers/storage.py:113 msgid "Account name" msgstr "账号名称" @@ -2994,74 +2994,74 @@ msgstr "复制成功" msgid "LAN" msgstr "局域网" -#: authentication/views/base.py:64 +#: authentication/views/base.py:61 #: perms/templates/perms/_msg_permed_items_expire.html:21 msgid "If you have any question, please contact the administrator" msgstr "如果有疑问或需求,请联系系统管理员" -#: authentication/views/dingtalk.py:42 +#: authentication/views/dingtalk.py:41 msgid "DingTalk Error, Please contact your system administrator" msgstr "钉钉错误,请联系系统管理员" -#: authentication/views/dingtalk.py:45 authentication/views/dingtalk.py:209 +#: authentication/views/dingtalk.py:44 authentication/views/dingtalk.py:208 msgid "DingTalk Error" msgstr "钉钉错误" -#: authentication/views/dingtalk.py:57 authentication/views/feishu.py:51 +#: authentication/views/dingtalk.py:56 authentication/views/feishu.py:50 #: authentication/views/wecom.py:57 msgid "" "The system configuration is incorrect. Please contact your administrator" msgstr "企业配置错误,请联系系统管理员" -#: authentication/views/dingtalk.py:61 +#: authentication/views/dingtalk.py:60 msgid "DingTalk is already bound" msgstr "钉钉已经绑定" -#: authentication/views/dingtalk.py:129 authentication/views/wecom.py:129 +#: authentication/views/dingtalk.py:128 authentication/views/wecom.py:129 msgid "Invalid user_id" msgstr "无效的 user_id" -#: authentication/views/dingtalk.py:145 +#: authentication/views/dingtalk.py:144 msgid "DingTalk query user failed" msgstr "钉钉查询用户失败" -#: authentication/views/dingtalk.py:154 +#: authentication/views/dingtalk.py:153 msgid "The DingTalk is already bound to another user" msgstr "该钉钉已经绑定其他用户" -#: authentication/views/dingtalk.py:161 +#: authentication/views/dingtalk.py:160 msgid "Binding DingTalk successfully" msgstr "绑定 钉钉 成功" -#: authentication/views/dingtalk.py:211 authentication/views/dingtalk.py:246 +#: authentication/views/dingtalk.py:210 authentication/views/dingtalk.py:245 msgid "Failed to get user from DingTalk" msgstr "从钉钉获取用户失败" -#: authentication/views/dingtalk.py:253 +#: authentication/views/dingtalk.py:252 msgid "Please login with a password and then bind the DingTalk" msgstr "请使用密码登录,然后绑定钉钉" -#: authentication/views/feishu.py:39 authentication/views/feishu.py:166 +#: authentication/views/feishu.py:38 authentication/views/feishu.py:165 msgid "FeiShu Error" msgstr "飞书错误" -#: authentication/views/feishu.py:67 +#: authentication/views/feishu.py:66 msgid "FeiShu is already bound" msgstr "飞书已经绑定" -#: authentication/views/feishu.py:108 +#: authentication/views/feishu.py:107 msgid "FeiShu query user failed" msgstr "飞书查询用户失败" -#: authentication/views/feishu.py:117 +#: authentication/views/feishu.py:116 msgid "The FeiShu is already bound to another user" msgstr "该飞书已经绑定其他用户" -#: authentication/views/feishu.py:124 +#: authentication/views/feishu.py:123 msgid "Binding FeiShu successfully" msgstr "绑定 飞书 成功" -#: authentication/views/feishu.py:168 +#: authentication/views/feishu.py:167 msgid "Failed to get user from FeiShu" msgstr "从飞书获取用户失败" @@ -3297,11 +3297,11 @@ msgstr "此操作需要确认当前用户" msgid "Unexpect error occur" msgstr "发生意外错误" -#: common/plugins/es.py:28 +#: common/plugins/es.py:31 msgid "Invalid elasticsearch config" msgstr "无效的 Elasticsearch 配置" -#: common/plugins/es.py:33 +#: common/plugins/es.py:36 msgid "Not Support Elasticsearch8" msgstr "不支持 Elasticsearch8" @@ -3317,11 +3317,11 @@ msgstr "企业微信错误,请联系系统管理员" msgid "Signature does not match" msgstr "签名不匹配" -#: common/sdk/sms/cmpp2.py:46 +#: common/sdk/sms/cmpp2.py:44 msgid "sp_id is 6 bits" msgstr "SP_id 为6位" -#: common/sdk/sms/cmpp2.py:216 +#: common/sdk/sms/cmpp2.py:214 msgid "Failed to connect to the CMPP gateway server, err: {}" msgstr "连接网关服务器错误,错误:{}" @@ -3404,15 +3404,15 @@ msgstr "无效地址" msgid "Hello %s" msgstr "你好 %s" -#: common/validators.py:17 +#: common/validators.py:16 msgid "Special char not allowed" msgstr "不能包含特殊字符" -#: common/validators.py:43 +#: common/validators.py:42 msgid "Should not contains special characters" msgstr "不能包含特殊字符" -#: common/validators.py:48 +#: common/validators.py:47 msgid "The mobile phone number format is incorrect" msgstr "手机号格式不正确" @@ -3446,7 +3446,7 @@ msgstr "你的账号已创建成功" msgid "JumpServer Open Source Bastion Host" msgstr "JumpServer 开源堡垒机" -#: jumpserver/views/celery_flower.py:23 +#: jumpserver/views/celery_flower.py:22 msgid "

Flower service unavailable, check it

" msgstr "Flower 服务不可用,请检查" @@ -3569,7 +3569,7 @@ msgstr "空白" msgid "VCS" msgstr "VCS" -#: ops/const.py:38 ops/models/adhoc.py:45 +#: ops/const.py:38 ops/models/adhoc.py:44 msgid "Adhoc" msgstr "命令" @@ -3626,20 +3626,20 @@ msgstr "输入在 {} - {} 范围之间" msgid "Require periodic or regularly perform setting" msgstr "需要周期或定期设置" -#: ops/models/adhoc.py:22 +#: ops/models/adhoc.py:21 msgid "Pattern" msgstr "模式" -#: ops/models/adhoc.py:24 ops/models/job.py:98 +#: ops/models/adhoc.py:23 ops/models/job.py:98 msgid "Module" msgstr "模块" -#: ops/models/adhoc.py:25 ops/models/celery.py:58 ops/models/job.py:97 +#: ops/models/adhoc.py:24 ops/models/celery.py:58 ops/models/job.py:97 #: terminal/models/component/task.py:16 msgid "Args" msgstr "参数" -#: ops/models/adhoc.py:26 ops/models/base.py:16 ops/models/base.py:53 +#: ops/models/adhoc.py:25 ops/models/base.py:16 ops/models/base.py:53 #: ops/models/job.py:106 ops/models/job.py:192 ops/models/playbook.py:25 #: terminal/models/session/sharing.py:23 msgid "Creator" @@ -4077,7 +4077,7 @@ msgstr "Web终端" msgid "Can view file manager" msgstr "文件管理" -#: rbac/models/permission.py:26 rbac/models/role.py:34 +#: rbac/models/permission.py:27 rbac/models/role.py:34 msgid "Permissions" msgstr "授权" @@ -4121,7 +4121,7 @@ msgstr "组织角色绑定" msgid "System role binding" msgstr "系统角色绑定" -#: rbac/serializers/permission.py:26 users/serializers/profile.py:132 +#: rbac/serializers/permission.py:25 users/serializers/profile.py:132 msgid "Perms" msgstr "权限" @@ -4157,7 +4157,7 @@ msgstr "工作台" msgid "Audit view" msgstr "审计台" -#: rbac/tree.py:27 settings/models.py:159 +#: rbac/tree.py:27 settings/models.py:158 msgid "System setting" msgstr "系统设置" @@ -4256,47 +4256,47 @@ msgstr "测试手机号 该字段是必填项。" msgid "Settings" msgstr "系统设置" -#: settings/models.py:36 +#: settings/models.py:35 msgid "Encrypted" msgstr "加密的" -#: settings/models.py:161 +#: settings/models.py:160 msgid "Can change email setting" msgstr "邮件设置" -#: settings/models.py:162 +#: settings/models.py:161 msgid "Can change auth setting" msgstr "认证设置" -#: settings/models.py:163 +#: settings/models.py:162 msgid "Can change system msg sub setting" msgstr "消息订阅设置" -#: settings/models.py:164 +#: settings/models.py:163 msgid "Can change sms setting" msgstr "短信设置" -#: settings/models.py:165 +#: settings/models.py:164 msgid "Can change security setting" msgstr "安全设置" -#: settings/models.py:166 +#: settings/models.py:165 msgid "Can change clean setting" msgstr "定期清理" -#: settings/models.py:167 +#: settings/models.py:166 msgid "Can change interface setting" msgstr "界面设置" -#: settings/models.py:168 +#: settings/models.py:167 msgid "Can change license setting" msgstr "许可证设置" -#: settings/models.py:169 +#: settings/models.py:168 msgid "Can change terminal setting" msgstr "终端设置" -#: settings/models.py:170 +#: settings/models.py:169 msgid "Can change other setting" msgstr "其它设置" @@ -4357,7 +4357,7 @@ msgid "Proxy server url" msgstr "回调地址" #: settings/serializers/auth/cas.py:18 settings/serializers/auth/oauth2.py:54 -#: settings/serializers/auth/saml2.py:34 +#: settings/serializers/auth/saml2.py:33 msgid "Logout completely" msgstr "同步注销" @@ -4369,7 +4369,7 @@ msgstr "用户名属性" msgid "Enable attributes map" msgstr "启用属性映射" -#: settings/serializers/auth/cas.py:28 settings/serializers/auth/saml2.py:33 +#: settings/serializers/auth/cas.py:28 settings/serializers/auth/saml2.py:32 msgid "Rename attr" msgstr "映射属性" @@ -4489,7 +4489,7 @@ msgid "Provider end session endpoint" msgstr "注销会话端点地址" #: settings/serializers/auth/oauth2.py:59 settings/serializers/auth/oidc.py:98 -#: settings/serializers/auth/saml2.py:35 +#: settings/serializers/auth/saml2.py:34 msgid "Always update user" msgstr "总是更新用户信息" @@ -4585,31 +4585,31 @@ msgstr "启用 Radius 认证" msgid "OTP in Radius" msgstr "使用 Radius OTP" -#: settings/serializers/auth/saml2.py:11 +#: settings/serializers/auth/saml2.py:10 msgid "SAML2" msgstr "SAML2" -#: settings/serializers/auth/saml2.py:14 +#: settings/serializers/auth/saml2.py:13 msgid "Enable SAML2 Auth" msgstr "启用 SAML2 认证" -#: settings/serializers/auth/saml2.py:17 +#: settings/serializers/auth/saml2.py:16 msgid "IDP metadata URL" msgstr "IDP metadata 地址" -#: settings/serializers/auth/saml2.py:20 +#: settings/serializers/auth/saml2.py:19 msgid "IDP metadata XML" msgstr "IDP metadata XML" -#: settings/serializers/auth/saml2.py:23 +#: settings/serializers/auth/saml2.py:22 msgid "SP advanced settings" msgstr "高级设置" -#: settings/serializers/auth/saml2.py:27 +#: settings/serializers/auth/saml2.py:26 msgid "SP private key" msgstr "SP 密钥" -#: settings/serializers/auth/saml2.py:31 +#: settings/serializers/auth/saml2.py:30 msgid "SP cert" msgstr "SP 证书" @@ -4793,14 +4793,14 @@ msgstr "云同步记录(天)" msgid "Session keep duration (day)" msgstr "会话日志(天)" -#: settings/serializers/cleaning.py:32 +#: settings/serializers/cleaning.py:33 msgid "" "Session, record, command will be delete if more than duration, only in " "database, OSS will not be affected." msgstr "" -"会话、录像,命令记录超过该时长将会被洲除(影响数据库存備,OSS 等不受影响)" +"会话、录像,命令记录超过该时长将会被清除(影响数据库存储,OSS 等不受影响)" -#: settings/serializers/cleaning.py:36 +#: settings/serializers/cleaning.py:37 msgid "Activity log keep days (day)" msgstr "活动记录(天)" @@ -5064,7 +5064,7 @@ msgstr "用户在新设备登录后,其他已登录的设备会自动退出" msgid "Only exist user login" msgstr "仅已存在用户登录" -#: settings/serializers/security.py:101 +#: settings/serializers/security.py:102 msgid "" "If enabled, non-existent users will not be allowed to log in; if disabled, " "users of other authentication methods except local authentication methods " @@ -5074,11 +5074,11 @@ msgstr "" "如果开启,不存在的用户将不被允许登录;如果关闭,除本地认证方式外,其他认证方" "式的用户都允许登录并自动创建用户(如果用户不存在)" -#: settings/serializers/security.py:104 +#: settings/serializers/security.py:105 msgid "Only from source login" msgstr "仅从用户来源登录" -#: settings/serializers/security.py:105 +#: settings/serializers/security.py:107 msgid "" "If it is enabled, the user will only authenticate to the source when logging " "in; if it is disabled, the user will authenticate all the enabled " @@ -5088,28 +5088,28 @@ msgstr "" "如果开启,用户登录时仅会向来源端进行认证;如果关闭,用户登录时会按照一定的顺" "序对所有已开启的认证方式进行顺序认证,只要有一个认证成功就可以直接登录" -#: settings/serializers/security.py:109 +#: settings/serializers/security.py:111 msgid "MFA verify TTL (secend)" msgstr "MFA 校验有效期(秒)" -#: settings/serializers/security.py:111 +#: settings/serializers/security.py:113 msgid "" "The verification MFA takes effect only when you view the account password" msgstr "目前仅在查看账号密码校验 MFA 时生效" -#: settings/serializers/security.py:116 +#: settings/serializers/security.py:118 msgid "Verify code TTL" msgstr "验证码有效时间" -#: settings/serializers/security.py:117 +#: settings/serializers/security.py:119 msgid "Unit: second, reset password and send SMS code expiration time" msgstr "重置密码的验证码及发送短信的验证码过期时间" -#: settings/serializers/security.py:121 +#: settings/serializers/security.py:123 msgid "Enable Login dynamic code" msgstr "启用登录附加码" -#: settings/serializers/security.py:122 +#: settings/serializers/security.py:124 msgid "" "The password and additional code are sent to a third party authentication " "system for verification" @@ -5117,93 +5117,93 @@ msgstr "" "密码和附加码一并发送给第三方认证系统进行校验, 如:有的第三方认证系统,需要 密" "码+6位数字 完成认证" -#: settings/serializers/security.py:127 +#: settings/serializers/security.py:129 msgid "MFA in login page" msgstr "MFA 在登录页面输入" -#: settings/serializers/security.py:128 +#: settings/serializers/security.py:130 msgid "Eu security regulations(GDPR) require MFA to be on the login page" msgstr "欧盟数据安全法规(GDPR) 要求 MFA 在登录页面,来确保系统登录安全" -#: settings/serializers/security.py:131 +#: settings/serializers/security.py:133 msgid "Enable Login captcha" msgstr "启用登录验证码" -#: settings/serializers/security.py:132 +#: settings/serializers/security.py:134 msgid "Enable captcha to prevent robot authentication" msgstr "开启验证码,防止机器人登录" -#: settings/serializers/security.py:154 +#: settings/serializers/security.py:156 msgid "Enable terminal register" msgstr "终端注册" -#: settings/serializers/security.py:156 +#: settings/serializers/security.py:158 msgid "" "Allow terminal register, after all terminal setup, you should disable this " "for security" msgstr "是否允许终端注册,当所有终端启动后,为了安全应该关闭" -#: settings/serializers/security.py:160 +#: settings/serializers/security.py:162 msgid "Enable watermark" msgstr "开启水印" -#: settings/serializers/security.py:161 +#: settings/serializers/security.py:163 msgid "Enabled, the web session and replay contains watermark information" msgstr "启用后,Web 会话和录像将包含水印信息" -#: settings/serializers/security.py:165 +#: settings/serializers/security.py:167 msgid "Connection max idle time (minute)" msgstr "连接最大空闲时间(分)" -#: settings/serializers/security.py:166 +#: settings/serializers/security.py:168 msgid "If idle time more than it, disconnect connection." msgstr "提示:如果超过该配置没有操作,连接会被断开" -#: settings/serializers/security.py:169 +#: settings/serializers/security.py:171 msgid "Remember manual auth" msgstr "保存手动输入密码" -#: settings/serializers/security.py:172 +#: settings/serializers/security.py:174 msgid "Insecure command alert" msgstr "危险命令告警" -#: settings/serializers/security.py:175 +#: settings/serializers/security.py:177 msgid "Email recipient" msgstr "邮件收件人" -#: settings/serializers/security.py:176 +#: settings/serializers/security.py:178 msgid "Multiple user using , split" msgstr "多个用户,使用 , 分割" -#: settings/serializers/security.py:179 +#: settings/serializers/security.py:181 msgid "Operation center" msgstr "作业中心" -#: settings/serializers/security.py:180 +#: settings/serializers/security.py:182 msgid "Allow user run batch command or not using ansible" msgstr "是否允许用户使用 ansible 执行批量命令" -#: settings/serializers/security.py:184 +#: settings/serializers/security.py:186 msgid "Operation center command blacklist" msgstr "作业中心命令黑名单" -#: settings/serializers/security.py:185 +#: settings/serializers/security.py:187 msgid "Commands that are not allowed execute." msgstr "不允许执行的命令" -#: settings/serializers/security.py:188 +#: settings/serializers/security.py:190 msgid "Session share" msgstr "会话分享" -#: settings/serializers/security.py:189 +#: settings/serializers/security.py:191 msgid "Enabled, Allows user active session to be shared with other users" msgstr "开启后允许用户分享已连接的资产会话给他人,协同工作" -#: settings/serializers/security.py:192 +#: settings/serializers/security.py:194 msgid "Remote Login Protection" msgstr "异地登录保护" -#: settings/serializers/security.py:194 +#: settings/serializers/security.py:196 msgid "" "The system determines whether the login IP address belongs to a common login " "city. If the account is logged in from a common login city, the system sends " @@ -5212,7 +5212,7 @@ msgstr "" "根据登录 IP 是否所属常用登录城市进行判断,若账号在非常用城市登录,会发送异地" "登录提醒" -#: settings/serializers/settings.py:71 +#: settings/serializers/settings.py:70 #, python-format msgid "[%s] %s" msgstr "[%s] %s" @@ -5281,11 +5281,11 @@ msgid "" "Tip: Default resolution to use when connecting graphical assets in Luna pages" msgstr "提示:在Luna 页面中连接图形化资产时默认使用的分辨率" -#: settings/tasks/ldap.py:25 +#: settings/tasks/ldap.py:24 msgid "Periodic import ldap user" msgstr "周期导入 LDAP 用户" -#: settings/tasks/ldap.py:46 +#: settings/tasks/ldap.py:45 msgid "Registration periodic import ldap user task" msgstr "注册周期导入 LDAP 用户 任务" @@ -5642,15 +5642,15 @@ msgstr "未开启会话共享" msgid "Terminals" msgstr "终端管理" -#: terminal/backends/command/models.py:20 +#: terminal/backends/command/models.py:19 msgid "Input" msgstr "输入" -#: terminal/backends/command/models.py:21 terminal/serializers/command.py:74 +#: terminal/backends/command/models.py:20 terminal/serializers/command.py:73 msgid "Output" msgstr "输出" -#: terminal/backends/command/models.py:25 terminal/serializers/command.py:23 +#: terminal/backends/command/models.py:24 terminal/serializers/command.py:22 #: terminal/templates/terminal/_msg_command_warning.html:10 msgid "Risk level" msgstr "风险等级" @@ -5740,7 +5740,7 @@ msgstr "可以并发" msgid "Tags" msgstr "标签" -#: terminal/models/applet/applet.py:47 terminal/serializers/storage.py:157 +#: terminal/models/applet/applet.py:47 terminal/serializers/storage.py:159 msgid "Hosts" msgstr "主机" @@ -5819,9 +5819,9 @@ msgstr "Redis 端口" #: terminal/models/component/endpoint.py:29 #: terminal/models/component/endpoint.py:100 -#: terminal/serializers/endpoint.py:73 terminal/serializers/storage.py:38 -#: terminal/serializers/storage.py:50 terminal/serializers/storage.py:80 -#: terminal/serializers/storage.py:90 terminal/serializers/storage.py:98 +#: terminal/serializers/endpoint.py:73 terminal/serializers/storage.py:40 +#: terminal/serializers/storage.py:52 terminal/serializers/storage.py:82 +#: terminal/serializers/storage.py:92 terminal/serializers/storage.py:100 msgid "Endpoint" msgstr "端点" @@ -5879,7 +5879,7 @@ msgstr "录像存储" msgid "type" msgstr "类型" -#: terminal/models/component/terminal.py:89 terminal/serializers/command.py:77 +#: terminal/models/component/terminal.py:89 terminal/serializers/command.py:76 msgid "Remote Address" msgstr "远端地址" @@ -6062,7 +6062,7 @@ msgstr "" "建议填写内网地址,否则填写当前站点 URL
例如:https://172.16.10.110 or " "https://dev.jumpserver.com" -#: terminal/serializers/applet_host.py:46 terminal/serializers/storage.py:168 +#: terminal/serializers/applet_host.py:46 terminal/serializers/storage.py:170 msgid "Ignore Certificate Verification" msgstr "忽略证书认证" @@ -6094,35 +6094,35 @@ msgstr "RDS 远程应用注销时间限制" msgid "Load status" msgstr "负载状态" -#: terminal/serializers/command.py:20 +#: terminal/serializers/command.py:19 msgid "Session ID" msgstr "会话ID" -#: terminal/serializers/command.py:42 +#: terminal/serializers/command.py:41 msgid "Command Filter ACL" msgstr "命令过滤器" -#: terminal/serializers/command.py:45 +#: terminal/serializers/command.py:44 msgid "Command Group" msgstr "命令组" -#: terminal/serializers/command.py:56 +#: terminal/serializers/command.py:55 msgid "Invalid command filter ACL id" msgstr "无效的 命令过滤器 ID" -#: terminal/serializers/command.py:60 +#: terminal/serializers/command.py:59 msgid "Invalid command group id" msgstr "无效的 命令组 ID" -#: terminal/serializers/command.py:64 +#: terminal/serializers/command.py:63 msgid "Invalid session id" msgstr "无效的 Session ID" -#: terminal/serializers/command.py:73 +#: terminal/serializers/command.py:72 msgid "Account " msgstr "账号" -#: terminal/serializers/command.py:75 +#: terminal/serializers/command.py:74 msgid "Timestamp" msgstr "时间戳" @@ -6198,65 +6198,65 @@ msgstr "终端显示" msgid "Command amount" msgstr "命令数量" -#: terminal/serializers/storage.py:20 +#: terminal/serializers/storage.py:22 msgid "Endpoint invalid: remove path `{}`" msgstr "端点无效: 移除路径 `{}`" -#: terminal/serializers/storage.py:26 +#: terminal/serializers/storage.py:28 msgid "Bucket" msgstr "桶名称" -#: terminal/serializers/storage.py:30 +#: terminal/serializers/storage.py:32 #: xpack/plugins/cloud/serializers/account_attrs.py:17 msgid "Access key id" msgstr "Access key ID(AK)" -#: terminal/serializers/storage.py:34 +#: terminal/serializers/storage.py:36 #: xpack/plugins/cloud/serializers/account_attrs.py:20 msgid "Access key secret" msgstr "Access key secret(SK)" -#: terminal/serializers/storage.py:65 xpack/plugins/cloud/models.py:209 +#: terminal/serializers/storage.py:67 xpack/plugins/cloud/models.py:209 msgid "Region" msgstr "地域" -#: terminal/serializers/storage.py:109 +#: terminal/serializers/storage.py:111 msgid "Container name" msgstr "容器名称" -#: terminal/serializers/storage.py:112 +#: terminal/serializers/storage.py:114 msgid "Account key" msgstr "账号密钥" -#: terminal/serializers/storage.py:115 +#: terminal/serializers/storage.py:117 msgid "Endpoint suffix" msgstr "端点后缀" -#: terminal/serializers/storage.py:135 +#: terminal/serializers/storage.py:137 msgid "The address format is incorrect" msgstr "地址格式不正确" -#: terminal/serializers/storage.py:142 +#: terminal/serializers/storage.py:144 msgid "Host invalid" msgstr "主机无效" -#: terminal/serializers/storage.py:145 +#: terminal/serializers/storage.py:147 msgid "Port invalid" msgstr "端口无效" -#: terminal/serializers/storage.py:160 +#: terminal/serializers/storage.py:162 msgid "Index by date" msgstr "按日期建索引" -#: terminal/serializers/storage.py:161 +#: terminal/serializers/storage.py:163 msgid "Whether to create an index by date" msgstr "是否根据日期动态建立索引" -#: terminal/serializers/storage.py:164 +#: terminal/serializers/storage.py:166 msgid "Index" msgstr "索引" -#: terminal/serializers/storage.py:166 +#: terminal/serializers/storage.py:168 msgid "Doc type" msgstr "文档类型" @@ -6431,7 +6431,7 @@ msgstr "工单批准信息" msgid "Ticket flow" msgstr "工单流程" -#: tickets/models/relation.py:10 +#: tickets/models/relation.py:12 msgid "Ticket session relation" msgstr "工单会话" @@ -6505,11 +6505,11 @@ msgstr "审批步骤" msgid "Relation snapshot" msgstr "工单快照" -#: tickets/models/ticket/general.py:398 +#: tickets/models/ticket/general.py:401 msgid "Please try again" msgstr "请再次尝试" -#: tickets/models/ticket/general.py:467 +#: tickets/models/ticket/general.py:470 msgid "Super ticket" msgstr "超级工单" @@ -6615,7 +6615,7 @@ msgid "Ticket information" msgstr "工单信息" #: tickets/templates/tickets/approve_check_password.html:29 -#: tickets/views/approve.py:38 +#: tickets/views/approve.py:39 msgid "Ticket approval" msgstr "工单审批" @@ -6627,28 +6627,28 @@ msgstr "同意" msgid "Go Login" msgstr "去登录" -#: tickets/views/approve.py:39 +#: tickets/views/approve.py:40 msgid "" "This ticket does not exist, the process has ended, or this link has expired" msgstr "工单不存在,或者工单流程已经结束,或者此链接已经过期" -#: tickets/views/approve.py:68 +#: tickets/views/approve.py:69 msgid "Click the button below to approve or reject" msgstr "点击下方按钮同意或者拒绝" -#: tickets/views/approve.py:70 +#: tickets/views/approve.py:71 msgid "After successful authentication, this ticket can be approved directly" msgstr "认证成功后,工单可直接审批" -#: tickets/views/approve.py:92 +#: tickets/views/approve.py:93 msgid "Illegal approval action" msgstr "无效的审批动作" -#: tickets/views/approve.py:105 +#: tickets/views/approve.py:106 msgid "This user is not authorized to approve this ticket" msgstr "此用户无权审批此工单" -#: users/api/user.py:191 +#: users/api/user.py:190 msgid "Could not reset self otp, use profile reset instead" msgstr "不能在该页面重置 MFA 多因子认证, 请去个人信息页面重置" @@ -6810,27 +6810,27 @@ msgstr "最后更新密码日期" msgid "Need update password" msgstr "需要更新密码" -#: users/models/user.py:949 +#: users/models/user.py:954 msgid "Can invite user" msgstr "可以邀请用户" -#: users/models/user.py:950 +#: users/models/user.py:955 msgid "Can remove user" msgstr "可以移除用户" -#: users/models/user.py:951 +#: users/models/user.py:956 msgid "Can match user" msgstr "可以匹配用户" -#: users/models/user.py:960 +#: users/models/user.py:965 msgid "Administrator" msgstr "管理员" -#: users/models/user.py:963 +#: users/models/user.py:968 msgid "Administrator is the super user of system" msgstr "Administrator是初始的超级管理员" -#: users/models/user.py:988 +#: users/models/user.py:993 msgid "User password history" msgstr "用户密码历史" @@ -7145,35 +7145,35 @@ msgstr "账号保护已开启,请根据提示完成以下操作" msgid "Open MFA Authenticator and enter the 6-bit dynamic code" msgstr "请打开 MFA 验证器,输入 6 位动态码" -#: users/views/profile/otp.py:87 +#: users/views/profile/otp.py:85 msgid "Already bound" msgstr "已经绑定" -#: users/views/profile/otp.py:88 +#: users/views/profile/otp.py:86 msgid "MFA already bound, disable first, then bound" msgstr "MFA(OTP) 已经绑定,请先禁用,再绑定" -#: users/views/profile/otp.py:115 +#: users/views/profile/otp.py:113 msgid "OTP enable success" msgstr "MFA(OTP) 启用成功" -#: users/views/profile/otp.py:116 +#: users/views/profile/otp.py:114 msgid "OTP enable success, return login page" msgstr "MFA(OTP) 启用成功,返回到登录页面" -#: users/views/profile/otp.py:158 +#: users/views/profile/otp.py:156 msgid "Disable OTP" msgstr "禁用虚拟 MFA(OTP)" -#: users/views/profile/otp.py:164 +#: users/views/profile/otp.py:162 msgid "OTP disable success" msgstr "MFA(OTP) 禁用成功" -#: users/views/profile/otp.py:165 +#: users/views/profile/otp.py:163 msgid "OTP disable success, return login page" msgstr "MFA(OTP) 禁用成功,返回登录页面" -#: users/views/profile/password.py:36 users/views/profile/password.py:41 +#: users/views/profile/password.py:33 users/views/profile/password.py:38 msgid "Password invalid" msgstr "用户名或密码无效" @@ -7207,11 +7207,11 @@ msgstr "重置密码成功,返回到登录页面" msgid "XPACK" msgstr "XPack" -#: xpack/plugins/cloud/api.py:40 +#: xpack/plugins/cloud/api.py:38 msgid "Test connection successful" msgstr "测试成功" -#: xpack/plugins/cloud/api.py:42 +#: xpack/plugins/cloud/api.py:40 msgid "Test connection failed: {}" msgstr "测试连接失败:{}" @@ -7267,7 +7267,7 @@ msgstr "ucloud" msgid "VMware" msgstr "VMware" -#: xpack/plugins/cloud/const.py:23 xpack/plugins/cloud/providers/nutanix.py:13 +#: xpack/plugins/cloud/const.py:23 xpack/plugins/cloud/providers/nutanix.py:15 msgid "Nutanix" msgstr "Nutanix" @@ -7399,106 +7399,106 @@ msgstr "实例" msgid "Sync instance detail" msgstr "同步实例详情" -#: xpack/plugins/cloud/providers/aws_international.py:17 +#: xpack/plugins/cloud/providers/aws_international.py:18 msgid "China (Beijing)" msgstr "中国(北京)" -#: xpack/plugins/cloud/providers/aws_international.py:18 +#: xpack/plugins/cloud/providers/aws_international.py:19 msgid "China (Ningxia)" msgstr "中国(宁夏)" -#: xpack/plugins/cloud/providers/aws_international.py:21 +#: xpack/plugins/cloud/providers/aws_international.py:22 msgid "US East (Ohio)" msgstr "美国东部(俄亥俄州)" -#: xpack/plugins/cloud/providers/aws_international.py:22 +#: xpack/plugins/cloud/providers/aws_international.py:23 msgid "US East (N. Virginia)" msgstr "美国东部(弗吉尼亚北部)" -#: xpack/plugins/cloud/providers/aws_international.py:23 +#: xpack/plugins/cloud/providers/aws_international.py:24 msgid "US West (N. California)" msgstr "美国西部(加利福尼亚北部)" -#: xpack/plugins/cloud/providers/aws_international.py:24 +#: xpack/plugins/cloud/providers/aws_international.py:25 msgid "US West (Oregon)" msgstr "美国西部(俄勒冈)" -#: xpack/plugins/cloud/providers/aws_international.py:25 +#: xpack/plugins/cloud/providers/aws_international.py:26 msgid "Africa (Cape Town)" msgstr "非洲(开普敦)" -#: xpack/plugins/cloud/providers/aws_international.py:26 +#: xpack/plugins/cloud/providers/aws_international.py:27 msgid "Asia Pacific (Hong Kong)" msgstr "亚太地区(香港)" -#: xpack/plugins/cloud/providers/aws_international.py:27 +#: xpack/plugins/cloud/providers/aws_international.py:28 msgid "Asia Pacific (Mumbai)" msgstr "亚太地区(孟买)" -#: xpack/plugins/cloud/providers/aws_international.py:28 +#: xpack/plugins/cloud/providers/aws_international.py:29 msgid "Asia Pacific (Osaka-Local)" msgstr "亚太区域(大阪当地)" -#: xpack/plugins/cloud/providers/aws_international.py:29 +#: xpack/plugins/cloud/providers/aws_international.py:30 msgid "Asia Pacific (Seoul)" msgstr "亚太区域(首尔)" -#: xpack/plugins/cloud/providers/aws_international.py:30 +#: xpack/plugins/cloud/providers/aws_international.py:31 msgid "Asia Pacific (Singapore)" msgstr "亚太区域(新加坡)" -#: xpack/plugins/cloud/providers/aws_international.py:31 +#: xpack/plugins/cloud/providers/aws_international.py:32 msgid "Asia Pacific (Sydney)" msgstr "亚太区域(悉尼)" -#: xpack/plugins/cloud/providers/aws_international.py:32 +#: xpack/plugins/cloud/providers/aws_international.py:33 msgid "Asia Pacific (Tokyo)" msgstr "亚太区域(东京)" -#: xpack/plugins/cloud/providers/aws_international.py:33 +#: xpack/plugins/cloud/providers/aws_international.py:34 msgid "Canada (Central)" msgstr "加拿大(中部)" -#: xpack/plugins/cloud/providers/aws_international.py:34 +#: xpack/plugins/cloud/providers/aws_international.py:35 msgid "Europe (Frankfurt)" msgstr "欧洲(法兰克福)" -#: xpack/plugins/cloud/providers/aws_international.py:35 +#: xpack/plugins/cloud/providers/aws_international.py:36 msgid "Europe (Ireland)" msgstr "欧洲(爱尔兰)" -#: xpack/plugins/cloud/providers/aws_international.py:36 +#: xpack/plugins/cloud/providers/aws_international.py:37 msgid "Europe (London)" msgstr "欧洲(伦敦)" -#: xpack/plugins/cloud/providers/aws_international.py:37 +#: xpack/plugins/cloud/providers/aws_international.py:38 msgid "Europe (Milan)" msgstr "欧洲(米兰)" -#: xpack/plugins/cloud/providers/aws_international.py:38 +#: xpack/plugins/cloud/providers/aws_international.py:39 msgid "Europe (Paris)" msgstr "欧洲(巴黎)" -#: xpack/plugins/cloud/providers/aws_international.py:39 +#: xpack/plugins/cloud/providers/aws_international.py:40 msgid "Europe (Stockholm)" msgstr "欧洲(斯德哥尔摩)" -#: xpack/plugins/cloud/providers/aws_international.py:40 +#: xpack/plugins/cloud/providers/aws_international.py:41 msgid "Middle East (Bahrain)" msgstr "中东(巴林)" -#: xpack/plugins/cloud/providers/aws_international.py:41 +#: xpack/plugins/cloud/providers/aws_international.py:42 msgid "South America (São Paulo)" msgstr "南美洲(圣保罗)" #: xpack/plugins/cloud/providers/baiducloud.py:54 -#: xpack/plugins/cloud/providers/jdcloud.py:127 +#: xpack/plugins/cloud/providers/jdcloud.py:125 msgid "CN North-Beijing" msgstr "华北-北京" #: xpack/plugins/cloud/providers/baiducloud.py:55 -#: xpack/plugins/cloud/providers/huaweicloud.py:40 -#: xpack/plugins/cloud/providers/jdcloud.py:130 +#: xpack/plugins/cloud/providers/huaweicloud.py:42 +#: xpack/plugins/cloud/providers/jdcloud.py:128 msgid "CN South-Guangzhou" msgstr "华南-广州" @@ -7507,7 +7507,7 @@ msgid "CN East-Suzhou" msgstr "华东-苏州" #: xpack/plugins/cloud/providers/baiducloud.py:57 -#: xpack/plugins/cloud/providers/huaweicloud.py:48 +#: xpack/plugins/cloud/providers/huaweicloud.py:50 msgid "CN-Hong Kong" msgstr "中国-香港" @@ -7520,72 +7520,72 @@ msgid "CN North-Baoding" msgstr "华北-保定" #: xpack/plugins/cloud/providers/baiducloud.py:60 -#: xpack/plugins/cloud/providers/jdcloud.py:129 +#: xpack/plugins/cloud/providers/jdcloud.py:127 msgid "CN East-Shanghai" msgstr "华东-上海" #: xpack/plugins/cloud/providers/baiducloud.py:61 -#: xpack/plugins/cloud/providers/huaweicloud.py:47 +#: xpack/plugins/cloud/providers/huaweicloud.py:49 msgid "AP-Singapore" msgstr "亚太-新加坡" -#: xpack/plugins/cloud/providers/huaweicloud.py:35 +#: xpack/plugins/cloud/providers/huaweicloud.py:37 msgid "AF-Johannesburg" msgstr "非洲-约翰内斯堡" -#: xpack/plugins/cloud/providers/huaweicloud.py:36 +#: xpack/plugins/cloud/providers/huaweicloud.py:38 msgid "CN North-Beijing4" msgstr "华北-北京4" -#: xpack/plugins/cloud/providers/huaweicloud.py:37 +#: xpack/plugins/cloud/providers/huaweicloud.py:39 msgid "CN North-Beijing1" msgstr "华北-北京1" -#: xpack/plugins/cloud/providers/huaweicloud.py:38 +#: xpack/plugins/cloud/providers/huaweicloud.py:40 msgid "CN East-Shanghai2" msgstr "华东-上海2" -#: xpack/plugins/cloud/providers/huaweicloud.py:39 +#: xpack/plugins/cloud/providers/huaweicloud.py:41 msgid "CN East-Shanghai1" msgstr "华东-上海1" -#: xpack/plugins/cloud/providers/huaweicloud.py:41 +#: xpack/plugins/cloud/providers/huaweicloud.py:43 msgid "LA-Mexico City1" msgstr "拉美-墨西哥城一" -#: xpack/plugins/cloud/providers/huaweicloud.py:42 +#: xpack/plugins/cloud/providers/huaweicloud.py:44 msgid "LA-Santiago" msgstr "拉美-圣地亚哥" -#: xpack/plugins/cloud/providers/huaweicloud.py:43 +#: xpack/plugins/cloud/providers/huaweicloud.py:45 msgid "LA-Sao Paulo1" msgstr "拉美-圣保罗一" -#: xpack/plugins/cloud/providers/huaweicloud.py:44 +#: xpack/plugins/cloud/providers/huaweicloud.py:46 msgid "EU-Paris" msgstr "欧洲-巴黎" -#: xpack/plugins/cloud/providers/huaweicloud.py:45 +#: xpack/plugins/cloud/providers/huaweicloud.py:47 msgid "CN Southwest-Guiyang1" msgstr "西南-贵阳1" -#: xpack/plugins/cloud/providers/huaweicloud.py:46 +#: xpack/plugins/cloud/providers/huaweicloud.py:48 msgid "AP-Bangkok" msgstr "亚太-曼谷" -#: xpack/plugins/cloud/providers/huaweicloud.py:50 +#: xpack/plugins/cloud/providers/huaweicloud.py:52 msgid "CN Northeast-Dalian" msgstr "华北-大连" -#: xpack/plugins/cloud/providers/huaweicloud.py:51 +#: xpack/plugins/cloud/providers/huaweicloud.py:53 msgid "CN North-Ulanqab1" msgstr "华北-乌兰察布一" -#: xpack/plugins/cloud/providers/huaweicloud.py:52 +#: xpack/plugins/cloud/providers/huaweicloud.py:54 msgid "CN South-Guangzhou-InvitationOnly" msgstr "华南-广州-友好用户环境" -#: xpack/plugins/cloud/providers/jdcloud.py:128 +#: xpack/plugins/cloud/providers/jdcloud.py:126 msgid "CN East-Suqian" msgstr "华东-宿迁" @@ -7710,7 +7710,7 @@ msgstr "执行同步实例任务" msgid "Period clean sync instance task execution" msgstr "定期清除同步实例任务执行记录" -#: xpack/plugins/cloud/utils.py:69 +#: xpack/plugins/cloud/utils.py:68 msgid "Account unavailable" msgstr "账号无效" @@ -7718,7 +7718,7 @@ msgstr "账号无效" msgid "Restore default successfully." msgstr "恢复默认成功!" -#: xpack/plugins/interface/meta.py:10 +#: xpack/plugins/interface/meta.py:9 msgid "Interface settings" msgstr "界面设置" @@ -7750,15 +7750,15 @@ msgstr "主题" msgid "Interface setting" msgstr "界面设置" -#: xpack/plugins/license/api.py:50 +#: xpack/plugins/license/api.py:52 msgid "License import successfully" msgstr "许可证导入成功" -#: xpack/plugins/license/api.py:51 +#: xpack/plugins/license/api.py:53 msgid "License is invalid" msgstr "无效的许可证" -#: xpack/plugins/license/meta.py:11 xpack/plugins/license/models.py:138 +#: xpack/plugins/license/meta.py:10 xpack/plugins/license/models.py:138 msgid "License" msgstr "许可证" From 418ac5a5ba80636d0d05355c87ef2b05433c5dcc Mon Sep 17 00:00:00 2001 From: Eric Date: Tue, 25 Jul 2023 15:45:48 +0800 Subject: [PATCH 035/177] =?UTF-8?q?perf:=20=E7=A7=BB=E9=99=A4=20Koko=20?= =?UTF-8?q?=E7=9A=84=E9=83=A8=E5=88=86=E6=95=B0=E6=8D=AE=E5=BA=93=E6=94=AF?= =?UTF-8?q?=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/terminal/connect_methods.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/apps/terminal/connect_methods.py b/apps/terminal/connect_methods.py index ed49d722e..fd6573a61 100644 --- a/apps/terminal/connect_methods.py +++ b/apps/terminal/connect_methods.py @@ -151,8 +151,6 @@ class ConnectMethodUtil: 'listen': [Protocol.http, Protocol.ssh], 'support': [ Protocol.ssh, Protocol.telnet, - Protocol.mysql, Protocol.postgresql, - Protocol.sqlserver, Protocol.mariadb, Protocol.redis, Protocol.mongodb, Protocol.k8s, Protocol.clickhouse, ], From c135837372a40b29fe7fad70105dc7089de1b9ea Mon Sep 17 00:00:00 2001 From: ibuler Date: Tue, 25 Jul 2023 17:12:06 +0800 Subject: [PATCH 036/177] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=20connect=20?= =?UTF-8?q?method?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/assets/const/host.py | 2 +- apps/assets/const/protocol.py | 12 +-- .../migrations/0121_auto_20230725_1458.py | 77 +++++++++++++++++++ apps/terminal/connect_methods.py | 16 ++-- 4 files changed, 93 insertions(+), 14 deletions(-) create mode 100644 apps/assets/migrations/0121_auto_20230725_1458.py diff --git a/apps/assets/const/host.py b/apps/assets/const/host.py index afb92a447..cb841bbc2 100644 --- a/apps/assets/const/host.py +++ b/apps/assets/const/host.py @@ -33,7 +33,7 @@ class HostTypes(BaseType): def _get_protocol_constrains(cls) -> dict: return { '*': { - 'choices': ['ssh', 'telnet', 'vnc', 'rdp'] + 'choices': ['ssh', 'sftp', 'telnet', 'vnc', 'rdp'] }, cls.WINDOWS: { 'choices': ['rdp', 'ssh', 'vnc', 'winrm'] diff --git a/apps/assets/const/protocol.py b/apps/assets/const/protocol.py index aface581c..f405decb8 100644 --- a/apps/assets/const/protocol.py +++ b/apps/assets/const/protocol.py @@ -11,6 +11,7 @@ __all__ = ['Protocol'] class Protocol(ChoicesMixin, models.TextChoices): ssh = 'ssh', 'SSH' + sftp = 'sftp', 'SFTP' rdp = 'rdp', 'RDP' telnet = 'telnet', 'Telnet' vnc = 'vnc', 'VNC' @@ -36,17 +37,16 @@ class Protocol(ChoicesMixin, models.TextChoices): cls.ssh: { 'port': 22, 'secret_types': ['password', 'ssh_key'], + }, + cls.sftp: { + 'port': 22, + 'secret_types': ['password', 'ssh_key'], 'setting': { - 'sftp_enabled': { - 'type': 'bool', - 'default': True, - 'label': _('SFTP enabled') - }, 'sftp_home': { 'type': 'str', 'default': '/tmp', 'label': _('SFTP home') - }, + } } }, cls.rdp: { diff --git a/apps/assets/migrations/0121_auto_20230725_1458.py b/apps/assets/migrations/0121_auto_20230725_1458.py new file mode 100644 index 000000000..d32eb86a1 --- /dev/null +++ b/apps/assets/migrations/0121_auto_20230725_1458.py @@ -0,0 +1,77 @@ +# Generated by Django 4.1.10 on 2023-07-25 06:58 + +from django.db import migrations + + +def migrate_platforms_sftp_protocol(apps, schema_editor): + platform_protocol_cls = apps.get_model('assets', 'PlatformProtocol') + platform_cls = apps.get_model('assets', 'Platform') + ssh_protocols = platform_protocol_cls.objects.filter(name='ssh', setting__sftp_enabled=True) + platforms_has_sftp = platform_cls.objects.filter(protocols__name='sftp') + + new_protocols = [] + print("\nPlatform add sftp protocol: ") + for protocol in ssh_protocols: + protocol_setting = protocol.setting or {} + if protocol.platform in platforms_has_sftp: + continue + + kwargs = { + 'name': 'sftp', + 'port': protocol.port, + 'primary': False, + 'required': False, + 'default': True, + 'public': True, + 'setting': { + 'sftp_home': protocol_setting.get('sftp_home', '/tmp'), + }, + 'platform': protocol.platform, + } + new_protocol = platform_protocol_cls(**kwargs) + new_protocols.append(new_protocol) + print(" - {}".format(protocol.platform.name)) + + new_protocols_dict = {(protocol.name, protocol.platform): protocol for protocol in new_protocols} + new_protocols = list(new_protocols_dict.values()) + platform_protocol_cls.objects.bulk_create(new_protocols, ignore_conflicts=True) + + +def migrate_assets_sftp_protocol(apps, schema_editor): + asset_cls = apps.get_model('assets', 'Asset') + platform_cls = apps.get_model('assets', 'Platform') + protocol_cls = apps.get_model('assets', 'Protocol') + sftp_platforms = list(platform_cls.objects.filter(protocols__name='sftp').values_list('id')) + + count = 0 + print("\nAsset add sftp protocol: ") + asset_ids = asset_cls.objects\ + .filter(platform__in=sftp_platforms)\ + .exclude(protocols__name='sftp')\ + .distinct()\ + .values_list('id', flat=True) + while True: + _asset_ids = asset_ids[count:count + 1000] + if not _asset_ids: + break + count += 1000 + + new_protocols = [] + ssh_protocols = protocol_cls.objects.filter(name='ssh', asset_id__in=_asset_ids).distinct() + ssh_protocols_map = {protocol.asset_id: protocol for protocol in ssh_protocols} + for asset_id, protocol in ssh_protocols_map.items(): + new_protocols.append(protocol_cls(name='sftp', port=protocol.port, asset_id=asset_id)) + protocol_cls.objects.bulk_create(new_protocols, ignore_conflicts=True) + print(" - Add {}".format(len(new_protocols))) + + +class Migration(migrations.Migration): + + dependencies = [ + ('assets', '0120_auto_20230630_1613'), + ] + + operations = [ + migrations.RunPython(migrate_platforms_sftp_protocol), + migrations.RunPython(migrate_assets_sftp_protocol), + ] diff --git a/apps/terminal/connect_methods.py b/apps/terminal/connect_methods.py index ed49d722e..1673c55f3 100644 --- a/apps/terminal/connect_methods.py +++ b/apps/terminal/connect_methods.py @@ -19,14 +19,15 @@ class WebMethod(TextChoices): @classmethod def get_spec_methods(cls): methods = { - Protocol.ssh: [cls.web_cli, cls.web_sftp], + Protocol.sftp: [cls.web_sftp] } return methods class NativeClient(TextChoices): # Koko - ssh = 'ssh', 'SSH' + ssh = 'ssh', 'SSH CLI' + sftp = 'sftp', 'SFTP CLI' putty = 'putty', 'PuTTY' xshell = 'xshell', 'Xshell' @@ -45,6 +46,7 @@ class NativeClient(TextChoices): 'default': [cls.ssh], 'windows': [cls.putty], }, + Protocol.sftp: [cls.sftp], Protocol.rdp: [cls.mstsc], Protocol.mysql: [cls.db_client], Protocol.mariadb: [cls.db_client], @@ -81,13 +83,11 @@ class NativeClient(TextChoices): for protocol, _clients in clients_map.items(): if not settings.XPACK_ENABLED and protocol in xpack_protocols: continue - if isinstance(_clients, dict): if os == 'all': _clients = list(itertools.chain(*_clients.values())) else: _clients = _clients.get(os, _clients['default']) - for client in _clients: if not settings.XPACK_ENABLED and client in cls.xpack_methods(): continue @@ -96,6 +96,7 @@ class NativeClient(TextChoices): 'label': client.label, 'type': 'native', }) + print("Methods: ", methods) return methods @classmethod @@ -103,8 +104,10 @@ class NativeClient(TextChoices): username = f'JMS-{token.id}' commands = { cls.ssh: f'ssh {username}@{endpoint.host} -p {endpoint.ssh_port}', + cls.sftp: f'sftp {username}@{endpoint.host} -P {endpoint.ssh_port}', cls.putty: f'putty.exe -ssh {username}@{endpoint.host} -P {endpoint.ssh_port}', cls.xshell: f'xshell.exe -url ssh://{username}:{token.value}@{endpoint.host}:{endpoint.ssh_port}', + # 前端自己处理了 # cls.mysql: 'mysql -h {hostname} -P {port} -u {username} -p', # cls.psql: { # 'default': 'psql -h {hostname} -p {port} -U {username} -W', @@ -125,7 +128,6 @@ class AppletMethod: from .models import Applet, AppletHost methods = defaultdict(list) - has_applet_hosts = AppletHost.objects.all().exists() applets = Applet.objects.filter(is_active=True) for applet in applets: @@ -150,7 +152,7 @@ class ConnectMethodUtil: 'web_methods': [WebMethod.web_cli], 'listen': [Protocol.http, Protocol.ssh], 'support': [ - Protocol.ssh, Protocol.telnet, + Protocol.ssh, Protocol.sftp, Protocol.telnet, Protocol.mysql, Protocol.postgresql, Protocol.sqlserver, Protocol.mariadb, Protocol.redis, Protocol.mongodb, @@ -294,7 +296,7 @@ class ConnectMethodUtil: for listen_protocol in listen: # Native method - if component == TerminalType.koko and protocol.value != Protocol.ssh: + if component == TerminalType.koko and protocol.value not in [Protocol.ssh, Protocol.sftp]: # koko 仅支持 ssh 的 native 方式,其他数据库的 native 方式不提供 continue methods[str(protocol)].extend([ From b0b6d19bc0125652bf10f64163863604c12f142e Mon Sep 17 00:00:00 2001 From: ibuler Date: Wed, 26 Jul 2023 15:31:02 +0800 Subject: [PATCH 037/177] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=20sftp=20?= =?UTF-8?q?=E5=8D=8F=E8=AE=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/terminal/connect_methods.py | 45 ++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/apps/terminal/connect_methods.py b/apps/terminal/connect_methods.py index bc8ffbc36..aab6f6c75 100644 --- a/apps/terminal/connect_methods.py +++ b/apps/terminal/connect_methods.py @@ -52,7 +52,6 @@ class NativeClient(TextChoices): Protocol.mariadb: [cls.db_client], Protocol.redis: [cls.db_client], Protocol.mongodb: [cls.db_client], - Protocol.oracle: [cls.db_client], Protocol.postgresql: [cls.db_client], } @@ -96,7 +95,6 @@ class NativeClient(TextChoices): 'label': client.label, 'type': 'native', }) - print("Methods: ", methods) return methods @classmethod @@ -150,12 +148,18 @@ class ConnectMethodUtil: protocols = { TerminalType.koko: { 'web_methods': [WebMethod.web_cli], - 'listen': [Protocol.http, Protocol.ssh], + 'listen': [Protocol.http, Protocol.ssh, Protocol.sftp], 'support': [ - Protocol.ssh, Protocol.sftp, Protocol.telnet, + Protocol.ssh, Protocol.telnet, Protocol.sftp, Protocol.redis, Protocol.mongodb, Protocol.k8s, Protocol.clickhouse, ], + # 限制客户端的协议,比如 koko 虽然也支持 数据库的 ssh 连接,但是不再这里拉起 + # Listen协议: [Asset协议] + 'client_limits': { + Protocol.sftp: [Protocol.sftp], + Protocol.ssh: [Protocol.ssh, Protocol.telnet], + }, 'match': 'm2m' }, TerminalType.chen: { @@ -262,20 +266,20 @@ class ConnectMethodUtil: methods = defaultdict(list) spec_web_methods = WebMethod.get_spec_methods() - native_methods = NativeClient.get_methods(os) applet_methods = AppletMethod.get_methods() + native_methods = NativeClient.get_methods(os=os) for component, component_protocol in cls.components().items(): support = component_protocol['support'] - component_web_methods = component_protocol.get('web_methods', []) + default_web_methods = component_protocol.get('web_methods', []) + client_limits = component_protocol.get('client_limits', {}) - for protocol in support: + for asset_protocol in support: # Web 方式 - web_methods = spec_web_methods.get(protocol, None) - if web_methods is None: - web_methods = component_web_methods - - methods[str(protocol)].extend([ + web_methods = spec_web_methods.get(asset_protocol, []) + if not web_methods: + web_methods = default_web_methods + methods[str(asset_protocol)].extend([ { 'component': component.value, 'type': 'web', @@ -288,31 +292,32 @@ class ConnectMethodUtil: # 客户端方式 if component_protocol['match'] == 'map': - listen = [protocol] + listen = [asset_protocol] else: listen = component_protocol['listen'] for listen_protocol in listen: - # Native method - if component == TerminalType.koko and protocol.value not in [Protocol.ssh, Protocol.sftp]: - # koko 仅支持 ssh 的 native 方式,其他数据库的 native 方式不提供 + limits = client_limits.get(listen_protocol, []) + if limits and asset_protocol not in limits: continue - methods[str(protocol)].extend([ + # Native method + client_methods = native_methods.get(listen_protocol, []) + methods[str(asset_protocol)].extend([ { 'component': component.value, 'type': 'native', 'endpoint_protocol': listen_protocol, **method } - for method in native_methods[listen_protocol] + for method in client_methods ]) # 远程应用方式,这个只有 tinker 提供,并且协议可能是自定义的 - for protocol, applet_methods in applet_methods.items(): + for asset_protocol, applet_methods in applet_methods.items(): for method in applet_methods: method['listen'] = 'rdp' method['component'] = TerminalType.tinker.value - methods[protocol].extend(applet_methods) + methods[asset_protocol].extend(applet_methods) cls._all_methods[os] = methods return methods From 3fc52cbb6861d069cf5e270acb9eda555a8bbb54 Mon Sep 17 00:00:00 2001 From: Eric Date: Wed, 26 Jul 2023 17:13:10 +0800 Subject: [PATCH 038/177] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E5=90=8C?= =?UTF-8?q?=E5=90=8D=E8=B4=A6=E5=8F=B7=E7=94=A8=E6=88=B7=E5=90=8D=E4=BB=A3?= =?UTF-8?q?=E5=A1=AB=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/authentication/api/connection_token.py | 3 --- apps/authentication/models/connection_token.py | 13 ++++++++++++- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/apps/authentication/api/connection_token.py b/apps/authentication/api/connection_token.py index 5ad3f81db..566d080b5 100644 --- a/apps/authentication/api/connection_token.py +++ b/apps/authentication/api/connection_token.py @@ -306,9 +306,6 @@ class ConnectionTokenViewSet(ExtraActionApiMixin, RootOrgViewMixin, JMSModelView if account.username != AliasAccount.INPUT: data['input_username'] = '' - elif account.username == AliasAccount.USER: - data['input_username'] = user.username - ticket = self._validate_acl(user, asset, account) if ticket: data['from_ticket'] = ticket diff --git a/apps/authentication/models/connection_token.py b/apps/authentication/models/connection_token.py index 7bc8afcc7..c8919b3a5 100644 --- a/apps/authentication/models/connection_token.py +++ b/apps/authentication/models/connection_token.py @@ -225,9 +225,20 @@ class ConnectionToken(JMSOrgBaseModel): account.asset = self.asset account.org_id = self.asset.org_id - if self.account in [AliasAccount.INPUT, AliasAccount.USER]: + # 手动账号 + if self.account == AliasAccount.INPUT: account.username = self.input_username account.secret = self.input_secret + + # 同名账号 + elif self.account == AliasAccount.USER: + account.username = self.user.username + account.secret = self.input_secret + + # 匿名账号 + elif self.account == AliasAccount.ANON: + account.username = '' + account.secret = '' else: account = self.asset.accounts.filter(name=self.account).first() if not account.secret and self.input_secret: From 114645732a66e9bad1f102ff70a7c838f741c067 Mon Sep 17 00:00:00 2001 From: Bai Date: Wed, 26 Jul 2023 19:22:55 +0800 Subject: [PATCH 039/177] =?UTF-8?q?perf:=20=E7=94=A8=E6=88=B7=E6=8E=88?= =?UTF-8?q?=E6=9D=83=E8=B4=A6=E5=8F=B7=20API=20=E8=BF=94=E5=9B=9E=20id=20?= =?UTF-8?q?=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/perms/serializers/user_permission.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/perms/serializers/user_permission.py b/apps/perms/serializers/user_permission.py index 44904e82e..ba69cdeaf 100644 --- a/apps/perms/serializers/user_permission.py +++ b/apps/perms/serializers/user_permission.py @@ -69,7 +69,7 @@ class AccountsPermedSerializer(serializers.ModelSerializer): class Meta: model = Account fields = [ - 'alias', 'name', 'username', 'has_username', + 'id', 'alias', 'name', 'username', 'has_username', 'has_secret', 'secret_type', 'actions' ] read_only_fields = fields From 3b6c2fc0c051dc5095d670c7a6fc1128baa01f33 Mon Sep 17 00:00:00 2001 From: ibuler Date: Wed, 26 Jul 2023 19:15:52 +0800 Subject: [PATCH 040/177] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=20sftp=20?= =?UTF-8?q?=E7=9A=84=E4=B8=80=E4=BA=9B=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/assets/api/mixin.py | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/apps/assets/api/mixin.py b/apps/assets/api/mixin.py index 2cd928605..7d3c1c7a8 100644 --- a/apps/assets/api/mixin.py +++ b/apps/assets/api/mixin.py @@ -2,7 +2,7 @@ from typing import List from rest_framework.request import Request -from assets.models import Node, PlatformProtocol, Protocol +from assets.models import Node, Protocol from assets.utils import get_node_from_request, is_query_node_all_assets from common.utils import lazyproperty, timeit @@ -42,7 +42,7 @@ class SerializeToTreeNodeMixin: 'name': _name(node), 'title': _name(node), 'pId': node.parent_key, - 'isParent': True, + 'isParent': node.assets_amount > 0, 'open': _open(node), 'meta': { 'data': { @@ -70,25 +70,18 @@ class SerializeToTreeNodeMixin: @timeit def serialize_assets(self, assets, node_key=None, pid=None): - sftp_enabled_platform = PlatformProtocol.objects \ - .filter(name='ssh', setting__sftp_enabled=True) \ - .values_list('platform', flat=True) \ - .distinct() if node_key is None: get_pid = lambda asset: getattr(asset, 'parent_key', '') else: get_pid = lambda asset: node_key - ssh_asset_ids = [ - str(i) for i in - Protocol.objects.filter(name='ssh').values_list('asset_id', flat=True) - ] + sftp_asset_ids = Protocol.objects.filter(name='sftp') \ + .values_list('asset_id', flat=True) + sftp_asset_ids = list(sftp_asset_ids) data = [ { 'id': str(asset.id), 'name': asset.name, - 'title': - f'{asset.address}\n{asset.comment}' - if asset.comment else asset.address, + 'title': f'{asset.address}\n{asset.comment}', 'pId': pid or get_pid(asset), 'isParent': False, 'open': False, @@ -99,8 +92,7 @@ class SerializeToTreeNodeMixin: 'data': { 'platform_type': asset.platform.type, 'org_name': asset.org_name, - 'sftp': (asset.platform_id in sftp_enabled_platform) \ - and (str(asset.id) in ssh_asset_ids), + 'sftp': asset.id in sftp_asset_ids, 'name': asset.name, 'address': asset.address }, From b5fc865cc6579356c2fa6641b8bb2897d8a57320 Mon Sep 17 00:00:00 2001 From: ibuler Date: Tue, 25 Jul 2023 14:35:42 +0800 Subject: [PATCH 041/177] =?UTF-8?q?perf:=20Oracle=20=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/assets/const/protocol.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/apps/assets/const/protocol.py b/apps/assets/const/protocol.py index f405decb8..9588149ad 100644 --- a/apps/assets/const/protocol.py +++ b/apps/assets/const/protocol.py @@ -119,7 +119,15 @@ class Protocol(ChoicesMixin, models.TextChoices): 'port': 1521, 'required': True, 'secret_types': ['password'], - 'xpack': True + 'xpack': True, + 'setting': { + 'sysdba': { + 'type': 'bool', + 'default': False, + 'label': _('SYSDBA'), + 'help_text': _('Connect as SYSDBA') + }, + } }, cls.sqlserver: { 'port': 1433, From 77944cc91b741a10ccae9ba4fc7c548aa1edcba8 Mon Sep 17 00:00:00 2001 From: Bai Date: Thu, 27 Jul 2023 10:19:47 +0800 Subject: [PATCH 042/177] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E5=88=9B?= =?UTF-8?q?=E5=BB=BA=E8=B5=84=E4=BA=A7=20is=5Fvalid=20=E4=BD=BF=E7=94=A8kw?= =?UTF-8?q?=E5=8F=82=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/assets/serializers/asset/common.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/assets/serializers/asset/common.py b/apps/assets/serializers/asset/common.py index 7d7eb4ec9..b88d22ce7 100644 --- a/apps/assets/serializers/asset/common.py +++ b/apps/assets/serializers/asset/common.py @@ -261,7 +261,7 @@ class AssetSerializer(BulkOrgResourceModelSerializer, WritableNestedModelSeriali def is_valid(self, raise_exception=False): self._set_protocols_default() - return super().is_valid(raise_exception) + return super().is_valid(raise_exception=raise_exception) def validate_protocols(self, protocols_data): # 目的是去重 From 665c833479089761aded313b913f008c49294550 Mon Sep 17 00:00:00 2001 From: Bai Date: Thu, 27 Jul 2023 10:42:05 +0800 Subject: [PATCH 043/177] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E5=88=9B?= =?UTF-8?q?=E5=BB=BA=20ES=20=E5=AD=98=E5=82=A8=20get=5Fmapping=20index=20?= =?UTF-8?q?=E4=BD=BF=E7=94=A8=E4=BD=8D=E7=BD=AE=E5=8F=82=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/common/plugins/es.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/common/plugins/es.py b/apps/common/plugins/es.py index 06b85cb00..27b97b3de 100644 --- a/apps/common/plugins/es.py +++ b/apps/common/plugins/es.py @@ -91,7 +91,7 @@ class ES(object): try: # 获取索引信息,如果没有定义,直接返回 - data = self.es.indices.get_mapping(self.index) + data = self.es.indices.get_mapping(index=self.index) except NotFoundError: return False From 99adb6ab7a0ff39ebd0e9b5f6504d29daad818b2 Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Thu, 27 Jul 2023 14:04:29 +0800 Subject: [PATCH 044/177] =?UTF-8?q?perf:=20=E6=94=B9=E9=80=A0username=5Fsu?= =?UTF-8?q?ggestions=20api=20=E6=94=B9=E4=B8=BApost=E8=AF=B7=E6=B1=82=20(#?= =?UTF-8?q?11110)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: feng <1304903146@qq.com> --- apps/accounts/api/account/account.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/apps/accounts/api/account/account.py b/apps/accounts/api/account/account.py index ddf88e0c7..94ee9086b 100644 --- a/apps/accounts/api/account/account.py +++ b/apps/accounts/api/account/account.py @@ -52,20 +52,21 @@ class AccountViewSet(OrgBulkModelViewSet): return Response(data=serializer.data) @action( - methods=['get'], detail=False, url_path='username-suggestions', + methods=['post'], detail=False, url_path='username-suggestions', permission_classes=[IsValidUser] ) def username_suggestions(self, request, *args, **kwargs): - asset_ids = request.query_params.get('assets') - node_keys = request.query_params.get('keys') - username = request.query_params.get('username') + asset_ids = request.data.get('assets') + node_ids = request.data.get('nodes') + username = request.data.get('username') assets = Asset.objects.all() if asset_ids: - assets = assets.filter(id__in=asset_ids.split(',')) - if node_keys: - patten = Node.get_node_all_children_key_pattern(node_keys.split(',')) - assets = assets.filter(nodes__key__regex=patten) + assets = assets.filter(id__in=asset_ids) + if node_ids: + nodes = Node.objects.filter(id__in=node_ids) + node_asset_ids = Node.get_nodes_all_assets(*nodes).values_list('id', flat=True) + assets = assets.filter(id__in=set(list(asset_ids) + list(node_asset_ids))) accounts = Account.objects.filter(asset__in=assets) if username: From 2741d7cbdc3b98505ad96ec869988e5a74adb773 Mon Sep 17 00:00:00 2001 From: "fangfang.dong" Date: Wed, 26 Jul 2023 19:36:15 +0800 Subject: [PATCH 045/177] =?UTF-8?q?feat:=20=E7=BB=88=E7=AB=AF=E4=BC=9A?= =?UTF-8?q?=E8=AF=9D=E5=88=86=E4=BA=AB=E5=A2=9E=E5=8A=A0=E6=B6=88=E6=81=AF?= =?UTF-8?q?=E9=80=9A=E7=9F=A5=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/locale/ja/LC_MESSAGES/django.po | 88 +++++++++++-------- apps/locale/zh/LC_MESSAGES/django.po | 88 +++++++++++-------- .../migrations/0064_sessionsharing_origin.py | 18 ++++ apps/terminal/models/session/sharing.py | 14 ++- apps/terminal/notifications.py | 24 +++++ apps/terminal/serializers/sharing.py | 2 +- apps/terminal/signal_handlers/__init__.py | 1 + .../signal_handlers/session_sharing.py | 13 +++ .../terminal/_msg_session_sharing.html | 16 ++++ 9 files changed, 186 insertions(+), 78 deletions(-) create mode 100644 apps/terminal/migrations/0064_sessionsharing_origin.py create mode 100644 apps/terminal/signal_handlers/session_sharing.py create mode 100644 apps/terminal/templates/terminal/_msg_session_sharing.html diff --git a/apps/locale/ja/LC_MESSAGES/django.po b/apps/locale/ja/LC_MESSAGES/django.po index 424fbf22b..893c9f0e6 100644 --- a/apps/locale/ja/LC_MESSAGES/django.po +++ b/apps/locale/ja/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-07-25 15:37+0800\n" +"POT-Creation-Date: 2023-07-26 19:15+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -202,6 +202,7 @@ msgstr "作成のみ" #: terminal/backends/command/models.py:17 terminal/models/session/session.py:31 #: terminal/notifications.py:155 terminal/serializers/command.py:17 #: terminal/templates/terminal/_msg_command_warning.html:4 +#: terminal/templates/terminal/_msg_session_sharing.html:4 #: tickets/models/ticket/apply_asset.py:16 xpack/plugins/cloud/models.py:212 msgid "Asset" msgstr "資産" @@ -236,6 +237,7 @@ msgstr "ソース ID" #: perms/models/asset_permission.py:70 perms/serializers/permission.py:39 #: terminal/backends/command/models.py:18 terminal/models/session/session.py:33 #: terminal/templates/terminal/_msg_command_warning.html:8 +#: terminal/templates/terminal/_msg_session_sharing.html:8 #: tickets/models/ticket/command_confirm.py:13 xpack/plugins/cloud/models.py:85 msgid "Account" msgstr "アカウント" @@ -314,7 +316,7 @@ msgid "Trigger mode" msgstr "トリガーモード" #: accounts/models/automations/backup_account.py:97 audits/models.py:194 -#: terminal/models/session/sharing.py:111 xpack/plugins/cloud/models.py:168 +#: terminal/models/session/sharing.py:119 xpack/plugins/cloud/models.py:168 msgid "Reason" msgstr "理由" @@ -655,10 +657,11 @@ msgstr "ID" #: perms/api/user_permission/mixin.py:55 perms/models/asset_permission.py:58 #: perms/serializers/permission.py:30 rbac/builtin.py:123 #: rbac/models/rolebinding.py:49 terminal/backends/command/models.py:16 -#: terminal/models/session/session.py:29 terminal/models/session/sharing.py:32 +#: terminal/models/session/session.py:29 terminal/models/session/sharing.py:35 #: terminal/notifications.py:156 terminal/notifications.py:205 #: terminal/serializers/command.py:16 #: terminal/templates/terminal/_msg_command_warning.html:6 +#: terminal/templates/terminal/_msg_session_sharing.html:6 #: tickets/models/comment.py:21 users/const.py:14 users/models/user.py:947 #: users/models/user.py:983 users/serializers/group.py:18 msgid "User" @@ -696,7 +699,7 @@ msgid "Key password" msgstr "キーパスワード" #: accounts/serializers/account/base.py:80 -#: assets/serializers/asset/common.py:309 +#: assets/serializers/asset/common.py:311 msgid "Spec info" msgstr "特別情報" @@ -745,7 +748,7 @@ msgstr "自動タスク実行履歴" #: accounts/serializers/automations/change_secret.py:155 audits/const.py:53 #: audits/models.py:59 audits/signal_handlers/activity_log.py:33 #: common/const/choices.py:18 ops/const.py:56 ops/serializers/celery.py:40 -#: terminal/const.py:76 terminal/models/session/sharing.py:107 +#: terminal/const.py:76 terminal/models/session/sharing.py:115 #: tickets/views/approve.py:115 msgid "Success" msgstr "成功" @@ -829,7 +832,7 @@ msgstr "レビュー担当者" #: acls/models/base.py:43 authentication/models/access_key.py:17 #: authentication/models/connection_token.py:53 #: authentication/templates/authentication/_access_key_modal.html:32 -#: perms/models/asset_permission.py:76 terminal/models/session/sharing.py:27 +#: perms/models/asset_permission.py:76 terminal/models/session/sharing.py:30 #: tickets/const.py:37 msgid "Active" msgstr "アクティブ" @@ -839,7 +842,7 @@ msgid "Users" msgstr "ユーザー" #: acls/models/base.py:98 assets/models/automations/base.py:17 -#: assets/models/cmd_filter.py:38 assets/serializers/asset/common.py:308 +#: assets/models/cmd_filter.py:38 assets/serializers/asset/common.py:310 #: rbac/tree.py:35 msgid "Accounts" msgstr "アカウント" @@ -1152,10 +1155,6 @@ msgstr "" msgid "Other" msgstr "その他" -#: assets/const/protocol.py:43 -msgid "SFTP enabled" -msgstr "SFTP が有効" - #: assets/const/protocol.py:48 msgid "SFTP home" msgstr "SFTP ルート パス" @@ -1368,7 +1367,7 @@ msgstr "ドメイン" msgid "Labels" msgstr "ラベル" -#: assets/models/asset/common.py:158 assets/serializers/asset/common.py:310 +#: assets/models/asset/common.py:158 assets/serializers/asset/common.py:312 #: assets/serializers/asset/host.py:11 msgid "Gathered info" msgstr "資産ハードウェア情報の収集" @@ -1702,19 +1701,19 @@ msgid "Node path" msgstr "ノードパスです" #: assets/serializers/asset/common.py:145 -#: assets/serializers/asset/common.py:311 +#: assets/serializers/asset/common.py:313 msgid "Auto info" msgstr "自動情報" -#: assets/serializers/asset/common.py:234 +#: assets/serializers/asset/common.py:236 msgid "Platform not exist" msgstr "プラットフォームが存在しません" -#: assets/serializers/asset/common.py:270 +#: assets/serializers/asset/common.py:272 msgid "port out of range (0-65535)" msgstr "ポート番号が範囲外です (0-65535)" -#: assets/serializers/asset/common.py:277 +#: assets/serializers/asset/common.py:279 msgid "Protocol is required: {}" msgstr "プロトコルが必要です: {}" @@ -1998,6 +1997,7 @@ msgstr "マップディレクトリ" #: audits/const.py:23 rbac/tree.py:229 #: terminal/templates/terminal/_msg_command_warning.html:18 +#: terminal/templates/terminal/_msg_session_sharing.html:10 msgid "View" msgstr "表示" @@ -2061,7 +2061,7 @@ msgid "Job audit log" msgstr "ジョブ監査ログ" #: audits/models.py:51 audits/models.py:95 audits/models.py:166 -#: terminal/models/session/session.py:38 terminal/models/session/sharing.py:99 +#: terminal/models/session/session.py:38 terminal/models/session/sharing.py:107 msgid "Remote addr" msgstr "リモートaddr" @@ -2078,8 +2078,8 @@ msgid "File" msgstr "書類" #: audits/models.py:62 terminal/backends/command/models.py:21 -#: terminal/models/session/replay.py:9 terminal/models/session/sharing.py:18 -#: terminal/models/session/sharing.py:81 +#: terminal/models/session/replay.py:9 terminal/models/session/sharing.py:21 +#: terminal/models/session/sharing.py:89 #: terminal/templates/terminal/_msg_command_alert.html:10 #: terminal/templates/terminal/_msg_command_warning.html:17 #: tickets/models/ticket/command_confirm.py:15 @@ -2940,7 +2940,8 @@ msgid "request new one" msgstr "新しいものを要求する" #: authentication/templates/authentication/_msg_reset_password_code.html:12 -#: terminal/models/session/sharing.py:25 terminal/models/session/sharing.py:83 +#: terminal/models/session/sharing.py:28 terminal/models/session/sharing.py:91 +#: terminal/templates/terminal/_msg_session_sharing.html:12 #: users/forms/profile.py:107 users/templates/users/forgot_password.html:66 msgid "Verify code" msgstr "コードの確認" @@ -3688,7 +3689,7 @@ msgstr "アルグ" #: ops/models/adhoc.py:25 ops/models/base.py:16 ops/models/base.py:53 #: ops/models/job.py:106 ops/models/job.py:192 ops/models/playbook.py:25 -#: terminal/models/session/sharing.py:23 +#: terminal/models/session/sharing.py:26 msgid "Creator" msgstr "作成者" @@ -3729,7 +3730,7 @@ msgstr "タスクモニターを表示できます" msgid "Kwargs" msgstr "クワーグ" -#: ops/models/celery.py:61 terminal/models/session/sharing.py:114 +#: ops/models/celery.py:61 terminal/models/session/sharing.py:122 #: tickets/const.py:25 msgid "Finished" msgstr "終了" @@ -3925,6 +3926,7 @@ msgstr "アプリ組織" #: rbac/const.py:7 rbac/models/rolebinding.py:56 #: rbac/serializers/rolebinding.py:40 settings/serializers/auth/ldap.py:63 #: terminal/templates/terminal/_msg_command_warning.html:21 +#: terminal/templates/terminal/_msg_session_sharing.html:14 #: tickets/models/ticket/general.py:302 tickets/serializers/ticket/ticket.py:60 msgid "Organization" msgstr "組織" @@ -5742,7 +5744,7 @@ msgstr "出力" msgid "Risk level" msgstr "リスクレベル" -#: terminal/connect_methods.py:34 +#: terminal/connect_methods.py:35 msgid "DB Client" msgstr "データベース クライアント" @@ -5998,7 +6000,7 @@ msgstr "セッション再生をダウンロードできます" msgid "Account id" msgstr "アカウント ID" -#: terminal/models/session/session.py:36 terminal/models/session/sharing.py:104 +#: terminal/models/session/session.py:36 terminal/models/session/sharing.py:112 msgid "Login from" msgstr "ログイン元" @@ -6030,56 +6032,61 @@ msgstr "セッションを終了できます" msgid "Can validate session action perm" msgstr "セッションアクションのパーマを検証できます" -#: terminal/models/session/sharing.py:30 +#: terminal/models/session/sharing.py:33 msgid "Expired time (min)" msgstr "期限切れ時間 (分)" -#: terminal/models/session/sharing.py:35 terminal/serializers/sharing.py:20 +#: terminal/models/session/sharing.py:37 terminal/serializers/sharing.py:20 #: terminal/serializers/sharing.py:52 msgid "Action permission" msgstr "アクションパーミッション" -#: terminal/models/session/sharing.py:40 terminal/models/session/sharing.py:86 +#: terminal/models/session/sharing.py:39 +msgid "Origin" +msgstr "" + +#: terminal/models/session/sharing.py:43 terminal/models/session/sharing.py:94 +#: terminal/notifications.py:261 msgid "Session sharing" msgstr "セッション共有" -#: terminal/models/session/sharing.py:42 +#: terminal/models/session/sharing.py:45 msgid "Can add super session sharing" msgstr "スーパーセッション共有を追加できます" -#: terminal/models/session/sharing.py:69 +#: terminal/models/session/sharing.py:77 msgid "Link not active" msgstr "リンクがアクティブでない" -#: terminal/models/session/sharing.py:71 +#: terminal/models/session/sharing.py:79 msgid "Link expired" msgstr "リンク期限切れ" -#: terminal/models/session/sharing.py:73 +#: terminal/models/session/sharing.py:81 msgid "User not allowed to join" msgstr "ユーザーはセッションに参加できません" -#: terminal/models/session/sharing.py:90 terminal/serializers/sharing.py:71 +#: terminal/models/session/sharing.py:98 terminal/serializers/sharing.py:71 msgid "Joiner" msgstr "ジョイナー" -#: terminal/models/session/sharing.py:93 +#: terminal/models/session/sharing.py:101 msgid "Date joined" msgstr "参加日" -#: terminal/models/session/sharing.py:96 +#: terminal/models/session/sharing.py:104 msgid "Date left" msgstr "日付が残っています" -#: terminal/models/session/sharing.py:119 +#: terminal/models/session/sharing.py:127 msgid "Session join record" msgstr "セッション参加記録" -#: terminal/models/session/sharing.py:135 +#: terminal/models/session/sharing.py:143 msgid "Invalid verification code" msgstr "検証コードが無効" -#: terminal/models/session/sharing.py:142 +#: terminal/models/session/sharing.py:150 msgid "You have already joined this session" msgstr "すでにこのセッションに参加しています" @@ -6388,6 +6395,10 @@ msgstr "チェックコマンドと録画ストレージの接続性" msgid "view" msgstr "表示" +#: terminal/templates/terminal/_msg_session_sharing.html:10 +msgid "Session sharing URL" +msgstr "セッション共有 URL" + #: terminal/utils/db_port_mapper.py:85 msgid "" "No available port is matched. The number of databases may have exceeded the " @@ -7892,6 +7903,9 @@ msgstr "究極のエディション" msgid "Community edition" msgstr "コミュニティ版" +#~ msgid "SFTP enabled" +#~ msgstr "SFTP が有効" + #~ msgid "Item" #~ msgstr "アイテム" diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po index 10fd864cc..1ee0dc26f 100644 --- a/apps/locale/zh/LC_MESSAGES/django.po +++ b/apps/locale/zh/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: JumpServer 0.3.3\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-07-25 15:37+0800\n" +"POT-Creation-Date: 2023-07-26 19:14+0800\n" "PO-Revision-Date: 2021-05-20 10:54+0800\n" "Last-Translator: ibuler \n" "Language-Team: JumpServer team\n" @@ -201,6 +201,7 @@ msgstr "仅创建" #: terminal/backends/command/models.py:17 terminal/models/session/session.py:31 #: terminal/notifications.py:155 terminal/serializers/command.py:17 #: terminal/templates/terminal/_msg_command_warning.html:4 +#: terminal/templates/terminal/_msg_session_sharing.html:4 #: tickets/models/ticket/apply_asset.py:16 xpack/plugins/cloud/models.py:212 msgid "Asset" msgstr "资产" @@ -235,6 +236,7 @@ msgstr "来源 ID" #: perms/models/asset_permission.py:70 perms/serializers/permission.py:39 #: terminal/backends/command/models.py:18 terminal/models/session/session.py:33 #: terminal/templates/terminal/_msg_command_warning.html:8 +#: terminal/templates/terminal/_msg_session_sharing.html:8 #: tickets/models/ticket/command_confirm.py:13 xpack/plugins/cloud/models.py:85 msgid "Account" msgstr "账号" @@ -313,7 +315,7 @@ msgid "Trigger mode" msgstr "触发模式" #: accounts/models/automations/backup_account.py:97 audits/models.py:194 -#: terminal/models/session/sharing.py:111 xpack/plugins/cloud/models.py:168 +#: terminal/models/session/sharing.py:119 xpack/plugins/cloud/models.py:168 msgid "Reason" msgstr "原因" @@ -651,10 +653,11 @@ msgstr "ID" #: perms/api/user_permission/mixin.py:55 perms/models/asset_permission.py:58 #: perms/serializers/permission.py:30 rbac/builtin.py:123 #: rbac/models/rolebinding.py:49 terminal/backends/command/models.py:16 -#: terminal/models/session/session.py:29 terminal/models/session/sharing.py:32 +#: terminal/models/session/session.py:29 terminal/models/session/sharing.py:35 #: terminal/notifications.py:156 terminal/notifications.py:205 #: terminal/serializers/command.py:16 #: terminal/templates/terminal/_msg_command_warning.html:6 +#: terminal/templates/terminal/_msg_session_sharing.html:6 #: tickets/models/comment.py:21 users/const.py:14 users/models/user.py:947 #: users/models/user.py:983 users/serializers/group.py:18 msgid "User" @@ -692,7 +695,7 @@ msgid "Key password" msgstr "密钥密码" #: accounts/serializers/account/base.py:80 -#: assets/serializers/asset/common.py:309 +#: assets/serializers/asset/common.py:311 msgid "Spec info" msgstr "特殊信息" @@ -741,7 +744,7 @@ msgstr "自动化任务执行历史" #: accounts/serializers/automations/change_secret.py:155 audits/const.py:53 #: audits/models.py:59 audits/signal_handlers/activity_log.py:33 #: common/const/choices.py:18 ops/const.py:56 ops/serializers/celery.py:40 -#: terminal/const.py:76 terminal/models/session/sharing.py:107 +#: terminal/const.py:76 terminal/models/session/sharing.py:115 #: tickets/views/approve.py:115 msgid "Success" msgstr "成功" @@ -825,7 +828,7 @@ msgstr "审批人" #: acls/models/base.py:43 authentication/models/access_key.py:17 #: authentication/models/connection_token.py:53 #: authentication/templates/authentication/_access_key_modal.html:32 -#: perms/models/asset_permission.py:76 terminal/models/session/sharing.py:27 +#: perms/models/asset_permission.py:76 terminal/models/session/sharing.py:30 #: tickets/const.py:37 msgid "Active" msgstr "激活中" @@ -835,7 +838,7 @@ msgid "Users" msgstr "用户管理" #: acls/models/base.py:98 assets/models/automations/base.py:17 -#: assets/models/cmd_filter.py:38 assets/serializers/asset/common.py:308 +#: assets/models/cmd_filter.py:38 assets/serializers/asset/common.py:310 #: rbac/tree.py:35 msgid "Accounts" msgstr "账号管理" @@ -1145,10 +1148,6 @@ msgstr "ChatGPT" msgid "Other" msgstr "其它" -#: assets/const/protocol.py:43 -msgid "SFTP enabled" -msgstr "SFTP 已启用" - #: assets/const/protocol.py:48 msgid "SFTP home" msgstr "SFTP 根路径" @@ -1361,7 +1360,7 @@ msgstr "网域" msgid "Labels" msgstr "标签管理" -#: assets/models/asset/common.py:158 assets/serializers/asset/common.py:310 +#: assets/models/asset/common.py:158 assets/serializers/asset/common.py:312 #: assets/serializers/asset/host.py:11 msgid "Gathered info" msgstr "收集资产硬件信息" @@ -1693,19 +1692,19 @@ msgid "Node path" msgstr "节点路径" #: assets/serializers/asset/common.py:145 -#: assets/serializers/asset/common.py:311 +#: assets/serializers/asset/common.py:313 msgid "Auto info" msgstr "自动化信息" -#: assets/serializers/asset/common.py:234 +#: assets/serializers/asset/common.py:236 msgid "Platform not exist" msgstr "平台不存在" -#: assets/serializers/asset/common.py:270 +#: assets/serializers/asset/common.py:272 msgid "port out of range (0-65535)" msgstr "端口超出范围 (0-65535)" -#: assets/serializers/asset/common.py:277 +#: assets/serializers/asset/common.py:279 msgid "Protocol is required: {}" msgstr "协议是必填的: {}" @@ -1982,6 +1981,7 @@ msgstr "映射目录" #: audits/const.py:23 rbac/tree.py:229 #: terminal/templates/terminal/_msg_command_warning.html:18 +#: terminal/templates/terminal/_msg_session_sharing.html:10 msgid "View" msgstr "查看" @@ -2045,7 +2045,7 @@ msgid "Job audit log" msgstr "作业审计日志" #: audits/models.py:51 audits/models.py:95 audits/models.py:166 -#: terminal/models/session/session.py:38 terminal/models/session/sharing.py:99 +#: terminal/models/session/session.py:38 terminal/models/session/sharing.py:107 msgid "Remote addr" msgstr "远端地址" @@ -2062,8 +2062,8 @@ msgid "File" msgstr "文件" #: audits/models.py:62 terminal/backends/command/models.py:21 -#: terminal/models/session/replay.py:9 terminal/models/session/sharing.py:18 -#: terminal/models/session/sharing.py:81 +#: terminal/models/session/replay.py:9 terminal/models/session/sharing.py:21 +#: terminal/models/session/sharing.py:89 #: terminal/templates/terminal/_msg_command_alert.html:10 #: terminal/templates/terminal/_msg_command_warning.html:17 #: tickets/models/ticket/command_confirm.py:15 @@ -2904,7 +2904,8 @@ msgid "request new one" msgstr "重新申请" #: authentication/templates/authentication/_msg_reset_password_code.html:12 -#: terminal/models/session/sharing.py:25 terminal/models/session/sharing.py:83 +#: terminal/models/session/sharing.py:28 terminal/models/session/sharing.py:91 +#: terminal/templates/terminal/_msg_session_sharing.html:12 #: users/forms/profile.py:107 users/templates/users/forgot_password.html:66 msgid "Verify code" msgstr "验证码" @@ -3641,7 +3642,7 @@ msgstr "参数" #: ops/models/adhoc.py:25 ops/models/base.py:16 ops/models/base.py:53 #: ops/models/job.py:106 ops/models/job.py:192 ops/models/playbook.py:25 -#: terminal/models/session/sharing.py:23 +#: terminal/models/session/sharing.py:26 msgid "Creator" msgstr "创建者" @@ -3682,7 +3683,7 @@ msgstr "可以查看任务监控" msgid "Kwargs" msgstr "其它参数" -#: ops/models/celery.py:61 terminal/models/session/sharing.py:114 +#: ops/models/celery.py:61 terminal/models/session/sharing.py:122 #: tickets/const.py:25 msgid "Finished" msgstr "结束" @@ -3877,6 +3878,7 @@ msgstr "组织管理" #: rbac/const.py:7 rbac/models/rolebinding.py:56 #: rbac/serializers/rolebinding.py:40 settings/serializers/auth/ldap.py:63 #: terminal/templates/terminal/_msg_command_warning.html:21 +#: terminal/templates/terminal/_msg_session_sharing.html:14 #: tickets/models/ticket/general.py:302 tickets/serializers/ticket/ticket.py:60 msgid "Organization" msgstr "组织" @@ -5655,7 +5657,7 @@ msgstr "输出" msgid "Risk level" msgstr "风险等级" -#: terminal/connect_methods.py:34 +#: terminal/connect_methods.py:35 msgid "DB Client" msgstr "数据库客户端" @@ -5911,7 +5913,7 @@ msgstr "可以下载会话录像" msgid "Account id" msgstr "账号 ID" -#: terminal/models/session/session.py:36 terminal/models/session/sharing.py:104 +#: terminal/models/session/session.py:36 terminal/models/session/sharing.py:112 msgid "Login from" msgstr "登录来源" @@ -5943,56 +5945,61 @@ msgstr "可以终断会话" msgid "Can validate session action perm" msgstr "可以验证会话动作权限" -#: terminal/models/session/sharing.py:30 +#: terminal/models/session/sharing.py:33 msgid "Expired time (min)" msgstr "过期时间 (分)" -#: terminal/models/session/sharing.py:35 terminal/serializers/sharing.py:20 +#: terminal/models/session/sharing.py:37 terminal/serializers/sharing.py:20 #: terminal/serializers/sharing.py:52 msgid "Action permission" msgstr "操作权限" -#: terminal/models/session/sharing.py:40 terminal/models/session/sharing.py:86 +#: terminal/models/session/sharing.py:39 +msgid "Origin" +msgstr "" + +#: terminal/models/session/sharing.py:43 terminal/models/session/sharing.py:94 +#: terminal/notifications.py:261 msgid "Session sharing" msgstr "会话分享" -#: terminal/models/session/sharing.py:42 +#: terminal/models/session/sharing.py:45 msgid "Can add super session sharing" msgstr "可以创建超级会话分享" -#: terminal/models/session/sharing.py:69 +#: terminal/models/session/sharing.py:77 msgid "Link not active" msgstr "链接失效" -#: terminal/models/session/sharing.py:71 +#: terminal/models/session/sharing.py:79 msgid "Link expired" msgstr "链接过期" -#: terminal/models/session/sharing.py:73 +#: terminal/models/session/sharing.py:81 msgid "User not allowed to join" msgstr "该用户无权加入会话" -#: terminal/models/session/sharing.py:90 terminal/serializers/sharing.py:71 +#: terminal/models/session/sharing.py:98 terminal/serializers/sharing.py:71 msgid "Joiner" msgstr "加入者" -#: terminal/models/session/sharing.py:93 +#: terminal/models/session/sharing.py:101 msgid "Date joined" msgstr "加入日期" -#: terminal/models/session/sharing.py:96 +#: terminal/models/session/sharing.py:104 msgid "Date left" msgstr "结束日期" -#: terminal/models/session/sharing.py:119 +#: terminal/models/session/sharing.py:127 msgid "Session join record" msgstr "会话加入记录" -#: terminal/models/session/sharing.py:135 +#: terminal/models/session/sharing.py:143 msgid "Invalid verification code" msgstr "验证码不正确" -#: terminal/models/session/sharing.py:142 +#: terminal/models/session/sharing.py:150 msgid "You have already joined this session" msgstr "您已经加入过此会话" @@ -6296,6 +6303,10 @@ msgstr "检查命令及录像存储可连接性 " msgid "view" msgstr "查看" +#: terminal/templates/terminal/_msg_session_sharing.html:10 +msgid "Session sharing URL" +msgstr "会话分享 URL" + #: terminal/utils/db_port_mapper.py:85 msgid "" "No available port is matched. The number of databases may have exceeded the " @@ -7778,6 +7789,9 @@ msgstr "旗舰版" msgid "Community edition" msgstr "社区版" +#~ msgid "SFTP enabled" +#~ msgstr "SFTP 已启用" + #~ msgid "Item" #~ msgstr "项目" diff --git a/apps/terminal/migrations/0064_sessionsharing_origin.py b/apps/terminal/migrations/0064_sessionsharing_origin.py new file mode 100644 index 000000000..91886fc16 --- /dev/null +++ b/apps/terminal/migrations/0064_sessionsharing_origin.py @@ -0,0 +1,18 @@ +# Generated by Django 4.1.10 on 2023-07-26 10:55 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('terminal', '0063_auto_20230621_1133'), + ] + + operations = [ + migrations.AddField( + model_name='sessionsharing', + name='origin', + field=models.URLField(blank=True, null=True, verbose_name='Origin'), + ), + ] diff --git a/apps/terminal/models/session/sharing.py b/apps/terminal/models/session/sharing.py index e5187a3b8..efae4f8a9 100644 --- a/apps/terminal/models/session/sharing.py +++ b/apps/terminal/models/session/sharing.py @@ -3,8 +3,11 @@ import datetime from django.db import models from django.utils import timezone from django.utils.translation import gettext_lazy as _ +from django.utils.functional import cached_property +from common.utils.random import random_string from common.db.models import JMSBaseModel +from common.db.fields import JsonListTextField from orgs.mixins.models import OrgModelMixin from orgs.utils import tmp_to_root_org from users.models import User @@ -30,10 +33,10 @@ class SessionSharing(JMSBaseModel, OrgModelMixin): default=0, verbose_name=_('Expired time (min)'), db_index=True ) users = models.TextField(blank=True, verbose_name=_("User")) - action_permission = models.CharField( max_length=16, verbose_name=_('Action permission'), default='writable' ) + origin = models.URLField(blank=True, null=True, verbose_name=_('Origin')) class Meta: ordering = ('-date_created',) @@ -45,15 +48,20 @@ class SessionSharing(JMSBaseModel, OrgModelMixin): def __str__(self): return 'Creator: {}'.format(self.creator) + @cached_property def users_display(self): if not self.users: return [] with tmp_to_root_org(): - user_ids = self.users.split(',') - users = User.objects.filter(id__in=user_ids) + users = self.users_queryset users = [str(user) for user in users] return users + @cached_property + def users_queryset(self): + user_ids = self.users.split(',') + return User.objects.filter(id__in=user_ids) + @property def date_expired(self): return self.date_created + datetime.timedelta(minutes=self.expired_time) diff --git a/apps/terminal/notifications.py b/apps/terminal/notifications.py index f200650a6..a09f8ccb1 100644 --- a/apps/terminal/notifications.py +++ b/apps/terminal/notifications.py @@ -255,3 +255,27 @@ class StorageConnectivityMessage(SystemMessage): 'subject': subject, 'message': message } + + +class SessionSharingMessage(UserMessage): + message_type_label = _('Session sharing') + + def __init__(self, user, instance): + super().__init__(user) + self.instance = instance + + def get_html_msg(self) -> dict: + instance = self.instance + context = { + 'asset': instance.session.asset, + 'created_by': instance.created_by, + 'account': instance.session.account, + 'session_url': '%s/koko/share/%s/' % (instance.origin, instance.id), + 'verify_code': instance.verify_code, + 'org': instance.org_name, + } + message = render_to_string('terminal/_msg_session_sharing.html', context) + return { + 'subject': self.message_type_label + ' ' + self.instance.created_by, + 'message': message + } diff --git a/apps/terminal/serializers/sharing.py b/apps/terminal/serializers/sharing.py index abc2dbdd3..42d74318b 100644 --- a/apps/terminal/serializers/sharing.py +++ b/apps/terminal/serializers/sharing.py @@ -26,7 +26,7 @@ class SessionSharingSerializer(OrgResourceModelSerializerMixin): fields_small = fields_mini + [ 'verify_code', 'is_active', 'expired_time', 'created_by', 'date_created', 'date_updated', 'users', 'users_display', - 'action_permission' + 'action_permission', 'origin', ] fields_fk = ['session', 'creator'] fields = fields_small + fields_fk diff --git a/apps/terminal/signal_handlers/__init__.py b/apps/terminal/signal_handlers/__init__.py index 265f6416d..5ba51e77a 100644 --- a/apps/terminal/signal_handlers/__init__.py +++ b/apps/terminal/signal_handlers/__init__.py @@ -1,3 +1,4 @@ from .applet import * from .db_port import * from .terminal import * +from .session_sharing import * diff --git a/apps/terminal/signal_handlers/session_sharing.py b/apps/terminal/signal_handlers/session_sharing.py new file mode 100644 index 000000000..f20ccf665 --- /dev/null +++ b/apps/terminal/signal_handlers/session_sharing.py @@ -0,0 +1,13 @@ +from django.db.models.signals import post_save +from django.dispatch import receiver + +from terminal.models import SessionSharing +from terminal.notifications import SessionSharingMessage + + +@receiver(post_save, sender=SessionSharing) +def on_session_sharing_created(sender, instance: SessionSharing, created, **kwargs): + if not created: + return + for user in instance.users_queryset: + SessionSharingMessage(user, instance).publish_async() diff --git a/apps/terminal/templates/terminal/_msg_session_sharing.html b/apps/terminal/templates/terminal/_msg_session_sharing.html new file mode 100644 index 000000000..b28129900 --- /dev/null +++ b/apps/terminal/templates/terminal/_msg_session_sharing.html @@ -0,0 +1,16 @@ +{% load i18n %} + +
+ {% trans 'Asset' %}: {{ asset }} +
+ {% trans 'User' %}: {{ created_by }} +
+ {% trans 'Account' %}: {{ account }} +
+ {% trans 'Session sharing URL' %}: {% trans 'View' %} +
+ {% trans 'Verify code' %}: {{ verify_code }} +
+ {% trans 'Organization' %}: {{ org }} +
+
From 7a37f919644124d97be1f1bf5cd6c980c34f542f Mon Sep 17 00:00:00 2001 From: nut Date: Wed, 26 Jul 2023 19:40:56 +0800 Subject: [PATCH 046/177] Update sharing.py --- apps/terminal/models/session/sharing.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/apps/terminal/models/session/sharing.py b/apps/terminal/models/session/sharing.py index efae4f8a9..e2ef06a5f 100644 --- a/apps/terminal/models/session/sharing.py +++ b/apps/terminal/models/session/sharing.py @@ -5,9 +5,7 @@ from django.utils import timezone from django.utils.translation import gettext_lazy as _ from django.utils.functional import cached_property -from common.utils.random import random_string from common.db.models import JMSBaseModel -from common.db.fields import JsonListTextField from orgs.mixins.models import OrgModelMixin from orgs.utils import tmp_to_root_org from users.models import User From 1239ffd4c834cdd6ee7a974da3ead25e29100a05 Mon Sep 17 00:00:00 2001 From: "fangfang.dong" Date: Thu, 27 Jul 2023 12:52:33 +0800 Subject: [PATCH 047/177] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=E4=BC=9A?= =?UTF-8?q?=E8=AF=9D=E5=88=86=E4=BA=ABurl=E7=9A=84=E6=9E=84=E9=80=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/locale/ja/LC_MESSAGES/django.po | 54 +++++++++---------- apps/locale/zh/LC_MESSAGES/django.po | 54 +++++++++---------- apps/terminal/models/session/sharing.py | 4 ++ apps/terminal/notifications.py | 2 +- apps/terminal/serializers/sharing.py | 2 +- .../terminal/_msg_session_sharing.html | 2 +- 6 files changed, 61 insertions(+), 57 deletions(-) diff --git a/apps/locale/ja/LC_MESSAGES/django.po b/apps/locale/ja/LC_MESSAGES/django.po index 893c9f0e6..607cafcf2 100644 --- a/apps/locale/ja/LC_MESSAGES/django.po +++ b/apps/locale/ja/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-07-26 19:15+0800\n" +"POT-Creation-Date: 2023-07-27 11:11+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -316,7 +316,7 @@ msgid "Trigger mode" msgstr "トリガーモード" #: accounts/models/automations/backup_account.py:97 audits/models.py:194 -#: terminal/models/session/sharing.py:119 xpack/plugins/cloud/models.py:168 +#: terminal/models/session/sharing.py:117 xpack/plugins/cloud/models.py:168 msgid "Reason" msgstr "理由" @@ -657,7 +657,7 @@ msgstr "ID" #: perms/api/user_permission/mixin.py:55 perms/models/asset_permission.py:58 #: perms/serializers/permission.py:30 rbac/builtin.py:123 #: rbac/models/rolebinding.py:49 terminal/backends/command/models.py:16 -#: terminal/models/session/session.py:29 terminal/models/session/sharing.py:35 +#: terminal/models/session/session.py:29 terminal/models/session/sharing.py:33 #: terminal/notifications.py:156 terminal/notifications.py:205 #: terminal/serializers/command.py:16 #: terminal/templates/terminal/_msg_command_warning.html:6 @@ -748,7 +748,7 @@ msgstr "自動タスク実行履歴" #: accounts/serializers/automations/change_secret.py:155 audits/const.py:53 #: audits/models.py:59 audits/signal_handlers/activity_log.py:33 #: common/const/choices.py:18 ops/const.py:56 ops/serializers/celery.py:40 -#: terminal/const.py:76 terminal/models/session/sharing.py:115 +#: terminal/const.py:76 terminal/models/session/sharing.py:113 #: tickets/views/approve.py:115 msgid "Success" msgstr "成功" @@ -832,7 +832,7 @@ msgstr "レビュー担当者" #: acls/models/base.py:43 authentication/models/access_key.py:17 #: authentication/models/connection_token.py:53 #: authentication/templates/authentication/_access_key_modal.html:32 -#: perms/models/asset_permission.py:76 terminal/models/session/sharing.py:30 +#: perms/models/asset_permission.py:76 terminal/models/session/sharing.py:28 #: tickets/const.py:37 msgid "Active" msgstr "アクティブ" @@ -2061,7 +2061,7 @@ msgid "Job audit log" msgstr "ジョブ監査ログ" #: audits/models.py:51 audits/models.py:95 audits/models.py:166 -#: terminal/models/session/session.py:38 terminal/models/session/sharing.py:107 +#: terminal/models/session/session.py:38 terminal/models/session/sharing.py:105 msgid "Remote addr" msgstr "リモートaddr" @@ -2078,8 +2078,8 @@ msgid "File" msgstr "書類" #: audits/models.py:62 terminal/backends/command/models.py:21 -#: terminal/models/session/replay.py:9 terminal/models/session/sharing.py:21 -#: terminal/models/session/sharing.py:89 +#: terminal/models/session/replay.py:9 terminal/models/session/sharing.py:19 +#: terminal/models/session/sharing.py:87 #: terminal/templates/terminal/_msg_command_alert.html:10 #: terminal/templates/terminal/_msg_command_warning.html:17 #: tickets/models/ticket/command_confirm.py:15 @@ -2940,7 +2940,7 @@ msgid "request new one" msgstr "新しいものを要求する" #: authentication/templates/authentication/_msg_reset_password_code.html:12 -#: terminal/models/session/sharing.py:28 terminal/models/session/sharing.py:91 +#: terminal/models/session/sharing.py:26 terminal/models/session/sharing.py:89 #: terminal/templates/terminal/_msg_session_sharing.html:12 #: users/forms/profile.py:107 users/templates/users/forgot_password.html:66 msgid "Verify code" @@ -3689,7 +3689,7 @@ msgstr "アルグ" #: ops/models/adhoc.py:25 ops/models/base.py:16 ops/models/base.py:53 #: ops/models/job.py:106 ops/models/job.py:192 ops/models/playbook.py:25 -#: terminal/models/session/sharing.py:26 +#: terminal/models/session/sharing.py:24 msgid "Creator" msgstr "作成者" @@ -3730,7 +3730,7 @@ msgstr "タスクモニターを表示できます" msgid "Kwargs" msgstr "クワーグ" -#: ops/models/celery.py:61 terminal/models/session/sharing.py:122 +#: ops/models/celery.py:61 terminal/models/session/sharing.py:120 #: tickets/const.py:25 msgid "Finished" msgstr "終了" @@ -6000,7 +6000,7 @@ msgstr "セッション再生をダウンロードできます" msgid "Account id" msgstr "アカウント ID" -#: terminal/models/session/session.py:36 terminal/models/session/sharing.py:112 +#: terminal/models/session/session.py:36 terminal/models/session/sharing.py:110 msgid "Login from" msgstr "ログイン元" @@ -6032,61 +6032,61 @@ msgstr "セッションを終了できます" msgid "Can validate session action perm" msgstr "セッションアクションのパーマを検証できます" -#: terminal/models/session/sharing.py:33 +#: terminal/models/session/sharing.py:31 msgid "Expired time (min)" msgstr "期限切れ時間 (分)" -#: terminal/models/session/sharing.py:37 terminal/serializers/sharing.py:20 +#: terminal/models/session/sharing.py:35 terminal/serializers/sharing.py:20 #: terminal/serializers/sharing.py:52 msgid "Action permission" msgstr "アクションパーミッション" -#: terminal/models/session/sharing.py:39 +#: terminal/models/session/sharing.py:37 msgid "Origin" -msgstr "" +msgstr "ソース" -#: terminal/models/session/sharing.py:43 terminal/models/session/sharing.py:94 +#: terminal/models/session/sharing.py:41 terminal/models/session/sharing.py:92 #: terminal/notifications.py:261 msgid "Session sharing" msgstr "セッション共有" -#: terminal/models/session/sharing.py:45 +#: terminal/models/session/sharing.py:43 msgid "Can add super session sharing" msgstr "スーパーセッション共有を追加できます" -#: terminal/models/session/sharing.py:77 +#: terminal/models/session/sharing.py:75 msgid "Link not active" msgstr "リンクがアクティブでない" -#: terminal/models/session/sharing.py:79 +#: terminal/models/session/sharing.py:77 msgid "Link expired" msgstr "リンク期限切れ" -#: terminal/models/session/sharing.py:81 +#: terminal/models/session/sharing.py:79 msgid "User not allowed to join" msgstr "ユーザーはセッションに参加できません" -#: terminal/models/session/sharing.py:98 terminal/serializers/sharing.py:71 +#: terminal/models/session/sharing.py:96 terminal/serializers/sharing.py:71 msgid "Joiner" msgstr "ジョイナー" -#: terminal/models/session/sharing.py:101 +#: terminal/models/session/sharing.py:99 msgid "Date joined" msgstr "参加日" -#: terminal/models/session/sharing.py:104 +#: terminal/models/session/sharing.py:102 msgid "Date left" msgstr "日付が残っています" -#: terminal/models/session/sharing.py:127 +#: terminal/models/session/sharing.py:125 msgid "Session join record" msgstr "セッション参加記録" -#: terminal/models/session/sharing.py:143 +#: terminal/models/session/sharing.py:141 msgid "Invalid verification code" msgstr "検証コードが無効" -#: terminal/models/session/sharing.py:150 +#: terminal/models/session/sharing.py:148 msgid "You have already joined this session" msgstr "すでにこのセッションに参加しています" diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po index 1ee0dc26f..ff4a4c2c3 100644 --- a/apps/locale/zh/LC_MESSAGES/django.po +++ b/apps/locale/zh/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: JumpServer 0.3.3\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-07-26 19:14+0800\n" +"POT-Creation-Date: 2023-07-27 11:11+0800\n" "PO-Revision-Date: 2021-05-20 10:54+0800\n" "Last-Translator: ibuler \n" "Language-Team: JumpServer team\n" @@ -315,7 +315,7 @@ msgid "Trigger mode" msgstr "触发模式" #: accounts/models/automations/backup_account.py:97 audits/models.py:194 -#: terminal/models/session/sharing.py:119 xpack/plugins/cloud/models.py:168 +#: terminal/models/session/sharing.py:117 xpack/plugins/cloud/models.py:168 msgid "Reason" msgstr "原因" @@ -653,7 +653,7 @@ msgstr "ID" #: perms/api/user_permission/mixin.py:55 perms/models/asset_permission.py:58 #: perms/serializers/permission.py:30 rbac/builtin.py:123 #: rbac/models/rolebinding.py:49 terminal/backends/command/models.py:16 -#: terminal/models/session/session.py:29 terminal/models/session/sharing.py:35 +#: terminal/models/session/session.py:29 terminal/models/session/sharing.py:33 #: terminal/notifications.py:156 terminal/notifications.py:205 #: terminal/serializers/command.py:16 #: terminal/templates/terminal/_msg_command_warning.html:6 @@ -744,7 +744,7 @@ msgstr "自动化任务执行历史" #: accounts/serializers/automations/change_secret.py:155 audits/const.py:53 #: audits/models.py:59 audits/signal_handlers/activity_log.py:33 #: common/const/choices.py:18 ops/const.py:56 ops/serializers/celery.py:40 -#: terminal/const.py:76 terminal/models/session/sharing.py:115 +#: terminal/const.py:76 terminal/models/session/sharing.py:113 #: tickets/views/approve.py:115 msgid "Success" msgstr "成功" @@ -828,7 +828,7 @@ msgstr "审批人" #: acls/models/base.py:43 authentication/models/access_key.py:17 #: authentication/models/connection_token.py:53 #: authentication/templates/authentication/_access_key_modal.html:32 -#: perms/models/asset_permission.py:76 terminal/models/session/sharing.py:30 +#: perms/models/asset_permission.py:76 terminal/models/session/sharing.py:28 #: tickets/const.py:37 msgid "Active" msgstr "激活中" @@ -2045,7 +2045,7 @@ msgid "Job audit log" msgstr "作业审计日志" #: audits/models.py:51 audits/models.py:95 audits/models.py:166 -#: terminal/models/session/session.py:38 terminal/models/session/sharing.py:107 +#: terminal/models/session/session.py:38 terminal/models/session/sharing.py:105 msgid "Remote addr" msgstr "远端地址" @@ -2062,8 +2062,8 @@ msgid "File" msgstr "文件" #: audits/models.py:62 terminal/backends/command/models.py:21 -#: terminal/models/session/replay.py:9 terminal/models/session/sharing.py:21 -#: terminal/models/session/sharing.py:89 +#: terminal/models/session/replay.py:9 terminal/models/session/sharing.py:19 +#: terminal/models/session/sharing.py:87 #: terminal/templates/terminal/_msg_command_alert.html:10 #: terminal/templates/terminal/_msg_command_warning.html:17 #: tickets/models/ticket/command_confirm.py:15 @@ -2904,7 +2904,7 @@ msgid "request new one" msgstr "重新申请" #: authentication/templates/authentication/_msg_reset_password_code.html:12 -#: terminal/models/session/sharing.py:28 terminal/models/session/sharing.py:91 +#: terminal/models/session/sharing.py:26 terminal/models/session/sharing.py:89 #: terminal/templates/terminal/_msg_session_sharing.html:12 #: users/forms/profile.py:107 users/templates/users/forgot_password.html:66 msgid "Verify code" @@ -3642,7 +3642,7 @@ msgstr "参数" #: ops/models/adhoc.py:25 ops/models/base.py:16 ops/models/base.py:53 #: ops/models/job.py:106 ops/models/job.py:192 ops/models/playbook.py:25 -#: terminal/models/session/sharing.py:26 +#: terminal/models/session/sharing.py:24 msgid "Creator" msgstr "创建者" @@ -3683,7 +3683,7 @@ msgstr "可以查看任务监控" msgid "Kwargs" msgstr "其它参数" -#: ops/models/celery.py:61 terminal/models/session/sharing.py:122 +#: ops/models/celery.py:61 terminal/models/session/sharing.py:120 #: tickets/const.py:25 msgid "Finished" msgstr "结束" @@ -5913,7 +5913,7 @@ msgstr "可以下载会话录像" msgid "Account id" msgstr "账号 ID" -#: terminal/models/session/session.py:36 terminal/models/session/sharing.py:112 +#: terminal/models/session/session.py:36 terminal/models/session/sharing.py:110 msgid "Login from" msgstr "登录来源" @@ -5945,61 +5945,61 @@ msgstr "可以终断会话" msgid "Can validate session action perm" msgstr "可以验证会话动作权限" -#: terminal/models/session/sharing.py:33 +#: terminal/models/session/sharing.py:31 msgid "Expired time (min)" msgstr "过期时间 (分)" -#: terminal/models/session/sharing.py:37 terminal/serializers/sharing.py:20 +#: terminal/models/session/sharing.py:35 terminal/serializers/sharing.py:20 #: terminal/serializers/sharing.py:52 msgid "Action permission" msgstr "操作权限" -#: terminal/models/session/sharing.py:39 +#: terminal/models/session/sharing.py:37 msgid "Origin" -msgstr "" +msgstr "来源" -#: terminal/models/session/sharing.py:43 terminal/models/session/sharing.py:94 +#: terminal/models/session/sharing.py:41 terminal/models/session/sharing.py:92 #: terminal/notifications.py:261 msgid "Session sharing" msgstr "会话分享" -#: terminal/models/session/sharing.py:45 +#: terminal/models/session/sharing.py:43 msgid "Can add super session sharing" msgstr "可以创建超级会话分享" -#: terminal/models/session/sharing.py:77 +#: terminal/models/session/sharing.py:75 msgid "Link not active" msgstr "链接失效" -#: terminal/models/session/sharing.py:79 +#: terminal/models/session/sharing.py:77 msgid "Link expired" msgstr "链接过期" -#: terminal/models/session/sharing.py:81 +#: terminal/models/session/sharing.py:79 msgid "User not allowed to join" msgstr "该用户无权加入会话" -#: terminal/models/session/sharing.py:98 terminal/serializers/sharing.py:71 +#: terminal/models/session/sharing.py:96 terminal/serializers/sharing.py:71 msgid "Joiner" msgstr "加入者" -#: terminal/models/session/sharing.py:101 +#: terminal/models/session/sharing.py:99 msgid "Date joined" msgstr "加入日期" -#: terminal/models/session/sharing.py:104 +#: terminal/models/session/sharing.py:102 msgid "Date left" msgstr "结束日期" -#: terminal/models/session/sharing.py:127 +#: terminal/models/session/sharing.py:125 msgid "Session join record" msgstr "会话加入记录" -#: terminal/models/session/sharing.py:143 +#: terminal/models/session/sharing.py:141 msgid "Invalid verification code" msgstr "验证码不正确" -#: terminal/models/session/sharing.py:150 +#: terminal/models/session/sharing.py:148 msgid "You have already joined this session" msgstr "您已经加入过此会话" diff --git a/apps/terminal/models/session/sharing.py b/apps/terminal/models/session/sharing.py index e2ef06a5f..92a75f9c4 100644 --- a/apps/terminal/models/session/sharing.py +++ b/apps/terminal/models/session/sharing.py @@ -46,6 +46,10 @@ class SessionSharing(JMSBaseModel, OrgModelMixin): def __str__(self): return 'Creator: {}'.format(self.creator) + @cached_property + def url(self): + return '%s/koko/share/%s/' % (self.origin, self.id) + @cached_property def users_display(self): if not self.users: diff --git a/apps/terminal/notifications.py b/apps/terminal/notifications.py index a09f8ccb1..0d2501450 100644 --- a/apps/terminal/notifications.py +++ b/apps/terminal/notifications.py @@ -270,7 +270,7 @@ class SessionSharingMessage(UserMessage): 'asset': instance.session.asset, 'created_by': instance.created_by, 'account': instance.session.account, - 'session_url': '%s/koko/share/%s/' % (instance.origin, instance.id), + 'url': instance.url, 'verify_code': instance.verify_code, 'org': instance.org_name, } diff --git a/apps/terminal/serializers/sharing.py b/apps/terminal/serializers/sharing.py index 42d74318b..c891a70b5 100644 --- a/apps/terminal/serializers/sharing.py +++ b/apps/terminal/serializers/sharing.py @@ -26,7 +26,7 @@ class SessionSharingSerializer(OrgResourceModelSerializerMixin): fields_small = fields_mini + [ 'verify_code', 'is_active', 'expired_time', 'created_by', 'date_created', 'date_updated', 'users', 'users_display', - 'action_permission', 'origin', + 'action_permission', 'origin', 'url', ] fields_fk = ['session', 'creator'] fields = fields_small + fields_fk diff --git a/apps/terminal/templates/terminal/_msg_session_sharing.html b/apps/terminal/templates/terminal/_msg_session_sharing.html index b28129900..d634304e5 100644 --- a/apps/terminal/templates/terminal/_msg_session_sharing.html +++ b/apps/terminal/templates/terminal/_msg_session_sharing.html @@ -7,7 +7,7 @@
{% trans 'Account' %}: {{ account }}
- {% trans 'Session sharing URL' %}: {% trans 'View' %} + {% trans 'Session sharing URL' %}: {% trans 'View' %}
{% trans 'Verify code' %}: {{ verify_code }}
From 1907c795c31b8ab0798bf0286b32ee2572c22f87 Mon Sep 17 00:00:00 2001 From: jiangweidong Date: Fri, 28 Jul 2023 10:40:48 +0800 Subject: [PATCH 048/177] =?UTF-8?q?feat:=20=E7=B3=BB=E7=BB=9F=E5=B7=A5?= =?UTF-8?q?=E5=85=B7=E5=A2=9E=E5=8A=A0=E6=9C=8D=E5=8A=A1=E5=99=A8=E6=97=B6?= =?UTF-8?q?=E9=97=B4=E5=8F=8Anmap=E5=B7=A5=E5=85=B7=20(#11078)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/settings/api/public.py | 13 ++++++- apps/settings/serializers/public.py | 8 +++- apps/settings/urls/api_urls.py | 1 + apps/settings/utils/__init__.py | 3 +- apps/settings/utils/nmap.py | 60 +++++++++++++++++++++++++++++ apps/settings/utils/ping.py | 17 +++++--- apps/settings/utils/telnet.py | 10 ++--- apps/settings/ws.py | 31 +++++++-------- 8 files changed, 115 insertions(+), 28 deletions(-) create mode 100644 apps/settings/utils/nmap.py diff --git a/apps/settings/api/public.py b/apps/settings/api/public.py index ab313cd4f..f2628a5d4 100644 --- a/apps/settings/api/public.py +++ b/apps/settings/api/public.py @@ -4,13 +4,14 @@ from rest_framework.permissions import AllowAny from common.permissions import IsValidUserOrConnectionToken from common.utils import get_logger, lazyproperty +from common.utils.timezone import local_now from jumpserver.utils import has_valid_xpack_license, get_xpack_license_info from .. import serializers from ..utils import get_interface_setting_or_default logger = get_logger(__name__) -__all__ = ['PublicSettingApi', 'OpenPublicSettingApi'] +__all__ = ['PublicSettingApi', 'OpenPublicSettingApi', 'ServerInfoApi'] class OpenPublicSettingApi(generics.RetrieveAPIView): @@ -55,3 +56,13 @@ class PublicSettingApi(OpenPublicSettingApi): # 提前把异常爆出来 values[name] = getattr(settings, name) return values + + +class ServerInfoApi(generics.RetrieveAPIView): + permission_classes = (IsValidUserOrConnectionToken,) + serializer_class = serializers.ServerInfoSerializer + + def get_object(self): + return { + "CURRENT_TIME": local_now(), + } diff --git a/apps/settings/serializers/public.py b/apps/settings/serializers/public.py index 8429ccd48..3d61bd98c 100644 --- a/apps/settings/serializers/public.py +++ b/apps/settings/serializers/public.py @@ -3,7 +3,9 @@ from rest_framework import serializers -__all__ = ['PublicSettingSerializer', 'PrivateSettingSerializer'] +__all__ = [ + 'PublicSettingSerializer', 'PrivateSettingSerializer', 'ServerInfoSerializer' +] class PublicSettingSerializer(serializers.Serializer): @@ -50,3 +52,7 @@ class PrivateSettingSerializer(PublicSettingSerializer): TICKETS_ENABLED = serializers.BooleanField() CONNECTION_TOKEN_REUSABLE = serializers.BooleanField() + + +class ServerInfoSerializer(serializers.Serializer): + CURRENT_TIME = serializers.DateTimeField() diff --git a/apps/settings/urls/api_urls.py b/apps/settings/urls/api_urls.py index 5cfc3bb36..ef94d02ba 100644 --- a/apps/settings/urls/api_urls.py +++ b/apps/settings/urls/api_urls.py @@ -23,4 +23,5 @@ urlpatterns = [ path('logo/', api.SettingsLogoApi.as_view(), name='settings-logo'), path('public/', api.PublicSettingApi.as_view(), name='public-setting'), path('public/open/', api.OpenPublicSettingApi.as_view(), name='open-public-setting'), + path('server-info/', api.ServerInfoApi.as_view(), name='server-info'), ] diff --git a/apps/settings/utils/__init__.py b/apps/settings/utils/__init__.py index 0927bde18..8983df3ad 100644 --- a/apps/settings/utils/__init__.py +++ b/apps/settings/utils/__init__.py @@ -1,7 +1,8 @@ # coding: utf-8 -# +# from .ldap import * from .common import * from .ping import * from .telnet import * +from .nmap import * diff --git a/apps/settings/utils/nmap.py b/apps/settings/utils/nmap.py new file mode 100644 index 000000000..6e4282678 --- /dev/null +++ b/apps/settings/utils/nmap.py @@ -0,0 +1,60 @@ +import time +import nmap + +from IPy import IP + +from common.utils.timezone import local_now_display + + +def generate_ips(ip_string): + # 支持的格式 + # 192.168.1.1-12 | 192.168.1.1-192.168.1.12 | 192.168.1.0/30 | 192.168.1.1 + ip_list = ip_string.split('-') + ips = [] + try: + if len(ip_list) == 2: + start_ip, end_ip = ip_list + if ip_list[1].find('.') == -1: + end_ip = start_ip[:start_ip.rindex('.') + 1] + end_ip + for ip in range(IP(start_ip).int(), IP(end_ip).int() + 1): + ips.extend(IP(ip)) + else: + ips.extend(IP(ip_list[0])) + except Exception: + ips = [] + return ips + + +def once_nmap(nm, ip, ports, timeout, display): + nmap_version = '.'.join(map(lambda x: str(x), nm.nmap_version())) + display(f'Starting Nmap {nmap_version} at {local_now_display()} for {ip}') + try: + is_ok = True + nm.scan(ip, arguments='-sS -sU -F', ports=ports, timeout=timeout) + tcp_port = nm[ip].get('tcp', {}) + udp_port = nm[ip].get('udp', {}) + display(f'PORT\tSTATE\tSERVICE') + for port, info in tcp_port.items(): + display(f"{port}\t{info.get('state', 'unknown')}\t{info.get('name', 'unknown')}") + for port, info in udp_port.items(): + display(f"{port}\t{info.get('state', 'unknown')}\t{info.get('name', 'unknown')}") + except Exception: + is_ok = False + display(f'Nmap scan report for {ip} error.') + return is_ok + + +def verbose_nmap(dest_ip, dest_port=None, timeout=None, display=print): + dest_port = ','.join(list(dest_port)) if dest_port else None + + ips = generate_ips(dest_ip) + nm = nmap.PortScanner() + success_num, start_time = 0, time.time() + display(f'[Summary] Nmap: {len(ips)} IP addresses were scanned') + for ip in ips: + ok = once_nmap(nm, str(ip), dest_port, timeout, display) + if ok: + success_num += 1 + display('') + display(f'[Done] Nmap: {len(ips)} IP addresses ({success_num} hosts up) ' + f'scanned in {round(time.time() - start_time, 2)} seconds') diff --git a/apps/settings/utils/ping.py b/apps/settings/utils/ping.py index 7b4f0a2a4..cb9e5e544 100644 --- a/apps/settings/utils/ping.py +++ b/apps/settings/utils/ping.py @@ -128,30 +128,37 @@ def ping(dest_addr, timeout, psize, flag=0): return delay -def verbose_ping(dest_addr, timeout=2, count=5, psize=64, display=None): +def verbose_ping(dest_ip, timeout=2, count=5, psize=64, display=None): """ Send `count' ping with `psize' size to `dest_addr' with the given `timeout' and display the result. """ - ip = lookup_domain(dest_addr) + ip = lookup_domain(dest_ip) if not ip: return if display is None: display = print - display("PING %s (%s): 56 data bytes" % (dest_addr, ip)) + error_count = 0 + display("PING %s (%s): 56 data bytes" % (dest_ip, ip)) for i in range(count): try: - delay = ping(dest_addr, timeout, psize) + delay = ping(dest_ip, timeout, psize) except socket.gaierror as e: display("failed. (socket error: '%s')" % str(e)) + error_count += 1 break if delay is None: display("Request timeout for icmp_seq %i" % i) + error_count += 1 else: - delay = delay * 1000 + delay *= 1000 display("64 bytes from %s: icmp_seq=0 ttl=115 time=%.3f ms" % (ip, delay)) time.sleep(1) + display(f'--- {dest_ip} ping statistics ---') + display(f'{count} packets transmitted, ' + f'{count - error_count} packets received, ' + f'{(error_count / count) * 100}% packet loss') print() diff --git a/apps/settings/utils/telnet.py b/apps/settings/utils/telnet.py index 22a1cf619..9cb0a2c0b 100644 --- a/apps/settings/utils/telnet.py +++ b/apps/settings/utils/telnet.py @@ -18,21 +18,21 @@ def telnet(dest_addr, port_number=23, timeout=10): return True, output.decode('utf-8', 'ignore') -def verbose_telnet(dest_addr, port_number=23, timeout=10, display=None): +def verbose_telnet(dest_ip, dest_port=23, timeout=10, display=None): if display is None: display = print - ip = lookup_domain(dest_addr) + ip = lookup_domain(dest_ip) if not ip: return - msg = 'Trying %s (%s:%s)' % (dest_addr, ip, port_number) + msg = 'Trying %s (%s:%s)' % (dest_ip, ip, dest_port) display(msg) try: - is_connective, resp = telnet(dest_addr, port_number, timeout) + is_connective, resp = telnet(dest_ip, dest_port, timeout) if is_connective: template = 'Connected to {0} {1}.\r\n{2}Connection closed by foreign host.' else: template = 'telnet: connect to {0} {1} {2}\r\ntelnet: Unable to connect to remote host' - msg = template.format(dest_addr, port_number, resp) + msg = template.format(dest_ip, dest_port, resp) except Exception as e: msg = 'Error: %s' % e display(msg) diff --git a/apps/settings/ws.py b/apps/settings/ws.py index 9e248536f..f5752e2a1 100644 --- a/apps/settings/ws.py +++ b/apps/settings/ws.py @@ -7,7 +7,7 @@ from channels.generic.websocket import JsonWebsocketConsumer from common.db.utils import close_old_connections from common.utils import get_logger -from .utils import verbose_ping, verbose_telnet +from .utils import verbose_ping, verbose_telnet, verbose_nmap logger = get_logger(__name__) @@ -24,27 +24,28 @@ class ToolsWebsocket(JsonWebsocketConsumer): def send_msg(self, msg): self.send_json({'msg': msg + '\r\n'}) - def imitate_ping(self, dest_addr, timeout=3, count=5, psize=64): + def imitate_ping(self, dest_ip, timeout=3, count=5, psize=64): """ - Send `count' ping with `psize' size to `dest_addr' with + Send `count' ping with `psize' size to `dest_ip' with the given `timeout' and display the result. """ - logger.info('receive request ping {}'.format(dest_addr)) - verbose_ping(dest_addr, timeout, count, psize, display=self.send_msg) + logger.info('receive request ping {}'.format(dest_ip)) + verbose_ping(dest_ip, timeout, count, psize, display=self.send_msg) - def imitate_telnet(self, dest_addr, port_num=23, timeout=10): - logger.info('receive request telnet {}'.format(dest_addr)) - verbose_telnet(dest_addr, port_num, timeout, display=self.send_msg) + def imitate_telnet(self, dest_ip, dest_port=23, timeout=10): + logger.info('receive request telnet {}'.format(dest_ip)) + verbose_telnet(dest_ip, dest_port, timeout, display=self.send_msg) + + def imitate_nmap(self, dest_ip, dest_port=None, timeout=None): + logger.info('receive request nmap {}'.format(dest_ip)) + verbose_nmap(dest_ip, dest_port, timeout, display=self.send_msg) def receive(self, text_data=None, bytes_data=None, **kwargs): data = json.loads(text_data) - tool_type = data.get('tool_type', 'Ping') - dest_addr = data.get('dest_addr') - if tool_type == 'Ping': - self.imitate_ping(dest_addr) - else: - port_num = data.get('port_num') - self.imitate_telnet(dest_addr, port_num) + tool_type = data.pop('tool_type', 'Ping') + + tool_func = getattr(self, f'imitate_{tool_type.lower()}') + tool_func(**data) self.close() def disconnect(self, code): From 962354c50d83b29a35308b99eda21b3f77d532ad Mon Sep 17 00:00:00 2001 From: ibuler Date: Fri, 28 Jul 2023 10:41:37 +0800 Subject: [PATCH 049/177] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=E5=BA=94?= =?UTF-8?q?=E7=94=A8=E5=8F=91=E5=B8=83=E6=9C=BA=E8=B4=A6=E5=8F=B7=E5=88=9B?= =?UTF-8?q?=E5=BB=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../migrations/0121_auto_20230725_1458.py | 5 +- apps/jumpserver/settings/custom.py | 1 - apps/locale/ja/LC_MESSAGES/django.po | 95 +++++++++++-------- apps/locale/zh/LC_MESSAGES/django.po | 95 +++++++++++-------- .../migrations/0015_auto_20200929_1728.py | 4 +- .../migrations/0064_auto_20230728_1001.py | 23 +++++ apps/terminal/models/applet/host.py | 8 +- apps/terminal/serializers/applet_host.py | 1 + apps/terminal/signal_handlers/applet.py | 6 +- 9 files changed, 149 insertions(+), 89 deletions(-) create mode 100644 apps/terminal/migrations/0064_auto_20230728_1001.py diff --git a/apps/assets/migrations/0121_auto_20230725_1458.py b/apps/assets/migrations/0121_auto_20230725_1458.py index d32eb86a1..65a115cce 100644 --- a/apps/assets/migrations/0121_auto_20230725_1458.py +++ b/apps/assets/migrations/0121_auto_20230725_1458.py @@ -6,7 +6,10 @@ from django.db import migrations def migrate_platforms_sftp_protocol(apps, schema_editor): platform_protocol_cls = apps.get_model('assets', 'PlatformProtocol') platform_cls = apps.get_model('assets', 'Platform') - ssh_protocols = platform_protocol_cls.objects.filter(name='ssh', setting__sftp_enabled=True) + ssh_protocols = platform_protocol_cls.objects \ + .filter(name='ssh', setting__sftp_enabled=True) \ + .exclude(name__in=('Gateway', 'RemoteAppHost')) \ + .filter(type='linux') platforms_has_sftp = platform_cls.objects.filter(protocols__name='sftp') new_protocols = [] diff --git a/apps/jumpserver/settings/custom.py b/apps/jumpserver/settings/custom.py index b9be9c75b..16d503f1c 100644 --- a/apps/jumpserver/settings/custom.py +++ b/apps/jumpserver/settings/custom.py @@ -86,7 +86,6 @@ TERMINAL_TELNET_REGEX = CONFIG.TERMINAL_TELNET_REGEX # 默认图形化分辨率 TERMINAL_GRAPHICAL_RESOLUTION = CONFIG.TERMINAL_GRAPHICAL_RESOLUTION - # Asset user auth external backend, default AuthBook backend BACKEND_ASSET_USER_AUTH_VAULT = False diff --git a/apps/locale/ja/LC_MESSAGES/django.po b/apps/locale/ja/LC_MESSAGES/django.po index 424fbf22b..a87020f10 100644 --- a/apps/locale/ja/LC_MESSAGES/django.po +++ b/apps/locale/ja/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-07-25 15:37+0800\n" +"POT-Creation-Date: 2023-07-28 10:38+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -288,7 +288,7 @@ msgstr "アカウントバックアップ計画" #: assets/models/automations/base.py:115 audits/models.py:60 #: ops/models/base.py:55 ops/models/celery.py:63 ops/models/job.py:194 #: ops/templates/ops/celery_task_log.html:75 -#: perms/models/asset_permission.py:72 terminal/models/applet/host.py:137 +#: perms/models/asset_permission.py:72 terminal/models/applet/host.py:139 #: terminal/models/session/session.py:44 #: tickets/models/ticket/apply_application.py:30 #: tickets/models/ticket/apply_asset.py:19 @@ -411,7 +411,7 @@ msgstr "開始日" #: accounts/models/automations/change_secret.py:91 #: assets/models/automations/base.py:116 ops/models/base.py:56 #: ops/models/celery.py:64 ops/models/job.py:195 -#: terminal/models/applet/host.py:138 +#: terminal/models/applet/host.py:140 msgid "Date finished" msgstr "終了日" @@ -696,7 +696,7 @@ msgid "Key password" msgstr "キーパスワード" #: accounts/serializers/account/base.py:80 -#: assets/serializers/asset/common.py:309 +#: assets/serializers/asset/common.py:311 msgid "Spec info" msgstr "特別情報" @@ -839,7 +839,7 @@ msgid "Users" msgstr "ユーザー" #: acls/models/base.py:98 assets/models/automations/base.py:17 -#: assets/models/cmd_filter.py:38 assets/serializers/asset/common.py:308 +#: assets/models/cmd_filter.py:38 assets/serializers/asset/common.py:310 #: rbac/tree.py:35 msgid "Accounts" msgstr "アカウント" @@ -1080,7 +1080,7 @@ msgstr "無効" msgid "Basic" msgstr "基本" -#: assets/const/base.py:35 assets/const/protocol.py:193 +#: assets/const/base.py:35 assets/const/protocol.py:201 #: assets/models/asset/web.py:13 msgid "Script" msgstr "脚本" @@ -1152,10 +1152,6 @@ msgstr "" msgid "Other" msgstr "その他" -#: assets/const/protocol.py:43 -msgid "SFTP enabled" -msgstr "SFTP が有効" - #: assets/const/protocol.py:48 msgid "SFTP home" msgstr "SFTP ルート パス" @@ -1189,28 +1185,36 @@ msgstr "AD ドメイン" msgid "Use SSL" msgstr "SSLの使用" -#: assets/const/protocol.py:149 +#: assets/const/protocol.py:127 +msgid "SYSDBA" +msgstr "" + +#: assets/const/protocol.py:128 +msgid "Connect as SYSDBA" +msgstr "" + +#: assets/const/protocol.py:157 msgid "Auth username" msgstr "ユーザー名で認証する" -#: assets/const/protocol.py:170 assets/models/asset/web.py:9 +#: assets/const/protocol.py:178 assets/models/asset/web.py:9 #: assets/serializers/asset/info/spec.py:16 msgid "Autofill" msgstr "自動充填" -#: assets/const/protocol.py:178 assets/models/asset/web.py:10 +#: assets/const/protocol.py:186 assets/models/asset/web.py:10 msgid "Username selector" msgstr "ユーザー名ピッカー" -#: assets/const/protocol.py:183 assets/models/asset/web.py:11 +#: assets/const/protocol.py:191 assets/models/asset/web.py:11 msgid "Password selector" msgstr "パスワードセレクター" -#: assets/const/protocol.py:188 assets/models/asset/web.py:12 +#: assets/const/protocol.py:196 assets/models/asset/web.py:12 msgid "Submit selector" msgstr "ボタンセレクターを確認する" -#: assets/const/protocol.py:211 +#: assets/const/protocol.py:219 msgid "API mode" msgstr "APIモード" @@ -1239,7 +1243,7 @@ msgstr "SSHパブリックキー" #: common/db/models.py:36 ops/models/adhoc.py:26 ops/models/job.py:113 #: ops/models/playbook.py:26 rbac/models/role.py:37 settings/models.py:37 #: terminal/models/applet/applet.py:44 terminal/models/applet/applet.py:248 -#: terminal/models/applet/host.py:139 terminal/models/component/endpoint.py:24 +#: terminal/models/applet/host.py:141 terminal/models/component/endpoint.py:24 #: terminal/models/component/endpoint.py:102 #: terminal/models/session/session.py:46 tickets/models/comment.py:32 #: tickets/models/ticket/general.py:297 users/models/user.py:792 @@ -1368,7 +1372,7 @@ msgstr "ドメイン" msgid "Labels" msgstr "ラベル" -#: assets/models/asset/common.py:158 assets/serializers/asset/common.py:310 +#: assets/models/asset/common.py:158 assets/serializers/asset/common.py:312 #: assets/serializers/asset/host.py:11 msgid "Gathered info" msgstr "資産ハードウェア情報の収集" @@ -1432,9 +1436,9 @@ msgstr "アセットの自動化タスク" #: assets/models/automations/base.py:113 audits/models.py:199 #: audits/serializers.py:50 ops/models/base.py:49 ops/models/job.py:186 -#: terminal/models/applet/applet.py:247 terminal/models/applet/host.py:136 +#: terminal/models/applet/applet.py:247 terminal/models/applet/host.py:138 #: terminal/models/component/status.py:30 terminal/serializers/applet.py:18 -#: terminal/serializers/applet_host.py:107 tickets/models/ticket/general.py:283 +#: terminal/serializers/applet_host.py:108 tickets/models/ticket/general.py:283 #: tickets/serializers/super_ticket.py:13 #: tickets/serializers/ticket/ticket.py:20 xpack/plugins/cloud/models.py:164 #: xpack/plugins/cloud/models.py:216 @@ -1702,19 +1706,19 @@ msgid "Node path" msgstr "ノードパスです" #: assets/serializers/asset/common.py:145 -#: assets/serializers/asset/common.py:311 +#: assets/serializers/asset/common.py:313 msgid "Auto info" msgstr "自動情報" -#: assets/serializers/asset/common.py:234 +#: assets/serializers/asset/common.py:236 msgid "Platform not exist" msgstr "プラットフォームが存在しません" -#: assets/serializers/asset/common.py:270 +#: assets/serializers/asset/common.py:272 msgid "port out of range (0-65535)" msgstr "ポート番号が範囲外です (0-65535)" -#: assets/serializers/asset/common.py:277 +#: assets/serializers/asset/common.py:279 msgid "Protocol is required: {}" msgstr "プロトコルが必要です: {}" @@ -2022,7 +2026,7 @@ msgid "Change password" msgstr "パスワードを変更する" #: audits/const.py:35 settings/serializers/terminal.py:6 -#: terminal/models/applet/host.py:25 terminal/models/component/terminal.py:163 +#: terminal/models/applet/host.py:26 terminal/models/component/terminal.py:163 #: terminal/serializers/session.py:46 terminal/serializers/session.py:55 msgid "Terminal" msgstr "ターミナル" @@ -2039,7 +2043,7 @@ msgstr "セッションログ" msgid "Login log" msgstr "ログインログ" -#: audits/const.py:43 terminal/models/applet/host.py:140 +#: audits/const.py:43 terminal/models/applet/host.py:142 #: terminal/models/component/task.py:24 msgid "Task" msgstr "タスク" @@ -2250,19 +2254,19 @@ msgstr "" msgid "Anonymous account is not supported for this asset" msgstr "匿名アカウントはこのプロパティではサポートされていません" -#: authentication/api/connection_token.py:323 +#: authentication/api/connection_token.py:320 msgid "Account not found" msgstr "アカウントが見つかりません" -#: authentication/api/connection_token.py:326 +#: authentication/api/connection_token.py:323 msgid "Permission expired" msgstr "承認の有効期限が切れています" -#: authentication/api/connection_token.py:340 +#: authentication/api/connection_token.py:337 msgid "ACL action is reject: {}({})" msgstr "ACL アクションは拒否です: {}({})" -#: authentication/api/connection_token.py:344 +#: authentication/api/connection_token.py:341 msgid "ACL action is review" msgstr "ACL アクションはレビューです" @@ -2718,11 +2722,11 @@ msgstr "ユーザーなしまたは期限切れのユーザー" msgid "No asset or inactive asset" msgstr "アセットがないか、有効化されていないアセット" -#: authentication/models/connection_token.py:269 +#: authentication/models/connection_token.py:280 msgid "Can view super connection token secret" msgstr "スーパー接続トークンのシークレットを表示できます" -#: authentication/models/connection_token.py:271 +#: authentication/models/connection_token.py:282 msgid "Super connection token" msgstr "スーパー接続トークン" @@ -4243,7 +4247,7 @@ msgid "My assets" msgstr "私の資産" #: rbac/tree.py:56 terminal/models/applet/applet.py:51 -#: terminal/models/applet/applet.py:244 terminal/models/applet/host.py:28 +#: terminal/models/applet/applet.py:244 terminal/models/applet/host.py:29 #: terminal/serializers/applet.py:15 msgid "Applet" msgstr "リモートアプリケーション" @@ -5742,7 +5746,7 @@ msgstr "出力" msgid "Risk level" msgstr "リスクレベル" -#: terminal/connect_methods.py:34 +#: terminal/connect_methods.py:35 msgid "DB Client" msgstr "データベース クライアント" @@ -5847,28 +5851,36 @@ msgstr "カスタムプラットフォームのみをサポート" msgid "Missing type in platform.yml" msgstr "platform.ymlにタイプがありません" -#: terminal/models/applet/applet.py:246 terminal/models/applet/host.py:34 -#: terminal/models/applet/host.py:134 +#: terminal/models/applet/applet.py:246 terminal/models/applet/host.py:35 +#: terminal/models/applet/host.py:136 msgid "Hosting" msgstr "ホスト マシン" -#: terminal/models/applet/host.py:19 terminal/serializers/applet_host.py:57 +#: terminal/models/applet/host.py:18 terminal/serializers/applet_host.py:57 msgid "Deploy options" msgstr "展開パラメーター" +#: terminal/models/applet/host.py:19 +msgid "Auto create accounts" +msgstr "アカウントの自動作成" + #: terminal/models/applet/host.py:20 +msgid "Accounts create amount" +msgstr "作成するアカウント数" + +#: terminal/models/applet/host.py:21 msgid "Inited" msgstr "初期化された" -#: terminal/models/applet/host.py:21 +#: terminal/models/applet/host.py:22 msgid "Date inited" msgstr "" -#: terminal/models/applet/host.py:22 +#: terminal/models/applet/host.py:23 msgid "Date synced" msgstr "同期日" -#: terminal/models/applet/host.py:135 +#: terminal/models/applet/host.py:137 msgid "Initial" msgstr "初期化" @@ -7892,6 +7904,9 @@ msgstr "究極のエディション" msgid "Community edition" msgstr "コミュニティ版" +#~ msgid "SFTP enabled" +#~ msgstr "SFTP が有効" + #~ msgid "Item" #~ msgstr "アイテム" diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po index 10fd864cc..388a31294 100644 --- a/apps/locale/zh/LC_MESSAGES/django.po +++ b/apps/locale/zh/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: JumpServer 0.3.3\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-07-25 15:37+0800\n" +"POT-Creation-Date: 2023-07-28 10:38+0800\n" "PO-Revision-Date: 2021-05-20 10:54+0800\n" "Last-Translator: ibuler \n" "Language-Team: JumpServer team\n" @@ -287,7 +287,7 @@ msgstr "账号备份计划" #: assets/models/automations/base.py:115 audits/models.py:60 #: ops/models/base.py:55 ops/models/celery.py:63 ops/models/job.py:194 #: ops/templates/ops/celery_task_log.html:75 -#: perms/models/asset_permission.py:72 terminal/models/applet/host.py:137 +#: perms/models/asset_permission.py:72 terminal/models/applet/host.py:139 #: terminal/models/session/session.py:44 #: tickets/models/ticket/apply_application.py:30 #: tickets/models/ticket/apply_asset.py:19 @@ -410,7 +410,7 @@ msgstr "开始日期" #: accounts/models/automations/change_secret.py:91 #: assets/models/automations/base.py:116 ops/models/base.py:56 #: ops/models/celery.py:64 ops/models/job.py:195 -#: terminal/models/applet/host.py:138 +#: terminal/models/applet/host.py:140 msgid "Date finished" msgstr "结束日期" @@ -692,7 +692,7 @@ msgid "Key password" msgstr "密钥密码" #: accounts/serializers/account/base.py:80 -#: assets/serializers/asset/common.py:309 +#: assets/serializers/asset/common.py:311 msgid "Spec info" msgstr "特殊信息" @@ -835,7 +835,7 @@ msgid "Users" msgstr "用户管理" #: acls/models/base.py:98 assets/models/automations/base.py:17 -#: assets/models/cmd_filter.py:38 assets/serializers/asset/common.py:308 +#: assets/models/cmd_filter.py:38 assets/serializers/asset/common.py:310 #: rbac/tree.py:35 msgid "Accounts" msgstr "账号管理" @@ -1073,7 +1073,7 @@ msgstr "禁用" msgid "Basic" msgstr "基本" -#: assets/const/base.py:35 assets/const/protocol.py:193 +#: assets/const/base.py:35 assets/const/protocol.py:201 #: assets/models/asset/web.py:13 msgid "Script" msgstr "脚本" @@ -1145,10 +1145,6 @@ msgstr "ChatGPT" msgid "Other" msgstr "其它" -#: assets/const/protocol.py:43 -msgid "SFTP enabled" -msgstr "SFTP 已启用" - #: assets/const/protocol.py:48 msgid "SFTP home" msgstr "SFTP 根路径" @@ -1182,28 +1178,36 @@ msgstr "AD 网域" msgid "Use SSL" msgstr "使用 SSL" -#: assets/const/protocol.py:149 +#: assets/const/protocol.py:127 +msgid "SYSDBA" +msgstr "" + +#: assets/const/protocol.py:128 +msgid "Connect as SYSDBA" +msgstr "" + +#: assets/const/protocol.py:157 msgid "Auth username" msgstr "使用用户名认证" -#: assets/const/protocol.py:170 assets/models/asset/web.py:9 +#: assets/const/protocol.py:178 assets/models/asset/web.py:9 #: assets/serializers/asset/info/spec.py:16 msgid "Autofill" msgstr "自动代填" -#: assets/const/protocol.py:178 assets/models/asset/web.py:10 +#: assets/const/protocol.py:186 assets/models/asset/web.py:10 msgid "Username selector" msgstr "用户名选择器" -#: assets/const/protocol.py:183 assets/models/asset/web.py:11 +#: assets/const/protocol.py:191 assets/models/asset/web.py:11 msgid "Password selector" msgstr "密码选择器" -#: assets/const/protocol.py:188 assets/models/asset/web.py:12 +#: assets/const/protocol.py:196 assets/models/asset/web.py:12 msgid "Submit selector" msgstr "确认按钮选择器" -#: assets/const/protocol.py:211 +#: assets/const/protocol.py:219 msgid "API mode" msgstr "API 模式" @@ -1232,7 +1236,7 @@ msgstr "SSH公钥" #: common/db/models.py:36 ops/models/adhoc.py:26 ops/models/job.py:113 #: ops/models/playbook.py:26 rbac/models/role.py:37 settings/models.py:37 #: terminal/models/applet/applet.py:44 terminal/models/applet/applet.py:248 -#: terminal/models/applet/host.py:139 terminal/models/component/endpoint.py:24 +#: terminal/models/applet/host.py:141 terminal/models/component/endpoint.py:24 #: terminal/models/component/endpoint.py:102 #: terminal/models/session/session.py:46 tickets/models/comment.py:32 #: tickets/models/ticket/general.py:297 users/models/user.py:792 @@ -1361,7 +1365,7 @@ msgstr "网域" msgid "Labels" msgstr "标签管理" -#: assets/models/asset/common.py:158 assets/serializers/asset/common.py:310 +#: assets/models/asset/common.py:158 assets/serializers/asset/common.py:312 #: assets/serializers/asset/host.py:11 msgid "Gathered info" msgstr "收集资产硬件信息" @@ -1425,9 +1429,9 @@ msgstr "资产自动化任务" #: assets/models/automations/base.py:113 audits/models.py:199 #: audits/serializers.py:50 ops/models/base.py:49 ops/models/job.py:186 -#: terminal/models/applet/applet.py:247 terminal/models/applet/host.py:136 +#: terminal/models/applet/applet.py:247 terminal/models/applet/host.py:138 #: terminal/models/component/status.py:30 terminal/serializers/applet.py:18 -#: terminal/serializers/applet_host.py:107 tickets/models/ticket/general.py:283 +#: terminal/serializers/applet_host.py:108 tickets/models/ticket/general.py:283 #: tickets/serializers/super_ticket.py:13 #: tickets/serializers/ticket/ticket.py:20 xpack/plugins/cloud/models.py:164 #: xpack/plugins/cloud/models.py:216 @@ -1693,19 +1697,19 @@ msgid "Node path" msgstr "节点路径" #: assets/serializers/asset/common.py:145 -#: assets/serializers/asset/common.py:311 +#: assets/serializers/asset/common.py:313 msgid "Auto info" msgstr "自动化信息" -#: assets/serializers/asset/common.py:234 +#: assets/serializers/asset/common.py:236 msgid "Platform not exist" msgstr "平台不存在" -#: assets/serializers/asset/common.py:270 +#: assets/serializers/asset/common.py:272 msgid "port out of range (0-65535)" msgstr "端口超出范围 (0-65535)" -#: assets/serializers/asset/common.py:277 +#: assets/serializers/asset/common.py:279 msgid "Protocol is required: {}" msgstr "协议是必填的: {}" @@ -2006,7 +2010,7 @@ msgid "Change password" msgstr "改密" #: audits/const.py:35 settings/serializers/terminal.py:6 -#: terminal/models/applet/host.py:25 terminal/models/component/terminal.py:163 +#: terminal/models/applet/host.py:26 terminal/models/component/terminal.py:163 #: terminal/serializers/session.py:46 terminal/serializers/session.py:55 msgid "Terminal" msgstr "终端" @@ -2023,7 +2027,7 @@ msgstr "会话日志" msgid "Login log" msgstr "登录日志" -#: audits/const.py:43 terminal/models/applet/host.py:140 +#: audits/const.py:43 terminal/models/applet/host.py:142 #: terminal/models/component/task.py:24 msgid "Task" msgstr "任务" @@ -2232,19 +2236,19 @@ msgstr "不允许使用可重复使用的连接令牌,未启用全局设置" msgid "Anonymous account is not supported for this asset" msgstr "匿名账号不支持当前资产" -#: authentication/api/connection_token.py:323 +#: authentication/api/connection_token.py:320 msgid "Account not found" msgstr "账号未找到" -#: authentication/api/connection_token.py:326 +#: authentication/api/connection_token.py:323 msgid "Permission expired" msgstr "授权已过期" -#: authentication/api/connection_token.py:340 +#: authentication/api/connection_token.py:337 msgid "ACL action is reject: {}({})" msgstr "ACL 动作是拒绝: {}({})" -#: authentication/api/connection_token.py:344 +#: authentication/api/connection_token.py:341 msgid "ACL action is review" msgstr "ACL 动作是复核" @@ -2686,11 +2690,11 @@ msgstr "没有用户或用户失效" msgid "No asset or inactive asset" msgstr "没有资产或资产未激活" -#: authentication/models/connection_token.py:269 +#: authentication/models/connection_token.py:280 msgid "Can view super connection token secret" msgstr "可以查看超级连接令牌密文" -#: authentication/models/connection_token.py:271 +#: authentication/models/connection_token.py:282 msgid "Super connection token" msgstr "超级连接令牌" @@ -4194,7 +4198,7 @@ msgid "My assets" msgstr "我的资产" #: rbac/tree.py:56 terminal/models/applet/applet.py:51 -#: terminal/models/applet/applet.py:244 terminal/models/applet/host.py:28 +#: terminal/models/applet/applet.py:244 terminal/models/applet/host.py:29 #: terminal/serializers/applet.py:15 msgid "Applet" msgstr "远程应用" @@ -5655,7 +5659,7 @@ msgstr "输出" msgid "Risk level" msgstr "风险等级" -#: terminal/connect_methods.py:34 +#: terminal/connect_methods.py:35 msgid "DB Client" msgstr "数据库客户端" @@ -5760,28 +5764,36 @@ msgstr "只支持自定义平台" msgid "Missing type in platform.yml" msgstr "在 platform.yml 中缺少类型" -#: terminal/models/applet/applet.py:246 terminal/models/applet/host.py:34 -#: terminal/models/applet/host.py:134 +#: terminal/models/applet/applet.py:246 terminal/models/applet/host.py:35 +#: terminal/models/applet/host.py:136 msgid "Hosting" msgstr "宿主机" -#: terminal/models/applet/host.py:19 terminal/serializers/applet_host.py:57 +#: terminal/models/applet/host.py:18 terminal/serializers/applet_host.py:57 msgid "Deploy options" msgstr "部署参数" +#: terminal/models/applet/host.py:19 +msgid "Auto create accounts" +msgstr "自动创建账号" + #: terminal/models/applet/host.py:20 +msgid "Accounts create amount" +msgstr "创建账号数量" + +#: terminal/models/applet/host.py:21 msgid "Inited" msgstr "已初始化" -#: terminal/models/applet/host.py:21 +#: terminal/models/applet/host.py:22 msgid "Date inited" msgstr "初始化日期" -#: terminal/models/applet/host.py:22 +#: terminal/models/applet/host.py:23 msgid "Date synced" msgstr "同步日期" -#: terminal/models/applet/host.py:135 +#: terminal/models/applet/host.py:137 msgid "Initial" msgstr "初始化" @@ -7778,6 +7790,9 @@ msgstr "旗舰版" msgid "Community edition" msgstr "社区版" +#~ msgid "SFTP enabled" +#~ msgstr "SFTP 已启用" + #~ msgid "Item" #~ msgstr "项目" diff --git a/apps/perms/migrations/0015_auto_20200929_1728.py b/apps/perms/migrations/0015_auto_20200929_1728.py index c241a2f71..9b8388c3b 100644 --- a/apps/perms/migrations/0015_auto_20200929_1728.py +++ b/apps/perms/migrations/0015_auto_20200929_1728.py @@ -14,12 +14,12 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='assetpermission', name='user_groups', - field=models.ManyToManyField(blank=True, related_name='assetpermissions', to='users.UserGroup', verbose_name='User group'), + field=models.ManyToManyField(blank=True, related_name='%(class)ss', to='users.usergroup', verbose_name='User group'), ), migrations.AlterField( model_name='assetpermission', name='users', - field=models.ManyToManyField(blank=True, related_name='assetpermissions', to=settings.AUTH_USER_MODEL, verbose_name='User'), + field=models.ManyToManyField(blank=True, related_name='%(class)ss', to=settings.AUTH_USER_MODEL, verbose_name='User'), ), migrations.AlterField( model_name='databaseapppermission', diff --git a/apps/terminal/migrations/0064_auto_20230728_1001.py b/apps/terminal/migrations/0064_auto_20230728_1001.py new file mode 100644 index 000000000..0610f174f --- /dev/null +++ b/apps/terminal/migrations/0064_auto_20230728_1001.py @@ -0,0 +1,23 @@ +# Generated by Django 4.1.10 on 2023-07-28 02:01 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('terminal', '0063_auto_20230621_1133'), + ] + + operations = [ + migrations.AddField( + model_name='applethost', + name='accounts_create_amount', + field=models.IntegerField(default=100, verbose_name='Accounts create amount'), + ), + migrations.AddField( + model_name='applethost', + name='auto_create_accounts', + field=models.BooleanField(default=True, verbose_name='Auto create accounts'), + ), + ] diff --git a/apps/terminal/models/applet/host.py b/apps/terminal/models/applet/host.py index b0e7c478c..a4945a890 100644 --- a/apps/terminal/models/applet/host.py +++ b/apps/terminal/models/applet/host.py @@ -1,4 +1,3 @@ -import os from collections import defaultdict from django.db import models @@ -17,6 +16,8 @@ __all__ = ['AppletHost', 'AppletHostDeployment'] class AppletHost(Host): deploy_options = models.JSONField(default=dict, verbose_name=_('Deploy options')) + auto_create_accounts = models.BooleanField(default=True, verbose_name=_('Auto create accounts')) + accounts_create_amount = models.IntegerField(default=100, verbose_name=_('Accounts create amount')) inited = models.BooleanField(default=False, verbose_name=_('Inited')) date_inited = models.DateTimeField(null=True, blank=True, verbose_name=_('Date inited')) date_synced = models.DateTimeField(null=True, blank=True, verbose_name=_('Date synced')) @@ -84,13 +85,14 @@ class AppletHost(Host): return random_string(16, special_char=True) def generate_accounts(self): + if not self.auto_create_accounts: + return self.generate_public_accounts() self.generate_private_accounts() def generate_public_accounts(self): - public_amount = int(os.getenv('TERMINAL_ACCOUNTS_AMOUNT', 100)) now_count = self.accounts.filter(privileged=False, username__startswith='jms').count() - need = public_amount - now_count + need = self.accounts_create_amount - now_count accounts = [] account_model = self.accounts.model diff --git a/apps/terminal/serializers/applet_host.py b/apps/terminal/serializers/applet_host.py index 392b2e2e3..59b87ca9d 100644 --- a/apps/terminal/serializers/applet_host.py +++ b/apps/terminal/serializers/applet_host.py @@ -62,6 +62,7 @@ class AppletHostSerializer(HostSerializer): class Meta(HostSerializer.Meta): model = AppletHost fields = HostSerializer.Meta.fields + [ + 'auto_create_accounts', 'accounts_create_amount', 'load', 'date_synced', 'deploy_options' ] extra_kwargs = { diff --git a/apps/terminal/signal_handlers/applet.py b/apps/terminal/signal_handlers/applet.py index 4fe390b8e..912510901 100644 --- a/apps/terminal/signal_handlers/applet.py +++ b/apps/terminal/signal_handlers/applet.py @@ -23,8 +23,9 @@ def on_applet_host_create(sender, instance, created=False, **kwargs): applets = Applet.objects.all() instance.applets.set(applets) - applet_host_generate_accounts.delay(instance.id) applet_host_change_pub_sub.publish(True) + if instance.auto_create_accounts: + applet_host_generate_accounts.delay(instance.id) @receiver(post_save, sender=User) @@ -35,6 +36,8 @@ def on_user_create_create_account(sender, instance, created=False, **kwargs): with tmp_to_builtin_org(system=1): applet_hosts = AppletHost.objects.all() for host in applet_hosts: + if not host.auto_create_accounts: + continue host.generate_private_accounts_by_usernames([instance.username]) @@ -57,7 +60,6 @@ def on_applet_create(sender, instance, created=False, **kwargs): return hosts = AppletHost.objects.all() instance.hosts.set(hosts) - applet_host_change_pub_sub.publish(True) From 2c22396093e35066fb8d8404b031b5c0018ef1d3 Mon Sep 17 00:00:00 2001 From: ibuler Date: Fri, 28 Jul 2023 10:49:33 +0800 Subject: [PATCH 050/177] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=E5=8E=BB?= =?UTF-8?q?=E6=8E=89=E5=86=B2=E7=AA=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../migrations/0064_auto_20230728_1001.py | 5 +++++ .../migrations/0064_sessionsharing_origin.py | 18 ------------------ 2 files changed, 5 insertions(+), 18 deletions(-) delete mode 100644 apps/terminal/migrations/0064_sessionsharing_origin.py diff --git a/apps/terminal/migrations/0064_auto_20230728_1001.py b/apps/terminal/migrations/0064_auto_20230728_1001.py index 0610f174f..264bcde38 100644 --- a/apps/terminal/migrations/0064_auto_20230728_1001.py +++ b/apps/terminal/migrations/0064_auto_20230728_1001.py @@ -20,4 +20,9 @@ class Migration(migrations.Migration): name='auto_create_accounts', field=models.BooleanField(default=True, verbose_name='Auto create accounts'), ), + migrations.AddField( + model_name='sessionsharing', + name='origin', + field=models.URLField(blank=True, null=True, verbose_name='Origin'), + ), ] diff --git a/apps/terminal/migrations/0064_sessionsharing_origin.py b/apps/terminal/migrations/0064_sessionsharing_origin.py deleted file mode 100644 index 91886fc16..000000000 --- a/apps/terminal/migrations/0064_sessionsharing_origin.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 4.1.10 on 2023-07-26 10:55 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('terminal', '0063_auto_20230621_1133'), - ] - - operations = [ - migrations.AddField( - model_name='sessionsharing', - name='origin', - field=models.URLField(blank=True, null=True, verbose_name='Origin'), - ), - ] From 5380dc0c2de3d6e094f8cd407ddd8adfe7ac6c7c Mon Sep 17 00:00:00 2001 From: ibuler Date: Fri, 28 Jul 2023 11:02:21 +0800 Subject: [PATCH 051/177] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=E7=BF=BB?= =?UTF-8?q?=E8=AF=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/locale/ja/LC_MESSAGES/django.mo | 4 +- apps/locale/ja/LC_MESSAGES/django.po | 51 ++++++++++++++--------- apps/locale/zh/LC_MESSAGES/django.mo | 4 +- apps/locale/zh/LC_MESSAGES/django.po | 52 +++++++++++++++--------- apps/terminal/serializers/applet_host.py | 9 +++- 5 files changed, 77 insertions(+), 43 deletions(-) diff --git a/apps/locale/ja/LC_MESSAGES/django.mo b/apps/locale/ja/LC_MESSAGES/django.mo index 62fb28861..e2cc899ec 100644 --- a/apps/locale/ja/LC_MESSAGES/django.mo +++ b/apps/locale/ja/LC_MESSAGES/django.mo @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bd82a00953513f7ddd38f6f1d45f770e3a02d1c4a2467bfd791218c10c8d717c -size 148960 +oid sha256:538beabe7c224b203bbc0ebaf191509a8f407f6b3e8194038fc203bde10d6d5a +size 150250 diff --git a/apps/locale/ja/LC_MESSAGES/django.po b/apps/locale/ja/LC_MESSAGES/django.po index 389fc66e5..bfd6cee82 100644 --- a/apps/locale/ja/LC_MESSAGES/django.po +++ b/apps/locale/ja/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-07-25 15:37+0800\n" +"POT-Creation-Date: 2023-07-28 10:57+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -316,7 +316,7 @@ msgid "Trigger mode" msgstr "トリガーモード" #: accounts/models/automations/backup_account.py:97 audits/models.py:194 -#: terminal/models/session/sharing.py:117 xpack/plugins/cloud/models.py:168 +#: terminal/models/session/sharing.py:121 xpack/plugins/cloud/models.py:168 msgid "Reason" msgstr "理由" @@ -748,7 +748,7 @@ msgstr "自動タスク実行履歴" #: accounts/serializers/automations/change_secret.py:155 audits/const.py:53 #: audits/models.py:59 audits/signal_handlers/activity_log.py:33 #: common/const/choices.py:18 ops/const.py:56 ops/serializers/celery.py:40 -#: terminal/const.py:76 terminal/models/session/sharing.py:113 +#: terminal/const.py:76 terminal/models/session/sharing.py:117 #: tickets/views/approve.py:115 msgid "Success" msgstr "成功" @@ -1441,7 +1441,7 @@ msgstr "アセットの自動化タスク" #: audits/serializers.py:50 ops/models/base.py:49 ops/models/job.py:186 #: terminal/models/applet/applet.py:247 terminal/models/applet/host.py:138 #: terminal/models/component/status.py:30 terminal/serializers/applet.py:18 -#: terminal/serializers/applet_host.py:108 tickets/models/ticket/general.py:283 +#: terminal/serializers/applet_host.py:115 tickets/models/ticket/general.py:283 #: tickets/serializers/super_ticket.py:13 #: tickets/serializers/ticket/ticket.py:20 xpack/plugins/cloud/models.py:164 #: xpack/plugins/cloud/models.py:216 @@ -2069,7 +2069,7 @@ msgid "Job audit log" msgstr "ジョブ監査ログ" #: audits/models.py:51 audits/models.py:95 audits/models.py:166 -#: terminal/models/session/session.py:38 terminal/models/session/sharing.py:105 +#: terminal/models/session/session.py:38 terminal/models/session/sharing.py:109 msgid "Remote addr" msgstr "リモートaddr" @@ -2087,7 +2087,7 @@ msgstr "書類" #: audits/models.py:62 terminal/backends/command/models.py:21 #: terminal/models/session/replay.py:9 terminal/models/session/sharing.py:19 -#: terminal/models/session/sharing.py:87 +#: terminal/models/session/sharing.py:91 #: terminal/templates/terminal/_msg_command_alert.html:10 #: terminal/templates/terminal/_msg_command_warning.html:17 #: tickets/models/ticket/command_confirm.py:15 @@ -2948,7 +2948,7 @@ msgid "request new one" msgstr "新しいものを要求する" #: authentication/templates/authentication/_msg_reset_password_code.html:12 -#: terminal/models/session/sharing.py:26 terminal/models/session/sharing.py:89 +#: terminal/models/session/sharing.py:26 terminal/models/session/sharing.py:93 #: terminal/templates/terminal/_msg_session_sharing.html:12 #: users/forms/profile.py:107 users/templates/users/forgot_password.html:66 msgid "Verify code" @@ -3738,7 +3738,7 @@ msgstr "タスクモニターを表示できます" msgid "Kwargs" msgstr "クワーグ" -#: ops/models/celery.py:61 terminal/models/session/sharing.py:120 +#: ops/models/celery.py:61 terminal/models/session/sharing.py:124 #: tickets/const.py:25 msgid "Finished" msgstr "終了" @@ -6016,7 +6016,7 @@ msgstr "セッション再生をダウンロードできます" msgid "Account id" msgstr "アカウント ID" -#: terminal/models/session/session.py:36 terminal/models/session/sharing.py:110 +#: terminal/models/session/session.py:36 terminal/models/session/sharing.py:114 msgid "Login from" msgstr "ログイン元" @@ -6061,7 +6061,7 @@ msgstr "アクションパーミッション" msgid "Origin" msgstr "ソース" -#: terminal/models/session/sharing.py:41 terminal/models/session/sharing.py:92 +#: terminal/models/session/sharing.py:41 terminal/models/session/sharing.py:96 #: terminal/notifications.py:261 msgid "Session sharing" msgstr "セッション共有" @@ -6070,39 +6070,39 @@ msgstr "セッション共有" msgid "Can add super session sharing" msgstr "スーパーセッション共有を追加できます" -#: terminal/models/session/sharing.py:75 +#: terminal/models/session/sharing.py:79 msgid "Link not active" msgstr "リンクがアクティブでない" -#: terminal/models/session/sharing.py:77 +#: terminal/models/session/sharing.py:81 msgid "Link expired" msgstr "リンク期限切れ" -#: terminal/models/session/sharing.py:79 +#: terminal/models/session/sharing.py:83 msgid "User not allowed to join" msgstr "ユーザーはセッションに参加できません" -#: terminal/models/session/sharing.py:96 terminal/serializers/sharing.py:71 +#: terminal/models/session/sharing.py:100 terminal/serializers/sharing.py:71 msgid "Joiner" msgstr "ジョイナー" -#: terminal/models/session/sharing.py:99 +#: terminal/models/session/sharing.py:103 msgid "Date joined" msgstr "参加日" -#: terminal/models/session/sharing.py:102 +#: terminal/models/session/sharing.py:106 msgid "Date left" msgstr "日付が残っています" -#: terminal/models/session/sharing.py:125 +#: terminal/models/session/sharing.py:129 msgid "Session join record" msgstr "セッション参加記録" -#: terminal/models/session/sharing.py:141 +#: terminal/models/session/sharing.py:145 msgid "Invalid verification code" msgstr "検証コードが無効" -#: terminal/models/session/sharing.py:148 +#: terminal/models/session/sharing.py:152 msgid "You have already joined this session" msgstr "すでにこのセッションに参加しています" @@ -6206,6 +6206,19 @@ msgstr "RDS 远程应用注销时间限制" msgid "Load status" msgstr "ロードステータス" +#: terminal/serializers/applet_host.py:72 +msgid "" +"These accounts are used to connect to the published application, the account " +"is now divided into two types, one is dedicated to each account, each user " +"has a private account, the other is public, when the application does not " +"support multiple open and the special has been used, the public account will " +"be used to connect" +msgstr "これらのアカウントは、公開されたアプリケーションに接続するために使用されます。アカウントは現在、2つのタイプに分類されています。1つは、各アカウントに専用のアカウントで、各ユーザーにはプライベートアカウントがあります。もう1つは公開されています。アプリケーションが複数のオープンをサポートしていない場合、および特別なものが使用されている場合、公開アカウントが使用されます。" + +#: terminal/serializers/applet_host.py:77 +msgid "The number of public accounts created automatically" +msgstr "自動的に作成される公開アカウントの数" + #: terminal/serializers/command.py:19 msgid "Session ID" msgstr "セッションID" diff --git a/apps/locale/zh/LC_MESSAGES/django.mo b/apps/locale/zh/LC_MESSAGES/django.mo index 145af8511..00fe60499 100644 --- a/apps/locale/zh/LC_MESSAGES/django.mo +++ b/apps/locale/zh/LC_MESSAGES/django.mo @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:859c812ee67cc9b5f79da96d5e72445a60bdd19af7db4a8b71196a065adefeab -size 121844 +oid sha256:2cf5749656bd07818b67191c2f665246e903d74e76c49ebcdec6004322f75314 +size 122767 diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po index bdea576a2..ade0170ab 100644 --- a/apps/locale/zh/LC_MESSAGES/django.po +++ b/apps/locale/zh/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: JumpServer 0.3.3\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-07-28 10:38+0800\n" +"POT-Creation-Date: 2023-07-28 10:57+0800\n" "PO-Revision-Date: 2021-05-20 10:54+0800\n" "Last-Translator: ibuler \n" "Language-Team: JumpServer team\n" @@ -315,7 +315,7 @@ msgid "Trigger mode" msgstr "触发模式" #: accounts/models/automations/backup_account.py:97 audits/models.py:194 -#: terminal/models/session/sharing.py:117 xpack/plugins/cloud/models.py:168 +#: terminal/models/session/sharing.py:121 xpack/plugins/cloud/models.py:168 msgid "Reason" msgstr "原因" @@ -744,7 +744,7 @@ msgstr "自动化任务执行历史" #: accounts/serializers/automations/change_secret.py:155 audits/const.py:53 #: audits/models.py:59 audits/signal_handlers/activity_log.py:33 #: common/const/choices.py:18 ops/const.py:56 ops/serializers/celery.py:40 -#: terminal/const.py:76 terminal/models/session/sharing.py:113 +#: terminal/const.py:76 terminal/models/session/sharing.py:117 #: tickets/views/approve.py:115 msgid "Success" msgstr "成功" @@ -1434,7 +1434,7 @@ msgstr "资产自动化任务" #: audits/serializers.py:50 ops/models/base.py:49 ops/models/job.py:186 #: terminal/models/applet/applet.py:247 terminal/models/applet/host.py:138 #: terminal/models/component/status.py:30 terminal/serializers/applet.py:18 -#: terminal/serializers/applet_host.py:108 tickets/models/ticket/general.py:283 +#: terminal/serializers/applet_host.py:115 tickets/models/ticket/general.py:283 #: tickets/serializers/super_ticket.py:13 #: tickets/serializers/ticket/ticket.py:20 xpack/plugins/cloud/models.py:164 #: xpack/plugins/cloud/models.py:216 @@ -2053,7 +2053,7 @@ msgid "Job audit log" msgstr "作业审计日志" #: audits/models.py:51 audits/models.py:95 audits/models.py:166 -#: terminal/models/session/session.py:38 terminal/models/session/sharing.py:105 +#: terminal/models/session/session.py:38 terminal/models/session/sharing.py:109 msgid "Remote addr" msgstr "远端地址" @@ -2071,7 +2071,7 @@ msgstr "文件" #: audits/models.py:62 terminal/backends/command/models.py:21 #: terminal/models/session/replay.py:9 terminal/models/session/sharing.py:19 -#: terminal/models/session/sharing.py:87 +#: terminal/models/session/sharing.py:91 #: terminal/templates/terminal/_msg_command_alert.html:10 #: terminal/templates/terminal/_msg_command_warning.html:17 #: tickets/models/ticket/command_confirm.py:15 @@ -2912,7 +2912,7 @@ msgid "request new one" msgstr "重新申请" #: authentication/templates/authentication/_msg_reset_password_code.html:12 -#: terminal/models/session/sharing.py:26 terminal/models/session/sharing.py:89 +#: terminal/models/session/sharing.py:26 terminal/models/session/sharing.py:93 #: terminal/templates/terminal/_msg_session_sharing.html:12 #: users/forms/profile.py:107 users/templates/users/forgot_password.html:66 msgid "Verify code" @@ -3691,7 +3691,7 @@ msgstr "可以查看任务监控" msgid "Kwargs" msgstr "其它参数" -#: ops/models/celery.py:61 terminal/models/session/sharing.py:120 +#: ops/models/celery.py:61 terminal/models/session/sharing.py:124 #: tickets/const.py:25 msgid "Finished" msgstr "结束" @@ -5929,7 +5929,7 @@ msgstr "可以下载会话录像" msgid "Account id" msgstr "账号 ID" -#: terminal/models/session/session.py:36 terminal/models/session/sharing.py:110 +#: terminal/models/session/session.py:36 terminal/models/session/sharing.py:114 msgid "Login from" msgstr "登录来源" @@ -5974,7 +5974,7 @@ msgstr "操作权限" msgid "Origin" msgstr "来源" -#: terminal/models/session/sharing.py:41 terminal/models/session/sharing.py:92 +#: terminal/models/session/sharing.py:41 terminal/models/session/sharing.py:96 #: terminal/notifications.py:261 msgid "Session sharing" msgstr "会话分享" @@ -5983,39 +5983,39 @@ msgstr "会话分享" msgid "Can add super session sharing" msgstr "可以创建超级会话分享" -#: terminal/models/session/sharing.py:75 +#: terminal/models/session/sharing.py:79 msgid "Link not active" msgstr "链接失效" -#: terminal/models/session/sharing.py:77 +#: terminal/models/session/sharing.py:81 msgid "Link expired" msgstr "链接过期" -#: terminal/models/session/sharing.py:79 +#: terminal/models/session/sharing.py:83 msgid "User not allowed to join" msgstr "该用户无权加入会话" -#: terminal/models/session/sharing.py:96 terminal/serializers/sharing.py:71 +#: terminal/models/session/sharing.py:100 terminal/serializers/sharing.py:71 msgid "Joiner" msgstr "加入者" -#: terminal/models/session/sharing.py:99 +#: terminal/models/session/sharing.py:103 msgid "Date joined" msgstr "加入日期" -#: terminal/models/session/sharing.py:102 +#: terminal/models/session/sharing.py:106 msgid "Date left" msgstr "结束日期" -#: terminal/models/session/sharing.py:125 +#: terminal/models/session/sharing.py:129 msgid "Session join record" msgstr "会话加入记录" -#: terminal/models/session/sharing.py:141 +#: terminal/models/session/sharing.py:145 msgid "Invalid verification code" msgstr "验证码不正确" -#: terminal/models/session/sharing.py:148 +#: terminal/models/session/sharing.py:152 msgid "You have already joined this session" msgstr "您已经加入过此会话" @@ -6117,6 +6117,20 @@ msgstr "RDS 远程应用注销时间限制" msgid "Load status" msgstr "负载状态" +#: terminal/serializers/applet_host.py:72 +msgid "" +"These accounts are used to connect to the published application, the account " +"is now divided into two types, one is dedicated to each account, each user " +"has a private account, the other is public, when the application does not " +"support multiple open and the special has been used, the public account will " +"be used to connect" +msgstr "这些账号用于连接发布的应用,账号现在分为两种类型,一种是专用的,每个用户都有一个专用账号。 " +"另一种是公共的,当应用不支持多开且专用的已经被使用时,会使用公共账号连接" + +#: terminal/serializers/applet_host.py:77 +msgid "The number of public accounts created automatically" +msgstr "公用账号自动创建的数量" + #: terminal/serializers/command.py:19 msgid "Session ID" msgstr "会话ID" diff --git a/apps/terminal/serializers/applet_host.py b/apps/terminal/serializers/applet_host.py index 59b87ca9d..1c65315b7 100644 --- a/apps/terminal/serializers/applet_host.py +++ b/apps/terminal/serializers/applet_host.py @@ -67,7 +67,14 @@ class AppletHostSerializer(HostSerializer): ] extra_kwargs = { **HostSerializer.Meta.extra_kwargs, - 'date_synced': {'read_only': True} + 'date_synced': {'read_only': True}, + 'auto_create_accounts': {'help_text': _( + 'These accounts are used to connect to the published application, ' + 'the account is now divided into two types, one is dedicated to each account, ' + 'each user has a private account, the other is public, ' + 'when the application does not support multiple open and the special has been used, ' + 'the public account will be used to connect')}, + 'accounts_create_amount': {'help_text': _('The number of public accounts created automatically')}, } def __init__(self, *args, data=None, **kwargs): From 1a4c5dca33289091faa77ccc0e371111c1d6624a Mon Sep 17 00:00:00 2001 From: ibuler Date: Fri, 28 Jul 2023 11:06:01 +0800 Subject: [PATCH 052/177] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=E7=BF=BB?= =?UTF-8?q?=E8=AF=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/locale/ja/LC_MESSAGES/django.po | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/locale/ja/LC_MESSAGES/django.po b/apps/locale/ja/LC_MESSAGES/django.po index bfd6cee82..04c99f607 100644 --- a/apps/locale/ja/LC_MESSAGES/django.po +++ b/apps/locale/ja/LC_MESSAGES/django.po @@ -5880,7 +5880,7 @@ msgstr "初期化された" #: terminal/models/applet/host.py:22 msgid "Date inited" -msgstr "" +msgstr "初期化日" #: terminal/models/applet/host.py:23 msgid "Date synced" From 107fda0f990aad0d5503b2ef7addc9fb37229761 Mon Sep 17 00:00:00 2001 From: ibuler Date: Fri, 28 Jul 2023 11:13:48 +0800 Subject: [PATCH 053/177] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=E5=8F=91?= =?UTF-8?q?=E5=B8=83=E6=9C=BA=E8=B4=A6=E5=8F=B7=E9=80=89=E6=8B=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/terminal/models/applet/applet.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/apps/terminal/models/applet/applet.py b/apps/terminal/models/applet/applet.py index edf7b332b..5a4a08fe3 100644 --- a/apps/terminal/models/applet/applet.py +++ b/apps/terminal/models/applet/applet.py @@ -216,9 +216,11 @@ class Applet(JMSBaseModel): if private_account and private_account.username not in accounts_username_used: account = private_account else: - accounts = accounts.exclude(username__in=accounts_username_used) \ - .filter(username__startswith='jms_') - account = self.random_select_prefer_account(user, host, accounts) + accounts = accounts.exclude(username__in=accounts_username_used) + public_accounts = accounts.filter(username__startswith='jms_{}'.format(self.name)) + if not public_accounts: + public_accounts = accounts.exclude(username__in=['Administrator', 'root']) + account = self.random_select_prefer_account(user, host, public_accounts) if not account: return ttl = 60 * 60 * 24 From 93350faa08ad1be1c9db570ee5c1628ca4f49d2a Mon Sep 17 00:00:00 2001 From: ibuler Date: Fri, 28 Jul 2023 11:15:24 +0800 Subject: [PATCH 054/177] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=E8=B4=A6?= =?UTF-8?q?=E5=8F=B7=E9=80=89=E6=8B=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/terminal/models/applet/applet.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/terminal/models/applet/applet.py b/apps/terminal/models/applet/applet.py index 5a4a08fe3..be6b397ff 100644 --- a/apps/terminal/models/applet/applet.py +++ b/apps/terminal/models/applet/applet.py @@ -217,7 +217,7 @@ class Applet(JMSBaseModel): account = private_account else: accounts = accounts.exclude(username__in=accounts_username_used) - public_accounts = accounts.filter(username__startswith='jms_{}'.format(self.name)) + public_accounts = accounts.filter(username__startswith='jms_') if not public_accounts: public_accounts = accounts.exclude(username__in=['Administrator', 'root']) account = self.random_select_prefer_account(user, host, public_accounts) From c86b28a305e8030f7c5bd2e7e2d743d92c7f828d Mon Sep 17 00:00:00 2001 From: jiangweidong Date: Fri, 28 Jul 2023 14:32:31 +0800 Subject: [PATCH 055/177] =?UTF-8?q?feat:=20=E6=94=AF=E6=8C=81=E6=89=B9?= =?UTF-8?q?=E9=87=8F=E5=AE=A1=E6=89=B9=E5=B7=A5=E5=8D=95=20(#11014)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/tickets/api/ticket.py | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/apps/tickets/api/ticket.py b/apps/tickets/api/ticket.py index 2fa710ed6..bbe4ca4d4 100644 --- a/apps/tickets/api/ticket.py +++ b/apps/tickets/api/ticket.py @@ -1,5 +1,6 @@ # -*- coding: utf-8 -*- # +from django.utils.translation import gettext_lazy as _ from rest_framework import viewsets from rest_framework.decorators import action from rest_framework.exceptions import MethodNotAllowed @@ -38,9 +39,9 @@ class TicketViewSet(CommonApiMixin, viewsets.ModelViewSet): ordering = ('-date_created',) rbac_perms = { 'open': 'tickets.view_ticket', + 'bulk': 'tickets.change_ticket', } - def retrieve(self, request, *args, **kwargs): instance = self.get_object() with tmp_to_root_org(): @@ -57,6 +58,10 @@ class TicketViewSet(CommonApiMixin, viewsets.ModelViewSet): def destroy(self, request, *args, **kwargs): raise MethodNotAllowed(self.action) + def ticket_not_allowed(self): + if self.model == Ticket: + raise MethodNotAllowed(self.action) + def get_queryset(self): with tmp_to_root_org(): queryset = self.model.get_user_related_tickets(self.request.user) @@ -74,6 +79,8 @@ class TicketViewSet(CommonApiMixin, viewsets.ModelViewSet): @action(detail=True, methods=[PUT, PATCH], permission_classes=[IsAssignee, ]) def approve(self, request, *args, **kwargs): + self.ticket_not_allowed() + partial = kwargs.pop('partial', False) instance = self.get_object() serializer = self.get_serializer(instance, data=request.data, partial=partial) @@ -95,6 +102,27 @@ class TicketViewSet(CommonApiMixin, viewsets.ModelViewSet): instance.close() return Response('ok') + @action(detail=False, methods=[PUT], permission_classes=[RBACPermission, ]) + def bulk(self, request, *args, **kwargs): + self.ticket_not_allowed() + + allow_action = ('approve', 'reject') + action_ = request.query_params.get('action') + if action_ not in allow_action: + msg = _("The parameter 'action' must be [{}]").format(','.join(allow_action)) + return Response({'error': msg}, status=400) + + ticket_ids = request.data.get('tickets', []) + queryset = self.get_queryset().filter(state='pending').filter(id__in=ticket_ids) + for obj in queryset: + if not obj.has_current_assignee(request.user): + return Response( + {'error': f"{_('User does not have permission')}: {obj}"}, status=400 + ) + handler = getattr(obj, action_) + handler(processor=request.user) + return Response('ok') + class ApplyAssetTicketViewSet(TicketViewSet): model = ApplyAssetTicket From 384b639dd319450d6078a48b4610657a75727569 Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Fri, 28 Jul 2023 14:33:09 +0800 Subject: [PATCH 056/177] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=E9=9A=90?= =?UTF-8?q?=E8=97=8F=20Chrome=20=E7=9A=84=E4=BB=A3=E5=A1=AB=E6=93=8D?= =?UTF-8?q?=E4=BD=9C=20(#11114)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Eric --- apps/terminal/applets/chrome/ChangeLog | 8 +++ apps/terminal/applets/chrome/app.py | 5 +- apps/terminal/applets/chrome/code_dialog.py | 65 ++++++++++++++++++++- apps/terminal/applets/chrome/manifest.yml | 2 +- 4 files changed, 74 insertions(+), 6 deletions(-) diff --git a/apps/terminal/applets/chrome/ChangeLog b/apps/terminal/applets/chrome/ChangeLog index 7a03e6949..81529958b 100644 --- a/apps/terminal/applets/chrome/ChangeLog +++ b/apps/terminal/applets/chrome/ChangeLog @@ -1,3 +1,11 @@ +# 2023-07-28 Version 0.7 +## 功能优化 + - 增加进度窗口,隐藏代填操作 + +# 2023-07-13 Version 0.6 +## 功能优化 + - 优化 Chrome 插件拦截逻辑 + # 2023-07-06 Version 0.5 ## 功能更新 - 增加匿名用户的支持,如果账号是匿名用户,username 和 secret 则为空 diff --git a/apps/terminal/applets/chrome/app.py b/apps/terminal/applets/chrome/app.py index 47cce8844..b19e219d1 100644 --- a/apps/terminal/applets/chrome/app.py +++ b/apps/terminal/applets/chrome/app.py @@ -9,7 +9,7 @@ from selenium.webdriver.chrome.service import Service from selenium.webdriver.common.by import By from selenium.webdriver.remote.webelement import WebElement -from code_dialog import CodeDialog +from code_dialog import CodeDialog, wrapper_progress_bar from common import (Asset, User, Account, Platform, Step) from common import (BaseApplication) from common import (notify_err_message, block_input, unblock_input) @@ -249,6 +249,7 @@ class AppletApplication(BaseApplication): self._chrome_options.add_argument("--app={}".format(self.asset.address)) self._chrome_options.add_argument("--user-data-dir={}".format(self._tmp_user_dir.name)) + @wrapper_progress_bar def run(self): service = Service() # driver 的 console 终端框不显示 @@ -256,11 +257,11 @@ class AppletApplication(BaseApplication): self.driver = webdriver.Chrome(options=self._chrome_options, service=service) self.driver.implicitly_wait(10) if self.app.asset.address != "": + self.driver.minimize_window() ok = self.app.execute(self.driver) if not ok: print("执行失败") self.driver.maximize_window() - def wait(self): disconnected_msg = "Unable to evaluate script: disconnected: not connected to DevTools\n" closed_msg = "Unable to evaluate script: no such window: target window already closed" diff --git a/apps/terminal/applets/chrome/code_dialog.py b/apps/terminal/applets/chrome/code_dialog.py index b3b93730c..862e80986 100644 --- a/apps/terminal/applets/chrome/code_dialog.py +++ b/apps/terminal/applets/chrome/code_dialog.py @@ -1,3 +1,5 @@ +import functools +import threading import tkinter as tk from tkinter import StringVar, messagebox from tkinter import ttk @@ -13,7 +15,7 @@ class CodeDialog(object): mainframe.grid(column=0, row=0, ) self.label = ttk.Label(mainframe, text=label, width=10) self.input = ttk.Entry(mainframe, textvariable=self.code, width=20) - self.button = ttk.Button(mainframe, text="ok", command=self.click_ok, width=5,) + self.button = ttk.Button(mainframe, text="ok", command=self.click_ok, width=5, ) self.label.grid(row=1, column=0) self.input.grid(row=1, column=1) self.button.grid(row=2, column=1, sticky=tk.E) @@ -32,6 +34,63 @@ class CodeDialog(object): self.root.destroy() +class TkProgressBar(object): + def __init__(self, wait_func=None): + self._wait_func = wait_func + self._done = threading.Event() + self._root = None + + def _check(self): + if self._done.isSet(): + self._root.destroy() + return + self._root.after(100, self._check) + + def stop(self): + self._done.set() + + def show(self): + if not self._wait_func: + return + root = tk.Tk() + width, height = root.winfo_screenwidth(), root.winfo_screenheight() + root.geometry('%dx%d' % (width, height)) + root.title('Progress') + root.grid() + pb_length = width - 20 + pb = ttk.Progressbar(root, orient='horizontal', length=pb_length, mode='indeterminate') + pb.pack(expand=True, padx=10, pady=10) + + self._root = root + self._root.after(60, pb.start) + self._root.after(100, self._check) + + def _wait_run_func(): + self._wait_func() + self.stop() + print('wait func done') + + self._root.attributes("-topmost", True) + self._root.attributes("-fullscreen", True) + threading.Thread(target=_wait_run_func).start() + self._root.mainloop() + + +# progress bar 装饰器,用于显示进度动画 +# 此方法会创建一个全屏的进度条窗口 +def wrapper_progress_bar(func): + def inner(*args, **kwargs): + wait_func = functools.partial(func, *args, **kwargs) + tk_process = TkProgressBar(wait_func=wait_func) + tk_process.show() + + return inner + + if __name__ == '__main__': - code = CodeDialog(title="Code Dialog", label="Code: ").wait_string() - print(code) + # code = CodeDialog(title="Code Dialog", label="Code: ").wait_string() + # print(code) + import time + progress = TkProgressBar(wait_func=lambda: time.sleep(15)) + progress.show() + print('end') diff --git a/apps/terminal/applets/chrome/manifest.yml b/apps/terminal/applets/chrome/manifest.yml index 066530eef..c740b23a6 100644 --- a/apps/terminal/applets/chrome/manifest.yml +++ b/apps/terminal/applets/chrome/manifest.yml @@ -1,6 +1,6 @@ name: chrome display_name: "{{ 'Chrome Browser' | trans }}" -version: 0.6 +version: 0.7 comment: "{{ 'Chrome Browser Open URL Page Address' | trans }}" author: JumpServer Team exec_type: python From e339a56042bbb57af7dd3f9bbfee8aad58760369 Mon Sep 17 00:00:00 2001 From: jiangweidong Date: Fri, 28 Jul 2023 14:34:38 +0800 Subject: [PATCH 057/177] =?UTF-8?q?feat:=20=E4=BA=91=E5=90=8C=E6=AD=A5?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=90=8C=E6=AD=A5=E7=AD=96=E7=95=A5=20(#1100?= =?UTF-8?q?1)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 1 + requirements/requirements.txt | 1 + 2 files changed, 2 insertions(+) diff --git a/Dockerfile b/Dockerfile index 992c9fca8..628e3266f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -44,6 +44,7 @@ ARG TOOLS=" \ unzip \ vim \ git \ + nmap \ wget" ARG APT_MIRROR=http://mirrors.ustc.edu.cn diff --git a/requirements/requirements.txt b/requirements/requirements.txt index 619d9aa70..dd144963b 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -69,6 +69,7 @@ jsonfield2==4.0.0.post0 geoip2==4.7.0 ipip-ipdb==1.6.1 pywinrm==0.4.3 +python-nmap==0.7.1 # Django environment Django==4.1.10 django-bootstrap3==23.4 From 38cee8eaa41f3c0645bffcafb0b502158ff47909 Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Fri, 28 Jul 2023 15:14:49 +0800 Subject: [PATCH 058/177] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8Dmigrations?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E9=94=99=E8=AF=AF=20(#11116)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: fangfang.dong --- apps/assets/migrations/0121_auto_20230725_1458.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/assets/migrations/0121_auto_20230725_1458.py b/apps/assets/migrations/0121_auto_20230725_1458.py index 65a115cce..011e9b40a 100644 --- a/apps/assets/migrations/0121_auto_20230725_1458.py +++ b/apps/assets/migrations/0121_auto_20230725_1458.py @@ -9,7 +9,7 @@ def migrate_platforms_sftp_protocol(apps, schema_editor): ssh_protocols = platform_protocol_cls.objects \ .filter(name='ssh', setting__sftp_enabled=True) \ .exclude(name__in=('Gateway', 'RemoteAppHost')) \ - .filter(type='linux') + .filter(platform__type='linux') platforms_has_sftp = platform_cls.objects.filter(protocols__name='sftp') new_protocols = [] From b55eb1236f6b17ebb3a6d569a3dcc6fcc2ea70e7 Mon Sep 17 00:00:00 2001 From: ibuler Date: Fri, 28 Jul 2023 16:15:12 +0800 Subject: [PATCH 059/177] =?UTF-8?q?perf:=20=E6=B7=BB=E5=8A=A0=E5=88=B0?= =?UTF-8?q?=E9=BB=98=E8=AE=A4=E7=BB=84=E7=BB=87=E4=B8=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/accounts/filters.py | 4 ++-- apps/orgs/signal_handlers/common.py | 8 ++++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/apps/accounts/filters.py b/apps/accounts/filters.py index be2cf1dfd..dc28d78aa 100644 --- a/apps/accounts/filters.py +++ b/apps/accounts/filters.py @@ -13,7 +13,7 @@ class AccountFilterSet(BaseFilterSet): hostname = drf_filters.CharFilter(field_name='name', lookup_expr='exact') username = drf_filters.CharFilter(field_name="username", lookup_expr='exact') address = drf_filters.CharFilter(field_name="asset__address", lookup_expr='exact') - asset = drf_filters.CharFilter(field_name="asset_id", lookup_expr='exact') + asset_id = drf_filters.CharFilter(field_name="asset", lookup_expr='exact') assets = drf_filters.CharFilter(field_name='asset_id', lookup_expr='exact') nodes = drf_filters.CharFilter(method='filter_nodes') node_id = drf_filters.CharFilter(method='filter_nodes') @@ -45,7 +45,7 @@ class AccountFilterSet(BaseFilterSet): class Meta: model = Account - fields = ['id', 'asset_id', 'source_id', 'secret_type'] + fields = ['id', 'asset', 'source_id', 'secret_type'] class GatheredAccountFilterSet(BaseFilterSet): diff --git a/apps/orgs/signal_handlers/common.py b/apps/orgs/signal_handlers/common.py index 998ee216c..83edeb425 100644 --- a/apps/orgs/signal_handlers/common.py +++ b/apps/orgs/signal_handlers/common.py @@ -103,8 +103,12 @@ def on_user_created_set_default_org(sender, instance, created, **kwargs): return if instance.orgs.count() > 0: return - with tmp_to_org(Organization.default()): - Organization.default().add_member(instance) + default_org = Organization.default() + with tmp_to_org(default_org): + default_org.add_member(instance) + default_group = UserGroup.objects.filter(name='Default').first() + if default_group: + default_group.users.add(instance) def _remove_user_resource(model, users, org, user_field_name='users'): From c201914bc8404846c0de2fc54d4b8990770a983f Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Fri, 28 Jul 2023 17:00:55 +0800 Subject: [PATCH 060/177] perf: change secret perf (#11120) Co-authored-by: feng <1304903146@qq.com> --- .../change_secret/host/aix/main.yml | 61 +++++++++++++++---- .../change_secret/host/posix/main.yml | 35 ++++++----- .../push_account/host/aix/main.yml | 32 +++++++--- .../push_account/host/posix/main.yml | 30 ++++++--- 4 files changed, 113 insertions(+), 45 deletions(-) diff --git a/apps/accounts/automations/change_secret/host/aix/main.yml b/apps/accounts/automations/change_secret/host/aix/main.yml index b51ddf69e..8593c7534 100644 --- a/apps/accounts/automations/change_secret/host/aix/main.yml +++ b/apps/accounts/automations/change_secret/host/aix/main.yml @@ -1,10 +1,41 @@ - hosts: demo gather_facts: no tasks: - - name: Test privileged account + - name: "Test privileged {{ jms_account.username }} account" ansible.builtin.ping: - - name: Change password + - name: "Check if {{ account.username }} user exists" + getent: + database: passwd + key: "{{ account.username }}" + register: user_info + ignore_errors: yes # 忽略错误,如果用户不存在时不会导致playbook失败 + + - name: "Add {{ account.username }} user" + ansible.builtin.user: + name: "{{ account.username }}" + shell: "{{ params.shell }}" + home: "{{ params.home | default('/home/' + account.username, true) }}" + groups: "{{ params.groups }}" + expires: -1 + state: present + when: user_info.failed + + - name: "Add {{ account.username }} group" + ansible.builtin.group: + name: "{{ account.username }}" + state: present + when: user_info.failed + + - name: "Add {{ account.username }} user to group" + ansible.builtin.user: + name: "{{ account.username }}" + groups: "{{ params.groups }}" + when: + - user_info.failed + - params.groups + + - name: "Change {{ account.username }} password" ansible.builtin.user: name: "{{ account.username }}" password: "{{ account.secret | password_hash('des') }}" @@ -12,31 +43,37 @@ ignore_errors: true when: account.secret_type == "password" - - name: create user If it already exists, no operation will be performed - ansible.builtin.user: - name: "{{ account.username }}" - when: account.secret_type == "ssh_key" - - name: remove jumpserver ssh key ansible.builtin.lineinfile: dest: "{{ ssh_params.dest }}" regexp: "{{ ssh_params.regexp }}" state: absent when: - - account.secret_type == "ssh_key" - - ssh_params.strategy == "set_jms" + - account.secret_type == "ssh_key" + - ssh_params.strategy == "set_jms" - - name: Change SSH key + - name: "Change {{ account.username }} SSH key" ansible.builtin.authorized_key: user: "{{ account.username }}" key: "{{ account.secret }}" exclusive: "{{ ssh_params.exclusive }}" when: account.secret_type == "ssh_key" + - name: "Set {{ account.username }} sudo setting" + ansible.builtin.lineinfile: + dest: /etc/sudoers + state: present + regexp: "^{{ account.username }} ALL=" + line: "{{ account.username + ' ALL=(ALL) NOPASSWD: ' + params.sudo }}" + validate: visudo -cf %s + when: + - user_info.failed + - params.sudo + - name: Refresh connection ansible.builtin.meta: reset_connection - - name: Verify password + - name: "Verify {{ account.username }} password" ansible.builtin.ping: become: no vars: @@ -45,7 +82,7 @@ ansible_become: no when: account.secret_type == "password" - - name: Verify SSH key + - name: "Verify {{ account.username }} SSH key" ansible.builtin.ping: become: no vars: diff --git a/apps/accounts/automations/change_secret/host/posix/main.yml b/apps/accounts/automations/change_secret/host/posix/main.yml index 325ad644d..5ed6a10b4 100644 --- a/apps/accounts/automations/change_secret/host/posix/main.yml +++ b/apps/accounts/automations/change_secret/host/posix/main.yml @@ -1,10 +1,17 @@ - hosts: demo gather_facts: no tasks: - - name: Test privileged account + - name: "Test privileged {{ jms_account.username }} account" ansible.builtin.ping: - - name: Check user + - name: "Check if {{ account.username }} user exists" + getent: + database: passwd + key: "{{ account.username }}" + register: user_info + ignore_errors: yes # 忽略错误,如果用户不存在时不会导致playbook失败 + + - name: "Add {{ account.username }} user" ansible.builtin.user: name: "{{ account.username }}" shell: "{{ params.shell }}" @@ -12,19 +19,23 @@ groups: "{{ params.groups }}" expires: -1 state: present + when: user_info.failed - name: "Add {{ account.username }} group" ansible.builtin.group: name: "{{ account.username }}" state: present + when: user_info.failed - - name: Add user groups + - name: "Add {{ account.username }} user to group" ansible.builtin.user: name: "{{ account.username }}" groups: "{{ params.groups }}" - when: params.groups + when: + - user_info.failed + - params.groups - - name: Change password + - name: "Change {{ account.username }} password" ansible.builtin.user: name: "{{ account.username }}" password: "{{ account.secret | password_hash('sha512') }}" @@ -32,11 +43,6 @@ ignore_errors: true when: account.secret_type == "password" - - name: create user If it already exists, no operation will be performed - ansible.builtin.user: - name: "{{ account.username }}" - when: account.secret_type == "ssh_key" - - name: remove jumpserver ssh key ansible.builtin.lineinfile: dest: "{{ ssh_params.dest }}" @@ -46,14 +52,14 @@ - account.secret_type == "ssh_key" - ssh_params.strategy == "set_jms" - - name: Change SSH key + - name: "Change {{ account.username }} SSH key" ansible.builtin.authorized_key: user: "{{ account.username }}" key: "{{ account.secret }}" exclusive: "{{ ssh_params.exclusive }}" when: account.secret_type == "ssh_key" - - name: Set sudo setting + - name: "Set {{ account.username }} sudo setting" ansible.builtin.lineinfile: dest: /etc/sudoers state: present @@ -61,12 +67,13 @@ line: "{{ account.username + ' ALL=(ALL) NOPASSWD: ' + params.sudo }}" validate: visudo -cf %s when: + - user_info.failed - params.sudo - name: Refresh connection ansible.builtin.meta: reset_connection - - name: Verify password + - name: "Verify {{ account.username }} password" ansible.builtin.ping: become: no vars: @@ -75,7 +82,7 @@ ansible_become: no when: account.secret_type == "password" - - name: Verify SSH key + - name: "Verify {{ account.username }} SSH key" ansible.builtin.ping: become: no vars: diff --git a/apps/accounts/automations/push_account/host/aix/main.yml b/apps/accounts/automations/push_account/host/aix/main.yml index 2dc10fdc2..8593c7534 100644 --- a/apps/accounts/automations/push_account/host/aix/main.yml +++ b/apps/accounts/automations/push_account/host/aix/main.yml @@ -1,10 +1,17 @@ - hosts: demo gather_facts: no tasks: - - name: Test privileged account + - name: "Test privileged {{ jms_account.username }} account" ansible.builtin.ping: - - name: Push user + - name: "Check if {{ account.username }} user exists" + getent: + database: passwd + key: "{{ account.username }}" + register: user_info + ignore_errors: yes # 忽略错误,如果用户不存在时不会导致playbook失败 + + - name: "Add {{ account.username }} user" ansible.builtin.user: name: "{{ account.username }}" shell: "{{ params.shell }}" @@ -12,22 +19,26 @@ groups: "{{ params.groups }}" expires: -1 state: present + when: user_info.failed - name: "Add {{ account.username }} group" ansible.builtin.group: name: "{{ account.username }}" state: present + when: user_info.failed - - name: Add user groups + - name: "Add {{ account.username }} user to group" ansible.builtin.user: name: "{{ account.username }}" groups: "{{ params.groups }}" - when: params.groups + when: + - user_info.failed + - params.groups - - name: Push user password + - name: "Change {{ account.username }} password" ansible.builtin.user: name: "{{ account.username }}" - password: "{{ account.secret | password_hash('sha512') }}" + password: "{{ account.secret | password_hash('des') }}" update_password: always ignore_errors: true when: account.secret_type == "password" @@ -41,14 +52,14 @@ - account.secret_type == "ssh_key" - ssh_params.strategy == "set_jms" - - name: Push SSH key + - name: "Change {{ account.username }} SSH key" ansible.builtin.authorized_key: user: "{{ account.username }}" key: "{{ account.secret }}" exclusive: "{{ ssh_params.exclusive }}" when: account.secret_type == "ssh_key" - - name: Set sudo setting + - name: "Set {{ account.username }} sudo setting" ansible.builtin.lineinfile: dest: /etc/sudoers state: present @@ -56,12 +67,13 @@ line: "{{ account.username + ' ALL=(ALL) NOPASSWD: ' + params.sudo }}" validate: visudo -cf %s when: + - user_info.failed - params.sudo - name: Refresh connection ansible.builtin.meta: reset_connection - - name: Verify password + - name: "Verify {{ account.username }} password" ansible.builtin.ping: become: no vars: @@ -70,7 +82,7 @@ ansible_become: no when: account.secret_type == "password" - - name: Verify SSH key + - name: "Verify {{ account.username }} SSH key" ansible.builtin.ping: become: no vars: diff --git a/apps/accounts/automations/push_account/host/posix/main.yml b/apps/accounts/automations/push_account/host/posix/main.yml index 2dc10fdc2..5ed6a10b4 100644 --- a/apps/accounts/automations/push_account/host/posix/main.yml +++ b/apps/accounts/automations/push_account/host/posix/main.yml @@ -1,10 +1,17 @@ - hosts: demo gather_facts: no tasks: - - name: Test privileged account + - name: "Test privileged {{ jms_account.username }} account" ansible.builtin.ping: - - name: Push user + - name: "Check if {{ account.username }} user exists" + getent: + database: passwd + key: "{{ account.username }}" + register: user_info + ignore_errors: yes # 忽略错误,如果用户不存在时不会导致playbook失败 + + - name: "Add {{ account.username }} user" ansible.builtin.user: name: "{{ account.username }}" shell: "{{ params.shell }}" @@ -12,19 +19,23 @@ groups: "{{ params.groups }}" expires: -1 state: present + when: user_info.failed - name: "Add {{ account.username }} group" ansible.builtin.group: name: "{{ account.username }}" state: present + when: user_info.failed - - name: Add user groups + - name: "Add {{ account.username }} user to group" ansible.builtin.user: name: "{{ account.username }}" groups: "{{ params.groups }}" - when: params.groups + when: + - user_info.failed + - params.groups - - name: Push user password + - name: "Change {{ account.username }} password" ansible.builtin.user: name: "{{ account.username }}" password: "{{ account.secret | password_hash('sha512') }}" @@ -41,14 +52,14 @@ - account.secret_type == "ssh_key" - ssh_params.strategy == "set_jms" - - name: Push SSH key + - name: "Change {{ account.username }} SSH key" ansible.builtin.authorized_key: user: "{{ account.username }}" key: "{{ account.secret }}" exclusive: "{{ ssh_params.exclusive }}" when: account.secret_type == "ssh_key" - - name: Set sudo setting + - name: "Set {{ account.username }} sudo setting" ansible.builtin.lineinfile: dest: /etc/sudoers state: present @@ -56,12 +67,13 @@ line: "{{ account.username + ' ALL=(ALL) NOPASSWD: ' + params.sudo }}" validate: visudo -cf %s when: + - user_info.failed - params.sudo - name: Refresh connection ansible.builtin.meta: reset_connection - - name: Verify password + - name: "Verify {{ account.username }} password" ansible.builtin.ping: become: no vars: @@ -70,7 +82,7 @@ ansible_become: no when: account.secret_type == "password" - - name: Verify SSH key + - name: "Verify {{ account.username }} SSH key" ansible.builtin.ping: become: no vars: From 53c8c2d9eae5b18237818cd8c7e967975c06c7a8 Mon Sep 17 00:00:00 2001 From: Bai Date: Fri, 28 Jul 2023 17:45:12 +0800 Subject: [PATCH 061/177] =?UTF-8?q?feat:=20rdp=20file=20=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E8=AE=BE=E7=BD=AE=E5=A4=9A=E5=B1=8F=E6=98=BE=E7=A4=BA=20(multi?= =?UTF-8?q?mon)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/authentication/api/connection_token.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/apps/authentication/api/connection_token.py b/apps/authentication/api/connection_token.py index 566d080b5..6a72a3d7a 100644 --- a/apps/authentication/api/connection_token.py +++ b/apps/authentication/api/connection_token.py @@ -65,6 +65,11 @@ class RDPFileClientProtocolURLMixin: 'smart sizing:i': '1', } + # 设置多屏显示 + multi_mon = is_true(self.request.query_params.get('multi_mon')) + if multi_mon: + rdp_options['use multimon:i'] = '1' + # 设置磁盘挂载 drives_redirect = is_true(self.request.query_params.get('drives_redirect')) if drives_redirect: From 07f4fdd92dc2f1a2d6fa36a4b5e34dec94d815b5 Mon Sep 17 00:00:00 2001 From: Bai Date: Fri, 28 Jul 2023 18:06:38 +0800 Subject: [PATCH 062/177] =?UTF-8?q?feat:=20rdp=20file=20=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E8=AE=BE=E7=BD=AE=E5=A4=9A=E5=B1=8F=E6=98=BE=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/authentication/api/connection_token.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/apps/authentication/api/connection_token.py b/apps/authentication/api/connection_token.py index 566d080b5..f16bb459c 100644 --- a/apps/authentication/api/connection_token.py +++ b/apps/authentication/api/connection_token.py @@ -64,6 +64,10 @@ class RDPFileClientProtocolURLMixin: 'use redirection server name:i': '0', 'smart sizing:i': '1', } + # 设置多屏显示 + multi_mon = is_true(self.request.query_params.get('multi_mon')) + if multi_mon: + rdp_options['use multimon:i'] = '1' # 设置磁盘挂载 drives_redirect = is_true(self.request.query_params.get('drives_redirect')) From 47dd73eb4c8e2364bc8533c4d5dcaf5d5a46f61c Mon Sep 17 00:00:00 2001 From: "fangfang.dong" Date: Mon, 31 Jul 2023 14:54:35 +0800 Subject: [PATCH 063/177] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8Des7=E5=88=9B?= =?UTF-8?q?=E5=BB=BAindex=E7=9A=84=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/common/plugins/es.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/apps/common/plugins/es.py b/apps/common/plugins/es.py index 27b97b3de..8438c43cc 100644 --- a/apps/common/plugins/es.py +++ b/apps/common/plugins/es.py @@ -131,7 +131,10 @@ class ES(object): } try: - self.es.indices.create(self.index, body=mappings) + if version == '6': + self.es.indices.create(self.index, body=mappings) + else: + self.es.indices.create(index=self.index, body=mappings) except RequestError as e: if e.error == 'resource_already_exists_exception': logger.warning(e) From 7776158279f376892fc37a75ad9c95670b665d00 Mon Sep 17 00:00:00 2001 From: ibuler Date: Mon, 31 Jul 2023 17:22:52 +0800 Subject: [PATCH 064/177] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=20django=5Fc?= =?UTF-8?q?as=5Fng=20=E7=9A=84=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- requirements/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/requirements.txt b/requirements/requirements.txt index dd144963b..a94cd102f 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -110,7 +110,7 @@ websockets==11.0.3 python-ldap==3.4.3 ldap3==2.9.1 django-radius@https://github.com/ibuler/django-radius/archive/refs/tags/1.5.0.zip -django-cas-ng==4.3.0 +django-cas-ng@https://github.com/ibuler/django-cas-ng/releases/download/v4.3.1/django-cas-ng-4.3.1.zip python-cas==1.6.0 django-auth-ldap==4.4.0 # Cloud req From 3b615719fe18f5265a30c65d195a8c237f1f8e60 Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Mon, 31 Jul 2023 17:39:30 +0800 Subject: [PATCH 065/177] =?UTF-8?q?feat:=20=E8=B4=A6=E5=8F=B7=E5=AF=86?= =?UTF-8?q?=E9=92=A5=E7=94=A8vault=E5=82=A8=E5=AD=98=20(#10830)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 账号密钥用vault储存 * perf: 优化 Vault * perf: 重构 Vault Backend 设计架构 (未完成) * perf: 重构 Vault Backend 设计架构 (未完成2) * perf: 重构 Vault Backend 设计架构 (未完成3) * perf: 重构 Vault Backend 设计架构 (未完成4) * perf: 重构 Vault Backend 设计架构 (未完成5) * perf: 重构 Vault Backend 设计架构 (已完成) * perf: 重构 Vault Backend 设计架构 (已完成) * perf: 重构 Vault Backend 设计架构 (已完成) * perf: 小优化 * perf: 优化 --------- Co-authored-by: feng <1304903146@qq.com> Co-authored-by: Bai Co-authored-by: feng626 <57284900+feng626@users.noreply.github.com> --- apps/accounts/api/account/account.py | 15 ++- apps/accounts/backends/__init__.py | 41 +++++++ apps/accounts/backends/base.py | 77 +++++++++++++ apps/accounts/backends/hcp/__init__.py | 1 + apps/accounts/backends/hcp/entries.py | 84 ++++++++++++++ apps/accounts/backends/hcp/main.py | 47 ++++++++ apps/accounts/backends/hcp/service.py | 103 ++++++++++++++++++ apps/accounts/backends/local/__init__.py | 1 + apps/accounts/backends/local/main.py | 36 ++++++ apps/accounts/const/__init__.py | 1 + apps/accounts/const/vault.py | 9 ++ .../migrations/0012_auto_20230621_1456.py | 28 +++++ apps/accounts/models/account.py | 25 ++++- apps/accounts/models/base.py | 9 +- apps/accounts/models/mixins/__init__.py | 1 + apps/accounts/models/mixins/vault.py | 88 +++++++++++++++ apps/accounts/serializers/account/account.py | 10 +- apps/accounts/serializers/account/base.py | 6 +- apps/accounts/signal_handlers.py | 25 ++++- apps/accounts/tasks/vault.py | 56 ++++++++++ apps/accounts/utils.py | 4 +- apps/common/db/fields.py | 19 +--- apps/common/db/utils.py | 19 +++- apps/common/decorators.py | 10 +- apps/common/sdk/im/dingtalk/__init__.py | 8 +- apps/jumpserver/conf.py | 6 + apps/jumpserver/settings/auth.py | 6 + apps/orgs/mixins/models.py | 1 + apps/orgs/utils.py | 11 +- apps/settings/api/__init__.py | 11 +- apps/settings/api/settings.py | 2 + apps/settings/api/vault.py | 60 ++++++++++ .../migrations/0008_alter_setting_options.py | 17 +++ apps/settings/models.py | 1 + apps/settings/serializers/__init__.py | 13 ++- apps/settings/serializers/vault.py | 23 ++++ apps/settings/urls/api_urls.py | 2 + requirements/requirements.txt | 2 + 38 files changed, 819 insertions(+), 59 deletions(-) create mode 100644 apps/accounts/backends/__init__.py create mode 100644 apps/accounts/backends/base.py create mode 100644 apps/accounts/backends/hcp/__init__.py create mode 100644 apps/accounts/backends/hcp/entries.py create mode 100644 apps/accounts/backends/hcp/main.py create mode 100644 apps/accounts/backends/hcp/service.py create mode 100644 apps/accounts/backends/local/__init__.py create mode 100644 apps/accounts/backends/local/main.py create mode 100644 apps/accounts/const/vault.py create mode 100644 apps/accounts/migrations/0012_auto_20230621_1456.py create mode 100644 apps/accounts/models/mixins/__init__.py create mode 100644 apps/accounts/models/mixins/vault.py create mode 100644 apps/accounts/tasks/vault.py create mode 100644 apps/settings/api/vault.py create mode 100644 apps/settings/migrations/0008_alter_setting_options.py create mode 100644 apps/settings/serializers/vault.py diff --git a/apps/accounts/api/account/account.py b/apps/accounts/api/account/account.py index 94ee9086b..573f731cc 100644 --- a/apps/accounts/api/account/account.py +++ b/apps/accounts/api/account/account.py @@ -26,6 +26,7 @@ class AccountViewSet(OrgBulkModelViewSet): filterset_class = AccountFilterSet serializer_classes = { 'default': serializers.AccountSerializer, + 'retrieve': serializers.AccountDetailSerializer, } rbac_perms = { 'partial_update': ['accounts.change_account'], @@ -133,11 +134,13 @@ class AccountHistoriesSecretAPI(ExtraFilterFieldsMixin, RecordViewLogMixin, List def get_queryset(self): account = self.get_object() histories = account.history.all() - last_history = account.history.first() - if not last_history: + latest_history = account.history.first() + if not latest_history: return histories - - if account.secret == last_history.secret \ - and account.secret_type == last_history.secret_type: - histories = histories.exclude(history_id=last_history.history_id) + if account.secret != latest_history.secret: + return histories + if account.secret_type != latest_history.secret_type: + return histories + histories = histories.exclude(history_id=latest_history.history_id) return histories + diff --git a/apps/accounts/backends/__init__.py b/apps/accounts/backends/__init__.py new file mode 100644 index 000000000..9bfd63dfb --- /dev/null +++ b/apps/accounts/backends/__init__.py @@ -0,0 +1,41 @@ +import os +from django.utils.functional import LazyObject +from importlib import import_module + +from common.utils import get_logger +from ..const import VaultTypeChoices + +__all__ = ['vault_client', 'get_vault_client'] + + +logger = get_logger(__file__) + + +def get_vault_client(raise_exception=False, **kwargs): + try: + tp = kwargs.get('VAULT_TYPE') + module_path = f'apps.accounts.backends.{tp}.main' + client = import_module(module_path).Vault(**kwargs) + except Exception as e: + logger.error(f'Init vault client failed: {e}') + if raise_exception: + raise + tp = VaultTypeChoices.local + module_path = f'apps.accounts.backends.{tp}.main' + kwargs['VAULT_TYPE'] = tp + client = import_module(module_path).Vault(**kwargs) + return client + + +class VaultClient(LazyObject): + + def _setup(self): + from jumpserver import settings as js_settings + from django.conf import settings + vault_config_names = [k for k in js_settings.__dict__.keys() if k.startswith('VAULT_')] + vault_configs = {name: getattr(settings, name, None) for name in vault_config_names} + self._wrapped = get_vault_client(**vault_configs) + + +""" 为了安全, 页面修改配置, 重启服务后才会重新初始化 vault_client """ +vault_client = VaultClient() diff --git a/apps/accounts/backends/base.py b/apps/accounts/backends/base.py new file mode 100644 index 000000000..12547a7cb --- /dev/null +++ b/apps/accounts/backends/base.py @@ -0,0 +1,77 @@ +from abc import ABC, abstractmethod + +from django.forms.models import model_to_dict + +__all__ = ['BaseVault'] + + +class BaseVault(ABC): + + def __init__(self, *args, **kwargs): + self.type = kwargs.get('VAULT_TYPE') + + def is_type(self, tp): + return self.type == tp + + def get(self, instance): + """ 返回 secret 值 """ + return self._get(instance) + + def create(self, instance): + if not instance.secret_has_save_to_vault: + self._create(instance) + self._clean_db_secret(instance) + self.save_metadata(instance) + + if instance.is_sync_metadata: + self.save_metadata(instance) + + def update(self, instance): + if not instance.secret_has_save_to_vault: + self._update(instance) + self._clean_db_secret(instance) + self.save_metadata(instance) + + if instance.is_sync_metadata: + self.save_metadata(instance) + + def delete(self, instance): + self._delete(instance) + + def save_metadata(self, instance): + metadata = model_to_dict(instance, fields=[ + 'name', 'username', 'secret_type', + 'connectivity', 'su_from', 'privileged' + ]) + metadata = {field: str(value) for field, value in metadata.items()} + return self._save_metadata(instance, metadata) + + # -------- abstractmethod -------- # + + @abstractmethod + def _get(self, instance): + raise NotImplementedError + + @abstractmethod + def _create(self, instance): + raise NotImplementedError + + @abstractmethod + def _update(self, instance): + raise NotImplementedError + + @abstractmethod + def _delete(self, instance): + raise NotImplementedError + + @abstractmethod + def _clean_db_secret(self, instance): + raise NotImplementedError + + @abstractmethod + def _save_metadata(self, instance, metadata): + raise NotImplementedError + + @abstractmethod + def is_active(self, *args, **kwargs) -> (bool, str): + raise NotImplementedError diff --git a/apps/accounts/backends/hcp/__init__.py b/apps/accounts/backends/hcp/__init__.py new file mode 100644 index 000000000..15b6a64ba --- /dev/null +++ b/apps/accounts/backends/hcp/__init__.py @@ -0,0 +1 @@ +from .main import * diff --git a/apps/accounts/backends/hcp/entries.py b/apps/accounts/backends/hcp/entries.py new file mode 100644 index 000000000..ff73ef98d --- /dev/null +++ b/apps/accounts/backends/hcp/entries.py @@ -0,0 +1,84 @@ +import sys +from abc import ABC + +from common.db.utils import Encryptor +from common.utils import lazyproperty + +current_module = sys.modules[__name__] + +__all__ = ['build_entry'] + + +class BaseEntry(ABC): + + def __init__(self, instance): + self.instance = instance + + @lazyproperty + def full_path(self): + path_base = self.path_base + path_spec = self.path_spec + path = f'{path_base}/{path_spec}' + return path + + @property + def path_base(self): + path = f'orgs/{self.instance.org_id}' + return path + + @property + def path_spec(self): + raise NotImplementedError + + def to_internal_data(self): + secret = getattr(self.instance, '_secret', None) + if secret is not None: + secret = Encryptor(secret).encrypt() + data = {'secret': secret} + return data + + @staticmethod + def to_external_data(data): + secret = data.pop('secret', None) + if secret is not None: + secret = Encryptor(secret).decrypt() + return secret + + +class AccountEntry(BaseEntry): + + @property + def path_spec(self): + path = f'assets/{self.instance.asset_id}/accounts/{self.instance.id}' + return path + + +class AccountTemplateEntry(BaseEntry): + + @property + def path_spec(self): + path = f'account-templates/{self.instance.id}' + return path + + +class HistoricalAccountEntry(BaseEntry): + + @property + def path_base(self): + account = self.instance.instance + path = f'accounts/{account.id}/' + return path + + @property + def path_spec(self): + path = f'histories/{self.instance.history_id}' + return path + + +def build_entry(instance) -> BaseEntry: + class_name = instance.__class__.__name__ + entry_class_name = f'{class_name}Entry' + entry_class = getattr(current_module, entry_class_name, None) + if not entry_class: + raise Exception(f'Entry class {entry_class_name} is not found') + return entry_class(instance) diff --git a/apps/accounts/backends/hcp/main.py b/apps/accounts/backends/hcp/main.py new file mode 100644 index 000000000..9fb752c1b --- /dev/null +++ b/apps/accounts/backends/hcp/main.py @@ -0,0 +1,47 @@ +from .entries import build_entry +from .service import VaultKVClient +from ..base import BaseVault + +__all__ = ['Vault'] + + +class Vault(BaseVault): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.client = VaultKVClient( + url=kwargs.get('VAULT_HCP_HOST'), + token=kwargs.get('VAULT_HCP_TOKEN'), + mount_point=kwargs.get('VAULT_HCP_MOUNT_POINT') + ) + + def is_active(self): + return self.client.is_active() + + def _get(self, instance): + entry = build_entry(instance) + # TODO: get data 是不是层数太多了 + data = self.client.get(path=entry.full_path).get('data', {}) + data = entry.to_external_data(data) + return data + + def _create(self, instance): + entry = build_entry(instance) + data = entry.to_internal_data() + self.client.create(path=entry.full_path, data=data) + + def _update(self, instance): + entry = build_entry(instance) + data = entry.to_internal_data() + self.client.patch(path=entry.full_path, data=data) + + def _delete(self, instance): + entry = build_entry(instance) + self.client.delete(path=entry.full_path) + + def _clean_db_secret(self, instance): + instance.is_sync_metadata = False + instance.mark_secret_save_to_vault() + + def _save_metadata(self, instance, metadata): + entry = build_entry(instance) + self.client.update_metadata(path=entry.full_path, metadata=metadata) diff --git a/apps/accounts/backends/hcp/service.py b/apps/accounts/backends/hcp/service.py new file mode 100644 index 000000000..179f98edb --- /dev/null +++ b/apps/accounts/backends/hcp/service.py @@ -0,0 +1,103 @@ +# -*- coding: utf-8 -*- +# +import hvac +from hvac import exceptions +from requests.exceptions import ConnectionError + +from common.utils import get_logger + +logger = get_logger(__name__) + +__all__ = ['VaultKVClient'] + + +class VaultKVClient(object): + max_versions = 20 + + def __init__(self, url, token, mount_point): + assert isinstance(self.max_versions, int) and self.max_versions >= 3, ( + 'max_versions must to be an integer that is greater than or equal to 3' + ) + self.client = hvac.Client(url=url, token=token) + self.mount_point = mount_point + self.enable_secrets_engine_if_need() + + def is_active(self): + try: + if not self.client.sys.is_initialized(): + return False, 'Vault is not initialized' + if self.client.sys.is_sealed(): + return False, 'Vault is sealed' + if not self.client.is_authenticated(): + return False, 'Vault is not authenticated' + except ConnectionError as e: + logger.error(str(e)) + return False, f'Vault is not reachable: {e}' + else: + return True, '' + + def enable_secrets_engine_if_need(self): + secrets_engines = self.client.sys.list_mounted_secrets_engines() + mount_points = secrets_engines.keys() + if f'{self.mount_point}/' in mount_points: + return + self.client.sys.enable_secrets_engine( + backend_type='kv', + path=self.mount_point, + options={'version': 2} # TODO: version 是否从配置中读取? + ) + self.client.secrets.kv.v2.configure( + max_versions=self.max_versions, + mount_point=self.mount_point + ) + + def get(self, path, version=None): + try: + response = self.client.secrets.kv.v2.read_secret_version( + path=path, + version=version, + mount_point=self.mount_point + ) + except exceptions.InvalidPath as e: + logger.error('Get secret error: {}'.format(e)) + return {} + data = response.get('data', {}) + return data + + def create(self, path, data: dict): + self._update_or_create(path=path, data=data) + + def update(self, path, data: dict): + """ 未更新的数据会被删除 """ + self._update_or_create(path=path, data=data) + + def patch(self, path, data: dict): + """ 未更新的数据不会被删除 """ + self.client.secrets.kv.v2.patch( + path=path, + secret=data, + mount_point=self.mount_point + ) + + def delete(self, path): + self.client.secrets.kv.v2.delete_metadata_and_all_versions( + path=path, + mount_point=self.mount_point, + ) + + def _update_or_create(self, path, data: dict): + self.client.secrets.kv.v2.create_or_update_secret( + path=path, + secret=data, + mount_point=self.mount_point + ) + + def update_metadata(self, path, metadata: dict): + try: + self.client.secrets.kv.v2.update_metadata( + path=path, + mount_point=self.mount_point, + custom_metadata=metadata + ) + except exceptions.InvalidPath as e: + logger.error('Update metadata error: {}'.format(e)) diff --git a/apps/accounts/backends/local/__init__.py b/apps/accounts/backends/local/__init__.py new file mode 100644 index 000000000..15b6a64ba --- /dev/null +++ b/apps/accounts/backends/local/__init__.py @@ -0,0 +1 @@ +from .main import * diff --git a/apps/accounts/backends/local/main.py b/apps/accounts/backends/local/main.py new file mode 100644 index 000000000..a3e608bbc --- /dev/null +++ b/apps/accounts/backends/local/main.py @@ -0,0 +1,36 @@ +from common.utils import get_logger +from ..base import BaseVault + +logger = get_logger(__name__) + +__all__ = ['Vault'] + + +class Vault(BaseVault): + + def is_active(self): + return True, '' + + def _get(self, instance): + secret = getattr(instance, '_secret', None) + return secret + + def _create(self, instance): + """ Ignore """ + pass + + def _update(self, instance): + """ Ignore """ + pass + + def _delete(self, instance): + """ Ignore """ + pass + + def _save_metadata(self, instance, metadata): + """ Ignore """ + pass + + def _clean_db_secret(self, instance): + """ Ignore *重要* 不能删除本地 secret """ + pass diff --git a/apps/accounts/const/__init__.py b/apps/accounts/const/__init__.py index 6db502556..0e1997f00 100644 --- a/apps/accounts/const/__init__.py +++ b/apps/accounts/const/__init__.py @@ -1,2 +1,3 @@ from .account import * from .automation import * +from .vault import * diff --git a/apps/accounts/const/vault.py b/apps/accounts/const/vault.py new file mode 100644 index 000000000..8b30b8afa --- /dev/null +++ b/apps/accounts/const/vault.py @@ -0,0 +1,9 @@ +from django.db import models +from django.utils.translation import ugettext_lazy as _ + +__all__ = ['VaultTypeChoices'] + + +class VaultTypeChoices(models.TextChoices): + local = 'local', _('Local Vault') + hcp = 'hcp', _('HCP Vault') diff --git a/apps/accounts/migrations/0012_auto_20230621_1456.py b/apps/accounts/migrations/0012_auto_20230621_1456.py new file mode 100644 index 000000000..389e2b63d --- /dev/null +++ b/apps/accounts/migrations/0012_auto_20230621_1456.py @@ -0,0 +1,28 @@ +# Generated by Django 3.2.19 on 2023-06-21 06:56 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('accounts', '0011_auto_20230506_1443'), + ] + + operations = [ + migrations.RenameField( + model_name='account', + old_name='secret', + new_name='_secret', + ), + migrations.RenameField( + model_name='accounttemplate', + old_name='secret', + new_name='_secret', + ), + migrations.RenameField( + model_name='historicalaccount', + old_name='secret', + new_name='_secret', + ), + ] diff --git a/apps/accounts/models/account.py b/apps/accounts/models/account.py index d84978b17..c6da60d48 100644 --- a/apps/accounts/models/account.py +++ b/apps/accounts/models/account.py @@ -7,9 +7,10 @@ from simple_history.models import HistoricalRecords from assets.models.base import AbsConnectivity from common.utils import lazyproperty from .base import BaseAccount +from .mixins import VaultModelMixin from ..const import AliasAccount, Source -__all__ = ['Account', 'AccountTemplate'] +__all__ = ['Account', 'AccountTemplate', 'AccountHistoricalRecords'] class AccountHistoricalRecords(HistoricalRecords): @@ -32,7 +33,7 @@ class AccountHistoricalRecords(HistoricalRecords): diff = attrs - history_attrs if not diff: return - super().post_save(instance, created, using=using, **kwargs) + return super().post_save(instance, created, using=using, **kwargs) def create_history_model(self, model, inherited): if self.included_fields and not self.excluded_fields: @@ -53,7 +54,7 @@ class Account(AbsConnectivity, BaseAccount): on_delete=models.SET_NULL, verbose_name=_("Su from") ) version = models.IntegerField(default=0, verbose_name=_('Version')) - history = AccountHistoricalRecords(included_fields=['id', 'secret', 'secret_type', 'version']) + history = AccountHistoricalRecords(included_fields=['id', '_secret', 'secret_type', 'version']) source = models.CharField(max_length=30, default=Source.LOCAL, verbose_name=_('Source')) source_id = models.CharField(max_length=128, null=True, blank=True, verbose_name=_('Source ID')) @@ -198,3 +199,21 @@ class AccountTemplate(BaseAccount): return self.bulk_update_accounts(accounts, {'secret': self.secret}) self.bulk_create_history_accounts(accounts, user_id) + + +def replace_history_model_with_mixin(): + """ + 替换历史模型中的父类为指定的Mixin类。 + + Parameters: + model (class): 历史模型类,例如 Account.history.model + mixin_class (class): 要替换为的Mixin类 + + Returns: + None + """ + model = Account.history.model + model.__bases__ = (VaultModelMixin,) + model.__bases__ + + +replace_history_model_with_mixin() diff --git a/apps/accounts/models/base.py b/apps/accounts/models/base.py index 3f9f70883..b06012c41 100644 --- a/apps/accounts/models/base.py +++ b/apps/accounts/models/base.py @@ -9,33 +9,32 @@ from django.db import models from django.utils.translation import gettext_lazy as _ from accounts.const import SecretType -from common.db import fields from common.utils import ( ssh_key_string_to_obj, ssh_key_gen, get_logger, random_string, lazyproperty, parse_ssh_public_key_str, is_openssh_format_key ) +from accounts.models.mixins import VaultModelMixin, VaultManagerMixin, VaultQuerySetMixin from orgs.mixins.models import JMSOrgBaseModel, OrgManager logger = get_logger(__file__) -class BaseAccountQuerySet(models.QuerySet): +class BaseAccountQuerySet(VaultQuerySetMixin, models.QuerySet): def active(self): return self.filter(is_active=True) -class BaseAccountManager(OrgManager): +class BaseAccountManager(VaultManagerMixin, OrgManager): def active(self): return self.get_queryset().active() -class BaseAccount(JMSOrgBaseModel): +class BaseAccount(VaultModelMixin, JMSOrgBaseModel): name = models.CharField(max_length=128, verbose_name=_("Name")) username = models.CharField(max_length=128, blank=True, verbose_name=_('Username'), db_index=True) secret_type = models.CharField( max_length=16, choices=SecretType.choices, default=SecretType.PASSWORD, verbose_name=_('Secret type') ) - secret = fields.EncryptTextField(blank=True, null=True, verbose_name=_('Secret')) privileged = models.BooleanField(verbose_name=_("Privileged"), default=False) is_active = models.BooleanField(default=True, verbose_name=_("Is active")) diff --git a/apps/accounts/models/mixins/__init__.py b/apps/accounts/models/mixins/__init__.py new file mode 100644 index 000000000..203d7b3cb --- /dev/null +++ b/apps/accounts/models/mixins/__init__.py @@ -0,0 +1 @@ +from .vault import * diff --git a/apps/accounts/models/mixins/vault.py b/apps/accounts/models/mixins/vault.py new file mode 100644 index 000000000..95c85265d --- /dev/null +++ b/apps/accounts/models/mixins/vault.py @@ -0,0 +1,88 @@ +from django.db import models +from django.db.models.signals import post_save +from django.utils.translation import ugettext_lazy as _ + +from common.db import fields + +__all__ = ['VaultQuerySetMixin', 'VaultManagerMixin', 'VaultModelMixin'] + + +class VaultQuerySetMixin(models.QuerySet): + + def update(self, **kwargs): + """ + 1. 替换 secret 为 _secret + 2. 触发 post_save 信号 + """ + if 'secret' in kwargs: + kwargs.update({ + '_secret': kwargs.pop('secret') + }) + rows = super().update(**kwargs) + + # 为了获取更新后的对象所以单独查询一次 + ids = self.values_list('id', flat=True) + objs = self.model.objects.filter(id__in=ids) + for obj in objs: + post_save.send(obj.__class__, instance=obj, created=False) + return rows + + +class VaultManagerMixin(models.Manager): + """ 触发 bulk_create 和 bulk_update 操作下的 post_save 信号 """ + + def bulk_create(self, objs, batch_size=None, ignore_conflicts=False): + objs = super().bulk_create(objs, batch_size=batch_size, ignore_conflicts=ignore_conflicts) + for obj in objs: + post_save.send(obj.__class__, instance=obj, created=True) + return objs + + def bulk_update(self, objs, batch_size=None, ignore_conflicts=False): + objs = super().bulk_update(objs, batch_size=batch_size, ignore_conflicts=ignore_conflicts) + for obj in objs: + post_save.send(obj.__class__, instance=obj, created=False) + return objs + + +class VaultModelMixin(models.Model): + _secret = fields.EncryptTextField(blank=True, null=True, verbose_name=_('Secret')) + is_sync_metadata = True + + class Meta: + abstract = True + + # 缓存 secret 值, lazy-property 不能用 + __secret = False + + @property + def secret(self): + if self.__secret is False: + from accounts.backends import vault_client + secret = vault_client.get(self) + if not secret and not self.secret_has_save_to_vault: + # vault_client 获取不到, 并且 secret 没有保存到 vault, 就从 self._secret 获取 + secret = self._secret + self.__secret = secret + return self.__secret + + @secret.setter + def secret(self, value): + """ + 保存的时候通过 post_save 信号监听进行处理, + 先保存到 db, 再保存到 vault 同时删除本地 db _secret 值 + """ + self._secret = value + + _secret_save_to_vault_mark = '# Secret-has-been-saved-to-vault #' + + def mark_secret_save_to_vault(self): + self._secret = self._secret_save_to_vault_mark + self.save() + + @property + def secret_has_save_to_vault(self): + return self._secret == self._secret_save_to_vault_mark + + def save(self, *args, **kwargs): + """ 通过 post_save signal 处理 _secret 数据 """ + return super().save(*args, **kwargs) diff --git a/apps/accounts/serializers/account/account.py b/apps/accounts/serializers/account/account.py index 54035e4be..9a4f1536b 100644 --- a/apps/accounts/serializers/account/account.py +++ b/apps/accounts/serializers/account/account.py @@ -198,7 +198,6 @@ class AccountAssetSerializer(serializers.ModelSerializer): class AccountSerializer(AccountCreateUpdateSerializerMixin, BaseAccountSerializer): asset = AccountAssetSerializer(label=_('Asset')) - has_secret = serializers.BooleanField(label=_("Has secret"), read_only=True) source = LabeledChoiceField( choices=Source.choices, label=_("Source"), required=False, allow_null=True, default=Source.LOCAL @@ -233,6 +232,15 @@ class AccountSerializer(AccountCreateUpdateSerializerMixin, BaseAccountSerialize return queryset +class AccountDetailSerializer(AccountSerializer): + has_secret = serializers.BooleanField(label=_("Has secret"), read_only=True) + + class Meta(AccountSerializer.Meta): + model = Account + fields = AccountSerializer.Meta.fields + ['has_secret'] + read_only_fields = AccountSerializer.Meta.read_only_fields + ['has_secret'] + + class AssetAccountBulkSerializerResultSerializer(serializers.Serializer): asset = serializers.CharField(read_only=True, label=_('Asset')) state = serializers.CharField(read_only=True, label=_('State')) diff --git a/apps/accounts/serializers/account/base.py b/apps/accounts/serializers/account/base.py index e2a837b03..5289ea25b 100644 --- a/apps/accounts/serializers/account/base.py +++ b/apps/accounts/serializers/account/base.py @@ -61,20 +61,18 @@ class AuthValidateMixin(serializers.Serializer): class BaseAccountSerializer(AuthValidateMixin, BulkOrgResourceModelSerializer): - has_secret = serializers.BooleanField(label=_("Has secret"), read_only=True) class Meta: model = BaseAccount fields_mini = ['id', 'name', 'username'] fields_small = fields_mini + [ - 'secret_type', 'secret', 'has_secret', 'passphrase', + 'secret_type', 'secret', 'passphrase', 'privileged', 'is_active', 'spec_info', ] fields_other = ['created_by', 'date_created', 'date_updated', 'comment'] fields = fields_small + fields_other read_only_fields = [ - 'has_secret', 'spec_info', - 'date_verified', 'created_by', 'date_created', + 'spec_info', 'date_verified', 'created_by', 'date_created', ] extra_kwargs = { 'spec_info': {'label': _('Spec info')}, diff --git a/apps/accounts/signal_handlers.py b/apps/accounts/signal_handlers.py index cf09842cc..868e85614 100644 --- a/apps/accounts/signal_handlers.py +++ b/apps/accounts/signal_handlers.py @@ -1,8 +1,9 @@ -from django.db.models.signals import pre_save +from django.db.models.signals import pre_save, post_save, post_delete from django.dispatch import receiver +from accounts.backends import vault_client from common.utils import get_logger -from .models import Account +from .models import Account, AccountTemplate logger = get_logger(__name__) @@ -13,3 +14,23 @@ def on_account_pre_save(sender, instance, **kwargs): instance.version = 1 else: instance.version = instance.history.count() + + +class VaultSignalHandler(object): + """ 处理 Vault 相关的信号 """ + + @staticmethod + def save_to_vault(sender, instance, created, **kwargs): + if created: + vault_client.create(instance) + else: + vault_client.update(instance) + + @staticmethod + def delete_to_vault(sender, instance, **kwargs): + vault_client.delete(instance) + + +for model in (Account, AccountTemplate, Account.history.model): + post_save.connect(VaultSignalHandler.save_to_vault, sender=model) + post_delete.connect(VaultSignalHandler.delete_to_vault, sender=model) diff --git a/apps/accounts/tasks/vault.py b/apps/accounts/tasks/vault.py new file mode 100644 index 000000000..a6c9ed6db --- /dev/null +++ b/apps/accounts/tasks/vault.py @@ -0,0 +1,56 @@ +import datetime + +from celery import shared_task +from django.utils.translation import gettext_lazy as _ + +from accounts.backends import vault_client +from accounts.models import Account, AccountTemplate +from common.utils import get_logger +from orgs.utils import tmp_to_root_org +from ..const import VaultTypeChoices + +logger = get_logger(__name__) + + +@shared_task(verbose_name=_('Sync secret to vault')) +def sync_secret_to_vault(): + if vault_client.is_type(VaultTypeChoices.local): + # 这里不能判断 settings.VAULT_TYPE, 必须判断当前 vault_client 的类型 + print('\033[35m>>> 当前 Vault 类型为本地数据库, 不需要同步') + return + + print('\033[33m>>> 开始同步密钥数据到 Vault ({})'.format(datetime.datetime.now())) + with tmp_to_root_org(): + to_sync_models = [Account, AccountTemplate, Account.history.model] + for model in to_sync_models: + print(f'\033[33m>>> 开始同步: {model.__module__}') + succeeded = [] + failed = [] + skipped = [] + instances = model.objects.all() + for instance in instances: + instance_desc = f'[{instance}]' + if instance.secret_has_save_to_vault: + print(f'\033[32m- 跳过同步: {instance_desc}, 原因: [已同步]') + skipped.append(instance) + continue + try: + vault_client.create(instance) + except Exception as e: + failed.append(instance) + print(f'\033[31m- 同步失败: {instance_desc}, 原因: [{e}]') + else: + succeeded.append(instance) + print(f'\033[32m- 同步成功: {instance_desc}') + + total = len(succeeded) + len(failed) + len(skipped) + print( + f'\033[33m>>> 同步完成: {model.__module__}, ' + f'共计: {total}, ' + f'成功: {len(succeeded)}, ' + f'失败: {len(failed)}, ' + f'跳过: {len(skipped)}' + ) + + print('\033[33m>>> 全部同步完成 ({})'.format(datetime.datetime.now())) + print('\033[0m') diff --git a/apps/accounts/utils.py b/apps/accounts/utils.py index 1a24008fc..c0e3fc1cd 100644 --- a/apps/accounts/utils.py +++ b/apps/accounts/utils.py @@ -1,9 +1,7 @@ from django.utils.translation import gettext_lazy as _ from rest_framework import serializers -from accounts.const import ( - SecretType, DEFAULT_PASSWORD_RULES -) +from accounts.const import SecretType, DEFAULT_PASSWORD_RULES from common.utils import ssh_key_gen, random_string from common.utils import validate_ssh_private_key, parse_ssh_private_key_str diff --git a/apps/common/db/fields.py b/apps/common/db/fields.py index f9f2d9f43..ad969d52e 100644 --- a/apps/common/db/fields.py +++ b/apps/common/db/fields.py @@ -11,12 +11,12 @@ from django.core.exceptions import ValidationError from django.core.validators import MinValueValidator, MaxValueValidator from django.db import models from django.db.models import Q, Manager, QuerySet -from django.utils.encoding import force_str from django.utils.translation import gettext_lazy as _ from rest_framework.utils.encoders import JSONEncoder from common.local import add_encrypted_field_set -from common.utils import signer, crypto, contains_ip +from common.utils import contains_ip +from .utils import Encryptor from .validators import PortRangeValidator __all__ = [ @@ -139,20 +139,11 @@ class EncryptMixin: EncryptMixin要放在最前面 """ - def decrypt_from_signer(self, value): - return signer.unsign(value) or "" - def from_db_value(self, value, expression, connection, context=None): if value is None: return value - value = force_str(value) - plain_value = crypto.decrypt(value) - - # 如果没有解开,使用原来的signer解密 - if not plain_value: - plain_value = self.decrypt_from_signer(value) - + plain_value = Encryptor(value).decrypt() # 可能和Json mix,所以要先解密,再json sp = super() if hasattr(sp, "from_db_value"): @@ -167,9 +158,9 @@ class EncryptMixin: sp = super() if hasattr(sp, "get_prep_value"): value = sp.get_prep_value(value) - value = force_str(value) + # 替换新的加密方式 - return crypto.encrypt(value) + return Encryptor(value).encrypt() class EncryptTextField(EncryptMixin, models.TextField): diff --git a/apps/common/db/utils.py b/apps/common/db/utils.py index 23384f2c8..23197a4f9 100644 --- a/apps/common/db/utils.py +++ b/apps/common/db/utils.py @@ -1,8 +1,9 @@ from contextlib import contextmanager from django.db import connections +from django.utils.encoding import force_text -from common.utils import get_logger +from common.utils import get_logger, signer, crypto logger = get_logger(__file__) @@ -55,3 +56,19 @@ def safe_db_connection(): close_old_connections() yield close_old_connections() + + +class Encryptor: + def __init__(self, value): + self.value = force_text(value) + + def decrypt(self): + plain_value = crypto.decrypt(self.value) + + # 如果没有解开,使用原来的signer解密 + if not plain_value: + plain_value = signer.unsign(self.value) or "" + return plain_value + + def encrypt(self): + return crypto.encrypt(self.value) diff --git a/apps/common/decorators.py b/apps/common/decorators.py index 4881c1517..353407ab1 100644 --- a/apps/common/decorators.py +++ b/apps/common/decorators.py @@ -67,12 +67,18 @@ class EventLoopThread(threading.Thread): _loop_thread = EventLoopThread() _loop_thread.setDaemon(True) _loop_thread.start() -executor = ThreadPoolExecutor(max_workers=10, - thread_name_prefix='debouncer') +executor = ThreadPoolExecutor( + max_workers=10, + thread_name_prefix='debouncer' +) _loop_debouncer_func_task_cache = {} _loop_debouncer_func_args_cache = {} +def get_loop(): + return _loop_thread.get_loop() + + def cancel_or_remove_debouncer_task(cache_key): task = _loop_debouncer_func_task_cache.get(cache_key, None) if not task: diff --git a/apps/common/sdk/im/dingtalk/__init__.py b/apps/common/sdk/im/dingtalk/__init__.py index 4f54e1ea2..65d466008 100644 --- a/apps/common/sdk/im/dingtalk/__init__.py +++ b/apps/common/sdk/im/dingtalk/__init__.py @@ -1,10 +1,10 @@ -import time -import hmac import base64 +import hmac +import time -from common.utils import get_logger -from common.sdk.im.utils import digest, as_request from common.sdk.im.mixin import BaseRequest +from common.sdk.im.utils import digest, as_request +from common.utils import get_logger from users.utils import construct_user_email logger = get_logger(__file__) diff --git a/apps/jumpserver/conf.py b/apps/jumpserver/conf.py index 067e3f7ee..98a6477d4 100644 --- a/apps/jumpserver/conf.py +++ b/apps/jumpserver/conf.py @@ -251,6 +251,12 @@ class Config(dict): # 临时密码 'AUTH_TEMP_TOKEN': False, + # Vault + 'VAULT_TYPE': 'local', + 'VAULT_HCP_HOST': '', + 'VAULT_HCP_TOKEN': '', + 'VAULT_HCP_MOUNT_POINT': 'jumpserver', + # Auth LDAP settings 'AUTH_LDAP': False, 'AUTH_LDAP_SERVER_URI': 'ldap://localhost:389', diff --git a/apps/jumpserver/settings/auth.py b/apps/jumpserver/settings/auth.py index fa3217f50..23c95df69 100644 --- a/apps/jumpserver/settings/auth.py +++ b/apps/jumpserver/settings/auth.py @@ -174,6 +174,12 @@ AUTH_OAUTH2_LOGOUT_URL_NAME = "authentication:oauth2:logout" # 临时 token AUTH_TEMP_TOKEN = CONFIG.AUTH_TEMP_TOKEN +# Vault +VAULT_TYPE = CONFIG.VAULT_TYPE +VAULT_HCP_HOST = CONFIG.VAULT_HCP_HOST +VAULT_HCP_TOKEN = CONFIG.VAULT_HCP_TOKEN +VAULT_HCP_MOUNT_POINT = CONFIG.VAULT_HCP_MOUNT_POINT + # Other setting # 这个是 User Login Private Token TOKEN_EXPIRATION = CONFIG.TOKEN_EXPIRATION diff --git a/apps/orgs/mixins/models.py b/apps/orgs/mixins/models.py index a9494ad1a..f41d4a67b 100644 --- a/apps/orgs/mixins/models.py +++ b/apps/orgs/mixins/models.py @@ -119,3 +119,4 @@ class OrgModelMixin(models.Model): class JMSOrgBaseModel(JMSBaseModel, OrgModelMixin): class Meta: abstract = True + diff --git a/apps/orgs/utils.py b/apps/orgs/utils.py index 6813e9f0b..ceed23907 100644 --- a/apps/orgs/utils.py +++ b/apps/orgs/utils.py @@ -1,10 +1,11 @@ # -*- coding: utf-8 -*- # import uuid -from inspect import signature -from functools import wraps -from werkzeug.local import LocalProxy from contextlib import contextmanager +from functools import wraps +from inspect import signature + +from werkzeug.local import LocalProxy from common.local import thread_local from .models import Organization @@ -133,6 +134,7 @@ def org_aware_func(org_arg_name): :param org_arg_name: 函数中包含org_id的对象是哪个参数 :return: """ + def decorate(func): @wraps(func) def wrapper(*args, **kwargs): @@ -149,7 +151,9 @@ def org_aware_func(org_arg_name): with tmp_to_org(org_aware_resource.org_id): # print("Current org id: {}".format(org_aware_resource.org_id)) return func(*args, **kwargs) + return wrapper + return decorate @@ -162,4 +166,5 @@ def ensure_in_real_or_default_org(func): if not current_org or current_org.is_root(): raise ValueError('You must in a real or default org!') return func(*args, **kwargs) + return wrapper diff --git a/apps/settings/api/__init__.py b/apps/settings/api/__init__.py index 176a6c2c6..13f4a2b18 100644 --- a/apps/settings/api/__init__.py +++ b/apps/settings/api/__init__.py @@ -1,8 +1,9 @@ -from .settings import * -from .ldap import * -from .wecom import * from .dingtalk import * -from .feishu import * -from .public import * from .email import * +from .feishu import * +from .ldap import * +from .public import * +from .settings import * from .sms import * +from .vault import * +from .wecom import * diff --git a/apps/settings/api/settings.py b/apps/settings/api/settings.py index 4bcef2889..ab7be6e9b 100644 --- a/apps/settings/api/settings.py +++ b/apps/settings/api/settings.py @@ -50,6 +50,7 @@ class SettingsApi(generics.RetrieveUpdateAPIView): 'huawei': serializers.HuaweiSMSSettingSerializer, 'cmpp2': serializers.CMPP2SMSSettingSerializer, 'custom': serializers.CustomSMSSettingSerializer, + 'vault': serializers.VaultSettingSerializer, } rbac_category_permissions = { @@ -75,6 +76,7 @@ class SettingsApi(generics.RetrieveUpdateAPIView): 'sms': 'settings.change_sms', 'alibaba': 'settings.change_sms', 'tencent': 'settings.change_sms', + 'vault': 'settings.change_vault', } def get_queryset(self): diff --git a/apps/settings/api/vault.py b/apps/settings/api/vault.py new file mode 100644 index 000000000..339b13ab3 --- /dev/null +++ b/apps/settings/api/vault.py @@ -0,0 +1,60 @@ +from django.utils.translation import gettext_lazy as _ +from django.conf import settings +from rest_framework import status +from rest_framework.generics import GenericAPIView +from rest_framework.views import Response, APIView + +from accounts.tasks.vault import sync_secret_to_vault +from accounts.backends import get_vault_client +from settings.models import Setting +from .. import serializers + + +class VaultTestingAPI(GenericAPIView): + serializer_class = serializers.VaultSettingSerializer + rbac_perms = { + 'POST': 'settings.change_vault' + } + + def get_config(self, request): + serializer = self.serializer_class(data=request.data) + serializer.is_valid(raise_exception=True) + data = serializer.validated_data + for k, v in data.items(): + if v: + continue + # 页面没有传递值, 从 settings 中获取 + data[k] = getattr(settings, k, None) + return data + + def post(self, request): + config = self.get_config(request) + try: + client = get_vault_client(raise_exception=True, **config) + ok, error = client.is_active() + except Exception as e: + ok, error = False, str(e) + + if ok: + _status, msg = status.HTTP_200_OK, _('Test success') + else: + _status, msg = status.HTTP_400_BAD_REQUEST, error + + return Response(status=_status, data={'msg': msg}) + + +class VaultSyncDataAPI(APIView): + perm_model = Setting + rbac_perms = { + 'POST': 'settings.change_vault' + } + + def post(self, request, *args, **kwargs): + task = self._run_task() + return Response({'task': task.id}, status=status.HTTP_201_CREATED) + + @staticmethod + def _run_task(): + task = sync_secret_to_vault.delay() + return task + diff --git a/apps/settings/migrations/0008_alter_setting_options.py b/apps/settings/migrations/0008_alter_setting_options.py new file mode 100644 index 000000000..9a8691d69 --- /dev/null +++ b/apps/settings/migrations/0008_alter_setting_options.py @@ -0,0 +1,17 @@ +# Generated by Django 3.2.19 on 2023-06-30 10:37 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('settings', '0007_migrate_ldap_sync_org_ids'), + ] + + operations = [ + migrations.AlterModelOptions( + name='setting', + options={'permissions': [('change_email', 'Can change email setting'), ('change_auth', 'Can change auth setting'), ('change_vault', 'Can change vault setting'), ('change_systemmsgsubscription', 'Can change system msg sub setting'), ('change_sms', 'Can change sms setting'), ('change_security', 'Can change security setting'), ('change_clean', 'Can change clean setting'), ('change_interface', 'Can change interface setting'), ('change_license', 'Can change license setting'), ('change_terminal', 'Can change terminal setting'), ('change_other', 'Can change other setting')], 'verbose_name': 'System setting'}, + ), + ] diff --git a/apps/settings/models.py b/apps/settings/models.py index ab570d07d..6aebf79b1 100644 --- a/apps/settings/models.py +++ b/apps/settings/models.py @@ -159,6 +159,7 @@ class Setting(models.Model): permissions = [ ('change_email', _('Can change email setting')), ('change_auth', _('Can change auth setting')), + ('change_vault', _('Can change vault setting')), ('change_systemmsgsubscription', _('Can change system msg sub setting')), ('change_sms', _('Can change sms setting')), ('change_security', _('Can change security setting')), diff --git a/apps/settings/serializers/__init__.py b/apps/settings/serializers/__init__.py index 0a55f645d..7abfb74e3 100644 --- a/apps/settings/serializers/__init__.py +++ b/apps/settings/serializers/__init__.py @@ -1,13 +1,14 @@ # coding: utf-8 # -from .basic import * from .auth import * -from .email import * -from .public import * -from .settings import * -from .security import * -from .terminal import * +from .basic import * from .cleaning import * +from .email import * from .other import * +from .public import * +from .security import * +from .settings import * +from .terminal import * +from .vault import * diff --git a/apps/settings/serializers/vault.py b/apps/settings/serializers/vault.py new file mode 100644 index 000000000..b3f8d4e78 --- /dev/null +++ b/apps/settings/serializers/vault.py @@ -0,0 +1,23 @@ +from django.utils.translation import ugettext_lazy as _ +from rest_framework import serializers + +from accounts.const import VaultTypeChoices +from common.serializers.fields import EncryptedField + +__all__ = ['VaultSettingSerializer'] + + +class VaultSettingSerializer(serializers.Serializer): + VAULT_TYPE = serializers.ChoiceField( + default=VaultTypeChoices.local, choices=VaultTypeChoices.choices, + required=False, label=_('Type') + ) + VAULT_HCP_HOST = serializers.CharField( + max_length=256, allow_blank=True, required=False, label=_('Host') + ) + VAULT_HCP_TOKEN = EncryptedField( + max_length=256, allow_blank=True, required=False, label=_('Token') + ) + VAULT_HCP_MOUNT_POINT = serializers.CharField( + max_length=256, allow_blank=True, required=False, label=_('Mount Point') + ) diff --git a/apps/settings/urls/api_urls.py b/apps/settings/urls/api_urls.py index ef94d02ba..ba074d4ee 100644 --- a/apps/settings/urls/api_urls.py +++ b/apps/settings/urls/api_urls.py @@ -18,6 +18,8 @@ urlpatterns = [ path('feishu/testing/', api.FeiShuTestingAPI.as_view(), name='feishu-testing'), path('sms//testing/', api.SMSTestingAPI.as_view(), name='sms-testing'), path('sms/backend/', api.SMSBackendAPI.as_view(), name='sms-backend'), + path('vault/testing/', api.VaultTestingAPI.as_view(), name='vault-testing'), + path('vault/sync/', api.VaultSyncDataAPI.as_view(), name='vault-sync'), path('setting/', api.SettingsApi.as_view(), name='settings-setting'), path('logo/', api.SettingsLogoApi.as_view(), name='settings-logo'), diff --git a/requirements/requirements.txt b/requirements/requirements.txt index a94cd102f..303358615 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -133,3 +133,5 @@ ipython==8.14.0 ForgeryPy3==0.3.1 django-debug-toolbar==4.1.0 Pympler==1.0.1 +hvac==1.1.1 +pyhcl==0.4.4 From 2ffadcb9bcd8d26f9a2728d5125669cc5bdab27e Mon Sep 17 00:00:00 2001 From: nut Date: Mon, 31 Jul 2023 17:53:08 +0800 Subject: [PATCH 066/177] Update es.py --- apps/common/plugins/es.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/apps/common/plugins/es.py b/apps/common/plugins/es.py index 8438c43cc..95f878263 100644 --- a/apps/common/plugins/es.py +++ b/apps/common/plugins/es.py @@ -131,10 +131,7 @@ class ES(object): } try: - if version == '6': - self.es.indices.create(self.index, body=mappings) - else: - self.es.indices.create(index=self.index, body=mappings) + self.es.indices.create(index=self.index, body=mappings) except RequestError as e: if e.error == 'resource_already_exists_exception': logger.warning(e) From 1ad0a2062717c8fe58320903cabfe4addbb5e64a Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Mon, 31 Jul 2023 18:31:11 +0800 Subject: [PATCH 067/177] =?UTF-8?q?fix:=20=E5=90=AF=E5=8A=A8500=20(#11133)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: feng <1304903146@qq.com> --- apps/accounts/const/vault.py | 2 +- apps/accounts/models/mixins/vault.py | 2 +- apps/common/db/utils.py | 4 ++-- apps/settings/serializers/vault.py | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/accounts/const/vault.py b/apps/accounts/const/vault.py index 8b30b8afa..1da2a591b 100644 --- a/apps/accounts/const/vault.py +++ b/apps/accounts/const/vault.py @@ -1,5 +1,5 @@ from django.db import models -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ __all__ = ['VaultTypeChoices'] diff --git a/apps/accounts/models/mixins/vault.py b/apps/accounts/models/mixins/vault.py index 95c85265d..a551f20aa 100644 --- a/apps/accounts/models/mixins/vault.py +++ b/apps/accounts/models/mixins/vault.py @@ -1,6 +1,6 @@ from django.db import models from django.db.models.signals import post_save -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from common.db import fields diff --git a/apps/common/db/utils.py b/apps/common/db/utils.py index 23197a4f9..69c82e583 100644 --- a/apps/common/db/utils.py +++ b/apps/common/db/utils.py @@ -1,7 +1,7 @@ from contextlib import contextmanager from django.db import connections -from django.utils.encoding import force_text +from django.utils.encoding import force_str from common.utils import get_logger, signer, crypto @@ -60,7 +60,7 @@ def safe_db_connection(): class Encryptor: def __init__(self, value): - self.value = force_text(value) + self.value = force_str(value) def decrypt(self): plain_value = crypto.decrypt(self.value) diff --git a/apps/settings/serializers/vault.py b/apps/settings/serializers/vault.py index b3f8d4e78..b8b94d5ca 100644 --- a/apps/settings/serializers/vault.py +++ b/apps/settings/serializers/vault.py @@ -1,4 +1,4 @@ -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from rest_framework import serializers from accounts.const import VaultTypeChoices From f9c9c9d525247b7bd2a64b91138840bb5879a057 Mon Sep 17 00:00:00 2001 From: Aaron3S Date: Mon, 31 Jul 2023 19:33:39 +0800 Subject: [PATCH 068/177] =?UTF-8?q?fix:=20=E7=A6=81=E6=AD=A2=E4=B8=80?= =?UTF-8?q?=E4=BA=9B=20ansible=20=E5=8F=98=E9=87=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/ops/models/playbook.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/apps/ops/models/playbook.py b/apps/ops/models/playbook.py index 82491480b..2d3c1f409 100644 --- a/apps/ops/models/playbook.py +++ b/apps/ops/models/playbook.py @@ -11,10 +11,15 @@ from ops.exception import PlaybookNoValidEntry from orgs.mixins.models import JMSOrgBaseModel dangerous_keywords = ( + 'hosts:localhost', + 'hosts:127.0.0.1', + 'hosts:::1', 'delegate_to:localhost', 'delegate_to:127.0.0.1', + 'delegate_to:::1', 'local_action', 'connection:local', + 'ansible_connection' ) @@ -48,7 +53,14 @@ class Playbook(JMSOrgBaseModel): with open(file, 'r') as f: for line_num, line in enumerate(f): for keyword in dangerous_keywords: - if keyword in line.replace(' ', ''): + clear_line = line.replace(' ', '')\ + .replace('\n', '')\ + .replace('\r', '')\ + .replace('\t', '') \ + .replace('\'', '') \ + .replace('\"', '')\ + .replace('\v', '') + if keyword in clear_line: result.append((line_num, keyword)) return result From b93b64255b3876ed0272f47e4b0b7aad269ee6b0 Mon Sep 17 00:00:00 2001 From: "fangfang.dong" Date: Mon, 31 Jul 2023 18:06:23 +0800 Subject: [PATCH 069/177] =?UTF-8?q?perf:=20=E7=BB=9F=E4=B8=80=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E5=90=8D=E7=A7=B0=E7=9A=84label=E6=98=BE=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/rbac/api/rolebinding.py | 9 +-------- apps/rbac/serializers/rolebinding.py | 12 ++++++++---- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/apps/rbac/api/rolebinding.py b/apps/rbac/api/rolebinding.py index 4f3354e5b..bd33a7168 100644 --- a/apps/rbac/api/rolebinding.py +++ b/apps/rbac/api/rolebinding.py @@ -27,14 +27,7 @@ class RoleBindingViewSet(OrgBulkModelViewSet): def get_queryset(self): queryset = self._get_queryset() \ - .prefetch_related('user', 'role', 'org') \ - .annotate( - user_display=Concat( - F('user__name'), Value('('), - F('user__username'), Value(')') - ), - role_display=F('role__name') - ) + .prefetch_related('user', 'role', 'org') return queryset def _get_queryset(self): diff --git a/apps/rbac/serializers/rolebinding.py b/apps/rbac/serializers/rolebinding.py index 5e26cdf42..c5e64946d 100644 --- a/apps/rbac/serializers/rolebinding.py +++ b/apps/rbac/serializers/rolebinding.py @@ -1,6 +1,8 @@ from django.utils.translation import gettext_lazy as _ from rest_framework import serializers +from common.serializers.fields import ObjectRelatedField +from users.models import User from orgs.serializers import CurrentOrgDefault from ..models import RoleBinding, SystemRoleBinding, OrgRoleBinding @@ -10,16 +12,18 @@ __all__ = [ class RoleBindingSerializer(serializers.ModelSerializer): + user = ObjectRelatedField( + required=False, queryset=User.objects, + label=_('User'), attrs=('id', 'name', 'username') + ) + class Meta: model = RoleBinding fields = [ - 'id', 'user', 'user_display', 'role', 'role_display', - 'scope', 'org', 'org_name', + 'id', 'user', 'role', 'scope', 'org', 'org_name', ] read_only_fields = ['scope'] extra_kwargs = { - 'user_display': {'label': _('User display')}, - 'role_display': {'label': _('Role display')}, 'org_name': {'label': _("Org name")} } From 5207b99696228252d182cb875b5fb4dade62fa10 Mon Sep 17 00:00:00 2001 From: ibuler Date: Tue, 1 Aug 2023 10:39:34 +0800 Subject: [PATCH 070/177] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=20inventory?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/ops/ansible/inventory.py | 9 +++++++-- apps/ops/models/job.py | 4 ++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/apps/ops/ansible/inventory.py b/apps/ops/ansible/inventory.py index 9c0d03849..653c5f40d 100644 --- a/apps/ops/ansible/inventory.py +++ b/apps/ops/ansible/inventory.py @@ -270,8 +270,13 @@ class JMSInventory: name = host.pop('name') name = name.replace('[', '_').replace(']', '_') data['all']['hosts'][name] = host - if self.exclude_localhost and data['all']['hosts'].__contains__('localhost'): - data['all']['hosts'].update({'localhost': {'ansible_host': '255.255.255.255'}}) + if not self.exclude_localhost: + data['all']['hosts'].update({ + 'localhost': { + 'ansible_host': '127.0.0.1', + 'ansible_connection': 'local' + } + }) return data def write_to_file(self, path): diff --git a/apps/ops/models/job.py b/apps/ops/models/job.py index 06a858bd6..3cd63e293 100644 --- a/apps/ops/models/job.py +++ b/apps/ops/models/job.py @@ -43,8 +43,8 @@ def get_parent_keys(key, include_self=True): class JMSPermedInventory(JMSInventory): def __init__(self, assets, account_policy='privileged_first', - account_prefer='root,Administrator', host_callback=None, exclude_localhost=False, user=None): - super().__init__(assets, account_policy, account_prefer, host_callback, exclude_localhost) + account_prefer='root,Administrator', host_callback=None, user=None): + super().__init__(assets, account_policy, account_prefer, host_callback, exclude_localhost=True) self.user = user self.assets_accounts_mapper = self.get_assets_accounts_mapper() From 6b333adc059dfa251745753b5f56ebf1e06cbd8e Mon Sep 17 00:00:00 2001 From: ibuler Date: Tue, 1 Aug 2023 10:42:58 +0800 Subject: [PATCH 071/177] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=20ansible=20?= =?UTF-8?q?version?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- requirements/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/requirements.txt b/requirements/requirements.txt index 303358615..cb47071f7 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -2,7 +2,7 @@ cython==3.0.0 aiofiles==23.1.0 amqp==5.1.1 -ansible-core@https://github.com/jumpserver/ansible/releases/download/v2.14.1/ansible-2.14.1.zip +ansible-core@https://github.com/jumpserver/ansible/releases/download/v2.14.1.2/ansible-2.14.1.2.zip ansible==7.1.0 ansible-runner==2.3.3 asn1crypto==1.5.1 From 681988f450fe6fe1a32da2d88a69d0f74d91fff6 Mon Sep 17 00:00:00 2001 From: feng <1304903146@qq.com> Date: Tue, 1 Aug 2023 15:38:08 +0800 Subject: [PATCH 072/177] fix: ansible task 500 --- apps/assets/automations/base/manager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/assets/automations/base/manager.py b/apps/assets/automations/base/manager.py index aa31c886f..2107e6e56 100644 --- a/apps/assets/automations/base/manager.py +++ b/apps/assets/automations/base/manager.py @@ -262,7 +262,7 @@ class BasePlaybookManager: info = self.file_to_json(runner.inventory) servers, not_valid = [], [] for k, host in info['all']['hosts'].items(): - jms_asset, jms_gateway = host['jms_asset'], host.get('gateway') + jms_asset, jms_gateway = host.get('jms_asset'), host.get('gateway') if not jms_gateway: continue From d17e2cde060afe727f8c9ba09bf054bd35f2e901 Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Tue, 1 Aug 2023 16:14:40 +0800 Subject: [PATCH 073/177] =?UTF-8?q?feat:=20=E7=BB=88=E7=AB=AF=E4=BC=9A?= =?UTF-8?q?=E8=AF=9D=E5=A2=9E=E5=8A=A0=E5=AD=97=E6=AE=B5:=20cmd=5Famount(?= =?UTF-8?q?=E5=91=BD=E4=BB=A4=E6=95=B0=E9=87=8F)=20(#11136)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 终端会话增加字段: command_amount(命令数量) * perf: 优化已产生会话的命令数量计算方式 * Update 0065_session_command_amount.py * Update session.py * Update session.py * perf: 优化会话命令数量的计算逻辑 * perf: 优化命令数量获取 --------- Co-authored-by: fangfang.dong Co-authored-by: Bai --- .../migrations/0065_session_command_amount.py | 18 +++++++++++++++++ apps/terminal/models/session/session.py | 20 +++++++++++++++++++ apps/terminal/serializers/session.py | 3 ++- apps/terminal/signal_handlers/__init__.py | 1 + apps/terminal/signal_handlers/session.py | 10 ++++++++++ 5 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 apps/terminal/migrations/0065_session_command_amount.py create mode 100644 apps/terminal/signal_handlers/session.py diff --git a/apps/terminal/migrations/0065_session_command_amount.py b/apps/terminal/migrations/0065_session_command_amount.py new file mode 100644 index 000000000..1733d7a19 --- /dev/null +++ b/apps/terminal/migrations/0065_session_command_amount.py @@ -0,0 +1,18 @@ +# Generated by Django 4.1.10 on 2023-07-31 10:46 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('terminal', '0064_auto_20230728_1001'), + ] + + operations = [ + migrations.AddField( + model_name='session', + name='cmd_amount', + field=models.IntegerField(default=-1, verbose_name='Command amount'), + ), + ] diff --git a/apps/terminal/models/session/session.py b/apps/terminal/models/session/session.py index 35c11727e..02c0a0f95 100644 --- a/apps/terminal/models/session/session.py +++ b/apps/terminal/models/session/session.py @@ -44,6 +44,7 @@ class Session(OrgModelMixin): date_start = models.DateTimeField(verbose_name=_("Date start"), db_index=True, default=timezone.now) date_end = models.DateTimeField(verbose_name=_("Date end"), null=True) comment = models.TextField(blank=True, null=True, verbose_name=_("Comment")) + cmd_amount = models.IntegerField(default=-1, verbose_name=_("Command amount")) upload_to = 'replay' ACTIVE_CACHE_KEY_PREFIX = 'SESSION_ACTIVE_{}' @@ -177,6 +178,25 @@ class Session(OrgModelMixin): @property def command_amount(self): + if self.need_update_cmd_amount: + cmd_amount = self.compute_command_amount() + self.cmd_amount = cmd_amount + self.save() + elif self.need_compute_cmd_amount: + cmd_amount = self.compute_command_amount() + else: + cmd_amount = self.cmd_amount + return cmd_amount + + @property + def need_update_cmd_amount(self): + return self.is_finished and self.need_compute_cmd_amount + + @property + def need_compute_cmd_amount(self): + return self.cmd_amount == -1 + + def compute_command_amount(self): command_store = get_multi_command_storage() return command_store.count(session=str(self.id)) diff --git a/apps/terminal/serializers/session.py b/apps/terminal/serializers/session.py index 999028133..072ddbb3f 100644 --- a/apps/terminal/serializers/session.py +++ b/apps/terminal/serializers/session.py @@ -30,7 +30,8 @@ class SessionSerializer(BulkOrgResourceModelSerializer): "user", "asset", "user_id", "asset_id", 'account', 'account_id', "protocol", 'type', "login_from", "remote_addr", "is_success", "is_finished", "has_replay", "has_command", - "date_start", "date_end", "comment", "terminal_display" + "date_start", "date_end", "comment", "terminal_display", + 'command_amount', ] fields_fk = ["terminal", ] fields_custom = ["can_replay", "can_join", "can_terminate"] diff --git a/apps/terminal/signal_handlers/__init__.py b/apps/terminal/signal_handlers/__init__.py index 5ba51e77a..0021ba500 100644 --- a/apps/terminal/signal_handlers/__init__.py +++ b/apps/terminal/signal_handlers/__init__.py @@ -2,3 +2,4 @@ from .applet import * from .db_port import * from .terminal import * from .session_sharing import * +from .session import * diff --git a/apps/terminal/signal_handlers/session.py b/apps/terminal/signal_handlers/session.py new file mode 100644 index 000000000..566173678 --- /dev/null +++ b/apps/terminal/signal_handlers/session.py @@ -0,0 +1,10 @@ +from django.db.models.signals import pre_save +from django.dispatch import receiver + +from terminal.models import Session + + +@receiver(pre_save, sender=Session) +def on_session_pre_save(sender, instance, **kwargs): + if instance.need_update_cmd_amount: + instance.cmd_amount = instance.compute_command_amount() From 44397caad42902b330d125527f9ce4a01d09c2fd Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Tue, 1 Aug 2023 16:40:38 +0800 Subject: [PATCH 074/177] =?UTF-8?q?perf:=20=E6=94=AF=E6=8C=81=E5=9C=A8?= =?UTF-8?q?=E7=BA=BF=E4=BC=9A=E8=AF=9D=E6=9A=82=E5=81=9C=E6=93=8D=E4=BD=9C?= =?UTF-8?q?=20(#11146)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * perf: 支持在线会话暂停操作 * perf: 优化代码 --------- Co-authored-by: Eric --- apps/locale/ja/LC_MESSAGES/django.po | 91 ++++++++++++++--------- apps/locale/zh/LC_MESSAGES/django.po | 86 ++++++++++++--------- apps/terminal/api/session/task.py | 51 +++++++++++-- apps/terminal/const.py | 6 ++ apps/terminal/models/component/task.py | 6 +- apps/terminal/models/session/session.py | 21 ++++++ apps/terminal/serializers/__init__.py | 13 ++-- apps/terminal/serializers/session.py | 2 +- apps/terminal/serializers/task.py | 10 +++ apps/terminal/signal_handlers/__init__.py | 4 +- apps/terminal/signal_handlers/session.py | 10 ++- apps/terminal/signal_handlers/terminal.py | 15 +++- apps/terminal/urls/api_urls.py | 3 +- apps/terminal/ws.py | 12 +-- 14 files changed, 231 insertions(+), 99 deletions(-) create mode 100644 apps/terminal/serializers/task.py diff --git a/apps/locale/ja/LC_MESSAGES/django.po b/apps/locale/ja/LC_MESSAGES/django.po index 04c99f607..a51437386 100644 --- a/apps/locale/ja/LC_MESSAGES/django.po +++ b/apps/locale/ja/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-07-28 10:57+0800\n" +"POT-Creation-Date: 2023-07-31 16:39+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -18,7 +18,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -#: accounts/api/automations/base.py:79 +#: accounts/api/automations/base.py:79 tickets/api/ticket.py:112 msgid "The parameter 'action' must be [{}]" msgstr "パラメータ 'action' は [{}] でなければなりません。" @@ -502,7 +502,7 @@ msgstr "アカウントの確認" #: settings/models.py:32 settings/serializers/sms.py:6 #: terminal/models/applet/applet.py:32 terminal/models/component/endpoint.py:12 #: terminal/models/component/endpoint.py:92 -#: terminal/models/component/storage.py:26 terminal/models/component/task.py:15 +#: terminal/models/component/storage.py:26 terminal/models/component/task.py:13 #: terminal/models/component/terminal.py:84 users/forms/profile.py:33 #: users/models/group.py:13 users/models/user.py:753 #: xpack/plugins/cloud/models.py:28 @@ -1245,7 +1245,7 @@ msgstr "SSHパブリックキー" #: assets/models/cmd_filter.py:88 assets/models/group.py:20 #: common/db/models.py:36 ops/models/adhoc.py:26 ops/models/job.py:113 #: ops/models/playbook.py:26 rbac/models/role.py:37 settings/models.py:37 -#: terminal/models/applet/applet.py:44 terminal/models/applet/applet.py:248 +#: terminal/models/applet/applet.py:44 terminal/models/applet/applet.py:250 #: terminal/models/applet/host.py:141 terminal/models/component/endpoint.py:24 #: terminal/models/component/endpoint.py:102 #: terminal/models/session/session.py:46 tickets/models/comment.py:32 @@ -1439,7 +1439,7 @@ msgstr "アセットの自動化タスク" #: assets/models/automations/base.py:113 audits/models.py:199 #: audits/serializers.py:50 ops/models/base.py:49 ops/models/job.py:186 -#: terminal/models/applet/applet.py:247 terminal/models/applet/host.py:138 +#: terminal/models/applet/applet.py:249 terminal/models/applet/host.py:138 #: terminal/models/component/status.py:30 terminal/serializers/applet.py:18 #: terminal/serializers/applet_host.py:115 tickets/models/ticket/general.py:283 #: tickets/serializers/super_ticket.py:13 @@ -2048,7 +2048,7 @@ msgid "Login log" msgstr "ログインログ" #: audits/const.py:43 terminal/models/applet/host.py:142 -#: terminal/models/component/task.py:24 +#: terminal/models/component/task.py:22 msgid "Task" msgstr "タスク" @@ -2248,29 +2248,29 @@ msgstr "外部ストレージへのFTPファイルのアップロード" msgid "This action require verify your MFA" msgstr "この操作には、MFAを検証する必要があります" -#: authentication/api/connection_token.py:221 +#: authentication/api/connection_token.py:230 msgid "Reusable connection token is not allowed, global setting not enabled" msgstr "" "再使用可能な接続トークンの使用は許可されていません。グローバル設定は有効に" "なっていません" -#: authentication/api/connection_token.py:301 +#: authentication/api/connection_token.py:310 msgid "Anonymous account is not supported for this asset" msgstr "匿名アカウントはこのプロパティではサポートされていません" -#: authentication/api/connection_token.py:320 +#: authentication/api/connection_token.py:329 msgid "Account not found" msgstr "アカウントが見つかりません" -#: authentication/api/connection_token.py:323 +#: authentication/api/connection_token.py:332 msgid "Permission expired" msgstr "承認の有効期限が切れています" -#: authentication/api/connection_token.py:337 +#: authentication/api/connection_token.py:346 msgid "ACL action is reject: {}({})" msgstr "ACL アクションは拒否です: {}({})" -#: authentication/api/connection_token.py:341 +#: authentication/api/connection_token.py:350 msgid "ACL action is review" msgstr "ACL アクションはレビューです" @@ -3691,7 +3691,7 @@ msgid "Module" msgstr "モジュール" #: ops/models/adhoc.py:24 ops/models/celery.py:58 ops/models/job.py:97 -#: terminal/models/component/task.py:16 +#: terminal/models/component/task.py:14 msgid "Args" msgstr "アルグ" @@ -3734,7 +3734,7 @@ msgstr "Celery タスク#タスク#" msgid "Can view task monitor" msgstr "タスクモニターを表示できます" -#: ops/models/celery.py:59 terminal/models/component/task.py:17 +#: ops/models/celery.py:59 terminal/models/component/task.py:15 msgid "Kwargs" msgstr "クワーグ" @@ -3871,7 +3871,7 @@ msgstr "例外ジョブのクリーンアップ" msgid "Task log" msgstr "タスクログ" -#: ops/templates/ops/celery_task_log.html:71 +#: ops/templates/ops/celery_task_log.html:71 terminal/serializers/task.py:10 msgid "Task name" msgstr "タスク名" @@ -4253,7 +4253,7 @@ msgid "My assets" msgstr "私の資産" #: rbac/tree.py:56 terminal/models/applet/applet.py:51 -#: terminal/models/applet/applet.py:244 terminal/models/applet/host.py:29 +#: terminal/models/applet/applet.py:246 terminal/models/applet/host.py:29 #: terminal/serializers/applet.py:15 msgid "Applet" msgstr "リモートアプリケーション" @@ -5563,8 +5563,8 @@ msgstr "期限切れです。" #, python-format msgid "" "\n" -" Your password has expired, please click this link update password.\n" +" Your password has expired, please click this link update password.\n" " " msgstr "" "\n" @@ -5585,34 +5585,34 @@ msgid "" " " msgstr "" "\n" -" クリックしてください リンク パスワードの更新\n" +" クリックしてください リンク パスワードの更新\n" " " #: templates/_message.html:43 #, python-format msgid "" "\n" -" Your information was incomplete. Please click this link to complete your information.\n" +" Your information was incomplete. Please click this link to complete your information.\n" " " msgstr "" "\n" -" あなたの情報が不完全なので、クリックしてください。 リンク 補完\n" +" あなたの情報が不完全なので、クリックしてください。 リンク 補完\n" " " #: templates/_message.html:56 #, python-format msgid "" "\n" -" Your ssh public key not set or expired. Please click this link to update\n" +" Your ssh public key not set or expired. Please click this link to update\n" " " msgstr "" "\n" -" SSHキーが設定されていないか無効になっている場合は、 リンク 更新\n" +" SSHキーが設定されていないか無効になっている場合は、 リンク 更新\n" " " #: templates/_mfa_login_field.html:28 @@ -5805,6 +5805,18 @@ msgstr "読み取り専用" msgid "Writable" msgstr "書き込み可能" +#: terminal/const.py:94 +msgid "Kill Session" +msgstr "セッションを終了する" + +#: terminal/const.py:95 +msgid "Lock Session" +msgstr "セッションをロックする" + +#: terminal/const.py:96 +msgid "Unlock Session" +msgstr "セッションのロックを解除する" + #: terminal/exceptions.py:8 msgid "Bulk create not support" msgstr "一括作成非サポート" @@ -5857,7 +5869,7 @@ msgstr "カスタムプラットフォームのみをサポート" msgid "Missing type in platform.yml" msgstr "platform.ymlにタイプがありません" -#: terminal/models/applet/applet.py:246 terminal/models/applet/host.py:35 +#: terminal/models/applet/applet.py:248 terminal/models/applet/host.py:35 #: terminal/models/applet/host.py:136 msgid "Hosting" msgstr "ホスト マシン" @@ -6028,23 +6040,23 @@ msgstr "リプレイ" msgid "Date end" msgstr "終了日" -#: terminal/models/session/session.py:240 +#: terminal/models/session/session.py:261 msgid "Session record" msgstr "セッション記録" -#: terminal/models/session/session.py:242 +#: terminal/models/session/session.py:263 msgid "Can monitor session" msgstr "セッションを監視できます" -#: terminal/models/session/session.py:243 +#: terminal/models/session/session.py:264 msgid "Can share session" msgstr "セッションを共有できます" -#: terminal/models/session/session.py:244 +#: terminal/models/session/session.py:265 msgid "Can terminate session" msgstr "セッションを終了できます" -#: terminal/models/session/session.py:245 +#: terminal/models/session/session.py:266 msgid "Can validate session action perm" msgstr "セッションアクションのパーマを検証できます" @@ -6213,7 +6225,12 @@ msgid "" "has a private account, the other is public, when the application does not " "support multiple open and the special has been used, the public account will " "be used to connect" -msgstr "これらのアカウントは、公開されたアプリケーションに接続するために使用されます。アカウントは現在、2つのタイプに分類されています。1つは、各アカウントに専用のアカウントで、各ユーザーにはプライベートアカウントがあります。もう1つは公開されています。アプリケーションが複数のオープンをサポートしていない場合、および特別なものが使用されている場合、公開アカウントが使用されます。" +msgstr "" +"これらのアカウントは、公開されたアプリケーションに接続するために使用されま" +"す。アカウントは現在、2つのタイプに分類されています。1つは、各アカウントに専" +"用のアカウントで、各ユーザーにはプライベートアカウントがあります。もう1つは公" +"開されています。アプリケーションが複数のオープンをサポートしていない場合、お" +"よび特別なものが使用されている場合、公開アカウントが使用されます。" #: terminal/serializers/applet_host.py:77 msgid "The number of public accounts created automatically" @@ -6388,6 +6405,10 @@ msgstr "インデックス" msgid "Doc type" msgstr "Docタイプ" +#: terminal/serializers/task.py:9 +msgid "Session id" +msgstr "セッション" + #: terminal/serializers/terminal.py:83 terminal/serializers/terminal.py:91 msgid "Not found" msgstr "見つかりません" diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po index ade0170ab..6a599c0a0 100644 --- a/apps/locale/zh/LC_MESSAGES/django.po +++ b/apps/locale/zh/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: JumpServer 0.3.3\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-07-28 10:57+0800\n" +"POT-Creation-Date: 2023-07-31 16:39+0800\n" "PO-Revision-Date: 2021-05-20 10:54+0800\n" "Last-Translator: ibuler \n" "Language-Team: JumpServer team\n" @@ -17,7 +17,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 2.4.3\n" -#: accounts/api/automations/base.py:79 +#: accounts/api/automations/base.py:79 tickets/api/ticket.py:112 msgid "The parameter 'action' must be [{}]" msgstr "参数 'action' 必须是 [{}]" @@ -501,7 +501,7 @@ msgstr "账号验证" #: settings/models.py:32 settings/serializers/sms.py:6 #: terminal/models/applet/applet.py:32 terminal/models/component/endpoint.py:12 #: terminal/models/component/endpoint.py:92 -#: terminal/models/component/storage.py:26 terminal/models/component/task.py:15 +#: terminal/models/component/storage.py:26 terminal/models/component/task.py:13 #: terminal/models/component/terminal.py:84 users/forms/profile.py:33 #: users/models/group.py:13 users/models/user.py:753 #: xpack/plugins/cloud/models.py:28 @@ -1238,7 +1238,7 @@ msgstr "SSH公钥" #: assets/models/cmd_filter.py:88 assets/models/group.py:20 #: common/db/models.py:36 ops/models/adhoc.py:26 ops/models/job.py:113 #: ops/models/playbook.py:26 rbac/models/role.py:37 settings/models.py:37 -#: terminal/models/applet/applet.py:44 terminal/models/applet/applet.py:248 +#: terminal/models/applet/applet.py:44 terminal/models/applet/applet.py:250 #: terminal/models/applet/host.py:141 terminal/models/component/endpoint.py:24 #: terminal/models/component/endpoint.py:102 #: terminal/models/session/session.py:46 tickets/models/comment.py:32 @@ -1432,7 +1432,7 @@ msgstr "资产自动化任务" #: assets/models/automations/base.py:113 audits/models.py:199 #: audits/serializers.py:50 ops/models/base.py:49 ops/models/job.py:186 -#: terminal/models/applet/applet.py:247 terminal/models/applet/host.py:138 +#: terminal/models/applet/applet.py:249 terminal/models/applet/host.py:138 #: terminal/models/component/status.py:30 terminal/serializers/applet.py:18 #: terminal/serializers/applet_host.py:115 tickets/models/ticket/general.py:283 #: tickets/serializers/super_ticket.py:13 @@ -2032,7 +2032,7 @@ msgid "Login log" msgstr "登录日志" #: audits/const.py:43 terminal/models/applet/host.py:142 -#: terminal/models/component/task.py:24 +#: terminal/models/component/task.py:22 msgid "Task" msgstr "任务" @@ -2232,27 +2232,27 @@ msgstr "上传 FTP 文件到外部存储" msgid "This action require verify your MFA" msgstr "该操作需要验证您的 MFA, 请先开启并配置" -#: authentication/api/connection_token.py:221 +#: authentication/api/connection_token.py:230 msgid "Reusable connection token is not allowed, global setting not enabled" msgstr "不允许使用可重复使用的连接令牌,未启用全局设置" -#: authentication/api/connection_token.py:301 +#: authentication/api/connection_token.py:310 msgid "Anonymous account is not supported for this asset" msgstr "匿名账号不支持当前资产" -#: authentication/api/connection_token.py:320 +#: authentication/api/connection_token.py:329 msgid "Account not found" msgstr "账号未找到" -#: authentication/api/connection_token.py:323 +#: authentication/api/connection_token.py:332 msgid "Permission expired" msgstr "授权已过期" -#: authentication/api/connection_token.py:337 +#: authentication/api/connection_token.py:346 msgid "ACL action is reject: {}({})" msgstr "ACL 动作是拒绝: {}({})" -#: authentication/api/connection_token.py:341 +#: authentication/api/connection_token.py:350 msgid "ACL action is review" msgstr "ACL 动作是复核" @@ -3644,7 +3644,7 @@ msgid "Module" msgstr "模块" #: ops/models/adhoc.py:24 ops/models/celery.py:58 ops/models/job.py:97 -#: terminal/models/component/task.py:16 +#: terminal/models/component/task.py:14 msgid "Args" msgstr "参数" @@ -3687,7 +3687,7 @@ msgstr "Celery 任务" msgid "Can view task monitor" msgstr "可以查看任务监控" -#: ops/models/celery.py:59 terminal/models/component/task.py:17 +#: ops/models/celery.py:59 terminal/models/component/task.py:15 msgid "Kwargs" msgstr "其它参数" @@ -3824,7 +3824,7 @@ msgstr "清理异常作业" msgid "Task log" msgstr "任务列表" -#: ops/templates/ops/celery_task_log.html:71 +#: ops/templates/ops/celery_task_log.html:71 terminal/serializers/task.py:10 msgid "Task name" msgstr "任务名称" @@ -4204,7 +4204,7 @@ msgid "My assets" msgstr "我的资产" #: rbac/tree.py:56 terminal/models/applet/applet.py:51 -#: terminal/models/applet/applet.py:244 terminal/models/applet/host.py:29 +#: terminal/models/applet/applet.py:246 terminal/models/applet/host.py:29 #: terminal/serializers/applet.py:15 msgid "Applet" msgstr "远程应用" @@ -5481,13 +5481,13 @@ msgstr "过期。" #, python-format msgid "" "\n" -" Your password has expired, please click this link update password.\n" +" Your password has expired, please click this link update password.\n" " " msgstr "" "\n" -" 您的密码已经过期,请点击 链接 更新密码\n" +" 您的密码已经过期,请点击 链接 更新密码\n" " " #: templates/_message.html:30 @@ -5511,8 +5511,8 @@ msgstr "" #, python-format msgid "" "\n" -" Your information was incomplete. Please click this link to complete your information.\n" +" Your information was incomplete. Please click this link to complete your information.\n" " " msgstr "" "\n" @@ -5524,13 +5524,13 @@ msgstr "" #, python-format msgid "" "\n" -" Your ssh public key not set or expired. Please click this link to update\n" +" Your ssh public key not set or expired. Please click this link to update\n" " " msgstr "" "\n" -" 您的SSH密钥没有设置或已失效,请点击 链接 更新\n" +" 您的SSH密钥没有设置或已失效,请点击 链接 更新\n" " " #: templates/_mfa_login_field.html:28 @@ -5718,6 +5718,18 @@ msgstr "只读" msgid "Writable" msgstr "读写" +#: terminal/const.py:94 +msgid "Kill Session" +msgstr "终断会话" + +#: terminal/const.py:95 +msgid "Lock Session" +msgstr "锁定会话" + +#: terminal/const.py:96 +msgid "Unlock Session" +msgstr "解锁会话" + #: terminal/exceptions.py:8 msgid "Bulk create not support" msgstr "不支持批量创建" @@ -5770,7 +5782,7 @@ msgstr "只支持自定义平台" msgid "Missing type in platform.yml" msgstr "在 platform.yml 中缺少类型" -#: terminal/models/applet/applet.py:246 terminal/models/applet/host.py:35 +#: terminal/models/applet/applet.py:248 terminal/models/applet/host.py:35 #: terminal/models/applet/host.py:136 msgid "Hosting" msgstr "宿主机" @@ -5941,23 +5953,23 @@ msgstr "回放" msgid "Date end" msgstr "结束日期" -#: terminal/models/session/session.py:240 +#: terminal/models/session/session.py:261 msgid "Session record" msgstr "会话记录" -#: terminal/models/session/session.py:242 +#: terminal/models/session/session.py:263 msgid "Can monitor session" msgstr "可以监控会话" -#: terminal/models/session/session.py:243 +#: terminal/models/session/session.py:264 msgid "Can share session" msgstr "可以分享会话" -#: terminal/models/session/session.py:244 +#: terminal/models/session/session.py:265 msgid "Can terminate session" msgstr "可以终断会话" -#: terminal/models/session/session.py:245 +#: terminal/models/session/session.py:266 msgid "Can validate session action perm" msgstr "可以验证会话动作权限" @@ -6124,8 +6136,10 @@ msgid "" "has a private account, the other is public, when the application does not " "support multiple open and the special has been used, the public account will " "be used to connect" -msgstr "这些账号用于连接发布的应用,账号现在分为两种类型,一种是专用的,每个用户都有一个专用账号。 " -"另一种是公共的,当应用不支持多开且专用的已经被使用时,会使用公共账号连接" +msgstr "" +"这些账号用于连接发布的应用,账号现在分为两种类型,一种是专用的,每个用户都有" +"一个专用账号。 另一种是公共的,当应用不支持多开且专用的已经被使用时,会使用公" +"共账号连接" #: terminal/serializers/applet_host.py:77 msgid "The number of public accounts created automatically" @@ -6297,6 +6311,10 @@ msgstr "索引" msgid "Doc type" msgstr "文档类型" +#: terminal/serializers/task.py:9 +msgid "Session id" +msgstr "会话 ID" + #: terminal/serializers/terminal.py:83 terminal/serializers/terminal.py:91 msgid "Not found" msgstr "没有发现" diff --git a/apps/terminal/api/session/task.py b/apps/terminal/api/session/task.py index 8daeeb4a7..f9dc8a2f2 100644 --- a/apps/terminal/api/session/task.py +++ b/apps/terminal/api/session/task.py @@ -3,17 +3,20 @@ import logging from rest_framework import status +from rest_framework.decorators import action from rest_framework.permissions import IsAuthenticated from rest_framework.views import APIView, Response from common.api import JMSBulkModelViewSet +from common.const.http import POST from common.utils import get_object_or_none from orgs.utils import tmp_to_root_org from terminal import serializers +from terminal.const import TaskNameType from terminal.models import Session, Task from terminal.utils import is_session_approver -__all__ = ['TaskViewSet', 'KillSessionAPI', 'KillSessionForTicketAPI'] +__all__ = ['TaskViewSet', 'KillSessionAPI', 'KillSessionForTicketAPI', ] logger = logging.getLogger(__file__) @@ -21,9 +24,44 @@ class TaskViewSet(JMSBulkModelViewSet): queryset = Task.objects.all() serializer_class = serializers.TaskSerializer filterset_fields = ('is_finished',) + serializer_classes = { + 'create_toggle_task': serializers.LockTaskSessionSerializer, + 'handle_ticket_task': serializers.LockTaskSessionSerializer, + 'default': serializers.TaskSerializer + } + rbac_perms = { + "create_toggle_task": "terminal.terminate_session", + } + + @action(methods=[POST], detail=False, url_path='toggle-lock-session') + def create_toggle_task(self, request, *args, **kwargs): + serializer = self.get_serializer(data=request.data) + serializer.is_valid(raise_exception=True) + session_id = serializer.validated_data['session_id'] + task_name = serializer.validated_data['task_name'] + session_ids = [session_id, ] + validated_session = create_sessions_tasks(session_ids, request.user, task_name=task_name) + return Response({"ok": validated_session}) + + @action(methods=[POST], detail=False, permission_classes=[IsAuthenticated, ], + url_path='toggle-lock-session-for-ticket', ) + def handle_ticket_task(self, request, *args, **kwargs): + serializer = self.get_serializer(data=request.data) + serializer.is_valid(raise_exception=True) + session_id = serializer.validated_data['session_id'] + task_name = serializer.validated_data['task_name'] + session_ids = [session_id, ] + user_id = request.user.id + for session_id in session_ids: + if not is_session_approver(session_id, user_id): + return Response({}, status=status.HTTP_403_FORBIDDEN) + with tmp_to_root_org(): + validated_session = create_sessions_tasks(session_ids, request.user, task_name=task_name) + + return Response({"ok": validated_session}) -def kill_sessions(session_ids, user): +def create_sessions_tasks(session_ids, user, task_name=TaskNameType.kill_session): validated_session = [] for session_id in session_ids: @@ -31,9 +69,10 @@ def kill_sessions(session_ids, user): if session and not session.is_finished: validated_session.append(session_id) Task.objects.create( - name="kill_session", args=session.id, terminal=session.terminal, + name=task_name, args=session.id, terminal=session.terminal, kwargs={ - 'terminated_by': str(user) + 'terminated_by': str(user), + 'created_by': str(user) } ) return validated_session @@ -47,7 +86,7 @@ class KillSessionAPI(APIView): def post(self, request, *args, **kwargs): session_ids = request.data - validated_session = kill_sessions(session_ids, request.user) + validated_session = create_sessions_tasks(session_ids, request.user) return Response({"ok": validated_session}) @@ -63,6 +102,6 @@ class KillSessionForTicketAPI(APIView): return Response({}, status=status.HTTP_403_FORBIDDEN) with tmp_to_root_org(): - validated_session = kill_sessions(session_ids, request.user) + validated_session = create_sessions_tasks(session_ids, request.user) return Response({"ok": validated_session}) diff --git a/apps/terminal/const.py b/apps/terminal/const.py index 8b04c74cc..c047343a4 100644 --- a/apps/terminal/const.py +++ b/apps/terminal/const.py @@ -88,3 +88,9 @@ class SessionType(TextChoices): class ActionPermission(TextChoices): readonly = "readonly", _('Read Only') writable = "writable", _('Writable') + + +class TaskNameType(TextChoices): + kill_session = "kill_session", _('Kill Session') + lock_session = "lock_session", _('Lock Session') + unlock_session = "unlock_session", _('Unlock Session') diff --git a/apps/terminal/models/component/task.py b/apps/terminal/models/component/task.py index b1694dcb8..c69a89423 100644 --- a/apps/terminal/models/component/task.py +++ b/apps/terminal/models/component/task.py @@ -4,15 +4,13 @@ from django.db import models from django.utils.translation import gettext_lazy as _ from common.db.models import JMSBaseModel +from terminal.const import TaskNameType as SessionTaskChoices from .terminal import Terminal class Task(JMSBaseModel): - NAME_CHOICES = ( - ("kill_session", "Kill Session"), - ) - name = models.CharField(max_length=128, choices=NAME_CHOICES, verbose_name=_("Name")) + name = models.CharField(max_length=128, choices=SessionTaskChoices.choices, verbose_name=_("Name")) args = models.CharField(max_length=1024, verbose_name=_("Args")) kwargs = models.JSONField(default=dict, verbose_name=_("Kwargs")) terminal = models.ForeignKey(Terminal, null=True, on_delete=models.SET_NULL) diff --git a/apps/terminal/models/session/session.py b/apps/terminal/models/session/session.py index 02c0a0f95..09f2df9e1 100644 --- a/apps/terminal/models/session/session.py +++ b/apps/terminal/models/session/session.py @@ -48,6 +48,7 @@ class Session(OrgModelMixin): upload_to = 'replay' ACTIVE_CACHE_KEY_PREFIX = 'SESSION_ACTIVE_{}' + LOCK_CACHE_KEY_PREFIX = 'TOGGLE_LOCKED_SESSION_{}' SUFFIX_MAP = {1: '.gz', 2: '.replay.gz', 3: '.cast.gz', 4: '.replay.mp4'} DEFAULT_SUFFIXES = ['.replay.gz', '.cast.gz', '.gz', '.replay.mp4'] @@ -145,6 +146,26 @@ class Session(OrgModelMixin): else: return True + @property + def is_locked(self): + if self.is_finished: + return False + key = self.LOCK_CACHE_KEY_PREFIX.format(self.id) + return bool(cache.get(key)) + + @classmethod + def lock_session(cls, session_id): + key = cls.LOCK_CACHE_KEY_PREFIX.format(session_id) + # 会话锁定时间为 None,表示永不过期 + # You can set TIMEOUT to None so that, by default, cache keys never expire. + # https://docs.djangoproject.com/en/4.1/topics/cache/ + cache.set(key, True, timeout=None) + + @classmethod + def unlock_session(cls, session_id): + key = cls.LOCK_CACHE_KEY_PREFIX.format(session_id) + cache.delete(key) + @lazyproperty def terminal_display(self): display = self.terminal.name if self.terminal else '' diff --git a/apps/terminal/serializers/__init__.py b/apps/terminal/serializers/__init__.py index 92d535c65..dc23362f9 100644 --- a/apps/terminal/serializers/__init__.py +++ b/apps/terminal/serializers/__init__.py @@ -1,10 +1,11 @@ # -*- coding: utf-8 -*- # from .applet import * -from .command import * -from .session import * -from .storage import * -from .sharing import * -from .terminal import * -from .endpoint import * from .applet_host import * +from .command import * +from .endpoint import * +from .session import * +from .sharing import * +from .storage import * +from .task import * +from .terminal import * diff --git a/apps/terminal/serializers/session.py b/apps/terminal/serializers/session.py index 072ddbb3f..16c224950 100644 --- a/apps/terminal/serializers/session.py +++ b/apps/terminal/serializers/session.py @@ -30,7 +30,7 @@ class SessionSerializer(BulkOrgResourceModelSerializer): "user", "asset", "user_id", "asset_id", 'account', 'account_id', "protocol", 'type', "login_from", "remote_addr", "is_success", "is_finished", "has_replay", "has_command", - "date_start", "date_end", "comment", "terminal_display", + "date_start", "date_end", "comment", "terminal_display", "is_locked", 'command_amount', ] fields_fk = ["terminal", ] diff --git a/apps/terminal/serializers/task.py b/apps/terminal/serializers/task.py new file mode 100644 index 000000000..4f077dac6 --- /dev/null +++ b/apps/terminal/serializers/task.py @@ -0,0 +1,10 @@ +from django.utils.translation import gettext_lazy as _ +from rest_framework import serializers + +from terminal.const import TaskNameType as SessionTaskChoices + + +class LockTaskSessionSerializer(serializers.Serializer): + + session_id = serializers.CharField(max_length=40, label=_('Session id')) + task_name = serializers.ChoiceField(choices=SessionTaskChoices.choices, label=_('Task name')) diff --git a/apps/terminal/signal_handlers/__init__.py b/apps/terminal/signal_handlers/__init__.py index 0021ba500..bd61c885c 100644 --- a/apps/terminal/signal_handlers/__init__.py +++ b/apps/terminal/signal_handlers/__init__.py @@ -1,5 +1,5 @@ from .applet import * from .db_port import * -from .terminal import * -from .session_sharing import * from .session import * +from .session_sharing import * +from .terminal import * diff --git a/apps/terminal/signal_handlers/session.py b/apps/terminal/signal_handlers/session.py index 566173678..7aa35307d 100644 --- a/apps/terminal/signal_handlers/session.py +++ b/apps/terminal/signal_handlers/session.py @@ -1,4 +1,4 @@ -from django.db.models.signals import pre_save +from django.db.models.signals import pre_save, post_save from django.dispatch import receiver from terminal.models import Session @@ -8,3 +8,11 @@ from terminal.models import Session def on_session_pre_save(sender, instance, **kwargs): if instance.need_update_cmd_amount: instance.cmd_amount = instance.compute_command_amount() + + +@receiver(post_save, sender=Session) +def on_session_finished(sender, instance: Session, created, **kwargs): + if not instance.is_finished: + return + # 清理一次可能因 task 未执行的缓存数据 + Session.unlock_session(instance.id) diff --git a/apps/terminal/signal_handlers/terminal.py b/apps/terminal/signal_handlers/terminal.py index 9a1536e02..a227c0cf1 100644 --- a/apps/terminal/signal_handlers/terminal.py +++ b/apps/terminal/signal_handlers/terminal.py @@ -5,7 +5,8 @@ from django.utils.functional import LazyObject from common.decorators import on_transaction_commit from common.utils import get_logger from common.utils.connection import RedisPubSub -from ..models import Task +from ..const import TaskNameType +from ..models import Task, Session from ..utils import DBPortManager db_port_manager: DBPortManager @@ -24,7 +25,17 @@ component_event_chan = ComponentEventChan() @receiver(post_save, sender=Task) @on_transaction_commit def on_task_created(sender, instance: Task, created, **kwargs): - if not created: + if not created and instance.is_finished: + # 当组件完成 task 时,修改 session 的 lock 状态 + session_id = instance.args + name = instance.name + if name == TaskNameType.lock_session: + Session.lock_session(session_id) + elif name == TaskNameType.unlock_session: + Session.unlock_session(session_id) + logger.debug(f"signal task post save: {instance.name}, " + f"session: {session_id}, " + f"is_finished: {instance.is_finished}") return event = { "type": instance.name, diff --git a/apps/terminal/urls/api_urls.py b/apps/terminal/urls/api_urls.py index c13892346..3c38bb934 100644 --- a/apps/terminal/urls/api_urls.py +++ b/apps/terminal/urls/api_urls.py @@ -2,10 +2,9 @@ # -*- coding: utf-8 -*- # -from django.urls import path, re_path +from django.urls import path from rest_framework_bulk.routes import BulkRouter -from common import api as capi from .. import api app_name = 'terminal' diff --git a/apps/terminal/ws.py b/apps/terminal/ws.py index c414ecfcf..70dd7b6f3 100644 --- a/apps/terminal/ws.py +++ b/apps/terminal/ws.py @@ -7,8 +7,8 @@ from rest_framework.renderers import JSONRenderer from common.db.utils import safe_db_connection from common.utils import get_logger from common.utils.connection import Subscription -from terminal.models import Terminal -from terminal.models import Session +from terminal.const import TaskNameType +from terminal.models import Session, Terminal from terminal.serializers import TaskSerializer, StatSerializer from .signal_handlers import component_event_chan @@ -45,7 +45,7 @@ class TerminalTaskWebsocket(JsonWebsocketConsumer): with safe_db_connection(): serializer.save() - def send_kill_tasks_msg(self, task_id=None): + def send_tasks_msg(self, task_id=None): content = self.get_terminal_tasks(task_id) self.send(bytes_data=content) @@ -60,7 +60,7 @@ class TerminalTaskWebsocket(JsonWebsocketConsumer): def watch_component_event(self): # 先发一次已有的任务 - self.send_kill_tasks_msg() + self.send_tasks_msg() ws = self @@ -68,8 +68,8 @@ class TerminalTaskWebsocket(JsonWebsocketConsumer): logger.debug('New component task msg recv: {}'.format(msg)) msg_type = msg.get('type') payload = msg.get('payload') - if msg_type == "kill_session": - ws.send_kill_tasks_msg(payload.get('id')) + if msg_type in TaskNameType.names: + ws.send_tasks_msg(payload.get('id')) return component_event_chan.subscribe(handle_task_msg_recv) From 8ed823d587375125306fbc8c353da5c8c55169fc Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Tue, 1 Aug 2023 17:42:16 +0800 Subject: [PATCH 075/177] =?UTF-8?q?feat:=20=E6=89=B9=E9=87=8F=E4=B8=8D?= =?UTF-8?q?=E6=98=AF=E5=8F=91=E5=B8=83=E6=9C=BA=20(#11150)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: feng <1304903146@qq.com> --- apps/terminal/api/applet/host.py | 28 +++++++++++++++--------- apps/terminal/serializers/applet_host.py | 9 +------- apps/terminal/tasks.py | 9 ++++---- 3 files changed, 24 insertions(+), 22 deletions(-) diff --git a/apps/terminal/api/applet/host.py b/apps/terminal/api/applet/host.py index cc40936e5..f0dce9785 100644 --- a/apps/terminal/api/applet/host.py +++ b/apps/terminal/api/applet/host.py @@ -1,3 +1,4 @@ +from rest_framework import status from rest_framework import viewsets from rest_framework.decorators import action from rest_framework.response import Response @@ -7,8 +8,7 @@ from common.permissions import IsServiceAccount from orgs.utils import tmp_to_builtin_org from terminal.models import AppletHost, AppletHostDeployment from terminal.serializers import ( - AppletHostSerializer, AppletHostDeploymentSerializer, - AppletHostStartupSerializer, AppletHostDeployAppletSerializer + AppletHostSerializer, AppletHostDeploymentSerializer, AppletHostStartupSerializer ) from terminal.tasks import run_applet_host_deployment, run_applet_host_deployment_install_applet @@ -63,12 +63,20 @@ class AppletHostDeploymentViewSet(viewsets.ModelViewSet): instance.save_task(task.id) return Response({'task': str(task.id)}, status=201) - @action(methods=['post'], detail=False, serializer_class=AppletHostDeployAppletSerializer) + @action(methods=['post'], detail=False) def applets(self, request, *args, **kwargs): - serializer = self.get_serializer(data=request.data) - serializer.is_valid(raise_exception=True) - applet_id = serializer.validated_data.pop('applet_id', '') - instance = serializer.save() - task = run_applet_host_deployment_install_applet.delay(instance.id, applet_id) - instance.save_task(task.id) - return Response({'task': str(task.id)}, status=201) + hosts = request.data.get('hosts', []) + applet_id = request.data.get('applet_id', '') + model = self.get_queryset().model + hosts_qs = AppletHost.objects.filter(id__in=hosts) + if not hosts_qs.exists(): + return Response(status=status.HTTP_404_NOT_FOUND) + + objs = [model(host=host) for host in hosts_qs] + applet_host_deployments = model.objects.bulk_create(objs) + applet_host_deployment_ids = [str(obj.id) for obj in applet_host_deployments] + + task = run_applet_host_deployment_install_applet.delay(applet_host_deployment_ids, applet_id) + task_id = str(task.id) + model.objects.filter(id__in=applet_host_deployment_ids).update(task=task_id) + return Response({'task': task_id}, status=201) diff --git a/apps/terminal/serializers/applet_host.py b/apps/terminal/serializers/applet_host.py index 1c65315b7..221c093d2 100644 --- a/apps/terminal/serializers/applet_host.py +++ b/apps/terminal/serializers/applet_host.py @@ -15,7 +15,7 @@ from ..models import AppletHost, AppletHostDeployment __all__ = [ 'AppletHostSerializer', 'AppletHostDeploymentSerializer', 'AppletHostAccountSerializer', 'AppletHostAppletReportSerializer', - 'AppletHostStartupSerializer', 'AppletHostDeployAppletSerializer' + 'AppletHostStartupSerializer' ] @@ -124,13 +124,6 @@ class AppletHostDeploymentSerializer(serializers.ModelSerializer): fields = fields_mini + ['comment'] + read_only_fields -class AppletHostDeployAppletSerializer(AppletHostDeploymentSerializer): - applet_id = serializers.UUIDField(write_only=True, allow_null=True, required=False) - - class Meta(AppletHostDeploymentSerializer.Meta): - fields = AppletHostDeploymentSerializer.Meta.fields + ['applet_id'] - - class AppletHostAccountSerializer(serializers.ModelSerializer): class Meta: model = Account diff --git a/apps/terminal/tasks.py b/apps/terminal/tasks.py index 380bd94f6..65fae3ded 100644 --- a/apps/terminal/tasks.py +++ b/apps/terminal/tasks.py @@ -98,12 +98,13 @@ def run_applet_host_deployment(did): @shared_task( verbose_name=_('Install applet'), - activity_callback=lambda self, did, applet_id, *args, **kwargs: ([did],) + activity_callback=lambda self, ids, applet_id, *args, **kwargs: (ids,) ) -def run_applet_host_deployment_install_applet(did, applet_id): +def run_applet_host_deployment_install_applet(ids, applet_id): with tmp_to_builtin_org(system=1): - deployment = AppletHostDeployment.objects.get(id=did) - deployment.install_applet(applet_id) + for did in ids: + deployment = AppletHostDeployment.objects.get(id=did) + deployment.install_applet(applet_id) @shared_task( From d182d14e26c2ac0760df1b27cc028be0f4e658a0 Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Tue, 1 Aug 2023 18:17:02 +0800 Subject: [PATCH 076/177] =?UTF-8?q?perf:=20=E8=B4=A6=E5=8F=B7=E5=A4=87?= =?UTF-8?q?=E4=BB=BD=E6=97=A5=E5=BF=97=E4=BC=98=E5=8C=96=20(#11151)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: feng <1304903146@qq.com> --- .../automations/backup_account/handlers.py | 51 +++++++++---------- .../automations/backup_account/manager.py | 12 ++--- 2 files changed, 27 insertions(+), 36 deletions(-) diff --git a/apps/accounts/automations/backup_account/handlers.py b/apps/accounts/automations/backup_account/handlers.py index 65c96c67d..7b087b101 100644 --- a/apps/accounts/automations/backup_account/handlers.py +++ b/apps/accounts/automations/backup_account/handlers.py @@ -1,22 +1,17 @@ import os import time -from openpyxl import Workbook from collections import defaultdict, OrderedDict from django.conf import settings -from django.db.models import F +from openpyxl import Workbook from rest_framework import serializers -from accounts.models import Account -from assets.const import AllTypes -from accounts.serializers import AccountSecretSerializer from accounts.notifications import AccountBackupExecutionTaskMsg -from users.models import User -from common.utils import get_logger -from common.utils.timezone import local_now_display +from accounts.serializers import AccountSecretSerializer +from assets.const import AllTypes from common.utils.file import encrypt_and_compress_zip_file - -logger = get_logger(__file__) +from common.utils.timezone import local_now_display +from users.models import User PATH = os.path.join(os.path.dirname(settings.BASE_DIR), 'tmp') @@ -99,7 +94,7 @@ class AssetAccountHandler(BaseAccountHandler): data = AccountSecretSerializer(_accounts, many=True).data data_map.update(cls.add_rows(data, header_fields, sheet_name)) - logger.info('\n\033[33m- 共备份 {} 条账号\033[0m'.format(accounts.count())) + print('\n\033[33m- 共备份 {} 条账号\033[0m'.format(accounts.count())) return data_map @@ -110,7 +105,7 @@ class AccountBackupHandler: self.is_frozen = False # 任务状态冻结标志 def create_excel(self): - logger.info( + print( '\n' '\033[32m>>> 正在生成资产或应用相关备份信息文件\033[0m' '' @@ -133,14 +128,14 @@ class AccountBackupHandler: wb.save(filename) files.append(filename) timedelta = round((time.time() - time_start), 2) - logger.info('步骤完成: 用时 {}s'.format(timedelta)) + print('步骤完成: 用时 {}s'.format(timedelta)) return files def send_backup_mail(self, files, recipients): if not files: return recipients = User.objects.filter(id__in=list(recipients)) - logger.info( + print( '\n' '\033[32m>>> 发送备份邮件\033[0m' '' @@ -155,7 +150,7 @@ class AccountBackupHandler: encrypt_and_compress_zip_file(attachment, password, files) attachment_list = [attachment, ] AccountBackupExecutionTaskMsg(plan_name, user).publish(attachment_list) - logger.info('邮件已发送至{}({})'.format(user, user.email)) + print('邮件已发送至{}({})'.format(user, user.email)) for file in files: os.remove(file) @@ -163,13 +158,13 @@ class AccountBackupHandler: self.execution.reason = reason[:1024] self.execution.is_success = is_success self.execution.save() - logger.info('已完成对任务状态的更新') + print('已完成对任务状态的更新') def step_finished(self, is_success): if is_success: - logger.info('任务执行成功') + print('任务执行成功') else: - logger.error('任务执行失败') + print('任务执行失败') def _run(self): is_success = False @@ -177,7 +172,7 @@ class AccountBackupHandler: try: recipients = self.execution.plan_snapshot.get('recipients') if not recipients: - logger.info( + print( '\n' '\033[32m>>> 该备份任务未分配收件人\033[0m' '' @@ -187,9 +182,9 @@ class AccountBackupHandler: self.send_backup_mail(files, recipients) except Exception as e: self.is_frozen = True - logger.error('任务执行被异常中断') - logger.info('下面打印发生异常的 Traceback 信息 : ') - logger.error(e, exc_info=True) + print('任务执行被异常中断') + print('下面打印发生异常的 Traceback 信息 : ') + print(e) error = str(e) else: is_success = True @@ -199,15 +194,15 @@ class AccountBackupHandler: self.step_finished(is_success) def run(self): - logger.info('任务开始: {}'.format(local_now_display())) + print('任务开始: {}'.format(local_now_display())) time_start = time.time() try: self._run() except Exception as e: - logger.error('任务运行出现异常') - logger.error('下面显示异常 Traceback 信息: ') - logger.error(e, exc_info=True) + print('任务运行出现异常') + print('下面显示异常 Traceback 信息: ') + print(e) finally: - logger.info('\n任务结束: {}'.format(local_now_display())) + print('\n任务结束: {}'.format(local_now_display())) timedelta = round((time.time() - time_start), 2) - logger.info('用时: {}'.format(timedelta)) + print('用时: {}'.format(timedelta)) diff --git a/apps/accounts/automations/backup_account/manager.py b/apps/accounts/automations/backup_account/manager.py index 311361c69..f523803d5 100644 --- a/apps/accounts/automations/backup_account/manager.py +++ b/apps/accounts/automations/backup_account/manager.py @@ -4,13 +4,9 @@ import time from django.utils import timezone -from common.utils import get_logger from common.utils.timezone import local_now_display - from .handlers import AccountBackupHandler -logger = get_logger(__name__) - class AccountBackupManager: def __init__(self, execution): @@ -23,7 +19,7 @@ class AccountBackupManager: def do_run(self): execution = self.execution - logger.info('\n\033[33m# 账号备份计划正在执行\033[0m') + print('\n\033[33m# 账号备份计划正在执行\033[0m') handler = AccountBackupHandler(execution) handler.run() @@ -35,10 +31,10 @@ class AccountBackupManager: self.time_end = time.time() self.date_end = timezone.now() - logger.info('\n\n' + '-' * 80) - logger.info('计划执行结束 {}\n'.format(local_now_display())) + print('\n\n' + '-' * 80) + print('计划执行结束 {}\n'.format(local_now_display())) self.timedelta = self.time_end - self.time_start - logger.info('用时: {}s'.format(self.timedelta)) + print('用时: {}s'.format(self.timedelta)) self.execution.timedelta = self.timedelta self.execution.save() From 93ba4443ddf96e0a9714f4704a7079c594903e66 Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Tue, 1 Aug 2023 19:48:32 +0800 Subject: [PATCH 077/177] =?UTF-8?q?perf:=20windows=20ssh=20=E5=8D=8F?= =?UTF-8?q?=E8=AE=AE=20=E9=BB=98=E8=AE=A4=E5=BC=80=E5=90=AF=20(#11158)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: feng <1304903146@qq.com> --- .../migrations/0122_auto_20230801_1940.py | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 apps/assets/migrations/0122_auto_20230801_1940.py diff --git a/apps/assets/migrations/0122_auto_20230801_1940.py b/apps/assets/migrations/0122_auto_20230801_1940.py new file mode 100644 index 000000000..3197ffec3 --- /dev/null +++ b/apps/assets/migrations/0122_auto_20230801_1940.py @@ -0,0 +1,24 @@ +# Generated by Django 4.1.10 on 2023-08-01 11:40 + +from django.db import migrations + + +def windows_platform_protocols_ssh_default(apps, schema_editor): + platform_cls = apps.get_model('assets', 'Platform') + windows_platform = platform_cls.objects.filter( + name='Windows', internal=True, type='windows' + ).first() + if not windows_platform: + return + + windows_platform.protocols.filter(name='ssh').update(default=True) + + +class Migration(migrations.Migration): + dependencies = [ + ('assets', '0121_auto_20230725_1458'), + ] + + operations = [ + migrations.RunPython(windows_platform_protocols_ssh_default) + ] From d486dfc7f79fab755409b1e7cc6636ab36f53145 Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Wed, 2 Aug 2023 13:11:46 +0800 Subject: [PATCH 078/177] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E5=9B=A0vault?= =?UTF-8?q?=20=E6=94=B9=E5=AF=86500=20=E9=97=AE=E9=A2=98=20(#11168)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: feng <1304903146@qq.com> --- apps/accounts/models/account.py | 3 --- apps/accounts/models/mixins/vault.py | 4 ++++ 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/apps/accounts/models/account.py b/apps/accounts/models/account.py index c6da60d48..0f4077536 100644 --- a/apps/accounts/models/account.py +++ b/apps/accounts/models/account.py @@ -155,9 +155,6 @@ class AccountTemplate(BaseAccount): ).first() return account - def __str__(self): - return self.username - @staticmethod def bulk_update_accounts(accounts, data): history_model = Account.history.model diff --git a/apps/accounts/models/mixins/vault.py b/apps/accounts/models/mixins/vault.py index a551f20aa..e517516a9 100644 --- a/apps/accounts/models/mixins/vault.py +++ b/apps/accounts/models/mixins/vault.py @@ -85,4 +85,8 @@ class VaultModelMixin(models.Model): def save(self, *args, **kwargs): """ 通过 post_save signal 处理 _secret 数据 """ + update_fields = kwargs.get('update_fields') + if update_fields and 'secret' in update_fields: + update_fields.remove('secret') + update_fields.append('_secret') return super().save(*args, **kwargs) From 99ae0066ae55074f380570e6773b924857a353c3 Mon Sep 17 00:00:00 2001 From: ibuler Date: Wed, 2 Aug 2023 11:34:17 +0800 Subject: [PATCH 079/177] =?UTF-8?q?perf:=20=E4=BD=BF=E7=94=A8=20poetry=20?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E4=BE=9D=E8=B5=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 6 +- Dockerfile-ee | 2 +- poetry.lock | 6037 +++++++++++++++++++++++++++ pyproject.toml | 171 + requirements/mac_pkg.sh | 2 +- requirements/requirements.txt | 1 + requirements/requirements_xpack.txt | 1 - 7 files changed, 6215 insertions(+), 5 deletions(-) create mode 100644 poetry.lock create mode 100644 pyproject.toml diff --git a/Dockerfile b/Dockerfile index 628e3266f..75db8b6a2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -81,14 +81,16 @@ RUN set -ex \ fi WORKDIR /tmp/build -COPY ./requirements ./requirements +COPY ./pyproject.toml ./pyproject.toml +COPY ./poetry.lock ./poetry.lock ARG PIP_MIRROR=https://pypi.douban.com/simple RUN --mount=type=cache,target=/root/.cache/pip \ set -ex \ && pip config set global.index-url ${PIP_MIRROR} \ - && pip install -r requirements/requirements.txt + && pip install poetry==1.5.1 \ + && poetry install --only=main COPY --from=stage-build /opt/jumpserver/release/jumpserver /opt/jumpserver RUN echo > /opt/jumpserver/config.yml \ diff --git a/Dockerfile-ee b/Dockerfile-ee index 63c65d21c..946615d34 100644 --- a/Dockerfile-ee +++ b/Dockerfile-ee @@ -7,4 +7,4 @@ WORKDIR /opt/jumpserver RUN --mount=type=cache,target=/root/.cache/pip \ set -ex \ - && pip install -r requirements/requirements_xpack.txt + && poetry install --only=xpack diff --git a/poetry.lock b/poetry.lock new file mode 100644 index 000000000..73b9958d4 --- /dev/null +++ b/poetry.lock @@ -0,0 +1,6037 @@ +# This file is automatically @generated by Poetry 1.5.1 and should not be changed by hand. + +[[package]] +name = "adal" +version = "1.2.7" +description = "Note: This library is already replaced by MSAL Python, available here: https://pypi.org/project/msal/ .ADAL Python remains available here as a legacy. The ADAL for Python library makes it easy for python application to authenticate to Azure Active Directory (AAD) in order to access AAD protected web resources." +optional = false +python-versions = "*" +files = [ + {file = "adal-1.2.7-py2.py3-none-any.whl", hash = "sha256:2a7451ed7441ddbc57703042204a3e30ef747478eea022c70f789fc7f084bc3d"}, + {file = "adal-1.2.7.tar.gz", hash = "sha256:d74f45b81317454d96e982fd1c50e6fb5c99ac2223728aea8764433a39f566f1"}, +] + +[package.dependencies] +cryptography = ">=1.1.0" +PyJWT = ">=1.0.0,<3" +python-dateutil = ">=2.1.0,<3" +requests = ">=2.0.0,<3" + +[[package]] +name = "aiofiles" +version = "23.1.0" +description = "File support for asyncio." +optional = false +python-versions = ">=3.7,<4.0" +files = [ + {file = "aiofiles-23.1.0-py3-none-any.whl", hash = "sha256:9312414ae06472eb6f1d163f555e466a23aed1c8f60c30cccf7121dba2e53eb2"}, + {file = "aiofiles-23.1.0.tar.gz", hash = "sha256:edd247df9a19e0db16534d4baaf536d6609a43e1de5401d7a4c1c148753a1635"}, +] + +[[package]] +name = "aiohttp" +version = "3.8.5" +description = "Async http client/server framework (asyncio)" +optional = false +python-versions = ">=3.6" +files = [ + {file = "aiohttp-3.8.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a94159871304770da4dd371f4291b20cac04e8c94f11bdea1c3478e557fbe0d8"}, + {file = "aiohttp-3.8.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:13bf85afc99ce6f9ee3567b04501f18f9f8dbbb2ea11ed1a2e079670403a7c84"}, + {file = "aiohttp-3.8.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2ce2ac5708501afc4847221a521f7e4b245abf5178cf5ddae9d5b3856ddb2f3a"}, + {file = "aiohttp-3.8.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:96943e5dcc37a6529d18766597c491798b7eb7a61d48878611298afc1fca946c"}, + {file = "aiohttp-3.8.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2ad5c3c4590bb3cc28b4382f031f3783f25ec223557124c68754a2231d989e2b"}, + {file = "aiohttp-3.8.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0c413c633d0512df4dc7fd2373ec06cc6a815b7b6d6c2f208ada7e9e93a5061d"}, + {file = "aiohttp-3.8.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:df72ac063b97837a80d80dec8d54c241af059cc9bb42c4de68bd5b61ceb37caa"}, + {file = "aiohttp-3.8.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c48c5c0271149cfe467c0ff8eb941279fd6e3f65c9a388c984e0e6cf57538e14"}, + {file = "aiohttp-3.8.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:368a42363c4d70ab52c2c6420a57f190ed3dfaca6a1b19afda8165ee16416a82"}, + {file = "aiohttp-3.8.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:7607ec3ce4993464368505888af5beb446845a014bc676d349efec0e05085905"}, + {file = "aiohttp-3.8.5-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:0d21c684808288a98914e5aaf2a7c6a3179d4df11d249799c32d1808e79503b5"}, + {file = "aiohttp-3.8.5-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:312fcfbacc7880a8da0ae8b6abc6cc7d752e9caa0051a53d217a650b25e9a691"}, + {file = "aiohttp-3.8.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ad093e823df03bb3fd37e7dec9d4670c34f9e24aeace76808fc20a507cace825"}, + {file = "aiohttp-3.8.5-cp310-cp310-win32.whl", hash = "sha256:33279701c04351a2914e1100b62b2a7fdb9a25995c4a104259f9a5ead7ed4802"}, + {file = "aiohttp-3.8.5-cp310-cp310-win_amd64.whl", hash = "sha256:6e4a280e4b975a2e7745573e3fc9c9ba0d1194a3738ce1cbaa80626cc9b4f4df"}, + {file = "aiohttp-3.8.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ae871a964e1987a943d83d6709d20ec6103ca1eaf52f7e0d36ee1b5bebb8b9b9"}, + {file = "aiohttp-3.8.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:461908b2578955045efde733719d62f2b649c404189a09a632d245b445c9c975"}, + {file = "aiohttp-3.8.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:72a860c215e26192379f57cae5ab12b168b75db8271f111019509a1196dfc780"}, + {file = "aiohttp-3.8.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cc14be025665dba6202b6a71cfcdb53210cc498e50068bc088076624471f8bb9"}, + {file = "aiohttp-3.8.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8af740fc2711ad85f1a5c034a435782fbd5b5f8314c9a3ef071424a8158d7f6b"}, + {file = "aiohttp-3.8.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:841cd8233cbd2111a0ef0a522ce016357c5e3aff8a8ce92bcfa14cef890d698f"}, + {file = "aiohttp-3.8.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ed1c46fb119f1b59304b5ec89f834f07124cd23ae5b74288e364477641060ff"}, + {file = "aiohttp-3.8.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:84f8ae3e09a34f35c18fa57f015cc394bd1389bce02503fb30c394d04ee6b938"}, + {file = "aiohttp-3.8.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:62360cb771707cb70a6fd114b9871d20d7dd2163a0feafe43fd115cfe4fe845e"}, + {file = "aiohttp-3.8.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:23fb25a9f0a1ca1f24c0a371523546366bb642397c94ab45ad3aedf2941cec6a"}, + {file = "aiohttp-3.8.5-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:b0ba0d15164eae3d878260d4c4df859bbdc6466e9e6689c344a13334f988bb53"}, + {file = "aiohttp-3.8.5-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:5d20003b635fc6ae3f96d7260281dfaf1894fc3aa24d1888a9b2628e97c241e5"}, + {file = "aiohttp-3.8.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0175d745d9e85c40dcc51c8f88c74bfbaef9e7afeeeb9d03c37977270303064c"}, + {file = "aiohttp-3.8.5-cp311-cp311-win32.whl", hash = "sha256:2e1b1e51b0774408f091d268648e3d57f7260c1682e7d3a63cb00d22d71bb945"}, + {file = "aiohttp-3.8.5-cp311-cp311-win_amd64.whl", hash = "sha256:043d2299f6dfdc92f0ac5e995dfc56668e1587cea7f9aa9d8a78a1b6554e5755"}, + {file = "aiohttp-3.8.5-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:cae533195e8122584ec87531d6df000ad07737eaa3c81209e85c928854d2195c"}, + {file = "aiohttp-3.8.5-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4f21e83f355643c345177a5d1d8079f9f28b5133bcd154193b799d380331d5d3"}, + {file = "aiohttp-3.8.5-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a7a75ef35f2df54ad55dbf4b73fe1da96f370e51b10c91f08b19603c64004acc"}, + {file = "aiohttp-3.8.5-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2e2e9839e14dd5308ee773c97115f1e0a1cb1d75cbeeee9f33824fa5144c7634"}, + {file = "aiohttp-3.8.5-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c44e65da1de4403d0576473e2344828ef9c4c6244d65cf4b75549bb46d40b8dd"}, + {file = "aiohttp-3.8.5-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:78d847e4cde6ecc19125ccbc9bfac4a7ab37c234dd88fbb3c5c524e8e14da543"}, + {file = "aiohttp-3.8.5-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:c7a815258e5895d8900aec4454f38dca9aed71085f227537208057853f9d13f2"}, + {file = "aiohttp-3.8.5-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:8b929b9bd7cd7c3939f8bcfffa92fae7480bd1aa425279d51a89327d600c704d"}, + {file = "aiohttp-3.8.5-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:5db3a5b833764280ed7618393832e0853e40f3d3e9aa128ac0ba0f8278d08649"}, + {file = "aiohttp-3.8.5-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:a0215ce6041d501f3155dc219712bc41252d0ab76474615b9700d63d4d9292af"}, + {file = "aiohttp-3.8.5-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:fd1ed388ea7fbed22c4968dd64bab0198de60750a25fe8c0c9d4bef5abe13824"}, + {file = "aiohttp-3.8.5-cp36-cp36m-win32.whl", hash = "sha256:6e6783bcc45f397fdebc118d772103d751b54cddf5b60fbcc958382d7dd64f3e"}, + {file = "aiohttp-3.8.5-cp36-cp36m-win_amd64.whl", hash = "sha256:b5411d82cddd212644cf9360879eb5080f0d5f7d809d03262c50dad02f01421a"}, + {file = "aiohttp-3.8.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:01d4c0c874aa4ddfb8098e85d10b5e875a70adc63db91f1ae65a4b04d3344cda"}, + {file = "aiohttp-3.8.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e5980a746d547a6ba173fd5ee85ce9077e72d118758db05d229044b469d9029a"}, + {file = "aiohttp-3.8.5-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2a482e6da906d5e6e653be079b29bc173a48e381600161c9932d89dfae5942ef"}, + {file = "aiohttp-3.8.5-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80bd372b8d0715c66c974cf57fe363621a02f359f1ec81cba97366948c7fc873"}, + {file = "aiohttp-3.8.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c1161b345c0a444ebcf46bf0a740ba5dcf50612fd3d0528883fdc0eff578006a"}, + {file = "aiohttp-3.8.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cd56db019015b6acfaaf92e1ac40eb8434847d9bf88b4be4efe5bfd260aee692"}, + {file = "aiohttp-3.8.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:153c2549f6c004d2754cc60603d4668899c9895b8a89397444a9c4efa282aaf4"}, + {file = "aiohttp-3.8.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:4a01951fabc4ce26ab791da5f3f24dca6d9a6f24121746eb19756416ff2d881b"}, + {file = "aiohttp-3.8.5-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bfb9162dcf01f615462b995a516ba03e769de0789de1cadc0f916265c257e5d8"}, + {file = "aiohttp-3.8.5-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:7dde0009408969a43b04c16cbbe252c4f5ef4574ac226bc8815cd7342d2028b6"}, + {file = "aiohttp-3.8.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:4149d34c32f9638f38f544b3977a4c24052042affa895352d3636fa8bffd030a"}, + {file = "aiohttp-3.8.5-cp37-cp37m-win32.whl", hash = "sha256:68c5a82c8779bdfc6367c967a4a1b2aa52cd3595388bf5961a62158ee8a59e22"}, + {file = "aiohttp-3.8.5-cp37-cp37m-win_amd64.whl", hash = "sha256:2cf57fb50be5f52bda004b8893e63b48530ed9f0d6c96c84620dc92fe3cd9b9d"}, + {file = "aiohttp-3.8.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:eca4bf3734c541dc4f374ad6010a68ff6c6748f00451707f39857f429ca36ced"}, + {file = "aiohttp-3.8.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1274477e4c71ce8cfe6c1ec2f806d57c015ebf84d83373676036e256bc55d690"}, + {file = "aiohttp-3.8.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:28c543e54710d6158fc6f439296c7865b29e0b616629767e685a7185fab4a6b9"}, + {file = "aiohttp-3.8.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:910bec0c49637d213f5d9877105d26e0c4a4de2f8b1b29405ff37e9fc0ad52b8"}, + {file = "aiohttp-3.8.5-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5443910d662db951b2e58eb70b0fbe6b6e2ae613477129a5805d0b66c54b6cb7"}, + {file = "aiohttp-3.8.5-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2e460be6978fc24e3df83193dc0cc4de46c9909ed92dd47d349a452ef49325b7"}, + {file = "aiohttp-3.8.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fb1558def481d84f03b45888473fc5a1f35747b5f334ef4e7a571bc0dfcb11f8"}, + {file = "aiohttp-3.8.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:34dd0c107799dcbbf7d48b53be761a013c0adf5571bf50c4ecad5643fe9cfcd0"}, + {file = "aiohttp-3.8.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:aa1990247f02a54185dc0dff92a6904521172a22664c863a03ff64c42f9b5410"}, + {file = "aiohttp-3.8.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:0e584a10f204a617d71d359fe383406305a4b595b333721fa50b867b4a0a1548"}, + {file = "aiohttp-3.8.5-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:a3cf433f127efa43fee6b90ea4c6edf6c4a17109d1d037d1a52abec84d8f2e42"}, + {file = "aiohttp-3.8.5-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:c11f5b099adafb18e65c2c997d57108b5bbeaa9eeee64a84302c0978b1ec948b"}, + {file = "aiohttp-3.8.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:84de26ddf621d7ac4c975dbea4c945860e08cccde492269db4e1538a6a6f3c35"}, + {file = "aiohttp-3.8.5-cp38-cp38-win32.whl", hash = "sha256:ab88bafedc57dd0aab55fa728ea10c1911f7e4d8b43e1d838a1739f33712921c"}, + {file = "aiohttp-3.8.5-cp38-cp38-win_amd64.whl", hash = "sha256:5798a9aad1879f626589f3df0f8b79b3608a92e9beab10e5fda02c8a2c60db2e"}, + {file = "aiohttp-3.8.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:a6ce61195c6a19c785df04e71a4537e29eaa2c50fe745b732aa937c0c77169f3"}, + {file = "aiohttp-3.8.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:773dd01706d4db536335fcfae6ea2440a70ceb03dd3e7378f3e815b03c97ab51"}, + {file = "aiohttp-3.8.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f83a552443a526ea38d064588613aca983d0ee0038801bc93c0c916428310c28"}, + {file = "aiohttp-3.8.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f7372f7341fcc16f57b2caded43e81ddd18df53320b6f9f042acad41f8e049a"}, + {file = "aiohttp-3.8.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ea353162f249c8097ea63c2169dd1aa55de1e8fecbe63412a9bc50816e87b761"}, + {file = "aiohttp-3.8.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e5d47ae48db0b2dcf70bc8a3bc72b3de86e2a590fc299fdbbb15af320d2659de"}, + {file = "aiohttp-3.8.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d827176898a2b0b09694fbd1088c7a31836d1a505c243811c87ae53a3f6273c1"}, + {file = "aiohttp-3.8.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3562b06567c06439d8b447037bb655ef69786c590b1de86c7ab81efe1c9c15d8"}, + {file = "aiohttp-3.8.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:4e874cbf8caf8959d2adf572a78bba17cb0e9d7e51bb83d86a3697b686a0ab4d"}, + {file = "aiohttp-3.8.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6809a00deaf3810e38c628e9a33271892f815b853605a936e2e9e5129762356c"}, + {file = "aiohttp-3.8.5-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:33776e945d89b29251b33a7e7d006ce86447b2cfd66db5e5ded4e5cd0340585c"}, + {file = "aiohttp-3.8.5-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:eaeed7abfb5d64c539e2db173f63631455f1196c37d9d8d873fc316470dfbacd"}, + {file = "aiohttp-3.8.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:e91d635961bec2d8f19dfeb41a539eb94bd073f075ca6dae6c8dc0ee89ad6f91"}, + {file = "aiohttp-3.8.5-cp39-cp39-win32.whl", hash = "sha256:00ad4b6f185ec67f3e6562e8a1d2b69660be43070bd0ef6fcec5211154c7df67"}, + {file = "aiohttp-3.8.5-cp39-cp39-win_amd64.whl", hash = "sha256:c0a9034379a37ae42dea7ac1e048352d96286626251862e448933c0f59cbd79c"}, + {file = "aiohttp-3.8.5.tar.gz", hash = "sha256:b9552ec52cc147dbf1944ac7ac98af7602e51ea2dcd076ed194ca3c0d1c7d0bc"}, +] + +[package.dependencies] +aiosignal = ">=1.1.2" +async-timeout = ">=4.0.0a3,<5.0" +attrs = ">=17.3.0" +charset-normalizer = ">=2.0,<4.0" +frozenlist = ">=1.1.1" +multidict = ">=4.5,<7.0" +yarl = ">=1.0,<2.0" + +[package.extras] +speedups = ["Brotli", "aiodns", "cchardet"] + +[[package]] +name = "aiosignal" +version = "1.3.1" +description = "aiosignal: a list of registered asynchronous callbacks" +optional = false +python-versions = ">=3.7" +files = [ + {file = "aiosignal-1.3.1-py3-none-any.whl", hash = "sha256:f8376fb07dd1e86a584e4fcdec80b36b7f81aac666ebc724e2c090300dd83b17"}, + {file = "aiosignal-1.3.1.tar.gz", hash = "sha256:54cd96e15e1649b75d6c87526a6ff0b6c1b0dd3459f43d9ca11d48c339b68cfc"}, +] + +[package.dependencies] +frozenlist = ">=1.1.0" + +[[package]] +name = "alibabacloud-credentials" +version = "0.3.2" +description = "The alibabacloud credentials module of alibabaCloud Python SDK." +optional = false +python-versions = ">=3.6" +files = [ + {file = "alibabacloud_credentials-0.3.2.tar.gz", hash = "sha256:65f0e1d5fed1b0751dc56b9dc565144e528803185193e4771a21ef9d9d138d59"}, +] + +[package.dependencies] +alibabacloud-tea = "*" + +[[package]] +name = "alibabacloud-dysmsapi20170525" +version = "2.0.24" +description = "Alibaba Cloud Dysmsapi (20170525) SDK Library for Python" +optional = false +python-versions = ">=3.6" +files = [ + {file = "alibabacloud_dysmsapi20170525-2.0.24-py3-none-any.whl", hash = "sha256:f65cad7e506a4408d51fe1dcfcc09cefb5b2a6dbcedaa3fd7a4d87ab72696bad"}, + {file = "alibabacloud_dysmsapi20170525-2.0.24.tar.gz", hash = "sha256:6223dfb9254669c761e573339cd01df80a9c6ca5b717291fc01e4a151a347570"}, +] + +[package.dependencies] +alibabacloud-endpoint-util = ">=0.0.3,<1.0.0" +alibabacloud-openapi-util = ">=0.2.1,<1.0.0" +alibabacloud-tea-openapi = ">=0.3.6,<1.0.0" +alibabacloud-tea-util = ">=0.3.9,<1.0.0" + +[[package]] +name = "alibabacloud-endpoint-util" +version = "0.0.3" +description = "The endpoint-util module of alibabaCloud Python SDK." +optional = false +python-versions = "*" +files = [ + {file = "alibabacloud_endpoint_util-0.0.3.tar.gz", hash = "sha256:8c0efb76fdcc3af4ca716ef24bbce770201a3f83f98c0afcf81655f684b9c7d2"}, +] + +[package.dependencies] +alibabacloud-tea = ">=0.0.1" + +[[package]] +name = "alibabacloud-gateway-spi" +version = "0.0.1" +description = "Alibaba Cloud Gateway SPI SDK Library for Python" +optional = false +python-versions = ">=3.6" +files = [ + {file = "alibabacloud_gateway_spi-0.0.1.tar.gz", hash = "sha256:1b259855708afc3c04d8711d8530c63f7645e1edc0cf97e2fd15461b08e11c30"}, +] + +[package.dependencies] +alibabacloud_credentials = ">=0.2.0,<1.0.0" + +[[package]] +name = "alibabacloud-openapi-util" +version = "0.2.1" +description = "Aliyun Tea OpenApi Library for Python" +optional = false +python-versions = "*" +files = [ + {file = "alibabacloud_openapi_util-0.2.1.tar.gz", hash = "sha256:5de2158a6e894b3364d9627090afdb6de4f6b92d1adf3a00e2c69206df30de15"}, +] + +[package.dependencies] +alibabacloud_tea_util = ">=0.0.2" +cryptography = ">=3.0.0" + +[[package]] +name = "alibabacloud-tea" +version = "0.3.3" +description = "The tea module of alibabaCloud Python SDK." +optional = false +python-versions = ">=3.6" +files = [ + {file = "alibabacloud-tea-0.3.3.tar.gz", hash = "sha256:90f1b3310552f7cb004f713e2b55d129acd4a885bd79342df6d621422de23775"}, +] + +[package.dependencies] +aiohttp = ">=3.7.0,<4.0.0" +requests = ">=2.21.0,<3.0.0" +urllib3 = "<2.0.0" + +[[package]] +name = "alibabacloud-tea-openapi" +version = "0.3.7" +description = "Alibaba Cloud openapi SDK Library for Python" +optional = false +python-versions = ">=3.6" +files = [ + {file = "alibabacloud_tea_openapi-0.3.7.tar.gz", hash = "sha256:bf677f3ddd35eeb499f08c0a38a024379c47dbcc0ba7a777a2ef7562abbe9c9f"}, +] + +[package.dependencies] +alibabacloud_credentials = ">=0.3.1,<1.0.0" +alibabacloud_gateway_spi = ">=0.0.1,<1.0.0" +alibabacloud_openapi_util = ">=0.2.1,<1.0.0" +alibabacloud_tea_util = ">=0.3.8,<1.0.0" +alibabacloud_tea_xml = ">=0.0.2,<1.0.0" + +[[package]] +name = "alibabacloud-tea-util" +version = "0.3.11" +description = "The tea-util module of alibabaCloud Python SDK." +optional = false +python-versions = ">=3.6" +files = [ + {file = "alibabacloud_tea_util-0.3.11.tar.gz", hash = "sha256:f68231e36ccd788ccf3b8d72d67bf76a0fa8f5b7a5f01489484a1f133b448f71"}, +] + +[package.dependencies] +alibabacloud-tea = ">=0.3.3" + +[[package]] +name = "alibabacloud-tea-xml" +version = "0.0.2" +description = "The tea-xml module of alibabaCloud Python SDK." +optional = false +python-versions = "*" +files = [ + {file = "alibabacloud_tea_xml-0.0.2.tar.gz", hash = "sha256:f0135e8148fd7d9c1f029db161863f37f144f837c280cba16c2edeb2f9c549d8"}, +] + +[package.dependencies] +alibabacloud-tea = ">=0.0.1" + +[[package]] +name = "aliyun-python-sdk-core" +version = "2.13.36" +description = "The core module of Aliyun Python SDK." +optional = false +python-versions = "*" +files = [ + {file = "aliyun-python-sdk-core-2.13.36.tar.gz", hash = "sha256:20bd54984fa316da700c7f355a51ab0b816690e2a0fcefb7b5ef013fed0da928"}, +] + +[package.dependencies] +cryptography = ">=2.6.0" +jmespath = ">=0.9.3,<1.0.0" + +[[package]] +name = "aliyun-python-sdk-core-v3" +version = "2.13.33" +description = "The core module of Aliyun Python SDK." +optional = false +python-versions = "*" +files = [ + {file = "aliyun-python-sdk-core-v3-2.13.33.tar.gz", hash = "sha256:d7df820fa31193be3f0a3a991c4126051900b3d2f09c0fc5ff7af43cf36ac245"}, +] + +[package.dependencies] +cryptography = ">=2.6.0" +jmespath = ">=0.9.3,<1.0.0" + +[[package]] +name = "aliyun-python-sdk-ecs" +version = "4.24.64" +description = "The ecs module of Aliyun Python sdk." +optional = false +python-versions = "*" +files = [ + {file = "aliyun-python-sdk-ecs-4.24.64.tar.gz", hash = "sha256:9ae49bfd6f79aa295117d22f8f3b0a1a62eeff0c2df2026a7c7b6a8299e411be"}, + {file = "aliyun_python_sdk_ecs-4.24.64-py2.py3-none-any.whl", hash = "sha256:c0f366f06bdf45e359f22d7e1864439687e00bd9de6d59d29dbd30d0019b9347"}, +] + +[package.dependencies] +aliyun-python-sdk-core = ">=2.11.5" + +[[package]] +name = "aliyun-python-sdk-kms" +version = "2.16.1" +description = "The kms module of Aliyun Python sdk." +optional = false +python-versions = "*" +files = [ + {file = "aliyun-python-sdk-kms-2.16.1.tar.gz", hash = "sha256:a372737715682014bace68bd40fe83332f4fd925009a3eb110d41bc66f270e7a"}, + {file = "aliyun_python_sdk_kms-2.16.1-py2.py3-none-any.whl", hash = "sha256:9bc39c693ba83944f5dfb871b118a2925eb8a5ee214dfcce61ee2ea3b6317ef1"}, +] + +[package.dependencies] +aliyun-python-sdk-core = ">=2.11.5" + +[[package]] +name = "amqp" +version = "5.1.1" +description = "Low-level AMQP client for Python (fork of amqplib)." +optional = false +python-versions = ">=3.6" +files = [ + {file = "amqp-5.1.1-py3-none-any.whl", hash = "sha256:6f0956d2c23d8fa6e7691934d8c3930eadb44972cbbd1a7ae3a520f735d43359"}, + {file = "amqp-5.1.1.tar.gz", hash = "sha256:2c1b13fecc0893e946c65cbd5f36427861cffa4ea2201d8f6fca22e2a373b5e2"}, +] + +[package.dependencies] +vine = ">=5.0.0" + +[[package]] +name = "ansible" +version = "7.1.0" +description = "Radically simple IT automation" +optional = false +python-versions = ">=3.9" +files = [ + {file = "ansible-7.1.0-py3-none-any.whl", hash = "sha256:dd6d24dab08793e416eb1564ea716c586caeb104d4abbcada05bed94f9cd01cc"}, + {file = "ansible-7.1.0.tar.gz", hash = "sha256:1e47238c4aa9e68c0c5367a3fd707ba6c3949b4aaf912b06440ad78dd2bf018d"}, +] + +[package.dependencies] +ansible-core = ">=2.14.1,<2.15.0" + +[[package]] +name = "ansible-core" +version = "2.14.1" +description = "Radically simple IT automation" +optional = false +python-versions = ">=3.9" +files = [ + {file = "ansible-2.14.1.2.zip", hash = "sha256:813b39d8e03d5ea23b47703b3ba4d0372f68141b33e2b1be28deb6ad28b31c73"}, +] + +[package.dependencies] +cryptography = "*" +jinja2 = ">=3.0.0" +packaging = "*" +PyYAML = ">=5.1" +resolvelib = ">=0.5.3,<0.9.0" + +[package.source] +type = "url" +url = "https://github.com/jumpserver/ansible/releases/download/v2.14.1.2/ansible-2.14.1.2.zip" + +[[package]] +name = "ansible-runner" +version = "2.3.3" +description = "\"Consistent Ansible Python API and CLI with container and process isolation runtime capabilities\"" +optional = false +python-versions = ">=3.8" +files = [ + {file = "ansible-runner-2.3.3.tar.gz", hash = "sha256:38ff635e4b94791de2956c81e265836ec4965b30e9ee35d72fcf3271dc46b98b"}, + {file = "ansible_runner-2.3.3-py3-none-any.whl", hash = "sha256:c57ae0d096760d66b2897b0f9009856c7b83fd5428dcb831f470cba348346396"}, +] + +[package.dependencies] +packaging = "*" +pexpect = ">=4.5" +python-daemon = "*" +pyyaml = "*" +six = "*" + +[[package]] +name = "anyio" +version = "3.7.1" +description = "High level compatibility layer for multiple asynchronous event loop implementations" +optional = false +python-versions = ">=3.7" +files = [ + {file = "anyio-3.7.1-py3-none-any.whl", hash = "sha256:91dee416e570e92c64041bd18b900d1d6fa78dff7048769ce5ac5ddad004fbb5"}, + {file = "anyio-3.7.1.tar.gz", hash = "sha256:44a3c9aba0f5defa43261a8b3efb97891f2bd7d804e0e1f56419befa1adfc780"}, +] + +[package.dependencies] +idna = ">=2.8" +sniffio = ">=1.1" + +[package.extras] +doc = ["Sphinx", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme (>=1.2.2)", "sphinxcontrib-jquery"] +test = ["anyio[trio]", "coverage[toml] (>=4.5)", "hypothesis (>=4.0)", "mock (>=4)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"] +trio = ["trio (<0.22)"] + +[[package]] +name = "appnope" +version = "0.1.3" +description = "Disable App Nap on macOS >= 10.9" +optional = false +python-versions = "*" +files = [ + {file = "appnope-0.1.3-py2.py3-none-any.whl", hash = "sha256:265a455292d0bd8a72453494fa24df5a11eb18373a60c7c0430889f22548605e"}, + {file = "appnope-0.1.3.tar.gz", hash = "sha256:02bd91c4de869fbb1e1c50aafc4098827a7a54ab2f39d9dcba6c9547ed920e24"}, +] + +[[package]] +name = "asgiref" +version = "3.7.2" +description = "ASGI specs, helper code, and adapters" +optional = false +python-versions = ">=3.7" +files = [ + {file = "asgiref-3.7.2-py3-none-any.whl", hash = "sha256:89b2ef2247e3b562a16eef663bc0e2e703ec6468e2fa8a5cd61cd449786d4f6e"}, + {file = "asgiref-3.7.2.tar.gz", hash = "sha256:9e0ce3aa93a819ba5b45120216b23878cf6e8525eb3848653452b4192b92afed"}, +] + +[package.extras] +tests = ["mypy (>=0.800)", "pytest", "pytest-asyncio"] + +[[package]] +name = "asn1crypto" +version = "1.5.1" +description = "Fast ASN.1 parser and serializer with definitions for private keys, public keys, certificates, CRL, OCSP, CMS, PKCS#3, PKCS#7, PKCS#8, PKCS#12, PKCS#5, X.509 and TSP" +optional = false +python-versions = "*" +files = [ + {file = "asn1crypto-1.5.1-py2.py3-none-any.whl", hash = "sha256:db4e40728b728508912cbb3d44f19ce188f218e9eba635821bb4b68564f8fd67"}, + {file = "asn1crypto-1.5.1.tar.gz", hash = "sha256:13ae38502be632115abf8a24cbe5f4da52e3b5231990aff31123c805306ccb9c"}, +] + +[[package]] +name = "asttokens" +version = "2.2.1" +description = "Annotate AST trees with source code positions" +optional = false +python-versions = "*" +files = [ + {file = "asttokens-2.2.1-py2.py3-none-any.whl", hash = "sha256:6b0ac9e93fb0335014d382b8fa9b3afa7df546984258005da0b9e7095b3deb1c"}, + {file = "asttokens-2.2.1.tar.gz", hash = "sha256:4622110b2a6f30b77e1473affaa97e711bc2f07d3f10848420ff1898edbe94f3"}, +] + +[package.dependencies] +six = "*" + +[package.extras] +test = ["astroid", "pytest"] + +[[package]] +name = "async-timeout" +version = "4.0.2" +description = "Timeout context manager for asyncio programs" +optional = false +python-versions = ">=3.6" +files = [ + {file = "async-timeout-4.0.2.tar.gz", hash = "sha256:2163e1640ddb52b7a8c80d0a67a08587e5d245cc9c553a74a847056bc2976b15"}, + {file = "async_timeout-4.0.2-py3-none-any.whl", hash = "sha256:8ca1e4fcf50d07413d66d1a5e416e42cfdf5851c981d679a09851a6853383b3c"}, +] + +[[package]] +name = "attrs" +version = "23.1.0" +description = "Classes Without Boilerplate" +optional = false +python-versions = ">=3.7" +files = [ + {file = "attrs-23.1.0-py3-none-any.whl", hash = "sha256:1f28b4522cdc2fb4256ac1a020c78acf9cba2c6b461ccd2c126f3aa8e8335d04"}, + {file = "attrs-23.1.0.tar.gz", hash = "sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015"}, +] + +[package.extras] +cov = ["attrs[tests]", "coverage[toml] (>=5.3)"] +dev = ["attrs[docs,tests]", "pre-commit"] +docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope-interface"] +tests = ["attrs[tests-no-zope]", "zope-interface"] +tests-no-zope = ["cloudpickle", "hypothesis", "mypy (>=1.1.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] + +[[package]] +name = "autobahn" +version = "23.6.2" +description = "WebSocket client & server library, WAMP real-time framework" +optional = false +python-versions = ">=3.9" +files = [ + {file = "autobahn-23.6.2.tar.gz", hash = "sha256:ec9421c52a2103364d1ef0468036e6019ee84f71721e86b36fe19ad6966c1181"}, +] + +[package.dependencies] +cryptography = ">=3.4.6" +hyperlink = ">=21.0.0" +setuptools = "*" +txaio = ">=21.2.1" + +[package.extras] +all = ["PyGObject (>=3.40.0)", "argon2_cffi (>=20.1.0)", "attrs (>=20.3.0)", "base58 (>=2.1.0)", "bitarray (>=2.7.5)", "cbor2 (>=5.2.0)", "cffi (>=1.14.5)", "click (>=8.1.2)", "ecdsa (>=0.16.1)", "eth-abi (>=4.0.0)", "flatbuffers (>=22.12.6)", "hkdf (>=0.0.3)", "jinja2 (>=2.11.3)", "mnemonic (>=0.19)", "msgpack (>=1.0.2)", "passlib (>=1.7.4)", "py-ecc (>=5.1.0)", "py-eth-sig-utils (>=0.4.0)", "py-multihash (>=2.0.1)", "py-ubjson (>=0.16.1)", "pynacl (>=1.4.0)", "pyopenssl (>=20.0.1)", "python-snappy (>=0.6.0)", "pytrie (>=0.4.0)", "qrcode (>=7.3.1)", "rlp (>=2.0.1)", "service_identity (>=18.1.0)", "spake2 (>=0.8)", "twisted (>=20.3.0)", "ujson (>=4.0.2)", "web3[ipfs] (>=6.0.0)", "xbr (>=21.2.1)", "yapf (==0.29.0)", "zlmdb (>=21.2.1)", "zope.interface (>=5.2.0)"] +compress = ["python-snappy (>=0.6.0)"] +dev = ["backports.tempfile (>=1.0)", "bumpversion (>=0.5.3)", "codecov (>=2.0.15)", "flake8 (<5)", "humanize (>=0.5.1)", "mypy (>=0.610)", "passlib", "pep8-naming (>=0.3.3)", "pip (>=9.0.1)", "pyenchant (>=1.6.6)", "pyflakes (>=1.0.0)", "pyinstaller (>=4.2)", "pylint (>=1.9.2)", "pytest (>=3.4.2)", "pytest-aiohttp", "pytest-asyncio (>=0.14.0)", "pytest-runner (>=2.11.1)", "pyyaml (>=4.2b4)", "qualname", "sphinx (>=1.7.1)", "sphinx-autoapi (>=1.7.0)", "sphinx_rtd_theme (>=0.1.9)", "sphinxcontrib-images (>=0.9.1)", "tox (>=4.2.8)", "tox-gh-actions (>=2.2.0)", "twine (>=3.3.0)", "twisted (>=22.10.0)", "txaio (>=20.4.1)", "watchdog (>=0.8.3)", "wheel (>=0.36.2)", "yapf (==0.29.0)"] +encryption = ["pynacl (>=1.4.0)", "pyopenssl (>=20.0.1)", "pytrie (>=0.4.0)", "qrcode (>=7.3.1)", "service_identity (>=18.1.0)"] +nvx = ["cffi (>=1.14.5)"] +scram = ["argon2_cffi (>=20.1.0)", "cffi (>=1.14.5)", "passlib (>=1.7.4)"] +serialization = ["cbor2 (>=5.2.0)", "flatbuffers (>=22.12.6)", "msgpack (>=1.0.2)", "py-ubjson (>=0.16.1)", "ujson (>=4.0.2)"] +twisted = ["attrs (>=20.3.0)", "twisted (>=20.3.0)", "zope.interface (>=5.2.0)"] +ui = ["PyGObject (>=3.40.0)"] +xbr = ["base58 (>=2.1.0)", "bitarray (>=2.7.5)", "cbor2 (>=5.2.0)", "click (>=8.1.2)", "ecdsa (>=0.16.1)", "eth-abi (>=4.0.0)", "hkdf (>=0.0.3)", "jinja2 (>=2.11.3)", "mnemonic (>=0.19)", "py-ecc (>=5.1.0)", "py-eth-sig-utils (>=0.4.0)", "py-multihash (>=2.0.1)", "rlp (>=2.0.1)", "spake2 (>=0.8)", "twisted (>=20.3.0)", "web3[ipfs] (>=6.0.0)", "xbr (>=21.2.1)", "yapf (==0.29.0)", "zlmdb (>=21.2.1)"] + +[[package]] +name = "automat" +version = "22.10.0" +description = "Self-service finite-state machines for the programmer on the go." +optional = false +python-versions = "*" +files = [ + {file = "Automat-22.10.0-py2.py3-none-any.whl", hash = "sha256:c3164f8742b9dc440f3682482d32aaff7bb53f71740dd018533f9de286b64180"}, + {file = "Automat-22.10.0.tar.gz", hash = "sha256:e56beb84edad19dcc11d30e8d9b895f75deeb5ef5e96b84a467066b3b84bb04e"}, +] + +[package.dependencies] +attrs = ">=19.2.0" +six = "*" + +[package.extras] +visualize = ["Twisted (>=16.1.1)", "graphviz (>0.5.1)"] + +[[package]] +name = "azure-common" +version = "1.1.28" +description = "Microsoft Azure Client Library for Python (Common)" +optional = false +python-versions = "*" +files = [ + {file = "azure-common-1.1.28.zip", hash = "sha256:4ac0cd3214e36b6a1b6a442686722a5d8cc449603aa833f3f0f40bda836704a3"}, + {file = "azure_common-1.1.28-py2.py3-none-any.whl", hash = "sha256:5c12d3dcf4ec20599ca6b0d3e09e86e146353d443e7fcc050c9a19c1f9df20ad"}, +] + +[[package]] +name = "azure-core" +version = "1.28.0" +description = "Microsoft Azure Core Library for Python" +optional = false +python-versions = ">=3.7" +files = [ + {file = "azure-core-1.28.0.zip", hash = "sha256:e9eefc66fc1fde56dab6f04d4e5d12c60754d5a9fa49bdcfd8534fc96ed936bd"}, + {file = "azure_core-1.28.0-py3-none-any.whl", hash = "sha256:dec36dfc8eb0b052a853f30c07437effec2f9e3e1fc8f703d9bdaa5cfc0043d9"}, +] + +[package.dependencies] +requests = ">=2.18.4" +six = ">=1.11.0" +typing-extensions = ">=4.3.0" + +[package.extras] +aio = ["aiohttp (>=3.0)"] + +[[package]] +name = "azure-identity" +version = "1.13.0" +description = "Microsoft Azure Identity Library for Python" +optional = false +python-versions = ">=3.7" +files = [ + {file = "azure-identity-1.13.0.zip", hash = "sha256:c931c27301ffa86b07b4dcf574e29da73e3deba9ab5d1fe4f445bb6a3117e260"}, + {file = "azure_identity-1.13.0-py3-none-any.whl", hash = "sha256:bd700cebb80cd9862098587c29d8677e819beca33c62568ced6d5a8e5e332b82"}, +] + +[package.dependencies] +azure-core = ">=1.11.0,<2.0.0" +cryptography = ">=2.5" +msal = ">=1.20.0,<2.0.0" +msal-extensions = ">=0.3.0,<2.0.0" +six = ">=1.12.0" + +[[package]] +name = "azure-mgmt-compute" +version = "30.0.0" +description = "Microsoft Azure Compute Management Client Library for Python" +optional = false +python-versions = ">=3.7" +files = [ + {file = "azure-mgmt-compute-30.0.0.zip", hash = "sha256:7320fbafc392770b03ed02b68760185e6094552ed98d7fd5ea77210a5a513c78"}, + {file = "azure_mgmt_compute-30.0.0-py3-none-any.whl", hash = "sha256:004fc790f6ed70cd17a45a3c3ebc0665391c96f101ee80eb8738330a53f0d959"}, +] + +[package.dependencies] +azure-common = ">=1.1,<2.0" +azure-mgmt-core = ">=1.3.2,<2.0.0" +isodate = ">=0.6.1,<1.0.0" + +[[package]] +name = "azure-mgmt-core" +version = "1.4.0" +description = "Microsoft Azure Management Core Library for Python" +optional = false +python-versions = ">=3.7" +files = [ + {file = "azure-mgmt-core-1.4.0.zip", hash = "sha256:d195208340094f98e5a6661b781cde6f6a051e79ce317caabd8ff97030a9b3ae"}, + {file = "azure_mgmt_core-1.4.0-py3-none-any.whl", hash = "sha256:81071675f186a585555ef01816f2774d49c1c9024cb76e5720c3c0f6b337bb7d"}, +] + +[package.dependencies] +azure-core = ">=1.26.2,<2.0.0" + +[[package]] +name = "azure-mgmt-network" +version = "23.1.0" +description = "Microsoft Azure Network Management Client Library for Python" +optional = false +python-versions = ">=3.7" +files = [ + {file = "azure-mgmt-network-23.1.0.zip", hash = "sha256:37172699113831d7ce1bb9da35c635007c73cffc549a85a58f55542b54b12bf3"}, + {file = "azure_mgmt_network-23.1.0-py3-none-any.whl", hash = "sha256:83afb63fdf7a526a4b2ee32e0a6038e9d05d4182bcaac1e0190a59152165648d"}, +] + +[package.dependencies] +azure-common = ">=1.1,<2.0" +azure-mgmt-core = ">=1.3.2,<2.0.0" +isodate = ">=0.6.1,<1.0.0" + +[[package]] +name = "azure-mgmt-subscription" +version = "3.1.1" +description = "Microsoft Azure Subscription Management Client Library for Python" +optional = false +python-versions = ">=3.7" +files = [ + {file = "azure-mgmt-subscription-3.1.1.zip", hash = "sha256:4e255b4ce9b924357bb8c5009b3c88a2014d3203b2495e2256fa027bf84e800e"}, + {file = "azure_mgmt_subscription-3.1.1-py3-none-any.whl", hash = "sha256:38d4574a8d47fa17e3587d756e296cb63b82ad8fb21cd8543bcee443a502bf48"}, +] + +[package.dependencies] +azure-common = ">=1.1,<2.0" +azure-mgmt-core = ">=1.3.2,<2.0.0" +msrest = ">=0.7.1" + +[[package]] +name = "azure-storage-blob" +version = "12.17.0" +description = "Microsoft Azure Blob Storage Client Library for Python" +optional = false +python-versions = ">=3.7" +files = [ + {file = "azure-storage-blob-12.17.0.zip", hash = "sha256:c14b785a17050b30fc326a315bdae6bc4a078855f4f94a4c303ad74a48dc8c63"}, + {file = "azure_storage_blob-12.17.0-py3-none-any.whl", hash = "sha256:0016e0c549a80282d7b4920c03f2f4ba35c53e6e3c7dbcd2a4a8c8eb3882c1e7"}, +] + +[package.dependencies] +azure-core = ">=1.28.0,<2.0.0" +cryptography = ">=2.1.4" +isodate = ">=0.6.1" +typing-extensions = ">=4.3.0" + +[package.extras] +aio = ["azure-core[aio] (>=1.28.0,<2.0.0)"] + +[[package]] +name = "backcall" +version = "0.2.0" +description = "Specifications for callback functions passed in to an API" +optional = false +python-versions = "*" +files = [ + {file = "backcall-0.2.0-py2.py3-none-any.whl", hash = "sha256:fbbce6a29f263178a1f7915c1940bde0ec2b2a967566fe1c65c1dfb7422bd255"}, + {file = "backcall-0.2.0.tar.gz", hash = "sha256:5cbdbf27be5e7cfadb448baf0aa95508f91f2bbc6c6437cd9cd06e2a4c215e1e"}, +] + +[[package]] +name = "bce-python-sdk" +version = "0.8.87" +description = "BCE SDK for python" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, <4" +files = [ + {file = "bce-python-sdk-0.8.87.tar.gz", hash = "sha256:be04dfd47883fd1ff59b6e33abfbc1f83b762b369c7f078fadf7b5ab48c1d2a9"}, + {file = "bce_python_sdk-0.8.87-py3-none-any.whl", hash = "sha256:75cbf523c2a106026b0f3c57a5d5c7a0853edb0900a52d585ea0561179972aef"}, +] + +[package.dependencies] +future = ">=0.6.0" +pycryptodome = ">=3.8.0" +six = ">=1.4.0" + +[[package]] +name = "bcrypt" +version = "4.0.1" +description = "Modern password hashing for your software and your servers" +optional = false +python-versions = ">=3.6" +files = [ + {file = "bcrypt-4.0.1-cp36-abi3-macosx_10_10_universal2.whl", hash = "sha256:b1023030aec778185a6c16cf70f359cbb6e0c289fd564a7cfa29e727a1c38f8f"}, + {file = "bcrypt-4.0.1-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:08d2947c490093a11416df18043c27abe3921558d2c03e2076ccb28a116cb6d0"}, + {file = "bcrypt-4.0.1-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0eaa47d4661c326bfc9d08d16debbc4edf78778e6aaba29c1bc7ce67214d4410"}, + {file = "bcrypt-4.0.1-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ae88eca3024bb34bb3430f964beab71226e761f51b912de5133470b649d82344"}, + {file = "bcrypt-4.0.1-cp36-abi3-manylinux_2_24_x86_64.whl", hash = "sha256:a522427293d77e1c29e303fc282e2d71864579527a04ddcfda6d4f8396c6c36a"}, + {file = "bcrypt-4.0.1-cp36-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:fbdaec13c5105f0c4e5c52614d04f0bca5f5af007910daa8b6b12095edaa67b3"}, + {file = "bcrypt-4.0.1-cp36-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:ca3204d00d3cb2dfed07f2d74a25f12fc12f73e606fcaa6975d1f7ae69cacbb2"}, + {file = "bcrypt-4.0.1-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:089098effa1bc35dc055366740a067a2fc76987e8ec75349eb9484061c54f535"}, + {file = "bcrypt-4.0.1-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:e9a51bbfe7e9802b5f3508687758b564069ba937748ad7b9e890086290d2f79e"}, + {file = "bcrypt-4.0.1-cp36-abi3-win32.whl", hash = "sha256:2caffdae059e06ac23fce178d31b4a702f2a3264c20bfb5ff541b338194d8fab"}, + {file = "bcrypt-4.0.1-cp36-abi3-win_amd64.whl", hash = "sha256:8a68f4341daf7522fe8d73874de8906f3a339048ba406be6ddc1b3ccb16fc0d9"}, + {file = "bcrypt-4.0.1-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf4fa8b2ca74381bb5442c089350f09a3f17797829d958fad058d6e44d9eb83c"}, + {file = "bcrypt-4.0.1-pp37-pypy37_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:67a97e1c405b24f19d08890e7ae0c4f7ce1e56a712a016746c8b2d7732d65d4b"}, + {file = "bcrypt-4.0.1-pp37-pypy37_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:b3b85202d95dd568efcb35b53936c5e3b3600c7cdcc6115ba461df3a8e89f38d"}, + {file = "bcrypt-4.0.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cbb03eec97496166b704ed663a53680ab57c5084b2fc98ef23291987b525cb7d"}, + {file = "bcrypt-4.0.1-pp38-pypy38_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:5ad4d32a28b80c5fa6671ccfb43676e8c1cc232887759d1cd7b6f56ea4355215"}, + {file = "bcrypt-4.0.1-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:b57adba8a1444faf784394de3436233728a1ecaeb6e07e8c22c8848f179b893c"}, + {file = "bcrypt-4.0.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:705b2cea8a9ed3d55b4491887ceadb0106acf7c6387699fca771af56b1cdeeda"}, + {file = "bcrypt-4.0.1-pp39-pypy39_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:2b3ac11cf45161628f1f3733263e63194f22664bf4d0c0f3ab34099c02134665"}, + {file = "bcrypt-4.0.1-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:3100851841186c25f127731b9fa11909ab7b1df6fc4b9f8353f4f1fd952fbf71"}, + {file = "bcrypt-4.0.1.tar.gz", hash = "sha256:27d375903ac8261cfe4047f6709d16f7d18d39b1ec92aaf72af989552a650ebd"}, +] + +[package.extras] +tests = ["pytest (>=3.2.1,!=3.3.0)"] +typecheck = ["mypy"] + +[[package]] +name = "beautifulsoup4" +version = "4.12.2" +description = "Screen-scraping library" +optional = false +python-versions = ">=3.6.0" +files = [ + {file = "beautifulsoup4-4.12.2-py3-none-any.whl", hash = "sha256:bd2520ca0d9d7d12694a53d44ac482d181b4ec1888909b035a3dbf40d0f57d4a"}, + {file = "beautifulsoup4-4.12.2.tar.gz", hash = "sha256:492bbc69dca35d12daac71c4db1bfff0c876c00ef4a2ffacce226d4638eb72da"}, +] + +[package.dependencies] +soupsieve = ">1.2" + +[package.extras] +html5lib = ["html5lib"] +lxml = ["lxml"] + +[[package]] +name = "billiard" +version = "4.1.0" +description = "Python multiprocessing fork with improvements and bugfixes" +optional = false +python-versions = ">=3.7" +files = [ + {file = "billiard-4.1.0-py3-none-any.whl", hash = "sha256:0f50d6be051c6b2b75bfbc8bfd85af195c5739c281d3f5b86a5640c65563614a"}, + {file = "billiard-4.1.0.tar.gz", hash = "sha256:1ad2eeae8e28053d729ba3373d34d9d6e210f6e4d8bf0a9c64f92bd053f1edf5"}, +] + +[[package]] +name = "boto" +version = "2.49.0" +description = "Amazon Web Services Library" +optional = false +python-versions = "*" +files = [ + {file = "boto-2.49.0-py2.py3-none-any.whl", hash = "sha256:147758d41ae7240dc989f0039f27da8ca0d53734be0eb869ef16e3adcfa462e8"}, + {file = "boto-2.49.0.tar.gz", hash = "sha256:ea0d3b40a2d852767be77ca343b58a9e3a4b00d9db440efb8da74b4e58025e5a"}, +] + +[[package]] +name = "boto3" +version = "1.28.9" +description = "The AWS SDK for Python" +optional = false +python-versions = ">= 3.7" +files = [ + {file = "boto3-1.28.9-py3-none-any.whl", hash = "sha256:01f078047eb4d238c6b9c6cc623f2af33b4ae67980c5326691e35cb5493ff6c7"}, + {file = "boto3-1.28.9.tar.gz", hash = "sha256:4cc0c6005be910e52077227e670930ab55a41ba86cdb6d1c052571d08cd4d32c"}, +] + +[package.dependencies] +botocore = ">=1.31.9,<1.32.0" +jmespath = ">=0.7.1,<2.0.0" +s3transfer = ">=0.6.0,<0.7.0" + +[package.extras] +crt = ["botocore[crt] (>=1.21.0,<2.0a0)"] + +[[package]] +name = "botocore" +version = "1.31.9" +description = "Low-level, data-driven core of boto 3." +optional = false +python-versions = ">= 3.7" +files = [ + {file = "botocore-1.31.9-py3-none-any.whl", hash = "sha256:e56ccd3536a90094ea5b176b5dd33bfe4f049efdf71af468ea1661bd424c787d"}, + {file = "botocore-1.31.9.tar.gz", hash = "sha256:bd849d3ac95f1781385ed831d753a04a3ec870a59d6598175aaedd71dc2baf5f"}, +] + +[package.dependencies] +jmespath = ">=0.7.1,<2.0.0" +python-dateutil = ">=2.1,<3.0.0" +urllib3 = ">=1.25.4,<1.27" + +[package.extras] +crt = ["awscrt (==0.16.26)"] + +[[package]] +name = "cachetools" +version = "5.3.1" +description = "Extensible memoizing collections and decorators" +optional = false +python-versions = ">=3.7" +files = [ + {file = "cachetools-5.3.1-py3-none-any.whl", hash = "sha256:95ef631eeaea14ba2e36f06437f36463aac3a096799e876ee55e5cdccb102590"}, + {file = "cachetools-5.3.1.tar.gz", hash = "sha256:dce83f2d9b4e1f732a8cd44af8e8fab2dbe46201467fc98b3ef8f269092bf62b"}, +] + +[[package]] +name = "celery" +version = "5.3.1" +description = "Distributed Task Queue." +optional = false +python-versions = ">=3.8" +files = [ + {file = "celery-5.3.1-py3-none-any.whl", hash = "sha256:27f8f3f3b58de6e0ab4f174791383bbd7445aff0471a43e99cfd77727940753f"}, + {file = "celery-5.3.1.tar.gz", hash = "sha256:f84d1c21a1520c116c2b7d26593926581191435a03aa74b77c941b93ca1c6210"}, +] + +[package.dependencies] +billiard = ">=4.1.0,<5.0" +click = ">=8.1.2,<9.0" +click-didyoumean = ">=0.3.0" +click-plugins = ">=1.1.1" +click-repl = ">=0.2.0" +kombu = ">=5.3.1,<6.0" +python-dateutil = ">=2.8.2" +tzdata = ">=2022.7" +vine = ">=5.0.0,<6.0" + +[package.extras] +arangodb = ["pyArango (>=2.0.1)"] +auth = ["cryptography (==41.0.1)"] +azureblockblob = ["azure-storage-blob (>=12.15.0)"] +brotli = ["brotli (>=1.0.0)", "brotlipy (>=0.7.0)"] +cassandra = ["cassandra-driver (>=3.25.0,<4)"] +consul = ["python-consul2 (==0.1.5)"] +cosmosdbsql = ["pydocumentdb (==2.3.5)"] +couchbase = ["couchbase (>=3.0.0)"] +couchdb = ["pycouchdb (==1.14.2)"] +django = ["Django (>=2.2.28)"] +dynamodb = ["boto3 (>=1.26.143)"] +elasticsearch = ["elasticsearch (<8.0)"] +eventlet = ["eventlet (>=0.32.0)"] +gevent = ["gevent (>=1.5.0)"] +librabbitmq = ["librabbitmq (>=2.0.0)"] +memcache = ["pylibmc (==1.6.3)"] +mongodb = ["pymongo[srv] (>=4.0.2)"] +msgpack = ["msgpack (==1.0.5)"] +pymemcache = ["python-memcached (==1.59)"] +pyro = ["pyro4 (==4.82)"] +pytest = ["pytest-celery (==0.0.0)"] +redis = ["redis (>=4.5.2,!=4.5.5)"] +s3 = ["boto3 (>=1.26.143)"] +slmq = ["softlayer-messaging (>=1.0.3)"] +solar = ["ephem (==4.1.4)"] +sqlalchemy = ["sqlalchemy (>=1.4.48,<2.1)"] +sqs = ["boto3 (>=1.26.143)", "kombu[sqs] (>=5.3.0)", "pycurl (>=7.43.0.5)", "urllib3 (>=1.26.16)"] +tblib = ["tblib (>=1.3.0)", "tblib (>=1.5.0)"] +yaml = ["PyYAML (>=3.10)"] +zookeeper = ["kazoo (>=1.3.1)"] +zstd = ["zstandard (==0.21.0)"] + +[[package]] +name = "certifi" +version = "2023.7.22" +description = "Python package for providing Mozilla's CA Bundle." +optional = false +python-versions = ">=3.6" +files = [ + {file = "certifi-2023.7.22-py3-none-any.whl", hash = "sha256:92d6037539857d8206b8f6ae472e8b77db8058fec5937a1ef3f54304089edbb9"}, + {file = "certifi-2023.7.22.tar.gz", hash = "sha256:539cc1d13202e33ca466e88b2807e29f4c13049d6d87031a3c110744495cb082"}, +] + +[[package]] +name = "cffi" +version = "1.15.1" +description = "Foreign Function Interface for Python calling C code." +optional = false +python-versions = "*" +files = [ + {file = "cffi-1.15.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:a66d3508133af6e8548451b25058d5812812ec3798c886bf38ed24a98216fab2"}, + {file = "cffi-1.15.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:470c103ae716238bbe698d67ad020e1db9d9dba34fa5a899b5e21577e6d52ed2"}, + {file = "cffi-1.15.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:9ad5db27f9cabae298d151c85cf2bad1d359a1b9c686a275df03385758e2f914"}, + {file = "cffi-1.15.1-cp27-cp27m-win32.whl", hash = "sha256:b3bbeb01c2b273cca1e1e0c5df57f12dce9a4dd331b4fa1635b8bec26350bde3"}, + {file = "cffi-1.15.1-cp27-cp27m-win_amd64.whl", hash = "sha256:e00b098126fd45523dd056d2efba6c5a63b71ffe9f2bbe1a4fe1716e1d0c331e"}, + {file = "cffi-1.15.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:d61f4695e6c866a23a21acab0509af1cdfd2c013cf256bbf5b6b5e2695827162"}, + {file = "cffi-1.15.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:ed9cb427ba5504c1dc15ede7d516b84757c3e3d7868ccc85121d9310d27eed0b"}, + {file = "cffi-1.15.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:39d39875251ca8f612b6f33e6b1195af86d1b3e60086068be9cc053aa4376e21"}, + {file = "cffi-1.15.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:285d29981935eb726a4399badae8f0ffdff4f5050eaa6d0cfc3f64b857b77185"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3eb6971dcff08619f8d91607cfc726518b6fa2a9eba42856be181c6d0d9515fd"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:21157295583fe8943475029ed5abdcf71eb3911894724e360acff1d61c1d54bc"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5635bd9cb9731e6d4a1132a498dd34f764034a8ce60cef4f5319c0541159392f"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2012c72d854c2d03e45d06ae57f40d78e5770d252f195b93f581acf3ba44496e"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd86c085fae2efd48ac91dd7ccffcfc0571387fe1193d33b6394db7ef31fe2a4"}, + {file = "cffi-1.15.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:fa6693661a4c91757f4412306191b6dc88c1703f780c8234035eac011922bc01"}, + {file = "cffi-1.15.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:59c0b02d0a6c384d453fece7566d1c7e6b7bae4fc5874ef2ef46d56776d61c9e"}, + {file = "cffi-1.15.1-cp310-cp310-win32.whl", hash = "sha256:cba9d6b9a7d64d4bd46167096fc9d2f835e25d7e4c121fb2ddfc6528fb0413b2"}, + {file = "cffi-1.15.1-cp310-cp310-win_amd64.whl", hash = "sha256:ce4bcc037df4fc5e3d184794f27bdaab018943698f4ca31630bc7f84a7b69c6d"}, + {file = "cffi-1.15.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3d08afd128ddaa624a48cf2b859afef385b720bb4b43df214f85616922e6a5ac"}, + {file = "cffi-1.15.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3799aecf2e17cf585d977b780ce79ff0dc9b78d799fc694221ce814c2c19db83"}, + {file = "cffi-1.15.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a591fe9e525846e4d154205572a029f653ada1a78b93697f3b5a8f1f2bc055b9"}, + {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3548db281cd7d2561c9ad9984681c95f7b0e38881201e157833a2342c30d5e8c"}, + {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:91fc98adde3d7881af9b59ed0294046f3806221863722ba7d8d120c575314325"}, + {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94411f22c3985acaec6f83c6df553f2dbe17b698cc7f8ae751ff2237d96b9e3c"}, + {file = "cffi-1.15.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:03425bdae262c76aad70202debd780501fabeaca237cdfddc008987c0e0f59ef"}, + {file = "cffi-1.15.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cc4d65aeeaa04136a12677d3dd0b1c0c94dc43abac5860ab33cceb42b801c1e8"}, + {file = "cffi-1.15.1-cp311-cp311-win32.whl", hash = "sha256:a0f100c8912c114ff53e1202d0078b425bee3649ae34d7b070e9697f93c5d52d"}, + {file = "cffi-1.15.1-cp311-cp311-win_amd64.whl", hash = "sha256:04ed324bda3cda42b9b695d51bb7d54b680b9719cfab04227cdd1e04e5de3104"}, + {file = "cffi-1.15.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50a74364d85fd319352182ef59c5c790484a336f6db772c1a9231f1c3ed0cbd7"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e263d77ee3dd201c3a142934a086a4450861778baaeeb45db4591ef65550b0a6"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cec7d9412a9102bdc577382c3929b337320c4c4c4849f2c5cdd14d7368c5562d"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4289fc34b2f5316fbb762d75362931e351941fa95fa18789191b33fc4cf9504a"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:173379135477dc8cac4bc58f45db08ab45d228b3363adb7af79436135d028405"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6975a3fac6bc83c4a65c9f9fcab9e47019a11d3d2cf7f3c0d03431bf145a941e"}, + {file = "cffi-1.15.1-cp36-cp36m-win32.whl", hash = "sha256:2470043b93ff09bf8fb1d46d1cb756ce6132c54826661a32d4e4d132e1977adf"}, + {file = "cffi-1.15.1-cp36-cp36m-win_amd64.whl", hash = "sha256:30d78fbc8ebf9c92c9b7823ee18eb92f2e6ef79b45ac84db507f52fbe3ec4497"}, + {file = "cffi-1.15.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:198caafb44239b60e252492445da556afafc7d1e3ab7a1fb3f0584ef6d742375"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5ef34d190326c3b1f822a5b7a45f6c4535e2f47ed06fec77d3d799c450b2651e"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8102eaf27e1e448db915d08afa8b41d6c7ca7a04b7d73af6514df10a3e74bd82"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5df2768244d19ab7f60546d0c7c63ce1581f7af8b5de3eb3004b9b6fc8a9f84b"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8c4917bd7ad33e8eb21e9a5bbba979b49d9a97acb3a803092cbc1133e20343c"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e2642fe3142e4cc4af0799748233ad6da94c62a8bec3a6648bf8ee68b1c7426"}, + {file = "cffi-1.15.1-cp37-cp37m-win32.whl", hash = "sha256:e229a521186c75c8ad9490854fd8bbdd9a0c9aa3a524326b55be83b54d4e0ad9"}, + {file = "cffi-1.15.1-cp37-cp37m-win_amd64.whl", hash = "sha256:a0b71b1b8fbf2b96e41c4d990244165e2c9be83d54962a9a1d118fd8657d2045"}, + {file = "cffi-1.15.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:320dab6e7cb2eacdf0e658569d2575c4dad258c0fcc794f46215e1e39f90f2c3"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e74c6b51a9ed6589199c787bf5f9875612ca4a8a0785fb2d4a84429badaf22a"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5c84c68147988265e60416b57fc83425a78058853509c1b0629c180094904a5"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b926aa83d1edb5aa5b427b4053dc420ec295a08e40911296b9eb1b6170f6cca"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:87c450779d0914f2861b8526e035c5e6da0a3199d8f1add1a665e1cbc6fc6d02"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f2c9f67e9821cad2e5f480bc8d83b8742896f1242dba247911072d4fa94c192"}, + {file = "cffi-1.15.1-cp38-cp38-win32.whl", hash = "sha256:8b7ee99e510d7b66cdb6c593f21c043c248537a32e0bedf02e01e9553a172314"}, + {file = "cffi-1.15.1-cp38-cp38-win_amd64.whl", hash = "sha256:00a9ed42e88df81ffae7a8ab6d9356b371399b91dbdf0c3cb1e84c03a13aceb5"}, + {file = "cffi-1.15.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:54a2db7b78338edd780e7ef7f9f6c442500fb0d41a5a4ea24fff1c929d5af585"}, + {file = "cffi-1.15.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fcd131dd944808b5bdb38e6f5b53013c5aa4f334c5cad0c72742f6eba4b73db0"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7473e861101c9e72452f9bf8acb984947aa1661a7704553a9f6e4baa5ba64415"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c9a799e985904922a4d207a94eae35c78ebae90e128f0c4e521ce339396be9d"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3bcde07039e586f91b45c88f8583ea7cf7a0770df3a1649627bf598332cb6984"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33ab79603146aace82c2427da5ca6e58f2b3f2fb5da893ceac0c42218a40be35"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d598b938678ebf3c67377cdd45e09d431369c3b1a5b331058c338e201f12b27"}, + {file = "cffi-1.15.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db0fbb9c62743ce59a9ff687eb5f4afbe77e5e8403d6697f7446e5f609976f76"}, + {file = "cffi-1.15.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:98d85c6a2bef81588d9227dde12db8a7f47f639f4a17c9ae08e773aa9c697bf3"}, + {file = "cffi-1.15.1-cp39-cp39-win32.whl", hash = "sha256:40f4774f5a9d4f5e344f31a32b5096977b5d48560c5592e2f3d2c4374bd543ee"}, + {file = "cffi-1.15.1-cp39-cp39-win_amd64.whl", hash = "sha256:70df4e3b545a17496c9b3f41f5115e69a4f2e77e94e1d2a8e1070bc0c38c8a3c"}, + {file = "cffi-1.15.1.tar.gz", hash = "sha256:d400bfb9a37b1351253cb402671cea7e89bdecc294e8016a707f6d1d8ac934f9"}, +] + +[package.dependencies] +pycparser = "*" + +[[package]] +name = "channels" +version = "4.0.0" +description = "Brings async, event-driven capabilities to Django 3.2 and up." +optional = false +python-versions = ">=3.7" +files = [ + {file = "channels-4.0.0-py3-none-any.whl", hash = "sha256:2253334ac76f67cba68c2072273f7e0e67dbdac77eeb7e318f511d2f9a53c5e4"}, + {file = "channels-4.0.0.tar.gz", hash = "sha256:0ce53507a7da7b148eaa454526e0e05f7da5e5d1c23440e4886cf146981d8420"}, +] + +[package.dependencies] +asgiref = ">=3.5.0,<4" +Django = ">=3.2" + +[package.extras] +daphne = ["daphne (>=4.0.0)"] +tests = ["async-timeout", "coverage (>=4.5,<5.0)", "pytest", "pytest-asyncio", "pytest-django"] + +[[package]] +name = "channels-redis" +version = "4.1.0" +description = "Redis-backed ASGI channel layer implementation" +optional = false +python-versions = ">=3.7" +files = [ + {file = "channels_redis-4.1.0-py3-none-any.whl", hash = "sha256:3696f5b9fe367ea495d402ba83d7c3c99e8ca0e1354ff8d913535976ed0abf73"}, + {file = "channels_redis-4.1.0.tar.gz", hash = "sha256:6bd4f75f4ab4a7db17cee495593ace886d7e914c66f8214a1f247ff6659c073a"}, +] + +[package.dependencies] +asgiref = ">=3.2.10,<4" +channels = "*" +msgpack = ">=1.0,<2.0" +redis = ">=4.5.3" + +[package.extras] +cryptography = ["cryptography (>=1.3.0)"] +tests = ["async-timeout", "cryptography (>=1.3.0)", "pytest", "pytest-asyncio", "pytest-timeout"] + +[[package]] +name = "chardet" +version = "5.1.0" +description = "Universal encoding detector for Python 3" +optional = false +python-versions = ">=3.7" +files = [ + {file = "chardet-5.1.0-py3-none-any.whl", hash = "sha256:362777fb014af596ad31334fde1e8c327dfdb076e1960d1694662d46a6917ab9"}, + {file = "chardet-5.1.0.tar.gz", hash = "sha256:0d62712b956bc154f85fb0a266e2a3c5913c2967e00348701b32411d6def31e5"}, +] + +[[package]] +name = "charset-normalizer" +version = "3.2.0" +description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +optional = false +python-versions = ">=3.7.0" +files = [ + {file = "charset-normalizer-3.2.0.tar.gz", hash = "sha256:3bb3d25a8e6c0aedd251753a79ae98a093c7e7b471faa3aa9a93a81431987ace"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0b87549028f680ca955556e3bd57013ab47474c3124dc069faa0b6545b6c9710"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7c70087bfee18a42b4040bb9ec1ca15a08242cf5867c58726530bdf3945672ed"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a103b3a7069b62f5d4890ae1b8f0597618f628b286b03d4bc9195230b154bfa9"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94aea8eff76ee6d1cdacb07dd2123a68283cb5569e0250feab1240058f53b623"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:db901e2ac34c931d73054d9797383d0f8009991e723dab15109740a63e7f902a"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b0dac0ff919ba34d4df1b6131f59ce95b08b9065233446be7e459f95554c0dc8"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:193cbc708ea3aca45e7221ae58f0fd63f933753a9bfb498a3b474878f12caaad"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09393e1b2a9461950b1c9a45d5fd251dc7c6f228acab64da1c9c0165d9c7765c"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:baacc6aee0b2ef6f3d308e197b5d7a81c0e70b06beae1f1fcacffdbd124fe0e3"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:bf420121d4c8dce6b889f0e8e4ec0ca34b7f40186203f06a946fa0276ba54029"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:c04a46716adde8d927adb9457bbe39cf473e1e2c2f5d0a16ceb837e5d841ad4f"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:aaf63899c94de41fe3cf934601b0f7ccb6b428c6e4eeb80da72c58eab077b19a"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d62e51710986674142526ab9f78663ca2b0726066ae26b78b22e0f5e571238dd"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-win32.whl", hash = "sha256:04e57ab9fbf9607b77f7d057974694b4f6b142da9ed4a199859d9d4d5c63fe96"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:48021783bdf96e3d6de03a6e39a1171ed5bd7e8bb93fc84cc649d11490f87cea"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:4957669ef390f0e6719db3613ab3a7631e68424604a7b448f079bee145da6e09"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:46fb8c61d794b78ec7134a715a3e564aafc8f6b5e338417cb19fe9f57a5a9bf2"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f779d3ad205f108d14e99bb3859aa7dd8e9c68874617c72354d7ecaec2a054ac"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f25c229a6ba38a35ae6e25ca1264621cc25d4d38dca2942a7fce0b67a4efe918"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2efb1bd13885392adfda4614c33d3b68dee4921fd0ac1d3988f8cbb7d589e72a"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f30b48dd7fa1474554b0b0f3fdfdd4c13b5c737a3c6284d3cdc424ec0ffff3a"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:246de67b99b6851627d945db38147d1b209a899311b1305dd84916f2b88526c6"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9bd9b3b31adcb054116447ea22caa61a285d92e94d710aa5ec97992ff5eb7cf3"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:8c2f5e83493748286002f9369f3e6607c565a6a90425a3a1fef5ae32a36d749d"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:3170c9399da12c9dc66366e9d14da8bf7147e1e9d9ea566067bbce7bb74bd9c2"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:7a4826ad2bd6b07ca615c74ab91f32f6c96d08f6fcc3902ceeedaec8cdc3bcd6"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:3b1613dd5aee995ec6d4c69f00378bbd07614702a315a2cf6c1d21461fe17c23"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9e608aafdb55eb9f255034709e20d5a83b6d60c054df0802fa9c9883d0a937aa"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-win32.whl", hash = "sha256:f2a1d0fd4242bd8643ce6f98927cf9c04540af6efa92323e9d3124f57727bfc1"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:681eb3d7e02e3c3655d1b16059fbfb605ac464c834a0c629048a30fad2b27489"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c57921cda3a80d0f2b8aec7e25c8aa14479ea92b5b51b6876d975d925a2ea346"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41b25eaa7d15909cf3ac4c96088c1f266a9a93ec44f87f1d13d4a0e86c81b982"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f058f6963fd82eb143c692cecdc89e075fa0828db2e5b291070485390b2f1c9c"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a7647ebdfb9682b7bb97e2a5e7cb6ae735b1c25008a70b906aecca294ee96cf4"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eef9df1eefada2c09a5e7a40991b9fc6ac6ef20b1372abd48d2794a316dc0449"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e03b8895a6990c9ab2cdcd0f2fe44088ca1c65ae592b8f795c3294af00a461c3"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:ee4006268ed33370957f55bf2e6f4d263eaf4dc3cfc473d1d90baff6ed36ce4a"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c4983bf937209c57240cff65906b18bb35e64ae872da6a0db937d7b4af845dd7"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:3bb7fda7260735efe66d5107fb7e6af6a7c04c7fce9b2514e04b7a74b06bf5dd"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:72814c01533f51d68702802d74f77ea026b5ec52793c791e2da806a3844a46c3"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:70c610f6cbe4b9fce272c407dd9d07e33e6bf7b4aa1b7ffb6f6ded8e634e3592"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-win32.whl", hash = "sha256:a401b4598e5d3f4a9a811f3daf42ee2291790c7f9d74b18d75d6e21dda98a1a1"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-win_amd64.whl", hash = "sha256:c0b21078a4b56965e2b12f247467b234734491897e99c1d51cee628da9786959"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:95eb302ff792e12aba9a8b8f8474ab229a83c103d74a750ec0bd1c1eea32e669"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1a100c6d595a7f316f1b6f01d20815d916e75ff98c27a01ae817439ea7726329"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6339d047dab2780cc6220f46306628e04d9750f02f983ddb37439ca47ced7149"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4b749b9cc6ee664a3300bb3a273c1ca8068c46be705b6c31cf5d276f8628a94"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a38856a971c602f98472050165cea2cdc97709240373041b69030be15047691f"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f87f746ee241d30d6ed93969de31e5ffd09a2961a051e60ae6bddde9ec3583aa"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89f1b185a01fe560bc8ae5f619e924407efca2191b56ce749ec84982fc59a32a"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e1c8a2f4c69e08e89632defbfabec2feb8a8d99edc9f89ce33c4b9e36ab63037"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2f4ac36d8e2b4cc1aa71df3dd84ff8efbe3bfb97ac41242fbcfc053c67434f46"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a386ebe437176aab38c041de1260cd3ea459c6ce5263594399880bbc398225b2"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:ccd16eb18a849fd8dcb23e23380e2f0a354e8daa0c984b8a732d9cfaba3a776d"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:e6a5bf2cba5ae1bb80b154ed68a3cfa2fa00fde979a7f50d6598d3e17d9ac20c"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:45de3f87179c1823e6d9e32156fb14c1927fcc9aba21433f088fdfb555b77c10"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-win32.whl", hash = "sha256:1000fba1057b92a65daec275aec30586c3de2401ccdcd41f8a5c1e2c87078706"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:8b2c760cfc7042b27ebdb4a43a4453bd829a5742503599144d54a032c5dc7e9e"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:855eafa5d5a2034b4621c74925d89c5efef61418570e5ef9b37717d9c796419c"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:203f0c8871d5a7987be20c72442488a0b8cfd0f43b7973771640fc593f56321f"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e857a2232ba53ae940d3456f7533ce6ca98b81917d47adc3c7fd55dad8fab858"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e86d77b090dbddbe78867a0275cb4df08ea195e660f1f7f13435a4649e954e5"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c4fb39a81950ec280984b3a44f5bd12819953dc5fa3a7e6fa7a80db5ee853952"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2dee8e57f052ef5353cf608e0b4c871aee320dd1b87d351c28764fc0ca55f9f4"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8700f06d0ce6f128de3ccdbc1acaea1ee264d2caa9ca05daaf492fde7c2a7200"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1920d4ff15ce893210c1f0c0e9d19bfbecb7983c76b33f046c13a8ffbd570252"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:c1c76a1743432b4b60ab3358c937a3fe1341c828ae6194108a94c69028247f22"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f7560358a6811e52e9c4d142d497f1a6e10103d3a6881f18d04dbce3729c0e2c"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:c8063cf17b19661471ecbdb3df1c84f24ad2e389e326ccaf89e3fb2484d8dd7e"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:cd6dbe0238f7743d0efe563ab46294f54f9bc8f4b9bcf57c3c666cc5bc9d1299"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:1249cbbf3d3b04902ff081ffbb33ce3377fa6e4c7356f759f3cd076cc138d020"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-win32.whl", hash = "sha256:6c409c0deba34f147f77efaa67b8e4bb83d2f11c8806405f76397ae5b8c0d1c9"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:7095f6fbfaa55defb6b733cfeb14efaae7a29f0b59d8cf213be4e7ca0b857b80"}, + {file = "charset_normalizer-3.2.0-py3-none-any.whl", hash = "sha256:8e098148dd37b4ce3baca71fb394c81dc5d9c7728c95df695d2dca218edf40e6"}, +] + +[[package]] +name = "click" +version = "8.1.6" +description = "Composable command line interface toolkit" +optional = false +python-versions = ">=3.7" +files = [ + {file = "click-8.1.6-py3-none-any.whl", hash = "sha256:fa244bb30b3b5ee2cae3da8f55c9e5e0c0e86093306301fb418eb9dc40fbded5"}, + {file = "click-8.1.6.tar.gz", hash = "sha256:48ee849951919527a045bfe3bf7baa8a959c423134e1a5b98c05c20ba75a1cbd"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + +[[package]] +name = "click-didyoumean" +version = "0.3.0" +description = "Enables git-like *did-you-mean* feature in click" +optional = false +python-versions = ">=3.6.2,<4.0.0" +files = [ + {file = "click-didyoumean-0.3.0.tar.gz", hash = "sha256:f184f0d851d96b6d29297354ed981b7dd71df7ff500d82fa6d11f0856bee8035"}, + {file = "click_didyoumean-0.3.0-py3-none-any.whl", hash = "sha256:a0713dc7a1de3f06bc0df5a9567ad19ead2d3d5689b434768a6145bff77c0667"}, +] + +[package.dependencies] +click = ">=7" + +[[package]] +name = "click-plugins" +version = "1.1.1" +description = "An extension module for click to enable registering CLI commands via setuptools entry-points." +optional = false +python-versions = "*" +files = [ + {file = "click-plugins-1.1.1.tar.gz", hash = "sha256:46ab999744a9d831159c3411bb0c79346d94a444df9a3a3742e9ed63645f264b"}, + {file = "click_plugins-1.1.1-py2.py3-none-any.whl", hash = "sha256:5d262006d3222f5057fd81e1623d4443e41dcda5dc815c06b442aa3c02889fc8"}, +] + +[package.dependencies] +click = ">=4.0" + +[package.extras] +dev = ["coveralls", "pytest (>=3.6)", "pytest-cov", "wheel"] + +[[package]] +name = "click-repl" +version = "0.3.0" +description = "REPL plugin for Click" +optional = false +python-versions = ">=3.6" +files = [ + {file = "click-repl-0.3.0.tar.gz", hash = "sha256:17849c23dba3d667247dc4defe1757fff98694e90fe37474f3feebb69ced26a9"}, + {file = "click_repl-0.3.0-py3-none-any.whl", hash = "sha256:fb7e06deb8da8de86180a33a9da97ac316751c094c6899382da7feeeeb51b812"}, +] + +[package.dependencies] +click = ">=7.0" +prompt-toolkit = ">=3.0.36" + +[package.extras] +testing = ["pytest (>=7.2.1)", "pytest-cov (>=4.0.0)", "tox (>=4.4.3)"] + +[[package]] +name = "colorama" +version = "0.4.6" +description = "Cross-platform colored terminal text." +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +files = [ + {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, + {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, +] + +[[package]] +name = "configparser" +version = "6.0.0" +description = "Updated configparser from stdlib for earlier Pythons." +optional = false +python-versions = ">=3.8" +files = [ + {file = "configparser-6.0.0-py3-none-any.whl", hash = "sha256:900ea2bb01b2540b1a644ad3d5351e9b961a4a012d4732f619375fb8f641ee19"}, + {file = "configparser-6.0.0.tar.gz", hash = "sha256:ec914ab1e56c672de1f5c3483964e68f71b34e457904b7b76e06b922aec067a8"}, +] + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +testing = ["pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-ruff", "types-backports"] + +[[package]] +name = "constantly" +version = "15.1.0" +description = "Symbolic constants in Python" +optional = false +python-versions = "*" +files = [ + {file = "constantly-15.1.0-py2.py3-none-any.whl", hash = "sha256:dd2fa9d6b1a51a83f0d7dd76293d734046aa176e384bf6e33b7e44880eb37c5d"}, + {file = "constantly-15.1.0.tar.gz", hash = "sha256:586372eb92059873e29eba4f9dec8381541b4d3834660707faf8ba59146dfc35"}, +] + +[[package]] +name = "coreapi" +version = "2.3.3" +description = "Python client library for Core API." +optional = false +python-versions = "*" +files = [ + {file = "coreapi-2.3.3-py2.py3-none-any.whl", hash = "sha256:bf39d118d6d3e171f10df9ede5666f63ad80bba9a29a8ec17726a66cf52ee6f3"}, + {file = "coreapi-2.3.3.tar.gz", hash = "sha256:46145fcc1f7017c076a2ef684969b641d18a2991051fddec9458ad3f78ffc1cb"}, +] + +[package.dependencies] +coreschema = "*" +itypes = "*" +requests = "*" +uritemplate = "*" + +[[package]] +name = "coreschema" +version = "0.0.4" +description = "Core Schema." +optional = false +python-versions = "*" +files = [ + {file = "coreschema-0.0.4-py2-none-any.whl", hash = "sha256:5e6ef7bf38c1525d5e55a895934ab4273548629f16aed5c0a6caa74ebf45551f"}, + {file = "coreschema-0.0.4.tar.gz", hash = "sha256:9503506007d482ab0867ba14724b93c18a33b22b6d19fb419ef2d239dd4a1607"}, +] + +[package.dependencies] +jinja2 = "*" + +[[package]] +name = "crcmod" +version = "1.7" +description = "CRC Generator" +optional = false +python-versions = "*" +files = [ + {file = "crcmod-1.7.tar.gz", hash = "sha256:dc7051a0db5f2bd48665a990d3ec1cc305a466a77358ca4492826f41f283601e"}, +] + +[[package]] +name = "cron-descriptor" +version = "1.4.0" +description = "A Python library that converts cron expressions into human readable strings." +optional = false +python-versions = "*" +files = [ + {file = "cron_descriptor-1.4.0.tar.gz", hash = "sha256:b6ff4e3a988d7ca04a4ab150248e9f166fb7a5c828a85090e75bcc25aa93b4dd"}, +] + +[package.extras] +dev = ["polib"] + +[[package]] +name = "cryptography" +version = "41.0.2" +description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." +optional = false +python-versions = ">=3.7" +files = [ + {file = "cryptography-41.0.2-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:01f1d9e537f9a15b037d5d9ee442b8c22e3ae11ce65ea1f3316a41c78756b711"}, + {file = "cryptography-41.0.2-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:079347de771f9282fbfe0e0236c716686950c19dee1b76240ab09ce1624d76d7"}, + {file = "cryptography-41.0.2-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:439c3cc4c0d42fa999b83ded80a9a1fb54d53c58d6e59234cfe97f241e6c781d"}, + {file = "cryptography-41.0.2-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f14ad275364c8b4e525d018f6716537ae7b6d369c094805cae45300847e0894f"}, + {file = "cryptography-41.0.2-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:84609ade00a6ec59a89729e87a503c6e36af98ddcd566d5f3be52e29ba993182"}, + {file = "cryptography-41.0.2-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:49c3222bb8f8e800aead2e376cbef687bc9e3cb9b58b29a261210456a7783d83"}, + {file = "cryptography-41.0.2-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:d73f419a56d74fef257955f51b18d046f3506270a5fd2ac5febbfa259d6c0fa5"}, + {file = "cryptography-41.0.2-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:2a034bf7d9ca894720f2ec1d8b7b5832d7e363571828037f9e0c4f18c1b58a58"}, + {file = "cryptography-41.0.2-cp37-abi3-win32.whl", hash = "sha256:d124682c7a23c9764e54ca9ab5b308b14b18eba02722b8659fb238546de83a76"}, + {file = "cryptography-41.0.2-cp37-abi3-win_amd64.whl", hash = "sha256:9c3fe6534d59d071ee82081ca3d71eed3210f76ebd0361798c74abc2bcf347d4"}, + {file = "cryptography-41.0.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:a719399b99377b218dac6cf547b6ec54e6ef20207b6165126a280b0ce97e0d2a"}, + {file = "cryptography-41.0.2-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:182be4171f9332b6741ee818ec27daff9fb00349f706629f5cbf417bd50e66fd"}, + {file = "cryptography-41.0.2-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:7a9a3bced53b7f09da251685224d6a260c3cb291768f54954e28f03ef14e3766"}, + {file = "cryptography-41.0.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:f0dc40e6f7aa37af01aba07277d3d64d5a03dc66d682097541ec4da03cc140ee"}, + {file = "cryptography-41.0.2-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:674b669d5daa64206c38e507808aae49904c988fa0a71c935e7006a3e1e83831"}, + {file = "cryptography-41.0.2-pp38-pypy38_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:7af244b012711a26196450d34f483357e42aeddb04128885d95a69bd8b14b69b"}, + {file = "cryptography-41.0.2-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:9b6d717393dbae53d4e52684ef4f022444fc1cce3c48c38cb74fca29e1f08eaa"}, + {file = "cryptography-41.0.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:192255f539d7a89f2102d07d7375b1e0a81f7478925b3bc2e0549ebf739dae0e"}, + {file = "cryptography-41.0.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f772610fe364372de33d76edcd313636a25684edb94cee53fd790195f5989d14"}, + {file = "cryptography-41.0.2-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:b332cba64d99a70c1e0836902720887fb4529ea49ea7f5462cf6640e095e11d2"}, + {file = "cryptography-41.0.2-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:9a6673c1828db6270b76b22cc696f40cde9043eb90373da5c2f8f2158957f42f"}, + {file = "cryptography-41.0.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:342f3767e25876751e14f8459ad85e77e660537ca0a066e10e75df9c9e9099f0"}, + {file = "cryptography-41.0.2.tar.gz", hash = "sha256:7d230bf856164de164ecb615ccc14c7fc6de6906ddd5b491f3af90d3514c925c"}, +] + +[package.dependencies] +cffi = ">=1.12" + +[package.extras] +docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=1.1.1)"] +docstest = ["pyenchant (>=1.6.11)", "sphinxcontrib-spelling (>=4.0.1)", "twine (>=1.12.0)"] +nox = ["nox"] +pep8test = ["black", "check-sdist", "mypy", "ruff"] +sdist = ["build"] +ssh = ["bcrypt (>=3.1.5)"] +test = ["pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] +test-randomorder = ["pytest-randomly"] + +[[package]] +name = "cython" +version = "3.0.0" +description = "The Cython compiler for writing C extensions in the Python language." +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "Cython-3.0.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7c7d728e1a49ad01d41181e3a9ea80b8d14e825f4679e4dd837cbf7bca7998a5"}, + {file = "Cython-3.0.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:626a4a6ef4b7ced87c348ea805488e4bd39dad9d0b39659aa9e1040b62bbfedf"}, + {file = "Cython-3.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:33c900d1ca9f622b969ac7d8fc44bdae140a4a6c7d8819413b51f3ccd0586a09"}, + {file = "Cython-3.0.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a65bc50dc1bc2faeafd9425defbdef6a468974f5c4192497ff7f14adccfdcd32"}, + {file = "Cython-3.0.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:3b71b399b10b038b056ad12dce1e317a8aa7a96e99de7e4fa2fa5d1c9415cfb9"}, + {file = "Cython-3.0.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f42f304c097cc53e9eb5f1a1d150380353d5018a3191f1b77f0de353c762181e"}, + {file = "Cython-3.0.0-cp310-cp310-win32.whl", hash = "sha256:3e234e2549e808d9259fdb23ebcfd145be30c638c65118326ec33a8d29248dc2"}, + {file = "Cython-3.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:829c8333195100448a23863cf64a07e1334fae6a275aefe871458937911531b6"}, + {file = "Cython-3.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:06db81b1a01858fcc406616f8528e686ffb6cf7c3d78fb83767832bfecea8ad8"}, + {file = "Cython-3.0.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c93634845238645ce7abf63a56b1c5b6248189005c7caff898fd4a0dac1c5e1e"}, + {file = "Cython-3.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa606675c6bd23478b1d174e2a84e3c5a2c660968f97dc455afe0fae198f9d3d"}, + {file = "Cython-3.0.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d3355e6f690184f984eeb108b0f5bbc4bcf8b9444f8168933acf79603abf7baf"}, + {file = "Cython-3.0.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:93a34e1ca8afa4b7075b02ed14a7e4969256297029fb1bfd4cbe48f7290dbcff"}, + {file = "Cython-3.0.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:bb1165ca9e78823f9ad1efa5b3d83156f868eabd679a615d140a3021bb92cd65"}, + {file = "Cython-3.0.0-cp311-cp311-win32.whl", hash = "sha256:2fadde1da055944f5e1e17625055f54ddd11f451889110278ef30e07bd5e1695"}, + {file = "Cython-3.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:254ed1f03a6c237fa64f0c6e44862058de65bfa2e6a3b48ca3c205492e0653aa"}, + {file = "Cython-3.0.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:4e212237b7531759befb92699c452cd65074a78051ae4ee36ff8b237395ecf3d"}, + {file = "Cython-3.0.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9f29307463eba53747b31f71394ed087e3e3e264dcc433e62de1d51f5c0c966c"}, + {file = "Cython-3.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:53328a8af0806bebbdb48a4191883b11ee9d9dfb084d84f58fa5a8ab58baefc9"}, + {file = "Cython-3.0.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5962e70b15e863e72bed6910e8c6ffef77d36cc98e2b31c474378f3b9e49b0e3"}, + {file = "Cython-3.0.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:9e69139f4e60ab14c50767a568612ea64d6907e9c8e0289590a170eb495e005f"}, + {file = "Cython-3.0.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:c40bdbcb2286f0aeeb5df9ce53d45da2d2a9b36a16b331cd0809d212d22a8fc7"}, + {file = "Cython-3.0.0-cp312-cp312-win32.whl", hash = "sha256:8abb8915eb2e57fa53d918afe641c05d1bcc6ed1913682ec1f28de71f4e3f398"}, + {file = "Cython-3.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:30a4bd2481e59bd7ab2539f835b78edc19fc455811e476916f56026b93afd28b"}, + {file = "Cython-3.0.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:0e1e4b7e4bfbf22fecfa5b852f0e499c442d4853b7ebd33ae37cdec9826ed5d8"}, + {file = "Cython-3.0.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b00df42cdd1a285a64491ba23de08ab14169d3257c840428d40eb7e8e9979af"}, + {file = "Cython-3.0.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:650d03ddddc08b051b4659778733f0f173ca7d327415755c05d265a6c1ba02fb"}, + {file = "Cython-3.0.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4965f2ebade17166f21a508d66dd60d2a0b3a3b90abe3f72003baa17ae020dd6"}, + {file = "Cython-3.0.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:4123c8d03167803df31da6b39de167cb9c04ac0aa4e35d4e5aa9d08ad511b84d"}, + {file = "Cython-3.0.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:296c53b6c0030cf82987eef163444e8d7631cc139d995f9d58679d9fd1ddbf31"}, + {file = "Cython-3.0.0-cp36-cp36m-win32.whl", hash = "sha256:0d2c1e172f1c81bafcca703093608e10dc16e3e2d24c5644c17606c7fdb1792c"}, + {file = "Cython-3.0.0-cp36-cp36m-win_amd64.whl", hash = "sha256:bc816d8eb3686d6f8d165f4156bac18c1147e1035dc28a76742d0b7fb5b7c032"}, + {file = "Cython-3.0.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8d86651347bbdbac1aca1824696c5e4c0a3b162946c422edcca2be12a03744d1"}, + {file = "Cython-3.0.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:84176bd04ce9f3cc8799b47ec6d1959fa1ea5e71424507df7bbf0b0915bbedef"}, + {file = "Cython-3.0.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:35abcf07b8277ec95bbe49a07b5c8760a2d941942ccfe759a94c8d2fe5602e9f"}, + {file = "Cython-3.0.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a44d6b9a29b2bff38bb648577b2fcf6a68cf8b1783eee89c2eb749f69494b98d"}, + {file = "Cython-3.0.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:4dc6bbe7cf079db37f1ebb9b0f10d0d7f29e293bb8688e92d50b5ea7a91d82f3"}, + {file = "Cython-3.0.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:e28763e75e380b8be62b02266a7995a781997c97c119efbdccb8fb954bcd7574"}, + {file = "Cython-3.0.0-cp37-cp37m-win32.whl", hash = "sha256:edae615cb4af51d5173e76ba9aea212424d025c57012e9cdf2f131f774c5ba71"}, + {file = "Cython-3.0.0-cp37-cp37m-win_amd64.whl", hash = "sha256:20c604e974832aaf8b7a1f5455ee7274b34df62a35ee095cd7d2ed7e818e6c53"}, + {file = "Cython-3.0.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c85fd2b1cbd9400d60ebe074795bb9a9188752f1612be3b35b0831a24879b91f"}, + {file = "Cython-3.0.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:090256c687106932339f87f888b95f0d69c617bc9b18801555545b695d29d8ab"}, + {file = "Cython-3.0.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cec2a67a0a7d9d4399758c0657ca03e5912e37218859cfbf046242cc532bfb3b"}, + {file = "Cython-3.0.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a1cdd01ce45333bc264a218c6e183700d6b998f029233f586a53c9b13455c2d2"}, + {file = "Cython-3.0.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:ecee663d2d50ca939fc5db81f2f8a219c2417b4651ad84254c50a03a9cb1aadd"}, + {file = "Cython-3.0.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:30f10e79393b411af7677c270ea69807acb9fc30205c8ff25561f4deef780ec1"}, + {file = "Cython-3.0.0-cp38-cp38-win32.whl", hash = "sha256:609777d3a7a0a23b225e84d967af4ad2485c8bdfcacef8037cf197e87d431ca0"}, + {file = "Cython-3.0.0-cp38-cp38-win_amd64.whl", hash = "sha256:7f4a6dfd42ae0a45797f50fc4f6add702abf46ab3e7cd61811a6c6a97a40e1a2"}, + {file = "Cython-3.0.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2d8158277c8942c0b20ff4c074fe6a51c5b89e6ac60cef606818de8c92773596"}, + {file = "Cython-3.0.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54e34f99b2a8c1e11478541b2822e6408c132b98b6b8f5ed89411e5e906631ea"}, + {file = "Cython-3.0.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:877d1c8745df59dd2061a0636c602729e9533ba13f13aa73a498f68662e1cbde"}, + {file = "Cython-3.0.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:204690be60f0ff32eb70b04f28ef0d1e50ffd7b3f77ba06a7dc2389ee3b848e0"}, + {file = "Cython-3.0.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:06fcb4628ccce2ba5abc8630adbeaf4016f63a359b4c6c3827b2d80e0673981c"}, + {file = "Cython-3.0.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:090e24cfa31c926d0b13d8bb2ef48175acdd061ae1413343c94a2b12a4a4fa6f"}, + {file = "Cython-3.0.0-cp39-cp39-win32.whl", hash = "sha256:4cd00f2158dc00f7f93a92444d0f663eda124c9c29bbbd658964f4e89c357fe8"}, + {file = "Cython-3.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:5b4cc896d49ce2bae8d6a030f9a4c64965b59c38acfbf4617685e17f7fcf1731"}, + {file = "Cython-3.0.0-py2.py3-none-any.whl", hash = "sha256:ff1aef1a03cfe293237c7a86ae9625b0411b2df30c53d1a7f29a8d381f38a1df"}, + {file = "Cython-3.0.0.tar.gz", hash = "sha256:350b18f9673e63101dbbfcf774ee2f57c20ac4636d255741d76ca79016b1bd82"}, +] + +[[package]] +name = "daphne" +version = "4.0.0" +description = "Django ASGI (HTTP/WebSocket) server" +optional = false +python-versions = ">=3.7" +files = [ + {file = "daphne-4.0.0-py3-none-any.whl", hash = "sha256:a288ece46012b6b719c37150be67c69ebfca0793a8521bf821533bad983179b2"}, + {file = "daphne-4.0.0.tar.gz", hash = "sha256:cce9afc8f49a4f15d4270b8cfb0e0fe811b770a5cc795474e97e4da287497666"}, +] + +[package.dependencies] +asgiref = ">=3.5.2,<4" +autobahn = ">=22.4.2" +twisted = {version = ">=22.4", extras = ["tls"]} + +[package.extras] +tests = ["django", "hypothesis", "pytest", "pytest-asyncio"] + +[[package]] +name = "data-tree" +version = "0.0.1" +description = "" +optional = false +python-versions = "*" +files = [ + {file = "data_tree-0.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:904cc0545cb3c8bc3fb81928c754b10510c1ae8ca9229de0c5cc8817eb301113"}, + {file = "data_tree-0.0.1.tar.gz", hash = "sha256:06f2a18b372cf2451166d426591f6e6fc73a7aabcad97255d50927aa3c3d5a0e"}, +] + +[[package]] +name = "debtcollector" +version = "2.5.0" +description = "A collection of Python deprecation patterns and strategies that help you collect your technical debt in a non-destructive manner." +optional = false +python-versions = ">=3.6" +files = [ + {file = "debtcollector-2.5.0-py3-none-any.whl", hash = "sha256:1393a527d2c72f143ffa6a629e9c33face6642634eece475b48cab7b04ba61f3"}, + {file = "debtcollector-2.5.0.tar.gz", hash = "sha256:dc9d1ad3f745c43f4bbedbca30f9ffe8905a8c028c9926e61077847d5ea257ab"}, +] + +[package.dependencies] +wrapt = ">=1.7.0" + +[[package]] +name = "decorator" +version = "5.1.1" +description = "Decorators for Humans" +optional = false +python-versions = ">=3.5" +files = [ + {file = "decorator-5.1.1-py3-none-any.whl", hash = "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186"}, + {file = "decorator-5.1.1.tar.gz", hash = "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330"}, +] + +[[package]] +name = "django" +version = "4.1.10" +description = "A high-level Python web framework that encourages rapid development and clean, pragmatic design." +optional = false +python-versions = ">=3.8" +files = [ + {file = "Django-4.1.10-py3-none-any.whl", hash = "sha256:26d0260c2fb8121009e62ffc548b2398dea2522b6454208a852fb0ef264c206c"}, + {file = "Django-4.1.10.tar.gz", hash = "sha256:56343019a9fd839e2e5bf203daf45f25af79d5bffa4c71d56eae4f4404d82ade"}, +] + +[package.dependencies] +asgiref = ">=3.5.2,<4" +sqlparse = ">=0.2.2" +tzdata = {version = "*", markers = "sys_platform == \"win32\""} + +[package.extras] +argon2 = ["argon2-cffi (>=19.1.0)"] +bcrypt = ["bcrypt"] + +[[package]] +name = "django-auth-ldap" +version = "4.4.0" +description = "Django LDAP authentication backend" +optional = false +python-versions = ">=3.8" +files = [ + {file = "django-auth-ldap-4.4.0.tar.gz", hash = "sha256:797931ac5d55c4ca14c179d5892420cc2a98aa81e44323d595f5419c1b45c306"}, + {file = "django_auth_ldap-4.4.0-py3-none-any.whl", hash = "sha256:da85f315a05b1327575aa67075049fab8753ddc05521a6fc6195755ff9ab72fd"}, +] + +[package.dependencies] +Django = ">=3.2" +python-ldap = ">=3.1" + +[[package]] +name = "django-bootstrap3" +version = "23.4" +description = "Bootstrap 3 for Django" +optional = false +python-versions = ">=3.8" +files = [ + {file = "django_bootstrap3-23.4-py3-none-any.whl", hash = "sha256:fc54b9afc6e0d33b9e2ac039dd022996ee95fc19bdf8320f4fd01ec611143ee3"}, + {file = "django_bootstrap3-23.4.tar.gz", hash = "sha256:975e6017bb25b29a86416c4fbac6020f15bfd36d66861f42a20dd4ccfdab435d"}, +] + +[package.dependencies] +beautifulsoup4 = ">=4.8.0" +django = ">=3.2" + +[[package]] +name = "django-cas-ng" +version = "4.3.0" +description = "" +optional = false +python-versions = ">=3.7" +files = [ + {file = "django-cas-ng-4.3.1.zip", hash = "sha256:aeea96ad7958e3cb40d9bb5ef6a1add66f720835dfe87cc1dfe163f92d084690"}, +] + +[package.dependencies] +Django = ">=2.2" +python-cas = ">=1.6.0" + +[package.source] +type = "url" +url = "https://github.com/ibuler/django-cas-ng/releases/download/v4.3.1/django-cas-ng-4.3.1.zip" + +[[package]] +name = "django-celery-beat" +version = "2.5.0" +description = "Database-backed Periodic Tasks." +optional = false +python-versions = "*" +files = [ + {file = "django-celery-beat-2.5.0.tar.gz", hash = "sha256:cd0a47f5958402f51ac0c715bc942ae33d7b50b4e48cba91bc3f2712be505df1"}, + {file = "django_celery_beat-2.5.0-py3-none-any.whl", hash = "sha256:ae460faa5ea142fba0875409095d22f6bd7bcc7377889b85e8cab5c0dfb781fe"}, +] + +[package.dependencies] +celery = ">=5.2.3,<6.0" +cron-descriptor = ">=1.2.32" +Django = ">=2.2,<5.0" +django-timezone-field = ">=5.0" +python-crontab = ">=2.3.4" +tzdata = "*" + +[[package]] +name = "django-debug-toolbar" +version = "4.1.0" +description = "A configurable set of panels that display various debug information about the current request/response." +optional = false +python-versions = ">=3.8" +files = [ + {file = "django_debug_toolbar-4.1.0-py3-none-any.whl", hash = "sha256:a0b532ef5d52544fd745d1dcfc0557fa75f6f0d1962a8298bd568427ef2fa436"}, + {file = "django_debug_toolbar-4.1.0.tar.gz", hash = "sha256:f57882e335593cb8e74c2bda9f1116bbb9ca8fc0d81b50a75ace0f83de5173c7"}, +] + +[package.dependencies] +django = ">=3.2.4" +sqlparse = ">=0.2" + +[[package]] +name = "django-filter" +version = "23.2" +description = "Django-filter is a reusable Django application for allowing users to filter querysets dynamically." +optional = false +python-versions = ">=3.7" +files = [ + {file = "django-filter-23.2.tar.gz", hash = "sha256:2fe15f78108475eda525692813205fa6f9e8c1caf1ae65daa5862d403c6dbf00"}, + {file = "django_filter-23.2-py3-none-any.whl", hash = "sha256:d12d8e0fc6d3eb26641e553e5d53b191eb8cec611427d4bdce0becb1f7c172b5"}, +] + +[package.dependencies] +Django = ">=3.2" + +[[package]] +name = "django-formtools" +version = "2.4.1" +description = "A set of high-level abstractions for Django forms" +optional = false +python-versions = ">=3.7" +files = [ + {file = "django-formtools-2.4.1.tar.gz", hash = "sha256:21f8d5dac737f1e636fa8a0a10969c1c32f525a6dfa27c29592827ba70d9643a"}, + {file = "django_formtools-2.4.1-py3-none-any.whl", hash = "sha256:49ea8a64ddef4728a558bf5f8f622c0f4053b979edcf193bf00dd80432ab2f12"}, +] + +[package.dependencies] +Django = ">=3.2" + +[[package]] +name = "django-private-storage" +version = "3.1" +description = "Private media file storage for Django projects" +optional = false +python-versions = "*" +files = [ + {file = "django-private-storage-3.1.tar.gz", hash = "sha256:e3f0440f5d8f0da0fdb9da0285dad00e279ea43da68324a8aaf0c31c999c8e8c"}, + {file = "django_private_storage-3.1-py3-none-any.whl", hash = "sha256:cd11fa3c40e15bf902b3566dde8082c86f1cbb2900115f15c63e4b5278d96fe7"}, +] + +[[package]] +name = "django-proxy" +version = "1.2.2" +description = "A simple HTTP proxy service as a Django app" +optional = false +python-versions = "*" +files = [ + {file = "django_proxy-1.2.2-py3-none-any.whl", hash = "sha256:f3e54e102cf2d328124f51ce8e76a08cb058ed4aea01bea23148bc785bbccafc"}, +] + +[package.dependencies] +requests = "*" + +[[package]] +name = "django-radius" +version = "1.4.0" +description = "Django authentication backend for RADIUS" +optional = false +python-versions = "*" +files = [ + {file = "1.5.0.zip", hash = "sha256:b50680dd1c577a099f90d510856b3e55aa496d8c876beabb5b0a79fc94fcfae9"}, +] + +[package.dependencies] +pyrad = ">=1.2,<2.2 || >2.2" + +[package.source] +type = "url" +url = "https://github.com/ibuler/django-radius/archive/refs/tags/1.5.0.zip" + +[[package]] +name = "django-ranged-response" +version = "0.2.0" +description = "Modified Django FileResponse that adds Content-Range headers." +optional = false +python-versions = "*" +files = [ + {file = "django-ranged-response-0.2.0.tar.gz", hash = "sha256:f71fff352a37316b9bead717fc76e4ddd6c9b99c4680cdf4783b9755af1cf985"}, +] + +[package.dependencies] +django = "*" + +[[package]] +name = "django-redis" +version = "5.3.0" +description = "Full featured redis cache backend for Django." +optional = false +python-versions = ">=3.6" +files = [ + {file = "django-redis-5.3.0.tar.gz", hash = "sha256:8bc5793ec06b28ea802aad85ec437e7646511d4e571e07ccad19cfed8b9ddd44"}, + {file = "django_redis-5.3.0-py3-none-any.whl", hash = "sha256:2d8660d39f586c41c9907d5395693c477434141690fd7eca9d32376af00b0aac"}, +] + +[package.dependencies] +Django = ">=3.2" +redis = ">=3,<4.0.0 || >4.0.0,<4.0.1 || >4.0.1" + +[package.extras] +hiredis = ["redis[hiredis] (>=3,!=4.0.0,!=4.0.1)"] + +[[package]] +name = "django-rest-swagger" +version = "2.2.0" +description = "Swagger UI for Django REST Framework 3.5+" +optional = false +python-versions = "*" +files = [ + {file = "django-rest-swagger-2.2.0.tar.gz", hash = "sha256:48f6aded9937e90ae7cbe9e6c932b9744b8af80cc4e010088b3278c700e0685b"}, + {file = "django_rest_swagger-2.2.0-py2.py3-none-any.whl", hash = "sha256:b039b0288bab4665cd45dc5d16f94b13911bc4ad0ed55f74ad3b90aa31c87c17"}, +] + +[package.dependencies] +coreapi = ">=2.3.0" +djangorestframework = ">=3.5.4" +openapi-codec = ">=1.3.1" +simplejson = "*" + +[[package]] +name = "django-simple-captcha" +version = "0.5.18" +description = "A very simple, yet powerful, Django captcha application" +optional = false +python-versions = "*" +files = [ + {file = "django-simple-captcha-0.5.18.tar.gz", hash = "sha256:6e1fcc4f4005f7d69ee7a2e59a7e863b5d3918f36a85a4d811498984aecc48ce"}, + {file = "django_simple_captcha-0.5.18-py2.py3-none-any.whl", hash = "sha256:567ad84fa64c86508c679b8425cc1410c44b3cd6467e54f8d31cf077d9366407"}, +] + +[package.dependencies] +Django = ">=3.2" +django-ranged-response = "0.2.0" +Pillow = ">=6.2.0" + +[package.extras] +test = ["testfixtures"] + +[[package]] +name = "django-simple-history" +version = "3.3.0" +description = "Store model history and view/revert changes from admin site." +optional = false +python-versions = ">=3.7" +files = [ + {file = "django-simple-history-3.3.0.tar.gz", hash = "sha256:2313d2d346f15a1e7a92adb3b6696b226f1cd0c1d920869ec40c4c4076614c41"}, + {file = "django_simple_history-3.3.0-py3-none-any.whl", hash = "sha256:dc1f98e558a0a1e0b6371c3b8efb85f86e02a6db56e83d0ec198343b7408d00a"}, +] + +[[package]] +name = "django-timezone-field" +version = "5.1" +description = "A Django app providing DB, form, and REST framework fields for zoneinfo and pytz timezone objects." +optional = false +python-versions = ">=3.7,<4.0" +files = [ + {file = "django_timezone_field-5.1-py3-none-any.whl", hash = "sha256:16ca9955a4e16064e32168b1a0d1cdb2839679c6cb56856c1f49f506e2ca4281"}, + {file = "django_timezone_field-5.1.tar.gz", hash = "sha256:73fc49519273cd5da1c7f16abc04a4bcad87b00cc02968d0d384c0fecf9a8a86"}, +] + +[package.dependencies] +Django = ">=2.2,<3.0.dev0 || >=3.2.dev0,<5.0" +pytz = "*" + +[[package]] +name = "djangorestframework" +version = "3.14.0" +description = "Web APIs for Django, made easy." +optional = false +python-versions = ">=3.6" +files = [ + {file = "djangorestframework-3.14.0-py3-none-any.whl", hash = "sha256:eb63f58c9f218e1a7d064d17a70751f528ed4e1d35547fdade9aaf4cd103fd08"}, + {file = "djangorestframework-3.14.0.tar.gz", hash = "sha256:579a333e6256b09489cbe0a067e66abe55c6595d8926be6b99423786334350c8"}, +] + +[package.dependencies] +django = ">=3.0" +pytz = "*" + +[[package]] +name = "djangorestframework-bulk" +version = "0.2.1" +description = "Django REST Framework bulk CRUD view mixins" +optional = false +python-versions = "*" +files = [ + {file = "djangorestframework-bulk-0.2.1.tar.gz", hash = "sha256:39230d8379acebd86d313df6c9150cafecb636eae1d097c30a26389ab9fee5b1"}, +] + +[package.dependencies] +django = "*" +djangorestframework = "*" +setuptools = "*" + +[[package]] +name = "dnspython" +version = "2.4.1" +description = "DNS toolkit" +optional = false +python-versions = ">=3.8,<4.0" +files = [ + {file = "dnspython-2.4.1-py3-none-any.whl", hash = "sha256:5b7488477388b8c0b70a8ce93b227c5603bc7b77f1565afe8e729c36c51447d7"}, + {file = "dnspython-2.4.1.tar.gz", hash = "sha256:c33971c79af5be968bb897e95c2448e11a645ee84d93b265ce0b7aabe5dfdca8"}, +] + +[package.extras] +dnssec = ["cryptography (>=2.6,<42.0)"] +doh = ["h2 (>=4.1.0)", "httpcore (>=0.17.3)", "httpx (>=0.24.1)"] +doq = ["aioquic (>=0.9.20)"] +idna = ["idna (>=2.1,<4.0)"] +trio = ["trio (>=0.14,<0.23)"] +wmi = ["wmi (>=1.5.1,<2.0.0)"] + +[[package]] +name = "docutils" +version = "0.20.1" +description = "Docutils -- Python Documentation Utilities" +optional = false +python-versions = ">=3.7" +files = [ + {file = "docutils-0.20.1-py3-none-any.whl", hash = "sha256:96f387a2c5562db4476f09f13bbab2192e764cac08ebbf3a34a95d9b1e4a59d6"}, + {file = "docutils-0.20.1.tar.gz", hash = "sha256:f08a4e276c3a1583a86dce3e34aba3fe04d02bba2dd51ed16106244e8a923e3b"}, +] + +[[package]] +name = "drf-nested-routers" +version = "0.93.4" +description = "Nested resources for the Django Rest Framework" +optional = false +python-versions = ">=3.5" +files = [ + {file = "drf-nested-routers-0.93.4.tar.gz", hash = "sha256:01aa556b8c08608bb74fb34f6ca065a5183f2cda4dc0478192cc17a2581d71b0"}, + {file = "drf_nested_routers-0.93.4-py2.py3-none-any.whl", hash = "sha256:996b77f3f4dfaf64569e7b8f04e3919945f90f95366838ca5b8bed9dd709d6c5"}, +] + +[package.dependencies] +Django = ">=1.11" +djangorestframework = ">=3.6.0" + +[[package]] +name = "drf-writable-nested" +version = "0.7.0" +description = "Writable nested helpers for django-rest-framework's serializers" +optional = false +python-versions = ">=3.7" +files = [ + {file = "drf_writable_nested-0.7.0-py3-none-any.whl", hash = "sha256:154c0381e8a3a477e0fd539d5e1caf8ff4c1097a9c0c0fe741d4858b11b0455b"}, +] + +[[package]] +name = "drf-yasg" +version = "1.21.7" +description = "Automated generation of real Swagger/OpenAPI 2.0 schemas from Django Rest Framework code." +optional = false +python-versions = ">=3.6" +files = [ + {file = "drf-yasg-1.21.7.tar.gz", hash = "sha256:4c3b93068b3dfca6969ab111155e4dd6f7b2d680b98778de8fd460b7837bdb0d"}, + {file = "drf_yasg-1.21.7-py3-none-any.whl", hash = "sha256:f85642072c35e684356475781b7ecf5d218fff2c6185c040664dd49f0a4be181"}, +] + +[package.dependencies] +django = ">=2.2.16" +djangorestframework = ">=3.10.3" +inflection = ">=0.3.1" +packaging = ">=21.0" +pytz = ">=2021.1" +pyyaml = ">=5.1" +uritemplate = ">=3.0.0" + +[package.extras] +coreapi = ["coreapi (>=2.3.3)", "coreschema (>=0.0.4)"] +validation = ["swagger-spec-validator (>=2.1.0)"] + +[[package]] +name = "ecdsa" +version = "0.18.0" +description = "ECDSA cryptographic signature library (pure python)" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ + {file = "ecdsa-0.18.0-py2.py3-none-any.whl", hash = "sha256:80600258e7ed2f16b9aa1d7c295bd70194109ad5a30fdee0eaeefef1d4c559dd"}, + {file = "ecdsa-0.18.0.tar.gz", hash = "sha256:190348041559e21b22a1d65cee485282ca11a6f81d503fddb84d5017e9ed1e49"}, +] + +[package.dependencies] +six = ">=1.9.0" + +[package.extras] +gmpy = ["gmpy"] +gmpy2 = ["gmpy2"] + +[[package]] +name = "elastic-transport" +version = "8.4.0" +description = "Transport classes and utilities shared among Python Elastic client libraries" +optional = false +python-versions = ">=3.6" +files = [ + {file = "elastic-transport-8.4.0.tar.gz", hash = "sha256:b9ad708ceb7fcdbc6b30a96f886609a109f042c0b9d9f2e44403b3133ba7ff10"}, + {file = "elastic_transport-8.4.0-py3-none-any.whl", hash = "sha256:19db271ab79c9f70f8c43f8f5b5111408781a6176b54ab2e54d713b6d9ceb815"}, +] + +[package.dependencies] +certifi = "*" +urllib3 = ">=1.26.2,<2" + +[package.extras] +develop = ["aiohttp", "mock", "pytest", "pytest-asyncio", "pytest-cov", "pytest-httpserver", "pytest-mock", "requests", "trustme"] + +[[package]] +name = "elasticsearch" +version = "8.8.2" +description = "Python client for Elasticsearch" +optional = false +python-versions = ">=3.6, <4" +files = [ + {file = "elasticsearch-8.8.2-py3-none-any.whl", hash = "sha256:bffd6ce4faaacf90e6f617241773b3da8fb94e2e83554f5508e2fab92ca79643"}, + {file = "elasticsearch-8.8.2.tar.gz", hash = "sha256:bed8cf8fcc6c3be7c254b579de4c29afab021f373c832246f912d37aef3c6bd5"}, +] + +[package.dependencies] +elastic-transport = ">=8,<9" + +[package.extras] +async = ["aiohttp (>=3,<4)"] +requests = ["requests (>=2.4.0,<3.0.0)"] + +[[package]] +name = "enum-compat" +version = "0.0.3" +description = "enum/enum34 compatibility package" +optional = false +python-versions = "*" +files = [ + {file = "enum-compat-0.0.3.tar.gz", hash = "sha256:3677daabed56a6f724451d585662253d8fb4e5569845aafa8bb0da36b1a8751e"}, + {file = "enum_compat-0.0.3-py3-none-any.whl", hash = "sha256:88091b617c7fc3bbbceae50db5958023c48dc40b50520005aa3bf27f8f7ea157"}, +] + +[[package]] +name = "ephem" +version = "4.1.4" +description = "Compute positions of the planets and stars" +optional = false +python-versions = "*" +files = [ + {file = "ephem-4.1.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:024752ae7074c660630046929e12650cc6e72e1c11b7554ccefbe16f8ce3c48d"}, + {file = "ephem-4.1.4-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:158bf9fb2b58cb77c606687c9ad35dc82903ed00617a12c93dd2d89a65d6374d"}, + {file = "ephem-4.1.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:11be09d245e77457e87988a4fdc811bdc6c5f1daaa73fb24289b220db720831d"}, + {file = "ephem-4.1.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:649bd2c85f5fc450136dacc0416af7127a07c0b2ce84bfdc89c1bc78129216a3"}, + {file = "ephem-4.1.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d6918b012365791b786ed0f30e8ea3941cbc49486dcf6c28d151f119c62d5be8"}, + {file = "ephem-4.1.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d343e9ca26f04a05b01fcaaf800224da5d15ad76902d7dc452c216e448293893"}, + {file = "ephem-4.1.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:d0403738f59aefe81ee5b0219cd909f2a05b03b7da465f9b233da57d3dea0de6"}, + {file = "ephem-4.1.4-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:d61f38f35c25049ca2b95aa4e12e952e5ef56b31eac4a9d6d4e24aacf9373101"}, + {file = "ephem-4.1.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4039aa2f0b8c204283fc478551d8b29c9473137ad8a910a5ff60ae3be6593c7b"}, + {file = "ephem-4.1.4-cp310-cp310-win32.whl", hash = "sha256:8979429643ac4e29a5496321c9c41a20cd7a6a530aee9865c7fab0008450ef28"}, + {file = "ephem-4.1.4-cp310-cp310-win_amd64.whl", hash = "sha256:589a2235f49232b92ee0247923360a264086a57b2c39d4191348f95ba5ce0c3d"}, + {file = "ephem-4.1.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:feab5f68ae9fa622d6316790c9cfc399e8b78f7958a61da4edf2cb5e0e675d44"}, + {file = "ephem-4.1.4-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:df9c482c8d25e69271311606b4de0e177e44ceb11781c7ebacf17cc5b391f832"}, + {file = "ephem-4.1.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1cceea883856817f3ea3f73442e3be3a4a56558cdb77cc85d02db4429ce5ab16"}, + {file = "ephem-4.1.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f3e9ea626bc522fd4dd1ff795f0922fcb4c4eb57effe91b6284411166ddd1fd7"}, + {file = "ephem-4.1.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aad22e769bd35415cad8f2ef6d4d875190d9bdad4fed2842fd19dac6f1ccb9dd"}, + {file = "ephem-4.1.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e3327218495235ec215ffe43253c0bf3fa982f59504b351c53b024f1c7b63752"}, + {file = "ephem-4.1.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:d2c56238a1aec72a78ad7061f5c531df97a66ea0cca45204b6b8141c3bb1540e"}, + {file = "ephem-4.1.4-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:fffe176bd94f4f61be5a54b54a966988cceb6ba69a6ed729aab166020fdb37c3"}, + {file = "ephem-4.1.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:8f9b27117e7a82f7f70db9cb23b5cc36d37b166a2f73c55e14d7225d0ab95afa"}, + {file = "ephem-4.1.4-cp311-cp311-win32.whl", hash = "sha256:9bb21c0b117c9122c0141b0a71ee6fbbb087ed2aab4a7ab60f009e95e9f4a521"}, + {file = "ephem-4.1.4-cp311-cp311-win_amd64.whl", hash = "sha256:55d7fb5c34b2e453e01fa4ca7ee375b19b438c9401ae8c4099ae4a3a37656972"}, + {file = "ephem-4.1.4-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:40067fc050c946c8d4c2d779805b61f063471a091e6124cbabcf61ac538011b2"}, + {file = "ephem-4.1.4-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7e2abe97aa2b091090012768b4d94793213cc01f0bf040dcc311a380ab08df69"}, + {file = "ephem-4.1.4-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3b2677d3a5b42aedc578de10b0eecdba6a50731f159cb28f7ad38c5f62143494"}, + {file = "ephem-4.1.4-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80a73da8ec61f86e5a97f73311159e61279dabdfbd17c9d4e2791a25a836f9ce"}, + {file = "ephem-4.1.4-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a146db114cfc942d123a38c301a8b8ca7eef2e37d2c5a4bd59e4abc99123c083"}, + {file = "ephem-4.1.4-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:4f3650c27c3ab6b73e2de7fd8de10e1c0d73f4683c9c5fb2e7113722ec2c2b53"}, + {file = "ephem-4.1.4-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:171fc5e7c4e9523f900dfd5ab6520bceb260a2b59fcb558d9aec17fd562b6251"}, + {file = "ephem-4.1.4-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:8974799afb37f17ac71e16e479d0e315d74bea4bed2becaf21d1b9304299bbaf"}, + {file = "ephem-4.1.4-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:3c39fb62c240f57533ea618295e510c44e466e74f2f4a899fbaa04b166b62d04"}, + {file = "ephem-4.1.4-cp36-cp36m-win32.whl", hash = "sha256:23e1432f021c69b2965c87a693ffd25caf08416e92bcb0fed91425083a374210"}, + {file = "ephem-4.1.4-cp36-cp36m-win_amd64.whl", hash = "sha256:86d6dda3581e61f6bad5479e26bca9e560671852ac00a5a8ed10f722635ddf71"}, + {file = "ephem-4.1.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:e731c3e2f1767fab14e5d4077a3519f70afd22cb7dd113274c2850f8ef8ff828"}, + {file = "ephem-4.1.4-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c8b79b47c7be0d64013fb5d97dd6bbfb9bf63ae07b2ec917be19d3b4cc5782b8"}, + {file = "ephem-4.1.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:89f759ce8e3489d15b9f3796d210196085dcb84cacdf24b2ece791b029245544"}, + {file = "ephem-4.1.4-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:daf1a1280102e14c718d684989da34151697a426522f8ae18b1081e8bad705c9"}, + {file = "ephem-4.1.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e3da3b76d5d5e339461059c3314013c152ef569c798bfd578bcfb504b875a837"}, + {file = "ephem-4.1.4-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:aac0a0e41deb2a197cf67e800a3d0f4029139b9ce12bed148ffe994ec78593f9"}, + {file = "ephem-4.1.4-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:85809803e349bb4a0d56880067549abdc2b93fddf93ac3d55486040cbec1553f"}, + {file = "ephem-4.1.4-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:93d8f8b4e6206d3401dbdb0cdabb0d15c59cf9c2a7ee7c586da8c7dbf1f2a136"}, + {file = "ephem-4.1.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:5beaa0cb659951211aec33a7c132557a1a161dacf53f1b1493830489cfc68215"}, + {file = "ephem-4.1.4-cp37-cp37m-win32.whl", hash = "sha256:bbd4727498928ece694ec1b33023f16b6d050d9952d4052129b24e08e04d67fd"}, + {file = "ephem-4.1.4-cp37-cp37m-win_amd64.whl", hash = "sha256:39c710d73449b1c495b58d803da881363a0cae4b728de9fa332f77bcb4686ac8"}, + {file = "ephem-4.1.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:24b7e90c731e851a56ab5e9d538915faaa54945e9b5211cfdf04e570fc27c529"}, + {file = "ephem-4.1.4-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ab40ad7a5ccd66cad4161ca2295c04f01a74ec596c936c3af97a67733e2cd5bf"}, + {file = "ephem-4.1.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:555d63d70e36e46e43b955c37cdb0f8b82ee2051c575960c4b01948be9f04e5e"}, + {file = "ephem-4.1.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3a29de7c737047cc2412edada9d03b761339d3560d7db471cd04f257e1e02f2f"}, + {file = "ephem-4.1.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4e737b49643a300fa15b788accc72802af93b49cd5d071e53111e08e3fba6570"}, + {file = "ephem-4.1.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:56c448a83290dabd1df5865fbf9e39d17400abcef37cb36de90ea1a860c0a08e"}, + {file = "ephem-4.1.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:3bd7da534a542d937b10f3c643301dc9b8bc09f7a40350b32efc32910232da9e"}, + {file = "ephem-4.1.4-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:0493ad1b3d2505acbf442e31aadb86fba096ba30008a586fe6361a9de5974ed3"}, + {file = "ephem-4.1.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:3442fba6afae0bcb643c9b069765033b67d2c8fe4350f9beb4f2f5cfdaaa7442"}, + {file = "ephem-4.1.4-cp38-cp38-win32.whl", hash = "sha256:8e0bb8379fb6b709a3cbceb6a11a3dc0f25e5b16a6f009b48e09d6b95f896d9c"}, + {file = "ephem-4.1.4-cp38-cp38-win_amd64.whl", hash = "sha256:a940cd4d8d7aed68efd3d6b717f393bbedf541d388ba11eb3ed56a9fc6cbb1ca"}, + {file = "ephem-4.1.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7f51a3bcd5f69c4070e8a6936e4a61019ad2d6b94bc8b5ca1e498dea0962a373"}, + {file = "ephem-4.1.4-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:41680b48aeae5b992371bf7ec1bc07457500ff4a6ea7d333793e945b97951de0"}, + {file = "ephem-4.1.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f11edaef2e4a4d010e21b5ff8bcd9435fbc7fe9e16923f81143f248ae8ae8e9d"}, + {file = "ephem-4.1.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:72078b49748318cbbbe1a49ab5dcd05e63c917151351175b590833e6163a1506"}, + {file = "ephem-4.1.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b2ba977ad0402ac44fe66af6e1119632efe84b7d1255f8f6f94d7768d9487453"}, + {file = "ephem-4.1.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:a21a11285904f43c3bc6909727d09109b8e38dc2e3cda662089601cb37b3d082"}, + {file = "ephem-4.1.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9aabc3cab5fb9440564dfdf79e39ee01d16554d7bfb8228cddfe9eada460dba9"}, + {file = "ephem-4.1.4-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:5327fd48fc8ff966023a6f177813fc058bb2a496c70b53a79f85bf2eba3ca93d"}, + {file = "ephem-4.1.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:1e429f6e0e05e4c8c54802e951cd1bde440dd6f896c2b5691ef5ebd9bc3ba489"}, + {file = "ephem-4.1.4-cp39-cp39-win32.whl", hash = "sha256:a8d125d04800425a9d944109710687bbb3703e8f04ac3bc8445779bb0ad5dcc2"}, + {file = "ephem-4.1.4-cp39-cp39-win_amd64.whl", hash = "sha256:4e8ec4e29c7f04d6334215775a8c4dc77eae8ed698384530d9415a98500ed01c"}, + {file = "ephem-4.1.4.tar.gz", hash = "sha256:73a59f0d2162d1624535c3c3b75f956556bdbb2055eaf554a7bef147d3f9c760"}, +] + +[[package]] +name = "esdk-obs-python" +version = "3.21.4" +description = "OBS Python SDK" +optional = false +python-versions = "*" +files = [ + {file = "esdk-obs-python-3.21.4.tar.gz", hash = "sha256:a3b2a01b0a10768b5b02812abe239048feaae199256cbde67315870121d8ab1e"}, +] + +[[package]] +name = "et-xmlfile" +version = "1.1.0" +description = "An implementation of lxml.xmlfile for the standard library" +optional = false +python-versions = ">=3.6" +files = [ + {file = "et_xmlfile-1.1.0-py3-none-any.whl", hash = "sha256:a2ba85d1d6a74ef63837eed693bcb89c3f752169b0e3e7ae5b16ca5e1b3deada"}, + {file = "et_xmlfile-1.1.0.tar.gz", hash = "sha256:8eb9e2bc2f8c97e37a2dc85a09ecdcdec9d8a396530a6d5a33b30b9a92da0c5c"}, +] + +[[package]] +name = "eventlet" +version = "0.33.3" +description = "Highly concurrent networking library" +optional = false +python-versions = "*" +files = [ + {file = "eventlet-0.33.3-py2.py3-none-any.whl", hash = "sha256:e43b9ae05ba4bb477a10307699c9aff7ff86121b2640f9184d29059f5a687df8"}, + {file = "eventlet-0.33.3.tar.gz", hash = "sha256:722803e7eadff295347539da363d68ae155b8b26ae6a634474d0a920be73cfda"}, +] + +[package.dependencies] +dnspython = ">=1.15.0" +greenlet = ">=0.3" +six = ">=1.10.0" + +[[package]] +name = "executing" +version = "1.2.0" +description = "Get the currently executing AST node of a frame, and other information" +optional = false +python-versions = "*" +files = [ + {file = "executing-1.2.0-py2.py3-none-any.whl", hash = "sha256:0314a69e37426e3608aada02473b4161d4caf5a4b244d1d0c48072b8fee7bacc"}, + {file = "executing-1.2.0.tar.gz", hash = "sha256:19da64c18d2d851112f09c287f8d3dbbdf725ab0e569077efb6cdcbd3497c107"}, +] + +[package.extras] +tests = ["asttokens", "littleutils", "pytest", "rich"] + +[[package]] +name = "flower" +version = "2.0.0" +description = "Celery Flower" +optional = false +python-versions = ">=3.7" +files = [ + {file = "flower-2.0.0-py2.py3-none-any.whl", hash = "sha256:571f9ed1c57a622e862de35eceb8a4244f023fbcfb7175f53e45ebe679f46d90"}, + {file = "flower-2.0.0.tar.gz", hash = "sha256:5657785d728a54914256c34fd0551fe2d7152aab08062ebc645bf86b97b8aec5"}, +] + +[package.dependencies] +celery = ">=5.0.5" +humanize = "*" +prometheus-client = ">=0.8.0" +pytz = "*" +tornado = ">=5.0.0,<7.0.0" + +[[package]] +name = "forgerypy3" +version = "0.3.1" +description = "A forged data generator updated to reflect current state of the original Ruby forgery gem" +optional = false +python-versions = "*" +files = [ + {file = "ForgeryPy3-0.3.1.tar.gz", hash = "sha256:03db26b2129252dc8c8c91aa5661171725a64707773c03c3ca0251b1dd173c93"}, +] + +[[package]] +name = "frozenlist" +version = "1.4.0" +description = "A list-like structure which implements collections.abc.MutableSequence" +optional = false +python-versions = ">=3.8" +files = [ + {file = "frozenlist-1.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:764226ceef3125e53ea2cb275000e309c0aa5464d43bd72abd661e27fffc26ab"}, + {file = "frozenlist-1.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d6484756b12f40003c6128bfcc3fa9f0d49a687e171186c2d85ec82e3758c559"}, + {file = "frozenlist-1.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9ac08e601308e41eb533f232dbf6b7e4cea762f9f84f6357136eed926c15d12c"}, + {file = "frozenlist-1.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d081f13b095d74b67d550de04df1c756831f3b83dc9881c38985834387487f1b"}, + {file = "frozenlist-1.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:71932b597f9895f011f47f17d6428252fc728ba2ae6024e13c3398a087c2cdea"}, + {file = "frozenlist-1.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:981b9ab5a0a3178ff413bca62526bb784249421c24ad7381e39d67981be2c326"}, + {file = "frozenlist-1.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e41f3de4df3e80de75845d3e743b3f1c4c8613c3997a912dbf0229fc61a8b963"}, + {file = "frozenlist-1.4.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6918d49b1f90821e93069682c06ffde41829c346c66b721e65a5c62b4bab0300"}, + {file = "frozenlist-1.4.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0e5c8764c7829343d919cc2dfc587a8db01c4f70a4ebbc49abde5d4b158b007b"}, + {file = "frozenlist-1.4.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:8d0edd6b1c7fb94922bf569c9b092ee187a83f03fb1a63076e7774b60f9481a8"}, + {file = "frozenlist-1.4.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:e29cda763f752553fa14c68fb2195150bfab22b352572cb36c43c47bedba70eb"}, + {file = "frozenlist-1.4.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:0c7c1b47859ee2cac3846fde1c1dc0f15da6cec5a0e5c72d101e0f83dcb67ff9"}, + {file = "frozenlist-1.4.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:901289d524fdd571be1c7be054f48b1f88ce8dddcbdf1ec698b27d4b8b9e5d62"}, + {file = "frozenlist-1.4.0-cp310-cp310-win32.whl", hash = "sha256:1a0848b52815006ea6596c395f87449f693dc419061cc21e970f139d466dc0a0"}, + {file = "frozenlist-1.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:b206646d176a007466358aa21d85cd8600a415c67c9bd15403336c331a10d956"}, + {file = "frozenlist-1.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:de343e75f40e972bae1ef6090267f8260c1446a1695e77096db6cfa25e759a95"}, + {file = "frozenlist-1.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ad2a9eb6d9839ae241701d0918f54c51365a51407fd80f6b8289e2dfca977cc3"}, + {file = "frozenlist-1.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:bd7bd3b3830247580de99c99ea2a01416dfc3c34471ca1298bccabf86d0ff4dc"}, + {file = "frozenlist-1.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bdf1847068c362f16b353163391210269e4f0569a3c166bc6a9f74ccbfc7e839"}, + {file = "frozenlist-1.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:38461d02d66de17455072c9ba981d35f1d2a73024bee7790ac2f9e361ef1cd0c"}, + {file = "frozenlist-1.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d5a32087d720c608f42caed0ef36d2b3ea61a9d09ee59a5142d6070da9041b8f"}, + {file = "frozenlist-1.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dd65632acaf0d47608190a71bfe46b209719bf2beb59507db08ccdbe712f969b"}, + {file = "frozenlist-1.4.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:261b9f5d17cac914531331ff1b1d452125bf5daa05faf73b71d935485b0c510b"}, + {file = "frozenlist-1.4.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:b89ac9768b82205936771f8d2eb3ce88503b1556324c9f903e7156669f521472"}, + {file = "frozenlist-1.4.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:008eb8b31b3ea6896da16c38c1b136cb9fec9e249e77f6211d479db79a4eaf01"}, + {file = "frozenlist-1.4.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:e74b0506fa5aa5598ac6a975a12aa8928cbb58e1f5ac8360792ef15de1aa848f"}, + {file = "frozenlist-1.4.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:490132667476f6781b4c9458298b0c1cddf237488abd228b0b3650e5ecba7467"}, + {file = "frozenlist-1.4.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:76d4711f6f6d08551a7e9ef28c722f4a50dd0fc204c56b4bcd95c6cc05ce6fbb"}, + {file = "frozenlist-1.4.0-cp311-cp311-win32.whl", hash = "sha256:a02eb8ab2b8f200179b5f62b59757685ae9987996ae549ccf30f983f40602431"}, + {file = "frozenlist-1.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:515e1abc578dd3b275d6a5114030b1330ba044ffba03f94091842852f806f1c1"}, + {file = "frozenlist-1.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:f0ed05f5079c708fe74bf9027e95125334b6978bf07fd5ab923e9e55e5fbb9d3"}, + {file = "frozenlist-1.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ca265542ca427bf97aed183c1676e2a9c66942e822b14dc6e5f42e038f92a503"}, + {file = "frozenlist-1.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:491e014f5c43656da08958808588cc6c016847b4360e327a62cb308c791bd2d9"}, + {file = "frozenlist-1.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:17ae5cd0f333f94f2e03aaf140bb762c64783935cc764ff9c82dff626089bebf"}, + {file = "frozenlist-1.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1e78fb68cf9c1a6aa4a9a12e960a5c9dfbdb89b3695197aa7064705662515de2"}, + {file = "frozenlist-1.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d5655a942f5f5d2c9ed93d72148226d75369b4f6952680211972a33e59b1dfdc"}, + {file = "frozenlist-1.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c11b0746f5d946fecf750428a95f3e9ebe792c1ee3b1e96eeba145dc631a9672"}, + {file = "frozenlist-1.4.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e66d2a64d44d50d2543405fb183a21f76b3b5fd16f130f5c99187c3fb4e64919"}, + {file = "frozenlist-1.4.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:88f7bc0fcca81f985f78dd0fa68d2c75abf8272b1f5c323ea4a01a4d7a614efc"}, + {file = "frozenlist-1.4.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:5833593c25ac59ede40ed4de6d67eb42928cca97f26feea219f21d0ed0959b79"}, + {file = "frozenlist-1.4.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:fec520865f42e5c7f050c2a79038897b1c7d1595e907a9e08e3353293ffc948e"}, + {file = "frozenlist-1.4.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:b826d97e4276750beca7c8f0f1a4938892697a6bcd8ec8217b3312dad6982781"}, + {file = "frozenlist-1.4.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:ceb6ec0a10c65540421e20ebd29083c50e6d1143278746a4ef6bcf6153171eb8"}, + {file = "frozenlist-1.4.0-cp38-cp38-win32.whl", hash = "sha256:2b8bcf994563466db019fab287ff390fffbfdb4f905fc77bc1c1d604b1c689cc"}, + {file = "frozenlist-1.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:a6c8097e01886188e5be3e6b14e94ab365f384736aa1fca6a0b9e35bd4a30bc7"}, + {file = "frozenlist-1.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:6c38721585f285203e4b4132a352eb3daa19121a035f3182e08e437cface44bf"}, + {file = "frozenlist-1.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a0c6da9aee33ff0b1a451e867da0c1f47408112b3391dd43133838339e410963"}, + {file = "frozenlist-1.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:93ea75c050c5bb3d98016b4ba2497851eadf0ac154d88a67d7a6816206f6fa7f"}, + {file = "frozenlist-1.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f61e2dc5ad442c52b4887f1fdc112f97caeff4d9e6ebe78879364ac59f1663e1"}, + {file = "frozenlist-1.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aa384489fefeb62321b238e64c07ef48398fe80f9e1e6afeff22e140e0850eef"}, + {file = "frozenlist-1.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:10ff5faaa22786315ef57097a279b833ecab1a0bfb07d604c9cbb1c4cdc2ed87"}, + {file = "frozenlist-1.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:007df07a6e3eb3e33e9a1fe6a9db7af152bbd8a185f9aaa6ece10a3529e3e1c6"}, + {file = "frozenlist-1.4.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f4f399d28478d1f604c2ff9119907af9726aed73680e5ed1ca634d377abb087"}, + {file = "frozenlist-1.4.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:c5374b80521d3d3f2ec5572e05adc94601985cc526fb276d0c8574a6d749f1b3"}, + {file = "frozenlist-1.4.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:ce31ae3e19f3c902de379cf1323d90c649425b86de7bbdf82871b8a2a0615f3d"}, + {file = "frozenlist-1.4.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7211ef110a9194b6042449431e08c4d80c0481e5891e58d429df5899690511c2"}, + {file = "frozenlist-1.4.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:556de4430ce324c836789fa4560ca62d1591d2538b8ceb0b4f68fb7b2384a27a"}, + {file = "frozenlist-1.4.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7645a8e814a3ee34a89c4a372011dcd817964ce8cb273c8ed6119d706e9613e3"}, + {file = "frozenlist-1.4.0-cp39-cp39-win32.whl", hash = "sha256:19488c57c12d4e8095a922f328df3f179c820c212940a498623ed39160bc3c2f"}, + {file = "frozenlist-1.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:6221d84d463fb110bdd7619b69cb43878a11d51cbb9394ae3105d082d5199167"}, + {file = "frozenlist-1.4.0.tar.gz", hash = "sha256:09163bdf0b2907454042edb19f887c6d33806adc71fbd54afc14908bfdc22251"}, +] + +[[package]] +name = "future" +version = "0.18.3" +description = "Clean single-source support for Python 3 and 2" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ + {file = "future-0.18.3.tar.gz", hash = "sha256:34a17436ed1e96697a86f9de3d15a3b0be01d8bc8de9c1dffd59fb8234ed5307"}, +] + +[[package]] +name = "geoip2" +version = "4.7.0" +description = "MaxMind GeoIP2 API" +optional = false +python-versions = ">=3.7" +files = [ + {file = "geoip2-4.7.0-py2.py3-none-any.whl", hash = "sha256:078fcd4cce26ea029b1e3252a0f0ec20a1f42e7ab0f19b7be3864f20f4db2b51"}, + {file = "geoip2-4.7.0.tar.gz", hash = "sha256:3bdde4994f6bc917eafab5b51e772d737b2ae00037a5b85001fb06dc68f779df"}, +] + +[package.dependencies] +aiohttp = ">=3.6.2,<4.0.0" +maxminddb = ">=2.3.0,<3.0.0" +requests = ">=2.24.0,<3.0.0" + +[[package]] +name = "gmssl" +version = "3.2.2" +description = "Pure-Python SM2/SM3/SM4 implementation" +optional = false +python-versions = "*" +files = [ + {file = "gmssl-3.2.2-py3-none-any.whl", hash = "sha256:59f069a91eb19ef59b9e7be4d436ed01c92ce064d3d7d45a8778fc07fd2cd068"}, + {file = "gmssl-3.2.2.linux-x86_64.tar.gz", hash = "sha256:f3d8c8c75dd34cd169f129c017f67fdd80cce2c67a13f9a0e3b1c58f8de6351e"}, +] + +[package.dependencies] +pycryptodomex = "*" + +[[package]] +name = "google-api-core" +version = "2.11.1" +description = "Google API client core library" +optional = false +python-versions = ">=3.7" +files = [ + {file = "google-api-core-2.11.1.tar.gz", hash = "sha256:25d29e05a0058ed5f19c61c0a78b1b53adea4d9364b464d014fbda941f6d1c9a"}, + {file = "google_api_core-2.11.1-py3-none-any.whl", hash = "sha256:d92a5a92dc36dd4f4b9ee4e55528a90e432b059f93aee6ad857f9de8cc7ae94a"}, +] + +[package.dependencies] +google-auth = ">=2.14.1,<3.0.dev0" +googleapis-common-protos = ">=1.56.2,<2.0.dev0" +grpcio = [ + {version = ">=1.33.2,<2.0dev", optional = true, markers = "extra == \"grpc\""}, + {version = ">=1.49.1,<2.0dev", optional = true, markers = "python_version >= \"3.11\" and extra == \"grpc\""}, +] +grpcio-status = [ + {version = ">=1.33.2,<2.0.dev0", optional = true, markers = "extra == \"grpc\""}, + {version = ">=1.49.1,<2.0.dev0", optional = true, markers = "python_version >= \"3.11\" and extra == \"grpc\""}, +] +protobuf = ">=3.19.5,<3.20.0 || >3.20.0,<3.20.1 || >3.20.1,<4.21.0 || >4.21.0,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<5.0.0.dev0" +requests = ">=2.18.0,<3.0.0.dev0" + +[package.extras] +grpc = ["grpcio (>=1.33.2,<2.0dev)", "grpcio (>=1.49.1,<2.0dev)", "grpcio-status (>=1.33.2,<2.0.dev0)", "grpcio-status (>=1.49.1,<2.0.dev0)"] +grpcgcp = ["grpcio-gcp (>=0.2.2,<1.0.dev0)"] +grpcio-gcp = ["grpcio-gcp (>=0.2.2,<1.0.dev0)"] + +[[package]] +name = "google-auth" +version = "2.22.0" +description = "Google Authentication Library" +optional = false +python-versions = ">=3.6" +files = [ + {file = "google-auth-2.22.0.tar.gz", hash = "sha256:164cba9af4e6e4e40c3a4f90a1a6c12ee56f14c0b4868d1ca91b32826ab334ce"}, + {file = "google_auth-2.22.0-py2.py3-none-any.whl", hash = "sha256:d61d1b40897407b574da67da1a833bdc10d5a11642566e506565d1b1a46ba873"}, +] + +[package.dependencies] +cachetools = ">=2.0.0,<6.0" +pyasn1-modules = ">=0.2.1" +rsa = ">=3.1.4,<5" +six = ">=1.9.0" +urllib3 = "<2.0" + +[package.extras] +aiohttp = ["aiohttp (>=3.6.2,<4.0.0.dev0)", "requests (>=2.20.0,<3.0.0.dev0)"] +enterprise-cert = ["cryptography (==36.0.2)", "pyopenssl (==22.0.0)"] +pyopenssl = ["cryptography (>=38.0.3)", "pyopenssl (>=20.0.0)"] +reauth = ["pyu2f (>=0.1.5)"] +requests = ["requests (>=2.20.0,<3.0.0.dev0)"] + +[[package]] +name = "google-cloud-compute" +version = "1.13.0" +description = "Google Cloud Compute API client library" +optional = false +python-versions = ">=3.7" +files = [ + {file = "google-cloud-compute-1.13.0.tar.gz", hash = "sha256:93b72129c6443c898da5a060d2021bc2d11c2a57ef2fbb9306afbb5126a376b9"}, + {file = "google_cloud_compute-1.13.0-py2.py3-none-any.whl", hash = "sha256:0f75d6c09cc504e43f4eceb2a466de9e9eb6fca819ca8ffdcf098ca5b21c7dc1"}, +] + +[package.dependencies] +google-api-core = {version = ">=1.34.0,<2.0.dev0 || >=2.11.dev0,<3.0.0dev", extras = ["grpc"]} +proto-plus = {version = ">=1.22.2,<2.0.0dev", markers = "python_version >= \"3.11\""} +protobuf = ">=3.19.5,<3.20.0 || >3.20.0,<3.20.1 || >3.20.1,<4.21.0 || >4.21.0,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<5.0.0dev" + +[[package]] +name = "googleapis-common-protos" +version = "1.60.0" +description = "Common protobufs used in Google APIs" +optional = false +python-versions = ">=3.7" +files = [ + {file = "googleapis-common-protos-1.60.0.tar.gz", hash = "sha256:e73ebb404098db405ba95d1e1ae0aa91c3e15a71da031a2eeb6b2e23e7bc3708"}, + {file = "googleapis_common_protos-1.60.0-py2.py3-none-any.whl", hash = "sha256:69f9bbcc6acde92cab2db95ce30a70bd2b81d20b12eff3f1aabaffcbe8a93918"}, +] + +[package.dependencies] +protobuf = ">=3.19.5,<3.20.0 || >3.20.0,<3.20.1 || >3.20.1,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<5.0.0.dev0" + +[package.extras] +grpc = ["grpcio (>=1.44.0,<2.0.0.dev0)"] + +[[package]] +name = "greenlet" +version = "2.0.2" +description = "Lightweight in-process concurrent programming" +optional = false +python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*" +files = [ + {file = "greenlet-2.0.2-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:bdfea8c661e80d3c1c99ad7c3ff74e6e87184895bbaca6ee8cc61209f8b9b85d"}, + {file = "greenlet-2.0.2-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:9d14b83fab60d5e8abe587d51c75b252bcc21683f24699ada8fb275d7712f5a9"}, + {file = "greenlet-2.0.2-cp27-cp27m-win32.whl", hash = "sha256:6c3acb79b0bfd4fe733dff8bc62695283b57949ebcca05ae5c129eb606ff2d74"}, + {file = "greenlet-2.0.2-cp27-cp27m-win_amd64.whl", hash = "sha256:283737e0da3f08bd637b5ad058507e578dd462db259f7f6e4c5c365ba4ee9343"}, + {file = "greenlet-2.0.2-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:d27ec7509b9c18b6d73f2f5ede2622441de812e7b1a80bbd446cb0633bd3d5ae"}, + {file = "greenlet-2.0.2-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:30bcf80dda7f15ac77ba5af2b961bdd9dbc77fd4ac6105cee85b0d0a5fcf74df"}, + {file = "greenlet-2.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:26fbfce90728d82bc9e6c38ea4d038cba20b7faf8a0ca53a9c07b67318d46088"}, + {file = "greenlet-2.0.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9190f09060ea4debddd24665d6804b995a9c122ef5917ab26e1566dcc712ceeb"}, + {file = "greenlet-2.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d75209eed723105f9596807495d58d10b3470fa6732dd6756595e89925ce2470"}, + {file = "greenlet-2.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:3a51c9751078733d88e013587b108f1b7a1fb106d402fb390740f002b6f6551a"}, + {file = "greenlet-2.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:76ae285c8104046b3a7f06b42f29c7b73f77683df18c49ab5af7983994c2dd91"}, + {file = "greenlet-2.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:2d4686f195e32d36b4d7cf2d166857dbd0ee9f3d20ae349b6bf8afc8485b3645"}, + {file = "greenlet-2.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:c4302695ad8027363e96311df24ee28978162cdcdd2006476c43970b384a244c"}, + {file = "greenlet-2.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c48f54ef8e05f04d6eff74b8233f6063cb1ed960243eacc474ee73a2ea8573ca"}, + {file = "greenlet-2.0.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a1846f1b999e78e13837c93c778dcfc3365902cfb8d1bdb7dd73ead37059f0d0"}, + {file = "greenlet-2.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a06ad5312349fec0ab944664b01d26f8d1f05009566339ac6f63f56589bc1a2"}, + {file = "greenlet-2.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:eff4eb9b7eb3e4d0cae3d28c283dc16d9bed6b193c2e1ace3ed86ce48ea8df19"}, + {file = "greenlet-2.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5454276c07d27a740c5892f4907c86327b632127dd9abec42ee62e12427ff7e3"}, + {file = "greenlet-2.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:7cafd1208fdbe93b67c7086876f061f660cfddc44f404279c1585bbf3cdc64c5"}, + {file = "greenlet-2.0.2-cp35-cp35m-macosx_10_14_x86_64.whl", hash = "sha256:910841381caba4f744a44bf81bfd573c94e10b3045ee00de0cbf436fe50673a6"}, + {file = "greenlet-2.0.2-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:18a7f18b82b52ee85322d7a7874e676f34ab319b9f8cce5de06067384aa8ff43"}, + {file = "greenlet-2.0.2-cp35-cp35m-win32.whl", hash = "sha256:03a8f4f3430c3b3ff8d10a2a86028c660355ab637cee9333d63d66b56f09d52a"}, + {file = "greenlet-2.0.2-cp35-cp35m-win_amd64.whl", hash = "sha256:4b58adb399c4d61d912c4c331984d60eb66565175cdf4a34792cd9600f21b394"}, + {file = "greenlet-2.0.2-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:703f18f3fda276b9a916f0934d2fb6d989bf0b4fb5a64825260eb9bfd52d78f0"}, + {file = "greenlet-2.0.2-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:32e5b64b148966d9cccc2c8d35a671409e45f195864560829f395a54226408d3"}, + {file = "greenlet-2.0.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2dd11f291565a81d71dab10b7033395b7a3a5456e637cf997a6f33ebdf06f8db"}, + {file = "greenlet-2.0.2-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e0f72c9ddb8cd28532185f54cc1453f2c16fb417a08b53a855c4e6a418edd099"}, + {file = "greenlet-2.0.2-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cd021c754b162c0fb55ad5d6b9d960db667faad0fa2ff25bb6e1301b0b6e6a75"}, + {file = "greenlet-2.0.2-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:3c9b12575734155d0c09d6c3e10dbd81665d5c18e1a7c6597df72fd05990c8cf"}, + {file = "greenlet-2.0.2-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:b9ec052b06a0524f0e35bd8790686a1da006bd911dd1ef7d50b77bfbad74e292"}, + {file = "greenlet-2.0.2-cp36-cp36m-win32.whl", hash = "sha256:dbfcfc0218093a19c252ca8eb9aee3d29cfdcb586df21049b9d777fd32c14fd9"}, + {file = "greenlet-2.0.2-cp36-cp36m-win_amd64.whl", hash = "sha256:9f35ec95538f50292f6d8f2c9c9f8a3c6540bbfec21c9e5b4b751e0a7c20864f"}, + {file = "greenlet-2.0.2-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:d5508f0b173e6aa47273bdc0a0b5ba055b59662ba7c7ee5119528f466585526b"}, + {file = "greenlet-2.0.2-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:f82d4d717d8ef19188687aa32b8363e96062911e63ba22a0cff7802a8e58e5f1"}, + {file = "greenlet-2.0.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c9c59a2120b55788e800d82dfa99b9e156ff8f2227f07c5e3012a45a399620b7"}, + {file = "greenlet-2.0.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2780572ec463d44c1d3ae850239508dbeb9fed38e294c68d19a24d925d9223ca"}, + {file = "greenlet-2.0.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:937e9020b514ceedb9c830c55d5c9872abc90f4b5862f89c0887033ae33c6f73"}, + {file = "greenlet-2.0.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:36abbf031e1c0f79dd5d596bfaf8e921c41df2bdf54ee1eed921ce1f52999a86"}, + {file = "greenlet-2.0.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:18e98fb3de7dba1c0a852731c3070cf022d14f0d68b4c87a19cc1016f3bb8b33"}, + {file = "greenlet-2.0.2-cp37-cp37m-win32.whl", hash = "sha256:3f6ea9bd35eb450837a3d80e77b517ea5bc56b4647f5502cd28de13675ee12f7"}, + {file = "greenlet-2.0.2-cp37-cp37m-win_amd64.whl", hash = "sha256:7492e2b7bd7c9b9916388d9df23fa49d9b88ac0640db0a5b4ecc2b653bf451e3"}, + {file = "greenlet-2.0.2-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:b864ba53912b6c3ab6bcb2beb19f19edd01a6bfcbdfe1f37ddd1778abfe75a30"}, + {file = "greenlet-2.0.2-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:ba2956617f1c42598a308a84c6cf021a90ff3862eddafd20c3333d50f0edb45b"}, + {file = "greenlet-2.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fc3a569657468b6f3fb60587e48356fe512c1754ca05a564f11366ac9e306526"}, + {file = "greenlet-2.0.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8eab883b3b2a38cc1e050819ef06a7e6344d4a990d24d45bc6f2cf959045a45b"}, + {file = "greenlet-2.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:acd2162a36d3de67ee896c43effcd5ee3de247eb00354db411feb025aa319857"}, + {file = "greenlet-2.0.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:0bf60faf0bc2468089bdc5edd10555bab6e85152191df713e2ab1fcc86382b5a"}, + {file = "greenlet-2.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b0ef99cdbe2b682b9ccbb964743a6aca37905fda5e0452e5ee239b1654d37f2a"}, + {file = "greenlet-2.0.2-cp38-cp38-win32.whl", hash = "sha256:b80f600eddddce72320dbbc8e3784d16bd3fb7b517e82476d8da921f27d4b249"}, + {file = "greenlet-2.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:4d2e11331fc0c02b6e84b0d28ece3a36e0548ee1a1ce9ddde03752d9b79bba40"}, + {file = "greenlet-2.0.2-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:88d9ab96491d38a5ab7c56dd7a3cc37d83336ecc564e4e8816dbed12e5aaefc8"}, + {file = "greenlet-2.0.2-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:561091a7be172ab497a3527602d467e2b3fbe75f9e783d8b8ce403fa414f71a6"}, + {file = "greenlet-2.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:971ce5e14dc5e73715755d0ca2975ac88cfdaefcaab078a284fea6cfabf866df"}, + {file = "greenlet-2.0.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:be4ed120b52ae4d974aa40215fcdfde9194d63541c7ded40ee12eb4dda57b76b"}, + {file = "greenlet-2.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94c817e84245513926588caf1152e3b559ff794d505555211ca041f032abbb6b"}, + {file = "greenlet-2.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:1a819eef4b0e0b96bb0d98d797bef17dc1b4a10e8d7446be32d1da33e095dbb8"}, + {file = "greenlet-2.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7efde645ca1cc441d6dc4b48c0f7101e8d86b54c8530141b09fd31cef5149ec9"}, + {file = "greenlet-2.0.2-cp39-cp39-win32.whl", hash = "sha256:ea9872c80c132f4663822dd2a08d404073a5a9b5ba6155bea72fb2a79d1093b5"}, + {file = "greenlet-2.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:db1a39669102a1d8d12b57de2bb7e2ec9066a6f2b3da35ae511ff93b01b5d564"}, + {file = "greenlet-2.0.2.tar.gz", hash = "sha256:e7c8dc13af7db097bed64a051d2dd49e9f0af495c26995c00a9ee842690d34c0"}, +] + +[package.extras] +docs = ["Sphinx", "docutils (<0.18)"] +test = ["objgraph", "psutil"] + +[[package]] +name = "grpcio" +version = "1.56.2" +description = "HTTP/2-based RPC framework" +optional = false +python-versions = ">=3.7" +files = [ + {file = "grpcio-1.56.2-cp310-cp310-linux_armv7l.whl", hash = "sha256:bf0b9959e673505ee5869950642428046edb91f99942607c2ecf635f8a4b31c9"}, + {file = "grpcio-1.56.2-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:5144feb20fe76e73e60c7d73ec3bf54f320247d1ebe737d10672480371878b48"}, + {file = "grpcio-1.56.2-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:a72797549935c9e0b9bc1def1768c8b5a709538fa6ab0678e671aec47ebfd55e"}, + {file = "grpcio-1.56.2-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c3f3237a57e42f79f1e560726576aedb3a7ef931f4e3accb84ebf6acc485d316"}, + {file = "grpcio-1.56.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:900bc0096c2ca2d53f2e5cebf98293a7c32f532c4aeb926345e9747452233950"}, + {file = "grpcio-1.56.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:97e0efaebbfd222bcaac2f1735c010c1d3b167112d9d237daebbeedaaccf3d1d"}, + {file = "grpcio-1.56.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c0c85c5cbe8b30a32fa6d802588d55ffabf720e985abe9590c7c886919d875d4"}, + {file = "grpcio-1.56.2-cp310-cp310-win32.whl", hash = "sha256:06e84ad9ae7668a109e970c7411e7992751a116494cba7c4fb877656527f9a57"}, + {file = "grpcio-1.56.2-cp310-cp310-win_amd64.whl", hash = "sha256:10954662f77dc36c9a1fb5cc4a537f746580d6b5734803be1e587252682cda8d"}, + {file = "grpcio-1.56.2-cp311-cp311-linux_armv7l.whl", hash = "sha256:c435f5ce1705de48e08fcbcfaf8aee660d199c90536e3e06f2016af7d6a938dd"}, + {file = "grpcio-1.56.2-cp311-cp311-macosx_10_10_universal2.whl", hash = "sha256:6108e5933eb8c22cd3646e72d5b54772c29f57482fd4c41a0640aab99eb5071d"}, + {file = "grpcio-1.56.2-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:8391cea5ce72f4a12368afd17799474015d5d3dc00c936a907eb7c7eaaea98a5"}, + {file = "grpcio-1.56.2-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:750de923b456ca8c0f1354d6befca45d1f3b3a789e76efc16741bd4132752d95"}, + {file = "grpcio-1.56.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fda2783c12f553cdca11c08e5af6eecbd717280dc8fbe28a110897af1c15a88c"}, + {file = "grpcio-1.56.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9e04d4e4cfafa7c5264e535b5d28e786f0571bea609c3f0aaab13e891e933e9c"}, + {file = "grpcio-1.56.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:89a49cc5ad08a38b6141af17e00d1dd482dc927c7605bc77af457b5a0fca807c"}, + {file = "grpcio-1.56.2-cp311-cp311-win32.whl", hash = "sha256:6a007a541dff984264981fbafeb052bfe361db63578948d857907df9488d8774"}, + {file = "grpcio-1.56.2-cp311-cp311-win_amd64.whl", hash = "sha256:af4063ef2b11b96d949dccbc5a987272f38d55c23c4c01841ea65a517906397f"}, + {file = "grpcio-1.56.2-cp37-cp37m-linux_armv7l.whl", hash = "sha256:a6ff459dac39541e6a2763a4439c4ca6bc9ecb4acc05a99b79246751f9894756"}, + {file = "grpcio-1.56.2-cp37-cp37m-macosx_10_10_universal2.whl", hash = "sha256:f20fd21f7538f8107451156dd1fe203300b79a9ddceba1ee0ac8132521a008ed"}, + {file = "grpcio-1.56.2-cp37-cp37m-manylinux_2_17_aarch64.whl", hash = "sha256:d1fbad1f9077372b6587ec589c1fc120b417b6c8ad72d3e3cc86bbbd0a3cee93"}, + {file = "grpcio-1.56.2-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ee26e9dfb3996aff7c870f09dc7ad44a5f6732b8bdb5a5f9905737ac6fd4ef1"}, + {file = "grpcio-1.56.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a4c60abd950d6de3e4f1ddbc318075654d275c29c846ab6a043d6ed2c52e4c8c"}, + {file = "grpcio-1.56.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:1c31e52a04e62c8577a7bf772b3e7bed4df9c9e0dd90f92b6ffa07c16cab63c9"}, + {file = "grpcio-1.56.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:345356b307cce5d14355e8e055b4ca5f99bc857c33a3dc1ddbc544fca9cd0475"}, + {file = "grpcio-1.56.2-cp37-cp37m-win_amd64.whl", hash = "sha256:42e63904ee37ae46aa23de50dac8b145b3596f43598fa33fe1098ab2cbda6ff5"}, + {file = "grpcio-1.56.2-cp38-cp38-linux_armv7l.whl", hash = "sha256:7c5ede2e2558f088c49a1ddda19080e4c23fb5d171de80a726b61b567e3766ed"}, + {file = "grpcio-1.56.2-cp38-cp38-macosx_10_10_universal2.whl", hash = "sha256:33971197c47965cc1d97d78d842163c283e998223b151bab0499b951fd2c0b12"}, + {file = "grpcio-1.56.2-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:d39f5d4af48c138cb146763eda14eb7d8b3ccbbec9fe86fb724cd16e0e914c64"}, + {file = "grpcio-1.56.2-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ded637176addc1d3eef35331c39acc598bac550d213f0a1bedabfceaa2244c87"}, + {file = "grpcio-1.56.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c90da4b124647547a68cf2f197174ada30c7bb9523cb976665dfd26a9963d328"}, + {file = "grpcio-1.56.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:3ccb621749a81dc7755243665a70ce45536ec413ef5818e013fe8dfbf5aa497b"}, + {file = "grpcio-1.56.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:4eb37dd8dd1aa40d601212afa27ca5be255ba792e2e0b24d67b8af5e012cdb7d"}, + {file = "grpcio-1.56.2-cp38-cp38-win32.whl", hash = "sha256:ddb4a6061933bd9332b74eac0da25f17f32afa7145a33a0f9711ad74f924b1b8"}, + {file = "grpcio-1.56.2-cp38-cp38-win_amd64.whl", hash = "sha256:8940d6de7068af018dfa9a959a3510e9b7b543f4c405e88463a1cbaa3b2b379a"}, + {file = "grpcio-1.56.2-cp39-cp39-linux_armv7l.whl", hash = "sha256:51173e8fa6d9a2d85c14426bdee5f5c4a0654fd5fddcc21fe9d09ab0f6eb8b35"}, + {file = "grpcio-1.56.2-cp39-cp39-macosx_10_10_universal2.whl", hash = "sha256:373b48f210f43327a41e397391715cd11cfce9ded2fe76a5068f9bacf91cc226"}, + {file = "grpcio-1.56.2-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:42a3bbb2bc07aef72a7d97e71aabecaf3e4eb616d39e5211e2cfe3689de860ca"}, + {file = "grpcio-1.56.2-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5344be476ac37eb9c9ad09c22f4ea193c1316bf074f1daf85bddb1b31fda5116"}, + {file = "grpcio-1.56.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c3fa3ab0fb200a2c66493828ed06ccd1a94b12eddbfb985e7fd3e5723ff156c6"}, + {file = "grpcio-1.56.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:b975b85d1d5efc36cf8b237c5f3849b64d1ba33d6282f5e991f28751317504a1"}, + {file = "grpcio-1.56.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:cbdf2c498e077282cd427cfd88bdce4668019791deef0be8155385ab2ba7837f"}, + {file = "grpcio-1.56.2-cp39-cp39-win32.whl", hash = "sha256:139f66656a762572ae718fa0d1f2dce47c05e9fbf7a16acd704c354405b97df9"}, + {file = "grpcio-1.56.2-cp39-cp39-win_amd64.whl", hash = "sha256:830215173ad45d670140ff99aac3b461f9be9a6b11bee1a17265aaaa746a641a"}, + {file = "grpcio-1.56.2.tar.gz", hash = "sha256:0ff789ae7d8ddd76d2ac02e7d13bfef6fc4928ac01e1dcaa182be51b6bcc0aaa"}, +] + +[package.extras] +protobuf = ["grpcio-tools (>=1.56.2)"] + +[[package]] +name = "grpcio-status" +version = "1.56.2" +description = "Status proto mapping for gRPC" +optional = false +python-versions = ">=3.6" +files = [ + {file = "grpcio-status-1.56.2.tar.gz", hash = "sha256:a046b2c0118df4a5687f4585cca9d3c3bae5c498c4dff055dcb43fb06a1180c8"}, + {file = "grpcio_status-1.56.2-py3-none-any.whl", hash = "sha256:63f3842867735f59f5d70e723abffd2e8501a6bcd915612a1119e52f10614782"}, +] + +[package.dependencies] +googleapis-common-protos = ">=1.5.5" +grpcio = ">=1.56.2" +protobuf = ">=4.21.6" + +[[package]] +name = "gunicorn" +version = "21.2.0" +description = "WSGI HTTP Server for UNIX" +optional = false +python-versions = ">=3.5" +files = [ + {file = "gunicorn-21.2.0-py3-none-any.whl", hash = "sha256:3213aa5e8c24949e792bcacfc176fef362e7aac80b76c56f6b5122bf350722f0"}, + {file = "gunicorn-21.2.0.tar.gz", hash = "sha256:88ec8bff1d634f98e61b9f65bc4bf3cd918a90806c6f5c48bc5603849ec81033"}, +] + +[package.dependencies] +packaging = "*" + +[package.extras] +eventlet = ["eventlet (>=0.24.1)"] +gevent = ["gevent (>=1.4.0)"] +setproctitle = ["setproctitle"] +tornado = ["tornado (>=0.2)"] + +[[package]] +name = "h11" +version = "0.14.0" +description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" +optional = false +python-versions = ">=3.7" +files = [ + {file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"}, + {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"}, +] + +[[package]] +name = "html2text" +version = "2020.1.16" +description = "Turn HTML into equivalent Markdown-structured text." +optional = false +python-versions = ">=3.5" +files = [ + {file = "html2text-2020.1.16-py3-none-any.whl", hash = "sha256:c7c629882da0cf377d66f073329ccf34a12ed2adf0169b9285ae4e63ef54c82b"}, + {file = "html2text-2020.1.16.tar.gz", hash = "sha256:e296318e16b059ddb97f7a8a1d6a5c1d7af4544049a01e261731d2d5cc277bbb"}, +] + +[[package]] +name = "httpsig" +version = "1.3.0" +description = "Secure HTTP request signing using the HTTP Signature draft specification" +optional = false +python-versions = "*" +files = [ + {file = "httpsig-1.3.0-py2.py3-none-any.whl", hash = "sha256:ce3ebd489a9b3325810adf0f4992718a3c931d026fe04cafc1177c24be1ec4d3"}, + {file = "httpsig-1.3.0.tar.gz", hash = "sha256:71d6d50246129c4f7cfec20f5e57e351d2b8492d631cc2aa967914acf91f6ce6"}, +] + +[package.dependencies] +pycryptodome = ">=3,<4" +six = "*" + +[[package]] +name = "httptools" +version = "0.6.0" +description = "A collection of framework independent HTTP protocol utils." +optional = false +python-versions = ">=3.5.0" +files = [ + {file = "httptools-0.6.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:818325afee467d483bfab1647a72054246d29f9053fd17cc4b86cda09cc60339"}, + {file = "httptools-0.6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72205730bf1be875003692ca54a4a7c35fac77b4746008966061d9d41a61b0f5"}, + {file = "httptools-0.6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:33eb1d4e609c835966e969a31b1dedf5ba16b38cab356c2ce4f3e33ffa94cad3"}, + {file = "httptools-0.6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6bdc6675ec6cb79d27e0575750ac6e2b47032742e24eed011b8db73f2da9ed40"}, + {file = "httptools-0.6.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:463c3bc5ef64b9cf091be9ac0e0556199503f6e80456b790a917774a616aff6e"}, + {file = "httptools-0.6.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:82f228b88b0e8c6099a9c4757ce9fdbb8b45548074f8d0b1f0fc071e35655d1c"}, + {file = "httptools-0.6.0-cp310-cp310-win_amd64.whl", hash = "sha256:0781fedc610293a2716bc7fa142d4c85e6776bc59d617a807ff91246a95dea35"}, + {file = "httptools-0.6.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:721e503245d591527cddd0f6fd771d156c509e831caa7a57929b55ac91ee2b51"}, + {file = "httptools-0.6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:274bf20eeb41b0956e34f6a81f84d26ed57c84dd9253f13dcb7174b27ccd8aaf"}, + {file = "httptools-0.6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:259920bbae18740a40236807915def554132ad70af5067e562f4660b62c59b90"}, + {file = "httptools-0.6.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03bfd2ae8a2d532952ac54445a2fb2504c804135ed28b53fefaf03d3a93eb1fd"}, + {file = "httptools-0.6.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:f959e4770b3fc8ee4dbc3578fd910fab9003e093f20ac8c621452c4d62e517cb"}, + {file = "httptools-0.6.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:6e22896b42b95b3237eccc42278cd72c0df6f23247d886b7ded3163452481e38"}, + {file = "httptools-0.6.0-cp311-cp311-win_amd64.whl", hash = "sha256:38f3cafedd6aa20ae05f81f2e616ea6f92116c8a0f8dcb79dc798df3356836e2"}, + {file = "httptools-0.6.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:47043a6e0ea753f006a9d0dd076a8f8c99bc0ecae86a0888448eb3076c43d717"}, + {file = "httptools-0.6.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:35a541579bed0270d1ac10245a3e71e5beeb1903b5fbbc8d8b4d4e728d48ff1d"}, + {file = "httptools-0.6.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65d802e7b2538a9756df5acc062300c160907b02e15ed15ba035b02bce43e89c"}, + {file = "httptools-0.6.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:26326e0a8fe56829f3af483200d914a7cd16d8d398d14e36888b56de30bec81a"}, + {file = "httptools-0.6.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:e41ccac9e77cd045f3e4ee0fc62cbf3d54d7d4b375431eb855561f26ee7a9ec4"}, + {file = "httptools-0.6.0-cp37-cp37m-win_amd64.whl", hash = "sha256:4e748fc0d5c4a629988ef50ac1aef99dfb5e8996583a73a717fc2cac4ab89932"}, + {file = "httptools-0.6.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:cf8169e839a0d740f3d3c9c4fa630ac1a5aaf81641a34575ca6773ed7ce041a1"}, + {file = "httptools-0.6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:5dcc14c090ab57b35908d4a4585ec5c0715439df07be2913405991dbb37e049d"}, + {file = "httptools-0.6.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d0b0571806a5168013b8c3d180d9f9d6997365a4212cb18ea20df18b938aa0b"}, + {file = "httptools-0.6.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0fb4a608c631f7dcbdf986f40af7a030521a10ba6bc3d36b28c1dc9e9035a3c0"}, + {file = "httptools-0.6.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:93f89975465133619aea8b1952bc6fa0e6bad22a447c6d982fc338fbb4c89649"}, + {file = "httptools-0.6.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:73e9d66a5a28b2d5d9fbd9e197a31edd02be310186db423b28e6052472dc8201"}, + {file = "httptools-0.6.0-cp38-cp38-win_amd64.whl", hash = "sha256:22c01fcd53648162730a71c42842f73b50f989daae36534c818b3f5050b54589"}, + {file = "httptools-0.6.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:3f96d2a351b5625a9fd9133c95744e8ca06f7a4f8f0b8231e4bbaae2c485046a"}, + {file = "httptools-0.6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:72ec7c70bd9f95ef1083d14a755f321d181f046ca685b6358676737a5fecd26a"}, + {file = "httptools-0.6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b703d15dbe082cc23266bf5d9448e764c7cb3fcfe7cb358d79d3fd8248673ef9"}, + {file = "httptools-0.6.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:82c723ed5982f8ead00f8e7605c53e55ffe47c47465d878305ebe0082b6a1755"}, + {file = "httptools-0.6.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b0a816bb425c116a160fbc6f34cece097fd22ece15059d68932af686520966bd"}, + {file = "httptools-0.6.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:dea66d94e5a3f68c5e9d86e0894653b87d952e624845e0b0e3ad1c733c6cc75d"}, + {file = "httptools-0.6.0-cp39-cp39-win_amd64.whl", hash = "sha256:23b09537086a5a611fad5696fc8963d67c7e7f98cb329d38ee114d588b0b74cd"}, + {file = "httptools-0.6.0.tar.gz", hash = "sha256:9fc6e409ad38cbd68b177cd5158fc4042c796b82ca88d99ec78f07bed6c6b796"}, +] + +[package.extras] +test = ["Cython (>=0.29.24,<0.30.0)"] + +[[package]] +name = "humanize" +version = "4.7.0" +description = "Python humanize utilities" +optional = false +python-versions = ">=3.8" +files = [ + {file = "humanize-4.7.0-py3-none-any.whl", hash = "sha256:df7c429c2d27372b249d3f26eb53b07b166b661326e0325793e0a988082e3889"}, + {file = "humanize-4.7.0.tar.gz", hash = "sha256:7ca0e43e870981fa684acb5b062deb307218193bca1a01f2b2676479df849b3a"}, +] + +[package.extras] +tests = ["freezegun", "pytest", "pytest-cov"] + +[[package]] +name = "hvac" +version = "1.1.1" +description = "HashiCorp Vault API client" +optional = false +python-versions = ">=3.6.2,<4.0.0" +files = [ + {file = "hvac-1.1.1-py3-none-any.whl", hash = "sha256:466e883665b4082933106b292649f9fba3bc0709a1ec1729e9e35b29477164b3"}, + {file = "hvac-1.1.1.tar.gz", hash = "sha256:f9dbcc46b98b250c785eb1050aa11ee34a0c8b6616b75218cf1346a9817992f9"}, +] + +[package.dependencies] +pyhcl = ">=0.4.4,<0.5.0" +requests = ">=2.27.1,<3.0.0" + +[[package]] +name = "hyperlink" +version = "21.0.0" +description = "A featureful, immutable, and correct URL for Python." +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "hyperlink-21.0.0-py2.py3-none-any.whl", hash = "sha256:e6b14c37ecb73e89c77d78cdb4c2cc8f3fb59a885c5b3f819ff4ed80f25af1b4"}, + {file = "hyperlink-21.0.0.tar.gz", hash = "sha256:427af957daa58bc909471c6c40f74c5450fa123dd093fc53efd2e91d2705a56b"}, +] + +[package.dependencies] +idna = ">=2.5" + +[[package]] +name = "idna" +version = "3.4" +description = "Internationalized Domain Names in Applications (IDNA)" +optional = false +python-versions = ">=3.5" +files = [ + {file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"}, + {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"}, +] + +[[package]] +name = "incremental" +version = "22.10.0" +description = "\"A small library that versions your Python projects.\"" +optional = false +python-versions = "*" +files = [ + {file = "incremental-22.10.0-py2.py3-none-any.whl", hash = "sha256:b864a1f30885ee72c5ac2835a761b8fe8aa9c28b9395cacf27286602688d3e51"}, + {file = "incremental-22.10.0.tar.gz", hash = "sha256:912feeb5e0f7e0188e6f42241d2f450002e11bbc0937c65865045854c24c0bd0"}, +] + +[package.extras] +mypy = ["click (>=6.0)", "mypy (==0.812)", "twisted (>=16.4.0)"] +scripts = ["click (>=6.0)", "twisted (>=16.4.0)"] + +[[package]] +name = "inflection" +version = "0.5.1" +description = "A port of Ruby on Rails inflector to Python" +optional = false +python-versions = ">=3.5" +files = [ + {file = "inflection-0.5.1-py2.py3-none-any.whl", hash = "sha256:f38b2b640938a4f35ade69ac3d053042959b62a0f1076a5bbaa1b9526605a8a2"}, + {file = "inflection-0.5.1.tar.gz", hash = "sha256:1a29730d366e996aaacffb2f1f1cb9593dc38e2ddd30c91250c6dde09ea9b417"}, +] + +[[package]] +name = "ipip-ipdb" +version = "1.6.1" +description = "IPIP.net officially supported IP database ipdb format parsing library" +optional = false +python-versions = "*" +files = [ + {file = "ipip-ipdb-1.6.1.tar.gz", hash = "sha256:4f396f8f8b1a2fc7fe3c41e1b05b479aac9aa1bc310b5b0182dbaa5376dc0bb9"}, +] + +[[package]] +name = "ipy" +version = "1.01" +description = "Class and tools for handling of IPv4 and IPv6 addresses and networks" +optional = false +python-versions = "*" +files = [ + {file = "IPy-1.01.tar.gz", hash = "sha256:edeca741dea2d54aca568fa23740288c3fe86c0f3ea700344571e9ef14a7cc1a"}, +] + +[[package]] +name = "ipython" +version = "8.14.0" +description = "IPython: Productive Interactive Computing" +optional = false +python-versions = ">=3.9" +files = [ + {file = "ipython-8.14.0-py3-none-any.whl", hash = "sha256:248aca623f5c99a6635bc3857677b7320b9b8039f99f070ee0d20a5ca5a8e6bf"}, + {file = "ipython-8.14.0.tar.gz", hash = "sha256:1d197b907b6ba441b692c48cf2a3a2de280dc0ac91a3405b39349a50272ca0a1"}, +] + +[package.dependencies] +appnope = {version = "*", markers = "sys_platform == \"darwin\""} +backcall = "*" +colorama = {version = "*", markers = "sys_platform == \"win32\""} +decorator = "*" +jedi = ">=0.16" +matplotlib-inline = "*" +pexpect = {version = ">4.3", markers = "sys_platform != \"win32\""} +pickleshare = "*" +prompt-toolkit = ">=3.0.30,<3.0.37 || >3.0.37,<3.1.0" +pygments = ">=2.4.0" +stack-data = "*" +traitlets = ">=5" + +[package.extras] +all = ["black", "curio", "docrepr", "ipykernel", "ipyparallel", "ipywidgets", "matplotlib", "matplotlib (!=3.2.0)", "nbconvert", "nbformat", "notebook", "numpy (>=1.21)", "pandas", "pytest (<7)", "pytest (<7.1)", "pytest-asyncio", "qtconsole", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "trio", "typing-extensions"] +black = ["black"] +doc = ["docrepr", "ipykernel", "matplotlib", "pytest (<7)", "pytest (<7.1)", "pytest-asyncio", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "typing-extensions"] +kernel = ["ipykernel"] +nbconvert = ["nbconvert"] +nbformat = ["nbformat"] +notebook = ["ipywidgets", "notebook"] +parallel = ["ipyparallel"] +qtconsole = ["qtconsole"] +test = ["pytest (<7.1)", "pytest-asyncio", "testpath"] +test-extra = ["curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.21)", "pandas", "pytest (<7.1)", "pytest-asyncio", "testpath", "trio"] + +[[package]] +name = "iso8601" +version = "2.0.0" +description = "Simple module to parse ISO 8601 dates" +optional = false +python-versions = ">=3.7,<4.0" +files = [ + {file = "iso8601-2.0.0-py3-none-any.whl", hash = "sha256:ebe10061b932edb8a8e33cc635d661926c59b9c3bed7a4f4edca8c62d400af10"}, + {file = "iso8601-2.0.0.tar.gz", hash = "sha256:739960d37c74c77bd9bd546a76562ccb581fe3d4820ff5c3141eb49c839fda8f"}, +] + +[[package]] +name = "isodate" +version = "0.6.1" +description = "An ISO 8601 date/time/duration parser and formatter" +optional = false +python-versions = "*" +files = [ + {file = "isodate-0.6.1-py2.py3-none-any.whl", hash = "sha256:0751eece944162659049d35f4f549ed815792b38793f07cf73381c1c87cbed96"}, + {file = "isodate-0.6.1.tar.gz", hash = "sha256:48c5881de7e8b0a0d648cb024c8062dc84e7b840ed81e864c7614fd3c127bde9"}, +] + +[package.dependencies] +six = "*" + +[[package]] +name = "itsdangerous" +version = "1.1.0" +description = "Various helpers to pass data to untrusted environments and back." +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "itsdangerous-1.1.0-py2.py3-none-any.whl", hash = "sha256:b12271b2047cb23eeb98c8b5622e2e5c5e9abd9784a153e9d8ef9cb4dd09d749"}, + {file = "itsdangerous-1.1.0.tar.gz", hash = "sha256:321b033d07f2a4136d3ec762eac9f16a10ccd60f53c0c91af90217ace7ba1f19"}, +] + +[[package]] +name = "itypes" +version = "1.2.0" +description = "Simple immutable types for python." +optional = false +python-versions = "*" +files = [ + {file = "itypes-1.2.0-py2.py3-none-any.whl", hash = "sha256:03da6872ca89d29aef62773672b2d408f490f80db48b23079a4b194c86dd04c6"}, + {file = "itypes-1.2.0.tar.gz", hash = "sha256:af886f129dea4a2a1e3d36595a2d139589e4dd287f5cab0b40e799ee81570ff1"}, +] + +[[package]] +name = "jedi" +version = "0.19.0" +description = "An autocompletion tool for Python that can be used for text editors." +optional = false +python-versions = ">=3.6" +files = [ + {file = "jedi-0.19.0-py2.py3-none-any.whl", hash = "sha256:cb8ce23fbccff0025e9386b5cf85e892f94c9b822378f8da49970471335ac64e"}, + {file = "jedi-0.19.0.tar.gz", hash = "sha256:bcf9894f1753969cbac8022a8c2eaee06bfa3724e4192470aaffe7eb6272b0c4"}, +] + +[package.dependencies] +parso = ">=0.8.3,<0.9.0" + +[package.extras] +docs = ["Jinja2 (==2.11.3)", "MarkupSafe (==1.1.1)", "Pygments (==2.8.1)", "alabaster (==0.7.12)", "babel (==2.9.1)", "chardet (==4.0.0)", "commonmark (==0.8.1)", "docutils (==0.17.1)", "future (==0.18.2)", "idna (==2.10)", "imagesize (==1.2.0)", "mock (==1.0.1)", "packaging (==20.9)", "pyparsing (==2.4.7)", "pytz (==2021.1)", "readthedocs-sphinx-ext (==2.1.4)", "recommonmark (==0.5.0)", "requests (==2.25.1)", "six (==1.15.0)", "snowballstemmer (==2.1.0)", "sphinx (==1.8.5)", "sphinx-rtd-theme (==0.4.3)", "sphinxcontrib-serializinghtml (==1.1.4)", "sphinxcontrib-websupport (==1.2.4)", "urllib3 (==1.26.4)"] +qa = ["flake8 (==5.0.4)", "mypy (==0.971)", "types-setuptools (==67.2.0.1)"] +testing = ["Django (<3.1)", "attrs", "colorama", "docopt", "pytest (<7.0.0)"] + +[[package]] +name = "jinja2" +version = "3.1.2" +description = "A very fast and expressive template engine." +optional = false +python-versions = ">=3.7" +files = [ + {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"}, + {file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"}, +] + +[package.dependencies] +MarkupSafe = ">=2.0" + +[package.extras] +i18n = ["Babel (>=2.7)"] + +[[package]] +name = "jmespath" +version = "0.10.0" +description = "JSON Matching Expressions" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ + {file = "jmespath-0.10.0-py2.py3-none-any.whl", hash = "sha256:cdf6525904cc597730141d61b36f2e4b8ecc257c420fa2f4549bac2c2d0cb72f"}, + {file = "jmespath-0.10.0.tar.gz", hash = "sha256:b85d0567b8666149a93172712e68920734333c0ce7e89b78b3e987f71e5ed4f9"}, +] + +[[package]] +name = "jms-storage" +version = "0.0.50" +description = "Jumpserver storage python sdk tools" +optional = false +python-versions = "*" +files = [ + {file = "jms-storage-0.0.50.tar.gz", hash = "sha256:f757180e145a9eb3390b8b32663a5feebcb1e720a6f2c36cc16f726ac047f28b"}, +] + +[package.dependencies] +azure-storage-blob = "12.17.0" +boto = "2.49.0" +boto3 = "1.28.9" +botocore = "1.31.9" +certifi = "2023.7.22" +chardet = "5.1.0" +crcmod = "1.7" +docutils = "0.20.1" +elasticsearch = "8.8.2" +esdk-obs-python = "3.21.4" +idna = "3.4" +oss2 = "2.18.1" +python-dateutil = "2.8.2" +pytz = "2023.3" +requests = "2.31.0" +s3transfer = "0.6.1" +six = "1.16.0" + +[[package]] +name = "jsonfield2" +version = "4.0.0.post0" +description = "A reusable Django field that allows you to store validated JSON in your model." +optional = false +python-versions = "*" +files = [ + {file = "jsonfield2-4.0.0.post0-py3-none-any.whl", hash = "sha256:bab284d3fc721067d5f3107a0adc87ee772e9b09cac5eca042fad6311c4842bd"}, + {file = "jsonfield2-4.0.0.post0.tar.gz", hash = "sha256:cbce2d7c52563550cd2048fcf3a57631019d3547f5ed142f42141d1d2dc53283"}, +] + +[package.dependencies] +Django = ">=2.2" + +[[package]] +name = "keystoneauth1" +version = "5.2.1" +description = "Authentication Library for OpenStack Identity" +optional = false +python-versions = ">=3.8" +files = [ + {file = "keystoneauth1-5.2.1-py3-none-any.whl", hash = "sha256:d2fcfdcfe347df8d92390e0806b4969289d884cd9ec3519e4c5aec53e66d0767"}, + {file = "keystoneauth1-5.2.1.tar.gz", hash = "sha256:f79b1c27ed5a69be4d03a5bc4967df3dfab0c5d76e85226fa2060cffadff74a1"}, +] + +[package.dependencies] +iso8601 = ">=0.1.11" +os-service-types = ">=1.2.0" +pbr = ">=2.0.0,<2.1.0 || >2.1.0" +requests = ">=2.14.2" +stevedore = ">=1.20.0" + +[package.extras] +betamax = ["betamax (>=0.7.0)", "fixtures (>=3.0.0)", "mock (>=2.0.0)"] +kerberos = ["requests-kerberos (>=0.8.0)"] +oauth1 = ["oauthlib (>=0.6.2)"] +saml2 = ["lxml (>=4.2.0)"] +test = ["PyYAML (>=3.12)", "bandit (>=1.1.0,<1.6.0)", "betamax (>=0.7.0)", "coverage (>=4.0,!=4.4)", "fixtures (>=3.0.0)", "flake8-docstrings (>=1.6.0,<1.7.0)", "flake8-import-order (>=0.17.1)", "hacking (>=4.1.0,<4.2.0)", "lxml (>=4.2.0)", "oauthlib (>=0.6.2)", "oslo.config (>=5.2.0)", "oslo.utils (>=3.33.0)", "oslotest (>=3.2.0)", "reno (>=3.1.0)", "requests-kerberos (>=0.8.0)", "requests-mock (>=1.2.0)", "stestr (>=1.0.0)", "testresources (>=2.0.0)", "testtools (>=2.2.0)"] + +[[package]] +name = "kombu" +version = "5.3.1" +description = "Messaging library for Python." +optional = false +python-versions = ">=3.8" +files = [ + {file = "kombu-5.3.1-py3-none-any.whl", hash = "sha256:48ee589e8833126fd01ceaa08f8a2041334e9f5894e5763c8486a550454551e9"}, + {file = "kombu-5.3.1.tar.gz", hash = "sha256:fbd7572d92c0bf71c112a6b45163153dea5a7b6a701ec16b568c27d0fd2370f2"}, +] + +[package.dependencies] +amqp = ">=5.1.1,<6.0.0" +vine = "*" + +[package.extras] +azureservicebus = ["azure-servicebus (>=7.10.0)"] +azurestoragequeues = ["azure-identity (>=1.12.0)", "azure-storage-queue (>=12.6.0)"] +confluentkafka = ["confluent-kafka (==2.1.1)"] +consul = ["python-consul2"] +librabbitmq = ["librabbitmq (>=2.0.0)"] +mongodb = ["pymongo (>=4.1.1)"] +msgpack = ["msgpack"] +pyro = ["pyro4"] +qpid = ["qpid-python (>=0.26)", "qpid-tools (>=0.26)"] +redis = ["redis (>=4.5.2)"] +slmq = ["softlayer-messaging (>=1.0.3)"] +sqlalchemy = ["sqlalchemy (>=1.4.48,<2.1)"] +sqs = ["boto3 (>=1.26.143)", "pycurl (>=7.43.0.5)", "urllib3 (>=1.26.16)"] +yaml = ["PyYAML (>=3.10)"] +zookeeper = ["kazoo (>=2.8.0)"] + +[[package]] +name = "kubernetes" +version = "27.2.0" +description = "Kubernetes python client" +optional = false +python-versions = ">=3.6" +files = [ + {file = "kubernetes-27.2.0-py2.py3-none-any.whl", hash = "sha256:0f9376329c85cf07615ed6886bf9bf21eb1cbfc05e14ec7b0f74ed8153cd2815"}, + {file = "kubernetes-27.2.0.tar.gz", hash = "sha256:d479931c6f37561dbfdf28fc5f46384b1cb8b28f9db344ed4a232ce91990825a"}, +] + +[package.dependencies] +certifi = ">=14.05.14" +google-auth = ">=1.0.1" +oauthlib = ">=3.2.2" +python-dateutil = ">=2.5.3" +pyyaml = ">=5.4.1" +requests = "*" +requests-oauthlib = "*" +six = ">=1.9.0" +urllib3 = ">=1.24.2" +websocket-client = ">=0.32.0,<0.40.0 || >0.40.0,<0.41.dev0 || >=0.43.dev0" + +[package.extras] +adal = ["adal (>=1.0.2)"] + +[[package]] +name = "ldap3" +version = "2.9.1" +description = "A strictly RFC 4510 conforming LDAP V3 pure Python client library" +optional = false +python-versions = "*" +files = [ + {file = "ldap3-2.9.1-py2.py3-none-any.whl", hash = "sha256:5869596fc4948797020d3f03b7939da938778a0f9e2009f7a072ccf92b8e8d70"}, + {file = "ldap3-2.9.1.tar.gz", hash = "sha256:f3e7fc4718e3f09dda568b57100095e0ce58633bcabbed8667ce3f8fbaa4229f"}, +] + +[package.dependencies] +pyasn1 = ">=0.4.6" + +[[package]] +name = "lml" +version = "0.1.0" +description = "Load me later. A lazy plugin management system." +optional = false +python-versions = "*" +files = [ + {file = "lml-0.1.0-py2.py3-none-any.whl", hash = "sha256:ec06e850019942a485639c8c2a26bdb99eae24505bee7492b649df98a0bed101"}, + {file = "lml-0.1.0.tar.gz", hash = "sha256:57a085a29bb7991d70d41c6c3144c560a8e35b4c1030ffb36d85fa058773bcc5"}, +] + +[[package]] +name = "lockfile" +version = "0.12.2" +description = "Platform-independent file locking module" +optional = false +python-versions = "*" +files = [ + {file = "lockfile-0.12.2-py2.py3-none-any.whl", hash = "sha256:6c3cb24f344923d30b2785d5ad75182c8ea7ac1b6171b08657258ec7429d50fa"}, + {file = "lockfile-0.12.2.tar.gz", hash = "sha256:6aed02de03cba24efabcd600b30540140634fc06cfa603822d508d5361e9f799"}, +] + +[[package]] +name = "lxml" +version = "4.9.3" +description = "Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API." +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, != 3.4.*" +files = [ + {file = "lxml-4.9.3-cp27-cp27m-macosx_11_0_x86_64.whl", hash = "sha256:b0a545b46b526d418eb91754565ba5b63b1c0b12f9bd2f808c852d9b4b2f9b5c"}, + {file = "lxml-4.9.3-cp27-cp27m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:075b731ddd9e7f68ad24c635374211376aa05a281673ede86cbe1d1b3455279d"}, + {file = "lxml-4.9.3-cp27-cp27m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:1e224d5755dba2f4a9498e150c43792392ac9b5380aa1b845f98a1618c94eeef"}, + {file = "lxml-4.9.3-cp27-cp27m-win32.whl", hash = "sha256:2c74524e179f2ad6d2a4f7caf70e2d96639c0954c943ad601a9e146c76408ed7"}, + {file = "lxml-4.9.3-cp27-cp27m-win_amd64.whl", hash = "sha256:4f1026bc732b6a7f96369f7bfe1a4f2290fb34dce00d8644bc3036fb351a4ca1"}, + {file = "lxml-4.9.3-cp27-cp27mu-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c0781a98ff5e6586926293e59480b64ddd46282953203c76ae15dbbbf302e8bb"}, + {file = "lxml-4.9.3-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:cef2502e7e8a96fe5ad686d60b49e1ab03e438bd9123987994528febd569868e"}, + {file = "lxml-4.9.3-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:b86164d2cff4d3aaa1f04a14685cbc072efd0b4f99ca5708b2ad1b9b5988a991"}, + {file = "lxml-4.9.3-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:42871176e7896d5d45138f6d28751053c711ed4d48d8e30b498da155af39aebd"}, + {file = "lxml-4.9.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:ae8b9c6deb1e634ba4f1930eb67ef6e6bf6a44b6eb5ad605642b2d6d5ed9ce3c"}, + {file = "lxml-4.9.3-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:411007c0d88188d9f621b11d252cce90c4a2d1a49db6c068e3c16422f306eab8"}, + {file = "lxml-4.9.3-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:cd47b4a0d41d2afa3e58e5bf1f62069255aa2fd6ff5ee41604418ca925911d76"}, + {file = "lxml-4.9.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0e2cb47860da1f7e9a5256254b74ae331687b9672dfa780eed355c4c9c3dbd23"}, + {file = "lxml-4.9.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:1247694b26342a7bf47c02e513d32225ededd18045264d40758abeb3c838a51f"}, + {file = "lxml-4.9.3-cp310-cp310-win32.whl", hash = "sha256:cdb650fc86227eba20de1a29d4b2c1bfe139dc75a0669270033cb2ea3d391b85"}, + {file = "lxml-4.9.3-cp310-cp310-win_amd64.whl", hash = "sha256:97047f0d25cd4bcae81f9ec9dc290ca3e15927c192df17331b53bebe0e3ff96d"}, + {file = "lxml-4.9.3-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:1f447ea5429b54f9582d4b955f5f1985f278ce5cf169f72eea8afd9502973dd5"}, + {file = "lxml-4.9.3-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:57d6ba0ca2b0c462f339640d22882acc711de224d769edf29962b09f77129cbf"}, + {file = "lxml-4.9.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:9767e79108424fb6c3edf8f81e6730666a50feb01a328f4a016464a5893f835a"}, + {file = "lxml-4.9.3-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:71c52db65e4b56b8ddc5bb89fb2e66c558ed9d1a74a45ceb7dcb20c191c3df2f"}, + {file = "lxml-4.9.3-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:d73d8ecf8ecf10a3bd007f2192725a34bd62898e8da27eb9d32a58084f93962b"}, + {file = "lxml-4.9.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0a3d3487f07c1d7f150894c238299934a2a074ef590b583103a45002035be120"}, + {file = "lxml-4.9.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9e28c51fa0ce5674be9f560c6761c1b441631901993f76700b1b30ca6c8378d6"}, + {file = "lxml-4.9.3-cp311-cp311-win32.whl", hash = "sha256:0bfd0767c5c1de2551a120673b72e5d4b628737cb05414f03c3277bf9bed3305"}, + {file = "lxml-4.9.3-cp311-cp311-win_amd64.whl", hash = "sha256:25f32acefac14ef7bd53e4218fe93b804ef6f6b92ffdb4322bb6d49d94cad2bc"}, + {file = "lxml-4.9.3-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:d3ff32724f98fbbbfa9f49d82852b159e9784d6094983d9a8b7f2ddaebb063d4"}, + {file = "lxml-4.9.3-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:48d6ed886b343d11493129e019da91d4039826794a3e3027321c56d9e71505be"}, + {file = "lxml-4.9.3-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:9a92d3faef50658dd2c5470af249985782bf754c4e18e15afb67d3ab06233f13"}, + {file = "lxml-4.9.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b4e4bc18382088514ebde9328da057775055940a1f2e18f6ad2d78aa0f3ec5b9"}, + {file = "lxml-4.9.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:fc9b106a1bf918db68619fdcd6d5ad4f972fdd19c01d19bdb6bf63f3589a9ec5"}, + {file = "lxml-4.9.3-cp312-cp312-win_amd64.whl", hash = "sha256:d37017287a7adb6ab77e1c5bee9bcf9660f90ff445042b790402a654d2ad81d8"}, + {file = "lxml-4.9.3-cp35-cp35m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:56dc1f1ebccc656d1b3ed288f11e27172a01503fc016bcabdcbc0978b19352b7"}, + {file = "lxml-4.9.3-cp35-cp35m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:578695735c5a3f51569810dfebd05dd6f888147a34f0f98d4bb27e92b76e05c2"}, + {file = "lxml-4.9.3-cp35-cp35m-win32.whl", hash = "sha256:704f61ba8c1283c71b16135caf697557f5ecf3e74d9e453233e4771d68a1f42d"}, + {file = "lxml-4.9.3-cp35-cp35m-win_amd64.whl", hash = "sha256:c41bfca0bd3532d53d16fd34d20806d5c2b1ace22a2f2e4c0008570bf2c58833"}, + {file = "lxml-4.9.3-cp36-cp36m-macosx_11_0_x86_64.whl", hash = "sha256:64f479d719dc9f4c813ad9bb6b28f8390360660b73b2e4beb4cb0ae7104f1c12"}, + {file = "lxml-4.9.3-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:dd708cf4ee4408cf46a48b108fb9427bfa00b9b85812a9262b5c668af2533ea5"}, + {file = "lxml-4.9.3-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c31c7462abdf8f2ac0577d9f05279727e698f97ecbb02f17939ea99ae8daa98"}, + {file = "lxml-4.9.3-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:e3cd95e10c2610c360154afdc2f1480aea394f4a4f1ea0a5eacce49640c9b190"}, + {file = "lxml-4.9.3-cp36-cp36m-manylinux_2_28_x86_64.whl", hash = "sha256:4930be26af26ac545c3dffb662521d4e6268352866956672231887d18f0eaab2"}, + {file = "lxml-4.9.3-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4aec80cde9197340bc353d2768e2a75f5f60bacda2bab72ab1dc499589b3878c"}, + {file = "lxml-4.9.3-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:14e019fd83b831b2e61baed40cab76222139926b1fb5ed0e79225bc0cae14584"}, + {file = "lxml-4.9.3-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0c0850c8b02c298d3c7006b23e98249515ac57430e16a166873fc47a5d549287"}, + {file = "lxml-4.9.3-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:aca086dc5f9ef98c512bac8efea4483eb84abbf926eaeedf7b91479feb092458"}, + {file = "lxml-4.9.3-cp36-cp36m-win32.whl", hash = "sha256:50baa9c1c47efcaef189f31e3d00d697c6d4afda5c3cde0302d063492ff9b477"}, + {file = "lxml-4.9.3-cp36-cp36m-win_amd64.whl", hash = "sha256:bef4e656f7d98aaa3486d2627e7d2df1157d7e88e7efd43a65aa5dd4714916cf"}, + {file = "lxml-4.9.3-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:46f409a2d60f634fe550f7133ed30ad5321ae2e6630f13657fb9479506b00601"}, + {file = "lxml-4.9.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:4c28a9144688aef80d6ea666c809b4b0e50010a2aca784c97f5e6bf143d9f129"}, + {file = "lxml-4.9.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:141f1d1a9b663c679dc524af3ea1773e618907e96075262726c7612c02b149a4"}, + {file = "lxml-4.9.3-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:53ace1c1fd5a74ef662f844a0413446c0629d151055340e9893da958a374f70d"}, + {file = "lxml-4.9.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:17a753023436a18e27dd7769e798ce302963c236bc4114ceee5b25c18c52c693"}, + {file = "lxml-4.9.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:7d298a1bd60c067ea75d9f684f5f3992c9d6766fadbc0bcedd39750bf344c2f4"}, + {file = "lxml-4.9.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:081d32421db5df44c41b7f08a334a090a545c54ba977e47fd7cc2deece78809a"}, + {file = "lxml-4.9.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:23eed6d7b1a3336ad92d8e39d4bfe09073c31bfe502f20ca5116b2a334f8ec02"}, + {file = "lxml-4.9.3-cp37-cp37m-win32.whl", hash = "sha256:1509dd12b773c02acd154582088820893109f6ca27ef7291b003d0e81666109f"}, + {file = "lxml-4.9.3-cp37-cp37m-win_amd64.whl", hash = "sha256:120fa9349a24c7043854c53cae8cec227e1f79195a7493e09e0c12e29f918e52"}, + {file = "lxml-4.9.3-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:4d2d1edbca80b510443f51afd8496be95529db04a509bc8faee49c7b0fb6d2cc"}, + {file = "lxml-4.9.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:8d7e43bd40f65f7d97ad8ef5c9b1778943d02f04febef12def25f7583d19baac"}, + {file = "lxml-4.9.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:71d66ee82e7417828af6ecd7db817913cb0cf9d4e61aa0ac1fde0583d84358db"}, + {file = "lxml-4.9.3-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:6fc3c450eaa0b56f815c7b62f2b7fba7266c4779adcf1cece9e6deb1de7305ce"}, + {file = "lxml-4.9.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:65299ea57d82fb91c7f019300d24050c4ddeb7c5a190e076b5f48a2b43d19c42"}, + {file = "lxml-4.9.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:eadfbbbfb41b44034a4c757fd5d70baccd43296fb894dba0295606a7cf3124aa"}, + {file = "lxml-4.9.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:3e9bdd30efde2b9ccfa9cb5768ba04fe71b018a25ea093379c857c9dad262c40"}, + {file = "lxml-4.9.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:fcdd00edfd0a3001e0181eab3e63bd5c74ad3e67152c84f93f13769a40e073a7"}, + {file = "lxml-4.9.3-cp38-cp38-win32.whl", hash = "sha256:57aba1bbdf450b726d58b2aea5fe47c7875f5afb2c4a23784ed78f19a0462574"}, + {file = "lxml-4.9.3-cp38-cp38-win_amd64.whl", hash = "sha256:92af161ecbdb2883c4593d5ed4815ea71b31fafd7fd05789b23100d081ecac96"}, + {file = "lxml-4.9.3-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:9bb6ad405121241e99a86efff22d3ef469024ce22875a7ae045896ad23ba2340"}, + {file = "lxml-4.9.3-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:8ed74706b26ad100433da4b9d807eae371efaa266ffc3e9191ea436087a9d6a7"}, + {file = "lxml-4.9.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:fbf521479bcac1e25a663df882c46a641a9bff6b56dc8b0fafaebd2f66fb231b"}, + {file = "lxml-4.9.3-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:303bf1edce6ced16bf67a18a1cf8339d0db79577eec5d9a6d4a80f0fb10aa2da"}, + {file = "lxml-4.9.3-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:5515edd2a6d1a5a70bfcdee23b42ec33425e405c5b351478ab7dc9347228f96e"}, + {file = "lxml-4.9.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:690dafd0b187ed38583a648076865d8c229661ed20e48f2335d68e2cf7dc829d"}, + {file = "lxml-4.9.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:b6420a005548ad52154c8ceab4a1290ff78d757f9e5cbc68f8c77089acd3c432"}, + {file = "lxml-4.9.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bb3bb49c7a6ad9d981d734ef7c7193bc349ac338776a0360cc671eaee89bcf69"}, + {file = "lxml-4.9.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d27be7405547d1f958b60837dc4c1007da90b8b23f54ba1f8b728c78fdb19d50"}, + {file = "lxml-4.9.3-cp39-cp39-win32.whl", hash = "sha256:8df133a2ea5e74eef5e8fc6f19b9e085f758768a16e9877a60aec455ed2609b2"}, + {file = "lxml-4.9.3-cp39-cp39-win_amd64.whl", hash = "sha256:4dd9a263e845a72eacb60d12401e37c616438ea2e5442885f65082c276dfb2b2"}, + {file = "lxml-4.9.3-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:6689a3d7fd13dc687e9102a27e98ef33730ac4fe37795d5036d18b4d527abd35"}, + {file = "lxml-4.9.3-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:f6bdac493b949141b733c5345b6ba8f87a226029cbabc7e9e121a413e49441e0"}, + {file = "lxml-4.9.3-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:05186a0f1346ae12553d66df1cfce6f251589fea3ad3da4f3ef4e34b2d58c6a3"}, + {file = "lxml-4.9.3-pp37-pypy37_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c2006f5c8d28dee289f7020f721354362fa304acbaaf9745751ac4006650254b"}, + {file = "lxml-4.9.3-pp38-pypy38_pp73-macosx_11_0_x86_64.whl", hash = "sha256:5c245b783db29c4e4fbbbfc9c5a78be496c9fea25517f90606aa1f6b2b3d5f7b"}, + {file = "lxml-4.9.3-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:4fb960a632a49f2f089d522f70496640fdf1218f1243889da3822e0a9f5f3ba7"}, + {file = "lxml-4.9.3-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:50670615eaf97227d5dc60de2dc99fb134a7130d310d783314e7724bf163f75d"}, + {file = "lxml-4.9.3-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:9719fe17307a9e814580af1f5c6e05ca593b12fb7e44fe62450a5384dbf61b4b"}, + {file = "lxml-4.9.3-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:3331bece23c9ee066e0fb3f96c61322b9e0f54d775fccefff4c38ca488de283a"}, + {file = "lxml-4.9.3-pp39-pypy39_pp73-macosx_11_0_x86_64.whl", hash = "sha256:ed667f49b11360951e201453fc3967344d0d0263aa415e1619e85ae7fd17b4e0"}, + {file = "lxml-4.9.3-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:8b77946fd508cbf0fccd8e400a7f71d4ac0e1595812e66025bac475a8e811694"}, + {file = "lxml-4.9.3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:e4da8ca0c0c0aea88fd46be8e44bd49716772358d648cce45fe387f7b92374a7"}, + {file = "lxml-4.9.3-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:fe4bda6bd4340caa6e5cf95e73f8fea5c4bfc55763dd42f1b50a94c1b4a2fbd4"}, + {file = "lxml-4.9.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:f3df3db1d336b9356dd3112eae5f5c2b8b377f3bc826848567f10bfddfee77e9"}, + {file = "lxml-4.9.3.tar.gz", hash = "sha256:48628bd53a426c9eb9bc066a923acaa0878d1e86129fd5359aee99285f4eed9c"}, +] + +[package.extras] +cssselect = ["cssselect (>=0.7)"] +html5 = ["html5lib"] +htmlsoup = ["BeautifulSoup4"] +source = ["Cython (>=0.29.35)"] + +[[package]] +name = "markupsafe" +version = "2.1.3" +description = "Safely add untrusted strings to HTML/XML markup." +optional = false +python-versions = ">=3.7" +files = [ + {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cd0f502fe016460680cd20aaa5a76d241d6f35a1c3350c474bac1273803893fa"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e09031c87a1e51556fdcb46e5bd4f59dfb743061cf93c4d6831bf894f125eb57"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:68e78619a61ecf91e76aa3e6e8e33fc4894a2bebe93410754bd28fce0a8a4f9f"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65c1a9bcdadc6c28eecee2c119465aebff8f7a584dd719facdd9e825ec61ab52"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:525808b8019e36eb524b8c68acdd63a37e75714eac50e988180b169d64480a00"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:962f82a3086483f5e5f64dbad880d31038b698494799b097bc59c2edf392fce6"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:aa7bd130efab1c280bed0f45501b7c8795f9fdbeb02e965371bbef3523627779"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c9c804664ebe8f83a211cace637506669e7890fec1b4195b505c214e50dd4eb7"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-win32.whl", hash = "sha256:10bbfe99883db80bdbaff2dcf681dfc6533a614f700da1287707e8a5d78a8431"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-win_amd64.whl", hash = "sha256:1577735524cdad32f9f694208aa75e422adba74f1baee7551620e43a3141f559"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ad9e82fb8f09ade1c3e1b996a6337afac2b8b9e365f926f5a61aacc71adc5b3c"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3c0fae6c3be832a0a0473ac912810b2877c8cb9d76ca48de1ed31e1c68386575"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b076b6226fb84157e3f7c971a47ff3a679d837cf338547532ab866c57930dbee"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bfce63a9e7834b12b87c64d6b155fdd9b3b96191b6bd334bf37db7ff1fe457f2"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:338ae27d6b8745585f87218a3f23f1512dbf52c26c28e322dbe54bcede54ccb9"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e4dd52d80b8c83fdce44e12478ad2e85c64ea965e75d66dbeafb0a3e77308fcc"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:df0be2b576a7abbf737b1575f048c23fb1d769f267ec4358296f31c2479db8f9"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-win32.whl", hash = "sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-win_amd64.whl", hash = "sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb0932dc158471523c9637e807d9bfb93e06a95cbf010f1a38b98623b929ef2b"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca379055a47383d02a5400cb0d110cef0a776fc644cda797db0c5696cfd7e18e"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:b7ff0f54cb4ff66dd38bebd335a38e2c22c41a8ee45aa608efc890ac3e3931bc"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c011a4149cfbcf9f03994ec2edffcb8b1dc2d2aede7ca243746df97a5d41ce48"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:56d9f2ecac662ca1611d183feb03a3fa4406469dafe241673d521dd5ae92a155"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-win32.whl", hash = "sha256:8758846a7e80910096950b67071243da3e5a20ed2546e6392603c096778d48e0"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-win_amd64.whl", hash = "sha256:787003c0ddb00500e49a10f2844fac87aa6ce977b90b0feaaf9de23c22508b24"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:2ef12179d3a291be237280175b542c07a36e7f60718296278d8593d21ca937d4"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2c1b19b3aaacc6e57b7e25710ff571c24d6c3613a45e905b1fde04d691b98ee0"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8afafd99945ead6e075b973fefa56379c5b5c53fd8937dad92c662da5d8fd5ee"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c41976a29d078bb235fea9b2ecd3da465df42a562910f9022f1a03107bd02be"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d080e0a5eb2529460b30190fcfcc4199bd7f827663f858a226a81bc27beaa97e"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:69c0f17e9f5a7afdf2cc9fb2d1ce6aabdb3bafb7f38017c0b77862bcec2bbad8"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:504b320cd4b7eff6f968eddf81127112db685e81f7e36e75f9f84f0df46041c3"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:42de32b22b6b804f42c5d98be4f7e5e977ecdd9ee9b660fda1a3edf03b11792d"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-win32.whl", hash = "sha256:ceb01949af7121f9fc39f7d27f91be8546f3fb112c608bc4029aef0bab86a2a5"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-win_amd64.whl", hash = "sha256:1b40069d487e7edb2676d3fbdb2b0829ffa2cd63a2ec26c4938b2d34391b4ecc"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8023faf4e01efadfa183e863fefde0046de576c6f14659e8782065bcece22198"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6b2b56950d93e41f33b4223ead100ea0fe11f8e6ee5f641eb753ce4b77a7042b"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9dcdfd0eaf283af041973bff14a2e143b8bd64e069f4c383416ecd79a81aab58"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:05fb21170423db021895e1ea1e1f3ab3adb85d1c2333cbc2310f2a26bc77272e"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:282c2cb35b5b673bbcadb33a585408104df04f14b2d9b01d4c345a3b92861c2c"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ab4a0df41e7c16a1392727727e7998a467472d0ad65f3ad5e6e765015df08636"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7ef3cb2ebbf91e330e3bb937efada0edd9003683db6b57bb108c4001f37a02ea"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:0a4e4a1aff6c7ac4cd55792abf96c915634c2b97e3cc1c7129578aa68ebd754e"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-win32.whl", hash = "sha256:fec21693218efe39aa7f8599346e90c705afa52c5b31ae019b2e57e8f6542bb2"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-win_amd64.whl", hash = "sha256:3fd4abcb888d15a94f32b75d8fd18ee162ca0c064f35b11134be77050296d6ba"}, + {file = "MarkupSafe-2.1.3.tar.gz", hash = "sha256:af598ed32d6ae86f1b747b82783958b1a4ab8f617b06fe68795c7f026abbdcad"}, +] + +[[package]] +name = "matplotlib-inline" +version = "0.1.6" +description = "Inline Matplotlib backend for Jupyter" +optional = false +python-versions = ">=3.5" +files = [ + {file = "matplotlib-inline-0.1.6.tar.gz", hash = "sha256:f887e5f10ba98e8d2b150ddcf4702c1e5f8b3a20005eb0f74bfdbd360ee6f304"}, + {file = "matplotlib_inline-0.1.6-py3-none-any.whl", hash = "sha256:f1f41aab5328aa5aaea9b16d083b128102f8712542f819fe7e6a420ff581b311"}, +] + +[package.dependencies] +traitlets = "*" + +[[package]] +name = "maxminddb" +version = "2.4.0" +description = "Reader for the MaxMind DB format" +optional = false +python-versions = ">=3.7" +files = [ + {file = "maxminddb-2.4.0.tar.gz", hash = "sha256:81e54e53408bd502650e5969ccba16780af659ec1db1c44b2c997e4330a5ed96"}, +] + +[[package]] +name = "msal" +version = "1.23.0" +description = "The Microsoft Authentication Library (MSAL) for Python library enables your app to access the Microsoft Cloud by supporting authentication of users with Microsoft Azure Active Directory accounts (AAD) and Microsoft Accounts (MSA) using industry standard OAuth2 and OpenID Connect." +optional = false +python-versions = "*" +files = [ + {file = "msal-1.23.0-py2.py3-none-any.whl", hash = "sha256:3342e0837a047007f9d479e814b559c3219767453d57920dc40a31986862048b"}, + {file = "msal-1.23.0.tar.gz", hash = "sha256:25c9a33acf84301f93d1fdbe9f1a9c60cd38af0d5fffdbfa378138fc7bc1e86b"}, +] + +[package.dependencies] +cryptography = ">=0.6,<44" +PyJWT = {version = ">=1.0.0,<3", extras = ["crypto"]} +requests = ">=2.0.0,<3" + +[package.extras] +broker = ["pymsalruntime (>=0.13.2,<0.14)"] + +[[package]] +name = "msal-extensions" +version = "1.0.0" +description = "Microsoft Authentication Library extensions (MSAL EX) provides a persistence API that can save your data on disk, encrypted on Windows, macOS and Linux. Concurrent data access will be coordinated by a file lock mechanism." +optional = false +python-versions = "*" +files = [ + {file = "msal-extensions-1.0.0.tar.gz", hash = "sha256:c676aba56b0cce3783de1b5c5ecfe828db998167875126ca4b47dc6436451354"}, + {file = "msal_extensions-1.0.0-py2.py3-none-any.whl", hash = "sha256:91e3db9620b822d0ed2b4d1850056a0f133cba04455e62f11612e40f5502f2ee"}, +] + +[package.dependencies] +msal = ">=0.4.1,<2.0.0" +portalocker = [ + {version = ">=1.0,<3", markers = "python_version >= \"3.5\" and platform_system != \"Windows\""}, + {version = ">=1.6,<3", markers = "python_version >= \"3.5\" and platform_system == \"Windows\""}, +] + +[[package]] +name = "msgpack" +version = "1.0.5" +description = "MessagePack serializer" +optional = false +python-versions = "*" +files = [ + {file = "msgpack-1.0.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:525228efd79bb831cf6830a732e2e80bc1b05436b086d4264814b4b2955b2fa9"}, + {file = "msgpack-1.0.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4f8d8b3bf1ff2672567d6b5c725a1b347fe838b912772aa8ae2bf70338d5a198"}, + {file = "msgpack-1.0.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cdc793c50be3f01106245a61b739328f7dccc2c648b501e237f0699fe1395b81"}, + {file = "msgpack-1.0.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5cb47c21a8a65b165ce29f2bec852790cbc04936f502966768e4aae9fa763cb7"}, + {file = "msgpack-1.0.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e42b9594cc3bf4d838d67d6ed62b9e59e201862a25e9a157019e171fbe672dd3"}, + {file = "msgpack-1.0.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:55b56a24893105dc52c1253649b60f475f36b3aa0fc66115bffafb624d7cb30b"}, + {file = "msgpack-1.0.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:1967f6129fc50a43bfe0951c35acbb729be89a55d849fab7686004da85103f1c"}, + {file = "msgpack-1.0.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:20a97bf595a232c3ee6d57ddaadd5453d174a52594bf9c21d10407e2a2d9b3bd"}, + {file = "msgpack-1.0.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d25dd59bbbbb996eacf7be6b4ad082ed7eacc4e8f3d2df1ba43822da9bfa122a"}, + {file = "msgpack-1.0.5-cp310-cp310-win32.whl", hash = "sha256:382b2c77589331f2cb80b67cc058c00f225e19827dbc818d700f61513ab47bea"}, + {file = "msgpack-1.0.5-cp310-cp310-win_amd64.whl", hash = "sha256:4867aa2df9e2a5fa5f76d7d5565d25ec76e84c106b55509e78c1ede0f152659a"}, + {file = "msgpack-1.0.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9f5ae84c5c8a857ec44dc180a8b0cc08238e021f57abdf51a8182e915e6299f0"}, + {file = "msgpack-1.0.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9e6ca5d5699bcd89ae605c150aee83b5321f2115695e741b99618f4856c50898"}, + {file = "msgpack-1.0.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5494ea30d517a3576749cad32fa27f7585c65f5f38309c88c6d137877fa28a5a"}, + {file = "msgpack-1.0.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1ab2f3331cb1b54165976a9d976cb251a83183631c88076613c6c780f0d6e45a"}, + {file = "msgpack-1.0.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28592e20bbb1620848256ebc105fc420436af59515793ed27d5c77a217477705"}, + {file = "msgpack-1.0.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fe5c63197c55bce6385d9aee16c4d0641684628f63ace85f73571e65ad1c1e8d"}, + {file = "msgpack-1.0.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ed40e926fa2f297e8a653c954b732f125ef97bdd4c889f243182299de27e2aa9"}, + {file = "msgpack-1.0.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:b2de4c1c0538dcb7010902a2b97f4e00fc4ddf2c8cda9749af0e594d3b7fa3d7"}, + {file = "msgpack-1.0.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:bf22a83f973b50f9d38e55c6aade04c41ddda19b00c4ebc558930d78eecc64ed"}, + {file = "msgpack-1.0.5-cp311-cp311-win32.whl", hash = "sha256:c396e2cc213d12ce017b686e0f53497f94f8ba2b24799c25d913d46c08ec422c"}, + {file = "msgpack-1.0.5-cp311-cp311-win_amd64.whl", hash = "sha256:6c4c68d87497f66f96d50142a2b73b97972130d93677ce930718f68828b382e2"}, + {file = "msgpack-1.0.5-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:a2b031c2e9b9af485d5e3c4520f4220d74f4d222a5b8dc8c1a3ab9448ca79c57"}, + {file = "msgpack-1.0.5-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4f837b93669ce4336e24d08286c38761132bc7ab29782727f8557e1eb21b2080"}, + {file = "msgpack-1.0.5-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1d46dfe3832660f53b13b925d4e0fa1432b00f5f7210eb3ad3bb9a13c6204a6"}, + {file = "msgpack-1.0.5-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:366c9a7b9057e1547f4ad51d8facad8b406bab69c7d72c0eb6f529cf76d4b85f"}, + {file = "msgpack-1.0.5-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:4c075728a1095efd0634a7dccb06204919a2f67d1893b6aa8e00497258bf926c"}, + {file = "msgpack-1.0.5-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:f933bbda5a3ee63b8834179096923b094b76f0c7a73c1cfe8f07ad608c58844b"}, + {file = "msgpack-1.0.5-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:36961b0568c36027c76e2ae3ca1132e35123dcec0706c4b7992683cc26c1320c"}, + {file = "msgpack-1.0.5-cp36-cp36m-win32.whl", hash = "sha256:b5ef2f015b95f912c2fcab19c36814963b5463f1fb9049846994b007962743e9"}, + {file = "msgpack-1.0.5-cp36-cp36m-win_amd64.whl", hash = "sha256:288e32b47e67f7b171f86b030e527e302c91bd3f40fd9033483f2cacc37f327a"}, + {file = "msgpack-1.0.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:137850656634abddfb88236008339fdaba3178f4751b28f270d2ebe77a563b6c"}, + {file = "msgpack-1.0.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0c05a4a96585525916b109bb85f8cb6511db1c6f5b9d9cbcbc940dc6b4be944b"}, + {file = "msgpack-1.0.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:56a62ec00b636583e5cb6ad313bbed36bb7ead5fa3a3e38938503142c72cba4f"}, + {file = "msgpack-1.0.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ef8108f8dedf204bb7b42994abf93882da1159728a2d4c5e82012edd92c9da9f"}, + {file = "msgpack-1.0.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:1835c84d65f46900920b3708f5ba829fb19b1096c1800ad60bae8418652a951d"}, + {file = "msgpack-1.0.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:e57916ef1bd0fee4f21c4600e9d1da352d8816b52a599c46460e93a6e9f17086"}, + {file = "msgpack-1.0.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:17358523b85973e5f242ad74aa4712b7ee560715562554aa2134d96e7aa4cbbf"}, + {file = "msgpack-1.0.5-cp37-cp37m-win32.whl", hash = "sha256:cb5aaa8c17760909ec6cb15e744c3ebc2ca8918e727216e79607b7bbce9c8f77"}, + {file = "msgpack-1.0.5-cp37-cp37m-win_amd64.whl", hash = "sha256:ab31e908d8424d55601ad7075e471b7d0140d4d3dd3272daf39c5c19d936bd82"}, + {file = "msgpack-1.0.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:b72d0698f86e8d9ddf9442bdedec15b71df3598199ba33322d9711a19f08145c"}, + {file = "msgpack-1.0.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:379026812e49258016dd84ad79ac8446922234d498058ae1d415f04b522d5b2d"}, + {file = "msgpack-1.0.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:332360ff25469c346a1c5e47cbe2a725517919892eda5cfaffe6046656f0b7bb"}, + {file = "msgpack-1.0.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:476a8fe8fae289fdf273d6d2a6cb6e35b5a58541693e8f9f019bfe990a51e4ba"}, + {file = "msgpack-1.0.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9985b214f33311df47e274eb788a5893a761d025e2b92c723ba4c63936b69b1"}, + {file = "msgpack-1.0.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:48296af57cdb1d885843afd73c4656be5c76c0c6328db3440c9601a98f303d87"}, + {file = "msgpack-1.0.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:addab7e2e1fcc04bd08e4eb631c2a90960c340e40dfc4a5e24d2ff0d5a3b3edb"}, + {file = "msgpack-1.0.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:916723458c25dfb77ff07f4c66aed34e47503b2eb3188b3adbec8d8aa6e00f48"}, + {file = "msgpack-1.0.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:821c7e677cc6acf0fd3f7ac664c98803827ae6de594a9f99563e48c5a2f27eb0"}, + {file = "msgpack-1.0.5-cp38-cp38-win32.whl", hash = "sha256:1c0f7c47f0087ffda62961d425e4407961a7ffd2aa004c81b9c07d9269512f6e"}, + {file = "msgpack-1.0.5-cp38-cp38-win_amd64.whl", hash = "sha256:bae7de2026cbfe3782c8b78b0db9cbfc5455e079f1937cb0ab8d133496ac55e1"}, + {file = "msgpack-1.0.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:20c784e66b613c7f16f632e7b5e8a1651aa5702463d61394671ba07b2fc9e025"}, + {file = "msgpack-1.0.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:266fa4202c0eb94d26822d9bfd7af25d1e2c088927fe8de9033d929dd5ba24c5"}, + {file = "msgpack-1.0.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:18334484eafc2b1aa47a6d42427da7fa8f2ab3d60b674120bce7a895a0a85bdd"}, + {file = "msgpack-1.0.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:57e1f3528bd95cc44684beda696f74d3aaa8a5e58c816214b9046512240ef437"}, + {file = "msgpack-1.0.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:586d0d636f9a628ddc6a17bfd45aa5b5efaf1606d2b60fa5d87b8986326e933f"}, + {file = "msgpack-1.0.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a740fa0e4087a734455f0fc3abf5e746004c9da72fbd541e9b113013c8dc3282"}, + {file = "msgpack-1.0.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:3055b0455e45810820db1f29d900bf39466df96ddca11dfa6d074fa47054376d"}, + {file = "msgpack-1.0.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:a61215eac016f391129a013c9e46f3ab308db5f5ec9f25811e811f96962599a8"}, + {file = "msgpack-1.0.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:362d9655cd369b08fda06b6657a303eb7172d5279997abe094512e919cf74b11"}, + {file = "msgpack-1.0.5-cp39-cp39-win32.whl", hash = "sha256:ac9dd47af78cae935901a9a500104e2dea2e253207c924cc95de149606dc43cc"}, + {file = "msgpack-1.0.5-cp39-cp39-win_amd64.whl", hash = "sha256:06f5174b5f8ed0ed919da0e62cbd4ffde676a374aba4020034da05fab67b9164"}, + {file = "msgpack-1.0.5.tar.gz", hash = "sha256:c075544284eadc5cddc70f4757331d99dcbc16b2bbd4849d15f8aae4cf36d31c"}, +] + +[[package]] +name = "msrest" +version = "0.7.1" +description = "AutoRest swagger generator Python client runtime." +optional = false +python-versions = ">=3.6" +files = [ + {file = "msrest-0.7.1-py3-none-any.whl", hash = "sha256:21120a810e1233e5e6cc7fe40b474eeb4ec6f757a15d7cf86702c369f9567c32"}, + {file = "msrest-0.7.1.zip", hash = "sha256:6e7661f46f3afd88b75667b7187a92829924446c7ea1d169be8c4bb7eeb788b9"}, +] + +[package.dependencies] +azure-core = ">=1.24.0" +certifi = ">=2017.4.17" +isodate = ">=0.6.0" +requests = ">=2.16,<3.0" +requests-oauthlib = ">=0.5.0" + +[package.extras] +async = ["aiodns", "aiohttp (>=3.0)"] + +[[package]] +name = "msrestazure" +version = "0.6.4" +description = "AutoRest swagger generator Python client runtime. Azure-specific module." +optional = false +python-versions = "*" +files = [ + {file = "msrestazure-0.6.4-py2.py3-none-any.whl", hash = "sha256:3de50f56147ef529b31e099a982496690468ecef33f0544cb0fa0cfe1e1de5b9"}, + {file = "msrestazure-0.6.4.tar.gz", hash = "sha256:a06f0dabc9a6f5efe3b6add4bd8fb623aeadacf816b7a35b0f89107e0544d189"}, +] + +[package.dependencies] +adal = ">=0.6.0,<2.0.0" +msrest = ">=0.6.0,<2.0.0" +six = "*" + +[[package]] +name = "multidict" +version = "6.0.4" +description = "multidict implementation" +optional = false +python-versions = ">=3.7" +files = [ + {file = "multidict-6.0.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0b1a97283e0c85772d613878028fec909f003993e1007eafa715b24b377cb9b8"}, + {file = "multidict-6.0.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:eeb6dcc05e911516ae3d1f207d4b0520d07f54484c49dfc294d6e7d63b734171"}, + {file = "multidict-6.0.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d6d635d5209b82a3492508cf5b365f3446afb65ae7ebd755e70e18f287b0adf7"}, + {file = "multidict-6.0.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c048099e4c9e9d615545e2001d3d8a4380bd403e1a0578734e0d31703d1b0c0b"}, + {file = "multidict-6.0.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ea20853c6dbbb53ed34cb4d080382169b6f4554d394015f1bef35e881bf83547"}, + {file = "multidict-6.0.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:16d232d4e5396c2efbbf4f6d4df89bfa905eb0d4dc5b3549d872ab898451f569"}, + {file = "multidict-6.0.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:36c63aaa167f6c6b04ef2c85704e93af16c11d20de1d133e39de6a0e84582a93"}, + {file = "multidict-6.0.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:64bdf1086b6043bf519869678f5f2757f473dee970d7abf6da91ec00acb9cb98"}, + {file = "multidict-6.0.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:43644e38f42e3af682690876cff722d301ac585c5b9e1eacc013b7a3f7b696a0"}, + {file = "multidict-6.0.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:7582a1d1030e15422262de9f58711774e02fa80df0d1578995c76214f6954988"}, + {file = "multidict-6.0.4-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:ddff9c4e225a63a5afab9dd15590432c22e8057e1a9a13d28ed128ecf047bbdc"}, + {file = "multidict-6.0.4-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:ee2a1ece51b9b9e7752e742cfb661d2a29e7bcdba2d27e66e28a99f1890e4fa0"}, + {file = "multidict-6.0.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a2e4369eb3d47d2034032a26c7a80fcb21a2cb22e1173d761a162f11e562caa5"}, + {file = "multidict-6.0.4-cp310-cp310-win32.whl", hash = "sha256:574b7eae1ab267e5f8285f0fe881f17efe4b98c39a40858247720935b893bba8"}, + {file = "multidict-6.0.4-cp310-cp310-win_amd64.whl", hash = "sha256:4dcbb0906e38440fa3e325df2359ac6cb043df8e58c965bb45f4e406ecb162cc"}, + {file = "multidict-6.0.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0dfad7a5a1e39c53ed00d2dd0c2e36aed4650936dc18fd9a1826a5ae1cad6f03"}, + {file = "multidict-6.0.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:64da238a09d6039e3bd39bb3aee9c21a5e34f28bfa5aa22518581f910ff94af3"}, + {file = "multidict-6.0.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ff959bee35038c4624250473988b24f846cbeb2c6639de3602c073f10410ceba"}, + {file = "multidict-6.0.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:01a3a55bd90018c9c080fbb0b9f4891db37d148a0a18722b42f94694f8b6d4c9"}, + {file = "multidict-6.0.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c5cb09abb18c1ea940fb99360ea0396f34d46566f157122c92dfa069d3e0e982"}, + {file = "multidict-6.0.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:666daae833559deb2d609afa4490b85830ab0dfca811a98b70a205621a6109fe"}, + {file = "multidict-6.0.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11bdf3f5e1518b24530b8241529d2050014c884cf18b6fc69c0c2b30ca248710"}, + {file = "multidict-6.0.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7d18748f2d30f94f498e852c67d61261c643b349b9d2a581131725595c45ec6c"}, + {file = "multidict-6.0.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:458f37be2d9e4c95e2d8866a851663cbc76e865b78395090786f6cd9b3bbf4f4"}, + {file = "multidict-6.0.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:b1a2eeedcead3a41694130495593a559a668f382eee0727352b9a41e1c45759a"}, + {file = "multidict-6.0.4-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:7d6ae9d593ef8641544d6263c7fa6408cc90370c8cb2bbb65f8d43e5b0351d9c"}, + {file = "multidict-6.0.4-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:5979b5632c3e3534e42ca6ff856bb24b2e3071b37861c2c727ce220d80eee9ed"}, + {file = "multidict-6.0.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:dcfe792765fab89c365123c81046ad4103fcabbc4f56d1c1997e6715e8015461"}, + {file = "multidict-6.0.4-cp311-cp311-win32.whl", hash = "sha256:3601a3cece3819534b11d4efc1eb76047488fddd0c85a3948099d5da4d504636"}, + {file = "multidict-6.0.4-cp311-cp311-win_amd64.whl", hash = "sha256:81a4f0b34bd92df3da93315c6a59034df95866014ac08535fc819f043bfd51f0"}, + {file = "multidict-6.0.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:67040058f37a2a51ed8ea8f6b0e6ee5bd78ca67f169ce6122f3e2ec80dfe9b78"}, + {file = "multidict-6.0.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:853888594621e6604c978ce2a0444a1e6e70c8d253ab65ba11657659dcc9100f"}, + {file = "multidict-6.0.4-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:39ff62e7d0f26c248b15e364517a72932a611a9b75f35b45be078d81bdb86603"}, + {file = "multidict-6.0.4-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:af048912e045a2dc732847d33821a9d84ba553f5c5f028adbd364dd4765092ac"}, + {file = "multidict-6.0.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1e8b901e607795ec06c9e42530788c45ac21ef3aaa11dbd0c69de543bfb79a9"}, + {file = "multidict-6.0.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62501642008a8b9871ddfccbf83e4222cf8ac0d5aeedf73da36153ef2ec222d2"}, + {file = "multidict-6.0.4-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:99b76c052e9f1bc0721f7541e5e8c05db3941eb9ebe7b8553c625ef88d6eefde"}, + {file = "multidict-6.0.4-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:509eac6cf09c794aa27bcacfd4d62c885cce62bef7b2c3e8b2e49d365b5003fe"}, + {file = "multidict-6.0.4-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:21a12c4eb6ddc9952c415f24eef97e3e55ba3af61f67c7bc388dcdec1404a067"}, + {file = "multidict-6.0.4-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:5cad9430ab3e2e4fa4a2ef4450f548768400a2ac635841bc2a56a2052cdbeb87"}, + {file = "multidict-6.0.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ab55edc2e84460694295f401215f4a58597f8f7c9466faec545093045476327d"}, + {file = "multidict-6.0.4-cp37-cp37m-win32.whl", hash = "sha256:5a4dcf02b908c3b8b17a45fb0f15b695bf117a67b76b7ad18b73cf8e92608775"}, + {file = "multidict-6.0.4-cp37-cp37m-win_amd64.whl", hash = "sha256:6ed5f161328b7df384d71b07317f4d8656434e34591f20552c7bcef27b0ab88e"}, + {file = "multidict-6.0.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5fc1b16f586f049820c5c5b17bb4ee7583092fa0d1c4e28b5239181ff9532e0c"}, + {file = "multidict-6.0.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1502e24330eb681bdaa3eb70d6358e818e8e8f908a22a1851dfd4e15bc2f8161"}, + {file = "multidict-6.0.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b692f419760c0e65d060959df05f2a531945af31fda0c8a3b3195d4efd06de11"}, + {file = "multidict-6.0.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45e1ecb0379bfaab5eef059f50115b54571acfbe422a14f668fc8c27ba410e7e"}, + {file = "multidict-6.0.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ddd3915998d93fbcd2566ddf9cf62cdb35c9e093075f862935573d265cf8f65d"}, + {file = "multidict-6.0.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:59d43b61c59d82f2effb39a93c48b845efe23a3852d201ed2d24ba830d0b4cf2"}, + {file = "multidict-6.0.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cc8e1d0c705233c5dd0c5e6460fbad7827d5d36f310a0fadfd45cc3029762258"}, + {file = "multidict-6.0.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d6aa0418fcc838522256761b3415822626f866758ee0bc6632c9486b179d0b52"}, + {file = "multidict-6.0.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6748717bb10339c4760c1e63da040f5f29f5ed6e59d76daee30305894069a660"}, + {file = "multidict-6.0.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:4d1a3d7ef5e96b1c9e92f973e43aa5e5b96c659c9bc3124acbbd81b0b9c8a951"}, + {file = "multidict-6.0.4-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4372381634485bec7e46718edc71528024fcdc6f835baefe517b34a33c731d60"}, + {file = "multidict-6.0.4-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:fc35cb4676846ef752816d5be2193a1e8367b4c1397b74a565a9d0389c433a1d"}, + {file = "multidict-6.0.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:4b9d9e4e2b37daddb5c23ea33a3417901fa7c7b3dee2d855f63ee67a0b21e5b1"}, + {file = "multidict-6.0.4-cp38-cp38-win32.whl", hash = "sha256:e41b7e2b59679edfa309e8db64fdf22399eec4b0b24694e1b2104fb789207779"}, + {file = "multidict-6.0.4-cp38-cp38-win_amd64.whl", hash = "sha256:d6c254ba6e45d8e72739281ebc46ea5eb5f101234f3ce171f0e9f5cc86991480"}, + {file = "multidict-6.0.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:16ab77bbeb596e14212e7bab8429f24c1579234a3a462105cda4a66904998664"}, + {file = "multidict-6.0.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bc779e9e6f7fda81b3f9aa58e3a6091d49ad528b11ed19f6621408806204ad35"}, + {file = "multidict-6.0.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4ceef517eca3e03c1cceb22030a3e39cb399ac86bff4e426d4fc6ae49052cc60"}, + {file = "multidict-6.0.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:281af09f488903fde97923c7744bb001a9b23b039a909460d0f14edc7bf59706"}, + {file = "multidict-6.0.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:52f2dffc8acaba9a2f27174c41c9e57f60b907bb9f096b36b1a1f3be71c6284d"}, + {file = "multidict-6.0.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b41156839806aecb3641f3208c0dafd3ac7775b9c4c422d82ee2a45c34ba81ca"}, + {file = "multidict-6.0.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d5e3fc56f88cc98ef8139255cf8cd63eb2c586531e43310ff859d6bb3a6b51f1"}, + {file = "multidict-6.0.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8316a77808c501004802f9beebde51c9f857054a0c871bd6da8280e718444449"}, + {file = "multidict-6.0.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f70b98cd94886b49d91170ef23ec5c0e8ebb6f242d734ed7ed677b24d50c82cf"}, + {file = "multidict-6.0.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bf6774e60d67a9efe02b3616fee22441d86fab4c6d335f9d2051d19d90a40063"}, + {file = "multidict-6.0.4-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:e69924bfcdda39b722ef4d9aa762b2dd38e4632b3641b1d9a57ca9cd18f2f83a"}, + {file = "multidict-6.0.4-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:6b181d8c23da913d4ff585afd1155a0e1194c0b50c54fcfe286f70cdaf2b7176"}, + {file = "multidict-6.0.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:52509b5be062d9eafc8170e53026fbc54cf3b32759a23d07fd935fb04fc22d95"}, + {file = "multidict-6.0.4-cp39-cp39-win32.whl", hash = "sha256:27c523fbfbdfd19c6867af7346332b62b586eed663887392cff78d614f9ec313"}, + {file = "multidict-6.0.4-cp39-cp39-win_amd64.whl", hash = "sha256:33029f5734336aa0d4c0384525da0387ef89148dc7191aae00ca5fb23d7aafc2"}, + {file = "multidict-6.0.4.tar.gz", hash = "sha256:3666906492efb76453c0e7b97f2cf459b0682e7402c0489a95484965dbc1da49"}, +] + +[[package]] +name = "mysqlclient" +version = "2.2.0" +description = "Python interface to MySQL" +optional = false +python-versions = ">=3.8" +files = [ + {file = "mysqlclient-2.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:68837b6bb23170acffb43ae411e47533a560b6360c06dac39aa55700972c93b2"}, + {file = "mysqlclient-2.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:5670679ff1be1cc3fef0fa81bf39f0cd70605ba121141050f02743eb878ac114"}, + {file = "mysqlclient-2.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:004fe1d30d2c2ff8072f8ea513bcec235fd9b896f70dad369461d0ad7e570e98"}, + {file = "mysqlclient-2.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:9c6b142836c7dba4f723bf9c93cc46b6e5081d65b2af807f400dda9eb85a16d0"}, + {file = "mysqlclient-2.2.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:955dba905a7443ce4788c63fdb9f8d688316260cf60b20ff51ac3b1c77616ede"}, + {file = "mysqlclient-2.2.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:530ece9995a36cadb6211b9787f0c9e05cdab6702549bdb4236af5e9b535ed6a"}, + {file = "mysqlclient-2.2.0.tar.gz", hash = "sha256:04368445f9c487d8abb7a878e3d23e923e6072c04a6c320f9e0dc8a82efba14e"}, +] + +[[package]] +name = "netaddr" +version = "0.8.0" +description = "A network address manipulation library for Python" +optional = false +python-versions = "*" +files = [ + {file = "netaddr-0.8.0-py2.py3-none-any.whl", hash = "sha256:9666d0232c32d2656e5e5f8d735f58fd6c7457ce52fc21c98d45f2af78f990ac"}, + {file = "netaddr-0.8.0.tar.gz", hash = "sha256:d6cc57c7a07b1d9d2e917aa8b36ae8ce61c35ba3fcd1b83ca31c5a0ee2b5a243"}, +] + +[[package]] +name = "netifaces" +version = "0.11.0" +description = "Portable network interface information." +optional = false +python-versions = "*" +files = [ + {file = "netifaces-0.11.0-cp27-cp27m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:eb4813b77d5df99903af4757ce980a98c4d702bbcb81f32a0b305a1537bdf0b1"}, + {file = "netifaces-0.11.0-cp27-cp27m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:5f9ca13babe4d845e400921973f6165a4c2f9f3379c7abfc7478160e25d196a4"}, + {file = "netifaces-0.11.0-cp27-cp27m-win32.whl", hash = "sha256:7dbb71ea26d304e78ccccf6faccef71bb27ea35e259fb883cfd7fd7b4f17ecb1"}, + {file = "netifaces-0.11.0-cp27-cp27m-win_amd64.whl", hash = "sha256:0f6133ac02521270d9f7c490f0c8c60638ff4aec8338efeff10a1b51506abe85"}, + {file = "netifaces-0.11.0-cp27-cp27mu-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:08e3f102a59f9eaef70948340aeb6c89bd09734e0dca0f3b82720305729f63ea"}, + {file = "netifaces-0.11.0-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:c03fb2d4ef4e393f2e6ffc6376410a22a3544f164b336b3a355226653e5efd89"}, + {file = "netifaces-0.11.0-cp34-cp34m-win32.whl", hash = "sha256:73ff21559675150d31deea8f1f8d7e9a9a7e4688732a94d71327082f517fc6b4"}, + {file = "netifaces-0.11.0-cp35-cp35m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:815eafdf8b8f2e61370afc6add6194bd5a7252ae44c667e96c4c1ecf418811e4"}, + {file = "netifaces-0.11.0-cp35-cp35m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:50721858c935a76b83dd0dd1ab472cad0a3ef540a1408057624604002fcfb45b"}, + {file = "netifaces-0.11.0-cp35-cp35m-win32.whl", hash = "sha256:c9a3a47cd3aaeb71e93e681d9816c56406ed755b9442e981b07e3618fb71d2ac"}, + {file = "netifaces-0.11.0-cp36-cp36m-macosx_10_15_x86_64.whl", hash = "sha256:aab1dbfdc55086c789f0eb37affccf47b895b98d490738b81f3b2360100426be"}, + {file = "netifaces-0.11.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c37a1ca83825bc6f54dddf5277e9c65dec2f1b4d0ba44b8fd42bc30c91aa6ea1"}, + {file = "netifaces-0.11.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:28f4bf3a1361ab3ed93c5ef360c8b7d4a4ae060176a3529e72e5e4ffc4afd8b0"}, + {file = "netifaces-0.11.0-cp36-cp36m-win32.whl", hash = "sha256:2650beee182fed66617e18474b943e72e52f10a24dc8cac1db36c41ee9c041b7"}, + {file = "netifaces-0.11.0-cp36-cp36m-win_amd64.whl", hash = "sha256:cb925e1ca024d6f9b4f9b01d83215fd00fe69d095d0255ff3f64bffda74025c8"}, + {file = "netifaces-0.11.0-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:84e4d2e6973eccc52778735befc01638498781ce0e39aa2044ccfd2385c03246"}, + {file = "netifaces-0.11.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:18917fbbdcb2d4f897153c5ddbb56b31fa6dd7c3fa9608b7e3c3a663df8206b5"}, + {file = "netifaces-0.11.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:48324183af7f1bc44f5f197f3dad54a809ad1ef0c78baee2c88f16a5de02c4c9"}, + {file = "netifaces-0.11.0-cp37-cp37m-win32.whl", hash = "sha256:8f7da24eab0d4184715d96208b38d373fd15c37b0dafb74756c638bd619ba150"}, + {file = "netifaces-0.11.0-cp37-cp37m-win_amd64.whl", hash = "sha256:2479bb4bb50968089a7c045f24d120f37026d7e802ec134c4490eae994c729b5"}, + {file = "netifaces-0.11.0-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:3ecb3f37c31d5d51d2a4d935cfa81c9bc956687c6f5237021b36d6fdc2815b2c"}, + {file = "netifaces-0.11.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:96c0fe9696398253f93482c84814f0e7290eee0bfec11563bd07d80d701280c3"}, + {file = "netifaces-0.11.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:c92ff9ac7c2282009fe0dcb67ee3cd17978cffbe0c8f4b471c00fe4325c9b4d4"}, + {file = "netifaces-0.11.0-cp38-cp38-win32.whl", hash = "sha256:d07b01c51b0b6ceb0f09fc48ec58debd99d2c8430b09e56651addeaf5de48048"}, + {file = "netifaces-0.11.0-cp38-cp38-win_amd64.whl", hash = "sha256:469fc61034f3daf095e02f9f1bbac07927b826c76b745207287bc594884cfd05"}, + {file = "netifaces-0.11.0-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:5be83986100ed1fdfa78f11ccff9e4757297735ac17391b95e17e74335c2047d"}, + {file = "netifaces-0.11.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:54ff6624eb95b8a07e79aa8817288659af174e954cca24cdb0daeeddfc03c4ff"}, + {file = "netifaces-0.11.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:841aa21110a20dc1621e3dd9f922c64ca64dd1eb213c47267a2c324d823f6c8f"}, + {file = "netifaces-0.11.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:e76c7f351e0444721e85f975ae92718e21c1f361bda946d60a214061de1f00a1"}, + {file = "netifaces-0.11.0.tar.gz", hash = "sha256:043a79146eb2907edf439899f262b3dfe41717d34124298ed281139a8b93ca32"}, +] + +[[package]] +name = "oauthlib" +version = "3.2.2" +description = "A generic, spec-compliant, thorough implementation of the OAuth request-signing logic" +optional = false +python-versions = ">=3.6" +files = [ + {file = "oauthlib-3.2.2-py3-none-any.whl", hash = "sha256:8139f29aac13e25d502680e9e19963e83f16838d48a0d71c287fe40e7067fbca"}, + {file = "oauthlib-3.2.2.tar.gz", hash = "sha256:9859c40929662bec5d64f34d01c99e093149682a3f38915dc0655d5a633dd918"}, +] + +[package.extras] +rsa = ["cryptography (>=3.0.0)"] +signals = ["blinker (>=1.4.0)"] +signedtoken = ["cryptography (>=3.0.0)", "pyjwt (>=2.0.0,<3)"] + +[[package]] +name = "olefile" +version = "0.46" +description = "Python package to parse, read and write Microsoft OLE2 files (Structured Storage or Compound Document, Microsoft Office)" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "olefile-0.46.zip", hash = "sha256:133b031eaf8fd2c9399b78b8bc5b8fcbe4c31e85295749bb17a87cba8f3c3964"}, +] + +[[package]] +name = "openapi-codec" +version = "1.3.2" +description = "An OpenAPI codec for Core API." +optional = false +python-versions = "*" +files = [ + {file = "openapi-codec-1.3.2.tar.gz", hash = "sha256:1bce63289edf53c601ea3683120641407ff6b708803b8954c8a876fe778d2145"}, +] + +[package.dependencies] +coreapi = ">=2.2.0" + +[[package]] +name = "openpyxl" +version = "3.0.10" +description = "A Python library to read/write Excel 2010 xlsx/xlsm files" +optional = false +python-versions = ">=3.6" +files = [ + {file = "openpyxl-3.0.10-py2.py3-none-any.whl", hash = "sha256:0ab6d25d01799f97a9464630abacbb34aafecdcaa0ef3cba6d6b3499867d0355"}, + {file = "openpyxl-3.0.10.tar.gz", hash = "sha256:e47805627aebcf860edb4edf7987b1309c1b3632f3750538ed962bbcc3bd7449"}, +] + +[package.dependencies] +et-xmlfile = "*" + +[[package]] +name = "oracledb" +version = "1.3.2" +description = "Python interface to Oracle Database" +optional = false +python-versions = ">=3.6" +files = [ + {file = "oracledb-1.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:bee717f90118a95f0c661d27e7a65255eb5e400b95cbe4019b75014b3691ef90"}, + {file = "oracledb-1.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:000c5a31ecc5569e6dec4dcaf4552509d88a19051e57deb0af96296f9937dc6a"}, + {file = "oracledb-1.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c37c249c4323b61c3e333c2cf724e19e6416d35130acf0f684eefad17a73b040"}, + {file = "oracledb-1.3.2-cp310-cp310-win32.whl", hash = "sha256:2680f460708904a2d2e4f853990bce10a963905205acf0e709c32cad353a5d2f"}, + {file = "oracledb-1.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:0fdfa5e119270332eab1ee5900a503423e87d1b8ae6da17c426dd34822217213"}, + {file = "oracledb-1.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:de0ada0cbea8b1524f0798cedc38dabc9a8bfcb67f738b914e7a8eb873cc854a"}, + {file = "oracledb-1.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:138904100c5218c33005ec5b07688ce68f40ea20c28b3b840738401ae2a862a1"}, + {file = "oracledb-1.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:839f7a4d8d34130dd99a44c064bc9eea130a0d2406f723398ebb0b29b6d3a8cf"}, + {file = "oracledb-1.3.2-cp311-cp311-win32.whl", hash = "sha256:8e37e2b41900a113894049f3c9d7b64e93f613ed52104f2f05ef3284e2e1bb8f"}, + {file = "oracledb-1.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:cedd48e7d107884d4a19c9ad449b3c3cb3b3e4d67a6eddacb966b1370cc1f35e"}, + {file = "oracledb-1.3.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3a285f35edf435a7f60f54074d9925deb63146b4cc0f6998eba75a282c8ce497"}, + {file = "oracledb-1.3.2-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e86e5203767e1216ceeda6b7c087b804fa2f44041680d5099900c3cf5724915"}, + {file = "oracledb-1.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:043d7d5fdda0ea43734cd4cf67771efddc9307eef10cc83afc19599d39a23d72"}, + {file = "oracledb-1.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:08cff689d8117c817458a633859a35c21fc44f39bf56c9c8f62ec02789d0e1e0"}, + {file = "oracledb-1.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2279f8550d80ed30315ef84e88b8ec5b533064e8a81ef96265647019ccee8e85"}, + {file = "oracledb-1.3.2-cp37-cp37m-win32.whl", hash = "sha256:af8d8635453961556b84e37a1dd40c94e18d1b5d3b54020fafce0f3e67472b90"}, + {file = "oracledb-1.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:6e8710cdb14c4510f65c11c02f1d97c079d20e0692a431a1af0e964064b7e32c"}, + {file = "oracledb-1.3.2-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:9808e4169e3f330f2ea6dd15376432886d7ed84344f447048d9305a520f31a7a"}, + {file = "oracledb-1.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e0b760c58f73a262af01e093fc9b183de59516b618319fb53b281eedde1dccbc"}, + {file = "oracledb-1.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ea5a26481c798978210505a1252eec6814cf28005e18a80f935cbcf5b74dabb"}, + {file = "oracledb-1.3.2-cp38-cp38-win32.whl", hash = "sha256:790798eb1e9b96639c02e91f3b3f00934d722d9de0ac375adcda37b83bba61a6"}, + {file = "oracledb-1.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:796b900fe85af572ff3d7227372ca3a2edd5f756e538e95ffbfc689df3881696"}, + {file = "oracledb-1.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5f669d7fa78a865d10ad9840a2cb6958b395c572c119ff51489a4a738302727e"}, + {file = "oracledb-1.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d5e20ed24335c59f42003750be3063f3d75f371af35eff47cc9177e9a4193af2"}, + {file = "oracledb-1.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eb49ebd84d65080703ea8a2b2edde3ac27a6fdc9c491db2dbde0b960f40e3c10"}, + {file = "oracledb-1.3.2-cp39-cp39-win32.whl", hash = "sha256:022a6631ac779f0d600870fea1f7600a03eabcb4609138e91ac77b8126a9373b"}, + {file = "oracledb-1.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:4fdeb8b2158d5fb93451d57152f9cfb25f0d876dcbb90305133267196c9efd84"}, + {file = "oracledb-1.3.2.tar.gz", hash = "sha256:bb3c391c167b5778ddb15a7538a2b36db5c9b88a50c86c61781ca9ff302bb643"}, +] + +[package.dependencies] +cryptography = ">=3.2.1" + +[[package]] +name = "os-service-types" +version = "1.7.0" +description = "Python library for consuming OpenStack sevice-types-authority data" +optional = false +python-versions = "*" +files = [ + {file = "os-service-types-1.7.0.tar.gz", hash = "sha256:31800299a82239363995b91f1ebf9106ac7758542a1e4ef6dc737a5932878c6c"}, + {file = "os_service_types-1.7.0-py2.py3-none-any.whl", hash = "sha256:0505c72205690910077fb72b88f2a1f07533c8d39f2fe75b29583481764965d6"}, +] + +[package.dependencies] +pbr = ">=2.0.0,<2.1.0 || >2.1.0" + +[[package]] +name = "oslo-config" +version = "9.1.1" +description = "Oslo Configuration API" +optional = false +python-versions = ">=3.8" +files = [ + {file = "oslo.config-9.1.1-py3-none-any.whl", hash = "sha256:7cd56e0b41b04f64dbc42e83e8164d5ef03466390f1216fbda2cb0e1c535c22c"}, + {file = "oslo.config-9.1.1.tar.gz", hash = "sha256:b07654b53d87792ae8e739962ad729c529c9938a118d891ece9ee31d59716bc9"}, +] + +[package.dependencies] +debtcollector = ">=1.2.0" +netaddr = ">=0.7.18" +"oslo.i18n" = ">=3.15.3" +PyYAML = ">=5.1" +requests = ">=2.18.0" +rfc3986 = ">=1.2.0" +stevedore = ">=1.20.0" + +[package.extras] +rst-generator = ["rst2txt (>=1.1.0)", "sphinx (>=1.8.0,!=2.1.0)"] +test = ["bandit (>=1.6.0,<1.7.0)", "coverage (>=4.0,!=4.4)", "fixtures (>=3.0.0)", "hacking (>=3.0.1,<3.1.0)", "mypy (>=0.720)", "oslo.log (>=3.36.0)", "oslotest (>=3.2.0)", "pre-commit (>=2.6.0)", "requests-mock (>=1.5.0)", "stestr (>=2.1.0)", "testscenarios (>=0.4)", "testtools (>=2.2.0)"] + +[[package]] +name = "oslo-i18n" +version = "6.0.0" +description = "Oslo i18n library" +optional = false +python-versions = ">=3.8" +files = [ + {file = "oslo.i18n-6.0.0-py3-none-any.whl", hash = "sha256:080fedf41b05d4dcd23a91d23ee2dea0863996e860a59695856269a42d939fc1"}, + {file = "oslo.i18n-6.0.0.tar.gz", hash = "sha256:ed10686b75f7c607825177a669155f4e259ce39f6143a375f6359bbcaa4a35cd"}, +] + +[package.dependencies] +pbr = ">=2.0.0,<2.1.0 || >2.1.0" + +[[package]] +name = "oslo-serialization" +version = "5.1.1" +description = "Oslo Serialization library" +optional = false +python-versions = ">=3.8" +files = [ + {file = "oslo.serialization-5.1.1-py3-none-any.whl", hash = "sha256:c5dfb97ce8ddd1d2708a9a3f4a091063f6c304940c7cb39f532f7f791441fdca"}, + {file = "oslo.serialization-5.1.1.tar.gz", hash = "sha256:8abbda8b1763a06071fc28c5d8a9be547ba285f4830e68a70ff88fe11f16bf43"}, +] + +[package.dependencies] +msgpack = ">=0.5.2" +"oslo.utils" = ">=3.33.0" +pbr = ">=2.0.0,<2.1.0 || >2.1.0" +pytz = ">=2013.6" + +[[package]] +name = "oslo-utils" +version = "6.2.0" +description = "Oslo Utility library" +optional = false +python-versions = ">=3.8" +files = [ + {file = "oslo.utils-6.2.0-py3-none-any.whl", hash = "sha256:30ba9fd431be468cd17b5d7c1a0ae6d63bb63aaaf97bf590123f13c6d95254a3"}, + {file = "oslo.utils-6.2.0.tar.gz", hash = "sha256:fe1d166f4cb004fbd6b6bc9adfbc32aedeaf3eb54eeaf70d91a224a87543c6a5"}, +] + +[package.dependencies] +debtcollector = ">=1.2.0" +iso8601 = ">=0.1.11" +netaddr = ">=0.7.18" +netifaces = ">=0.10.4" +"oslo.i18n" = ">=3.15.3" +packaging = ">=20.4" +pyparsing = ">=2.1.0" +pytz = ">=2013.6" +tzdata = ">=2022.4" + +[[package]] +name = "oss2" +version = "2.18.1" +description = "Aliyun OSS (Object Storage Service) SDK" +optional = false +python-versions = "*" +files = [ + {file = "oss2-2.18.1.tar.gz", hash = "sha256:5a901f6c0f3ac42f792e16a1e1c04e60f34e6cc9eb2bc4c0c3ce6e7bda2da4cc"}, +] + +[package.dependencies] +aliyun-python-sdk-core = ">=2.13.12" +aliyun-python-sdk-kms = ">=2.4.1" +crcmod = ">=1.7" +pycryptodome = ">=3.4.7" +requests = "!=2.9.0" +six = "*" + +[[package]] +name = "packaging" +version = "23.1" +description = "Core utilities for Python packages" +optional = false +python-versions = ">=3.7" +files = [ + {file = "packaging-23.1-py3-none-any.whl", hash = "sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61"}, + {file = "packaging-23.1.tar.gz", hash = "sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f"}, +] + +[[package]] +name = "paramiko" +version = "3.2.0" +description = "SSH2 protocol library" +optional = false +python-versions = ">=3.6" +files = [ + {file = "paramiko-3.2.0-py3-none-any.whl", hash = "sha256:df0f9dd8903bc50f2e10580af687f3015bf592a377cd438d2ec9546467a14eb8"}, + {file = "paramiko-3.2.0.tar.gz", hash = "sha256:93cdce625a8a1dc12204439d45033f3261bdb2c201648cfcdc06f9fd0f94ec29"}, +] + +[package.dependencies] +bcrypt = ">=3.2" +cryptography = ">=3.3" +pynacl = ">=1.5" + +[package.extras] +all = ["gssapi (>=1.4.1)", "invoke (>=2.0)", "pyasn1 (>=0.1.7)", "pywin32 (>=2.1.8)"] +gssapi = ["gssapi (>=1.4.1)", "pyasn1 (>=0.1.7)", "pywin32 (>=2.1.8)"] +invoke = ["invoke (>=2.0)"] + +[[package]] +name = "parso" +version = "0.8.3" +description = "A Python Parser" +optional = false +python-versions = ">=3.6" +files = [ + {file = "parso-0.8.3-py2.py3-none-any.whl", hash = "sha256:c001d4636cd3aecdaf33cbb40aebb59b094be2a74c556778ef5576c175e19e75"}, + {file = "parso-0.8.3.tar.gz", hash = "sha256:8c07be290bb59f03588915921e29e8a50002acaf2cdc5fa0e0114f91709fafa0"}, +] + +[package.extras] +qa = ["flake8 (==3.8.3)", "mypy (==0.782)"] +testing = ["docopt", "pytest (<6.0.0)"] + +[[package]] +name = "passlib" +version = "1.7.4" +description = "comprehensive password hashing framework supporting over 30 schemes" +optional = false +python-versions = "*" +files = [ + {file = "passlib-1.7.4-py2.py3-none-any.whl", hash = "sha256:aa6bca462b8d8bda89c70b382f0c298a20b5560af6cbfa2dce410c0a2fb669f1"}, + {file = "passlib-1.7.4.tar.gz", hash = "sha256:defd50f72b65c5402ab2c573830a6978e5f202ad0d984793c8dde2c4152ebe04"}, +] + +[package.extras] +argon2 = ["argon2-cffi (>=18.2.0)"] +bcrypt = ["bcrypt (>=3.1.0)"] +build-docs = ["cloud-sptheme (>=1.10.1)", "sphinx (>=1.6)", "sphinxcontrib-fulltoc (>=1.2.0)"] +totp = ["cryptography"] + +[[package]] +name = "pbr" +version = "5.11.1" +description = "Python Build Reasonableness" +optional = false +python-versions = ">=2.6" +files = [ + {file = "pbr-5.11.1-py2.py3-none-any.whl", hash = "sha256:567f09558bae2b3ab53cb3c1e2e33e726ff3338e7bae3db5dc954b3a44eef12b"}, + {file = "pbr-5.11.1.tar.gz", hash = "sha256:aefc51675b0b533d56bb5fd1c8c6c0522fe31896679882e1c4c63d5e4a0fccb3"}, +] + +[[package]] +name = "pexpect" +version = "4.8.0" +description = "Pexpect allows easy control of interactive console applications." +optional = false +python-versions = "*" +files = [ + {file = "pexpect-4.8.0-py2.py3-none-any.whl", hash = "sha256:0b48a55dcb3c05f3329815901ea4fc1537514d6ba867a152b581d69ae3710937"}, + {file = "pexpect-4.8.0.tar.gz", hash = "sha256:fc65a43959d153d0114afe13997d439c22823a27cefceb5ff35c2178c6784c0c"}, +] + +[package.dependencies] +ptyprocess = ">=0.5" + +[[package]] +name = "phonenumbers" +version = "8.13.17" +description = "Python version of Google's common library for parsing, formatting, storing and validating international phone numbers." +optional = false +python-versions = "*" +files = [ + {file = "phonenumbers-8.13.17-py2.py3-none-any.whl", hash = "sha256:e8ffd86b2e0b844fd6189fdb0927dbe8707cb03b59102cba5532b3ea305cc1bd"}, + {file = "phonenumbers-8.13.17.tar.gz", hash = "sha256:89671217c706cbaa3ced101deefafa779836feac3e059434d886ac31f09f32c0"}, +] + +[[package]] +name = "pickleshare" +version = "0.7.5" +description = "Tiny 'shelve'-like database with concurrency support" +optional = false +python-versions = "*" +files = [ + {file = "pickleshare-0.7.5-py2.py3-none-any.whl", hash = "sha256:9649af414d74d4df115d5d718f82acb59c9d418196b7b4290ed47a12ce62df56"}, + {file = "pickleshare-0.7.5.tar.gz", hash = "sha256:87683d47965c1da65cdacaf31c8441d12b8044cdec9aca500cd78fc2c683afca"}, +] + +[[package]] +name = "pillow" +version = "10.0.0" +description = "Python Imaging Library (Fork)" +optional = false +python-versions = ">=3.8" +files = [ + {file = "Pillow-10.0.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:1f62406a884ae75fb2f818694469519fb685cc7eaff05d3451a9ebe55c646891"}, + {file = "Pillow-10.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d5db32e2a6ccbb3d34d87c87b432959e0db29755727afb37290e10f6e8e62614"}, + {file = "Pillow-10.0.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:edf4392b77bdc81f36e92d3a07a5cd072f90253197f4a52a55a8cec48a12483b"}, + {file = "Pillow-10.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:520f2a520dc040512699f20fa1c363eed506e94248d71f85412b625026f6142c"}, + {file = "Pillow-10.0.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:8c11160913e3dd06c8ffdb5f233a4f254cb449f4dfc0f8f4549eda9e542c93d1"}, + {file = "Pillow-10.0.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:a74ba0c356aaa3bb8e3eb79606a87669e7ec6444be352870623025d75a14a2bf"}, + {file = "Pillow-10.0.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d5d0dae4cfd56969d23d94dc8e89fb6a217be461c69090768227beb8ed28c0a3"}, + {file = "Pillow-10.0.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:22c10cc517668d44b211717fd9775799ccec4124b9a7f7b3635fc5386e584992"}, + {file = "Pillow-10.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:dffe31a7f47b603318c609f378ebcd57f1554a3a6a8effbc59c3c69f804296de"}, + {file = "Pillow-10.0.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:9fb218c8a12e51d7ead2a7c9e101a04982237d4855716af2e9499306728fb485"}, + {file = "Pillow-10.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d35e3c8d9b1268cbf5d3670285feb3528f6680420eafe35cccc686b73c1e330f"}, + {file = "Pillow-10.0.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ed64f9ca2f0a95411e88a4efbd7a29e5ce2cea36072c53dd9d26d9c76f753b3"}, + {file = "Pillow-10.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b6eb5502f45a60a3f411c63187db83a3d3107887ad0d036c13ce836f8a36f1d"}, + {file = "Pillow-10.0.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:c1fbe7621c167ecaa38ad29643d77a9ce7311583761abf7836e1510c580bf3dd"}, + {file = "Pillow-10.0.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:cd25d2a9d2b36fcb318882481367956d2cf91329f6892fe5d385c346c0649629"}, + {file = "Pillow-10.0.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:3b08d4cc24f471b2c8ca24ec060abf4bebc6b144cb89cba638c720546b1cf538"}, + {file = "Pillow-10.0.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d737a602fbd82afd892ca746392401b634e278cb65d55c4b7a8f48e9ef8d008d"}, + {file = "Pillow-10.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:3a82c40d706d9aa9734289740ce26460a11aeec2d9c79b7af87bb35f0073c12f"}, + {file = "Pillow-10.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:bc2ec7c7b5d66b8ec9ce9f720dbb5fa4bace0f545acd34870eff4a369b44bf37"}, + {file = "Pillow-10.0.0-cp312-cp312-macosx_10_10_x86_64.whl", hash = "sha256:d80cf684b541685fccdd84c485b31ce73fc5c9b5d7523bf1394ce134a60c6883"}, + {file = "Pillow-10.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:76de421f9c326da8f43d690110f0e79fe3ad1e54be811545d7d91898b4c8493e"}, + {file = "Pillow-10.0.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:81ff539a12457809666fef6624684c008e00ff6bf455b4b89fd00a140eecd640"}, + {file = "Pillow-10.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce543ed15570eedbb85df19b0a1a7314a9c8141a36ce089c0a894adbfccb4568"}, + {file = "Pillow-10.0.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:685ac03cc4ed5ebc15ad5c23bc555d68a87777586d970c2c3e216619a5476223"}, + {file = "Pillow-10.0.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:d72e2ecc68a942e8cf9739619b7f408cc7b272b279b56b2c83c6123fcfa5cdff"}, + {file = "Pillow-10.0.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d50b6aec14bc737742ca96e85d6d0a5f9bfbded018264b3b70ff9d8c33485551"}, + {file = "Pillow-10.0.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:00e65f5e822decd501e374b0650146063fbb30a7264b4d2744bdd7b913e0cab5"}, + {file = "Pillow-10.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:f31f9fdbfecb042d046f9d91270a0ba28368a723302786c0009ee9b9f1f60199"}, + {file = "Pillow-10.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:1ce91b6ec08d866b14413d3f0bbdea7e24dfdc8e59f562bb77bc3fe60b6144ca"}, + {file = "Pillow-10.0.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:349930d6e9c685c089284b013478d6f76e3a534e36ddfa912cde493f235372f3"}, + {file = "Pillow-10.0.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:3a684105f7c32488f7153905a4e3015a3b6c7182e106fe3c37fbb5ef3e6994c3"}, + {file = "Pillow-10.0.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b4f69b3700201b80bb82c3a97d5e9254084f6dd5fb5b16fc1a7b974260f89f43"}, + {file = "Pillow-10.0.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f07ea8d2f827d7d2a49ecf1639ec02d75ffd1b88dcc5b3a61bbb37a8759ad8d"}, + {file = "Pillow-10.0.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:040586f7d37b34547153fa383f7f9aed68b738992380ac911447bb78f2abe530"}, + {file = "Pillow-10.0.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:f88a0b92277de8e3ca715a0d79d68dc82807457dae3ab8699c758f07c20b3c51"}, + {file = "Pillow-10.0.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:c7cf14a27b0d6adfaebb3ae4153f1e516df54e47e42dcc073d7b3d76111a8d86"}, + {file = "Pillow-10.0.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:3400aae60685b06bb96f99a21e1ada7bc7a413d5f49bce739828ecd9391bb8f7"}, + {file = "Pillow-10.0.0-cp38-cp38-win_amd64.whl", hash = "sha256:dbc02381779d412145331789b40cc7b11fdf449e5d94f6bc0b080db0a56ea3f0"}, + {file = "Pillow-10.0.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:9211e7ad69d7c9401cfc0e23d49b69ca65ddd898976d660a2fa5904e3d7a9baa"}, + {file = "Pillow-10.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:faaf07ea35355b01a35cb442dd950d8f1bb5b040a7787791a535de13db15ed90"}, + {file = "Pillow-10.0.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c9f72a021fbb792ce98306ffb0c348b3c9cb967dce0f12a49aa4c3d3fdefa967"}, + {file = "Pillow-10.0.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f7c16705f44e0504a3a2a14197c1f0b32a95731d251777dcb060aa83022cb2d"}, + {file = "Pillow-10.0.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:76edb0a1fa2b4745fb0c99fb9fb98f8b180a1bbceb8be49b087e0b21867e77d3"}, + {file = "Pillow-10.0.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:368ab3dfb5f49e312231b6f27b8820c823652b7cd29cfbd34090565a015e99ba"}, + {file = "Pillow-10.0.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:608bfdee0d57cf297d32bcbb3c728dc1da0907519d1784962c5f0c68bb93e5a3"}, + {file = "Pillow-10.0.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5c6e3df6bdd396749bafd45314871b3d0af81ff935b2d188385e970052091017"}, + {file = "Pillow-10.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:7be600823e4c8631b74e4a0d38384c73f680e6105a7d3c6824fcf226c178c7e6"}, + {file = "Pillow-10.0.0-pp310-pypy310_pp73-macosx_10_10_x86_64.whl", hash = "sha256:92be919bbc9f7d09f7ae343c38f5bb21c973d2576c1d45600fce4b74bafa7ac0"}, + {file = "Pillow-10.0.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f8182b523b2289f7c415f589118228d30ac8c355baa2f3194ced084dac2dbba"}, + {file = "Pillow-10.0.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:38250a349b6b390ee6047a62c086d3817ac69022c127f8a5dc058c31ccef17f3"}, + {file = "Pillow-10.0.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:88af2003543cc40c80f6fca01411892ec52b11021b3dc22ec3bc9d5afd1c5334"}, + {file = "Pillow-10.0.0-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:c189af0545965fa8d3b9613cfdb0cd37f9d71349e0f7750e1fd704648d475ed2"}, + {file = "Pillow-10.0.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce7b031a6fc11365970e6a5686d7ba8c63e4c1cf1ea143811acbb524295eabed"}, + {file = "Pillow-10.0.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:db24668940f82321e746773a4bc617bfac06ec831e5c88b643f91f122a785684"}, + {file = "Pillow-10.0.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:efe8c0681042536e0d06c11f48cebe759707c9e9abf880ee213541c5b46c5bf3"}, + {file = "Pillow-10.0.0.tar.gz", hash = "sha256:9c82b5b3e043c7af0d95792d0d20ccf68f61a1fec6b3530e718b688422727396"}, +] + +[package.extras] +docs = ["furo", "olefile", "sphinx (>=2.4)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinx-removed-in", "sphinxext-opengraph"] +tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"] + +[[package]] +name = "portalocker" +version = "2.7.0" +description = "Wraps the portalocker recipe for easy usage" +optional = false +python-versions = ">=3.5" +files = [ + {file = "portalocker-2.7.0-py2.py3-none-any.whl", hash = "sha256:a07c5b4f3985c3cf4798369631fb7011adb498e2a46d8440efc75a8f29a0f983"}, + {file = "portalocker-2.7.0.tar.gz", hash = "sha256:032e81d534a88ec1736d03f780ba073f047a06c478b06e2937486f334e955c51"}, +] + +[package.dependencies] +pywin32 = {version = ">=226", markers = "platform_system == \"Windows\""} + +[package.extras] +docs = ["sphinx (>=1.7.1)"] +redis = ["redis"] +tests = ["pytest (>=5.4.1)", "pytest-cov (>=2.8.1)", "pytest-mypy (>=0.8.0)", "pytest-timeout (>=2.1.0)", "redis", "sphinx (>=6.0.0)"] + +[[package]] +name = "prettytable" +version = "3.8.0" +description = "A simple Python library for easily displaying tabular data in a visually appealing ASCII table format" +optional = false +python-versions = ">=3.8" +files = [ + {file = "prettytable-3.8.0-py3-none-any.whl", hash = "sha256:03481bca25ae0c28958c8cd6ac5165c159ce89f7ccde04d5c899b24b68bb13b7"}, + {file = "prettytable-3.8.0.tar.gz", hash = "sha256:031eae6a9102017e8c7c7906460d150b7ed78b20fd1d8c8be4edaf88556c07ce"}, +] + +[package.dependencies] +wcwidth = "*" + +[package.extras] +tests = ["pytest", "pytest-cov", "pytest-lazy-fixture"] + +[[package]] +name = "prometheus-client" +version = "0.17.1" +description = "Python client for the Prometheus monitoring system." +optional = false +python-versions = ">=3.6" +files = [ + {file = "prometheus_client-0.17.1-py3-none-any.whl", hash = "sha256:e537f37160f6807b8202a6fc4764cdd19bac5480ddd3e0d463c3002b34462101"}, + {file = "prometheus_client-0.17.1.tar.gz", hash = "sha256:21e674f39831ae3f8acde238afd9a27a37d0d2fb5a28ea094f0ce25d2cbf2091"}, +] + +[package.extras] +twisted = ["twisted"] + +[[package]] +name = "prompt-toolkit" +version = "3.0.39" +description = "Library for building powerful interactive command lines in Python" +optional = false +python-versions = ">=3.7.0" +files = [ + {file = "prompt_toolkit-3.0.39-py3-none-any.whl", hash = "sha256:9dffbe1d8acf91e3de75f3b544e4842382fc06c6babe903ac9acb74dc6e08d88"}, + {file = "prompt_toolkit-3.0.39.tar.gz", hash = "sha256:04505ade687dc26dc4284b1ad19a83be2f2afe83e7a828ace0c72f3a1df72aac"}, +] + +[package.dependencies] +wcwidth = "*" + +[[package]] +name = "proto-plus" +version = "1.22.3" +description = "Beautiful, Pythonic protocol buffers." +optional = false +python-versions = ">=3.6" +files = [ + {file = "proto-plus-1.22.3.tar.gz", hash = "sha256:fdcd09713cbd42480740d2fe29c990f7fbd885a67efc328aa8be6ee3e9f76a6b"}, + {file = "proto_plus-1.22.3-py3-none-any.whl", hash = "sha256:a49cd903bc0b6ab41f76bf65510439d56ca76f868adf0274e738bfdd096894df"}, +] + +[package.dependencies] +protobuf = ">=3.19.0,<5.0.0dev" + +[package.extras] +testing = ["google-api-core[grpc] (>=1.31.5)"] + +[[package]] +name = "protobuf" +version = "4.23.4" +description = "" +optional = false +python-versions = ">=3.7" +files = [ + {file = "protobuf-4.23.4-cp310-abi3-win32.whl", hash = "sha256:5fea3c64d41ea5ecf5697b83e41d09b9589e6f20b677ab3c48e5f242d9b7897b"}, + {file = "protobuf-4.23.4-cp310-abi3-win_amd64.whl", hash = "sha256:7b19b6266d92ca6a2a87effa88ecc4af73ebc5cfde194dc737cf8ef23a9a3b12"}, + {file = "protobuf-4.23.4-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:8547bf44fe8cec3c69e3042f5c4fb3e36eb2a7a013bb0a44c018fc1e427aafbd"}, + {file = "protobuf-4.23.4-cp37-abi3-manylinux2014_aarch64.whl", hash = "sha256:fee88269a090ada09ca63551bf2f573eb2424035bcf2cb1b121895b01a46594a"}, + {file = "protobuf-4.23.4-cp37-abi3-manylinux2014_x86_64.whl", hash = "sha256:effeac51ab79332d44fba74660d40ae79985901ac21bca408f8dc335a81aa597"}, + {file = "protobuf-4.23.4-cp37-cp37m-win32.whl", hash = "sha256:c3e0939433c40796ca4cfc0fac08af50b00eb66a40bbbc5dee711998fb0bbc1e"}, + {file = "protobuf-4.23.4-cp37-cp37m-win_amd64.whl", hash = "sha256:9053df6df8e5a76c84339ee4a9f5a2661ceee4a0dab019e8663c50ba324208b0"}, + {file = "protobuf-4.23.4-cp38-cp38-win32.whl", hash = "sha256:e1c915778d8ced71e26fcf43c0866d7499891bca14c4368448a82edc61fdbc70"}, + {file = "protobuf-4.23.4-cp38-cp38-win_amd64.whl", hash = "sha256:351cc90f7d10839c480aeb9b870a211e322bf05f6ab3f55fcb2f51331f80a7d2"}, + {file = "protobuf-4.23.4-cp39-cp39-win32.whl", hash = "sha256:6dd9b9940e3f17077e820b75851126615ee38643c2c5332aa7a359988820c720"}, + {file = "protobuf-4.23.4-cp39-cp39-win_amd64.whl", hash = "sha256:0a5759f5696895de8cc913f084e27fd4125e8fb0914bb729a17816a33819f474"}, + {file = "protobuf-4.23.4-py3-none-any.whl", hash = "sha256:e9d0be5bf34b275b9f87ba7407796556abeeba635455d036c7351f7c183ef8ff"}, + {file = "protobuf-4.23.4.tar.gz", hash = "sha256:ccd9430c0719dce806b93f89c91de7977304729e55377f872a92465d548329a9"}, +] + +[[package]] +name = "psutil" +version = "5.9.5" +description = "Cross-platform lib for process and system monitoring in Python." +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "psutil-5.9.5-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:be8929ce4313f9f8146caad4272f6abb8bf99fc6cf59344a3167ecd74f4f203f"}, + {file = "psutil-5.9.5-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:ab8ed1a1d77c95453db1ae00a3f9c50227ebd955437bcf2a574ba8adbf6a74d5"}, + {file = "psutil-5.9.5-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:4aef137f3345082a3d3232187aeb4ac4ef959ba3d7c10c33dd73763fbc063da4"}, + {file = "psutil-5.9.5-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:ea8518d152174e1249c4f2a1c89e3e6065941df2fa13a1ab45327716a23c2b48"}, + {file = "psutil-5.9.5-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:acf2aef9391710afded549ff602b5887d7a2349831ae4c26be7c807c0a39fac4"}, + {file = "psutil-5.9.5-cp27-none-win32.whl", hash = "sha256:5b9b8cb93f507e8dbaf22af6a2fd0ccbe8244bf30b1baad6b3954e935157ae3f"}, + {file = "psutil-5.9.5-cp27-none-win_amd64.whl", hash = "sha256:8c5f7c5a052d1d567db4ddd231a9d27a74e8e4a9c3f44b1032762bd7b9fdcd42"}, + {file = "psutil-5.9.5-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:3c6f686f4225553615612f6d9bc21f1c0e305f75d7d8454f9b46e901778e7217"}, + {file = "psutil-5.9.5-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7a7dd9997128a0d928ed4fb2c2d57e5102bb6089027939f3b722f3a210f9a8da"}, + {file = "psutil-5.9.5-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89518112647f1276b03ca97b65cc7f64ca587b1eb0278383017c2a0dcc26cbe4"}, + {file = "psutil-5.9.5-cp36-abi3-win32.whl", hash = "sha256:104a5cc0e31baa2bcf67900be36acde157756b9c44017b86b2c049f11957887d"}, + {file = "psutil-5.9.5-cp36-abi3-win_amd64.whl", hash = "sha256:b258c0c1c9d145a1d5ceffab1134441c4c5113b2417fafff7315a917a026c3c9"}, + {file = "psutil-5.9.5-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:c607bb3b57dc779d55e1554846352b4e358c10fff3abf3514a7a6601beebdb30"}, + {file = "psutil-5.9.5.tar.gz", hash = "sha256:5410638e4df39c54d957fc51ce03048acd8e6d60abc0f5107af51e5fb566eb3c"}, +] + +[package.extras] +test = ["enum34", "ipaddress", "mock", "pywin32", "wmi"] + +[[package]] +name = "psycopg2" +version = "2.9.6" +description = "psycopg2 - Python-PostgreSQL Database Adapter" +optional = false +python-versions = ">=3.6" +files = [ + {file = "psycopg2-2.9.6-cp310-cp310-win32.whl", hash = "sha256:f7a7a5ee78ba7dc74265ba69e010ae89dae635eea0e97b055fb641a01a31d2b1"}, + {file = "psycopg2-2.9.6-cp310-cp310-win_amd64.whl", hash = "sha256:f75001a1cbbe523e00b0ef896a5a1ada2da93ccd752b7636db5a99bc57c44494"}, + {file = "psycopg2-2.9.6-cp311-cp311-win32.whl", hash = "sha256:53f4ad0a3988f983e9b49a5d9765d663bbe84f508ed655affdb810af9d0972ad"}, + {file = "psycopg2-2.9.6-cp311-cp311-win_amd64.whl", hash = "sha256:b81fcb9ecfc584f661b71c889edeae70bae30d3ef74fa0ca388ecda50b1222b7"}, + {file = "psycopg2-2.9.6-cp36-cp36m-win32.whl", hash = "sha256:11aca705ec888e4f4cea97289a0bf0f22a067a32614f6ef64fcf7b8bfbc53744"}, + {file = "psycopg2-2.9.6-cp36-cp36m-win_amd64.whl", hash = "sha256:36c941a767341d11549c0fbdbb2bf5be2eda4caf87f65dfcd7d146828bd27f39"}, + {file = "psycopg2-2.9.6-cp37-cp37m-win32.whl", hash = "sha256:869776630c04f335d4124f120b7fb377fe44b0a7645ab3c34b4ba42516951889"}, + {file = "psycopg2-2.9.6-cp37-cp37m-win_amd64.whl", hash = "sha256:a8ad4a47f42aa6aec8d061fdae21eaed8d864d4bb0f0cade5ad32ca16fcd6258"}, + {file = "psycopg2-2.9.6-cp38-cp38-win32.whl", hash = "sha256:2362ee4d07ac85ff0ad93e22c693d0f37ff63e28f0615a16b6635a645f4b9214"}, + {file = "psycopg2-2.9.6-cp38-cp38-win_amd64.whl", hash = "sha256:d24ead3716a7d093b90b27b3d73459fe8cd90fd7065cf43b3c40966221d8c394"}, + {file = "psycopg2-2.9.6-cp39-cp39-win32.whl", hash = "sha256:1861a53a6a0fd248e42ea37c957d36950da00266378746588eab4f4b5649e95f"}, + {file = "psycopg2-2.9.6-cp39-cp39-win_amd64.whl", hash = "sha256:ded2faa2e6dfb430af7713d87ab4abbfc764d8d7fb73eafe96a24155f906ebf5"}, + {file = "psycopg2-2.9.6.tar.gz", hash = "sha256:f15158418fd826831b28585e2ab48ed8df2d0d98f502a2b4fe619e7d5ca29011"}, +] + +[[package]] +name = "psycopg2-binary" +version = "2.9.6" +description = "psycopg2 - Python-PostgreSQL Database Adapter" +optional = false +python-versions = ">=3.6" +files = [ + {file = "psycopg2-binary-2.9.6.tar.gz", hash = "sha256:1f64dcfb8f6e0c014c7f55e51c9759f024f70ea572fbdef123f85318c297947c"}, + {file = "psycopg2_binary-2.9.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d26e0342183c762de3276cca7a530d574d4e25121ca7d6e4a98e4f05cb8e4df7"}, + {file = "psycopg2_binary-2.9.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c48d8f2db17f27d41fb0e2ecd703ea41984ee19362cbce52c097963b3a1b4365"}, + {file = "psycopg2_binary-2.9.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffe9dc0a884a8848075e576c1de0290d85a533a9f6e9c4e564f19adf8f6e54a7"}, + {file = "psycopg2_binary-2.9.6-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8a76e027f87753f9bd1ab5f7c9cb8c7628d1077ef927f5e2446477153a602f2c"}, + {file = "psycopg2_binary-2.9.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6460c7a99fc939b849431f1e73e013d54aa54293f30f1109019c56a0b2b2ec2f"}, + {file = "psycopg2_binary-2.9.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ae102a98c547ee2288637af07393dd33f440c25e5cd79556b04e3fca13325e5f"}, + {file = "psycopg2_binary-2.9.6-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:9972aad21f965599ed0106f65334230ce826e5ae69fda7cbd688d24fa922415e"}, + {file = "psycopg2_binary-2.9.6-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:7a40c00dbe17c0af5bdd55aafd6ff6679f94a9be9513a4c7e071baf3d7d22a70"}, + {file = "psycopg2_binary-2.9.6-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:cacbdc5839bdff804dfebc058fe25684cae322987f7a38b0168bc1b2df703fb1"}, + {file = "psycopg2_binary-2.9.6-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7f0438fa20fb6c7e202863e0d5ab02c246d35efb1d164e052f2f3bfe2b152bd0"}, + {file = "psycopg2_binary-2.9.6-cp310-cp310-win32.whl", hash = "sha256:b6c8288bb8a84b47e07013bb4850f50538aa913d487579e1921724631d02ea1b"}, + {file = "psycopg2_binary-2.9.6-cp310-cp310-win_amd64.whl", hash = "sha256:61b047a0537bbc3afae10f134dc6393823882eb263088c271331602b672e52e9"}, + {file = "psycopg2_binary-2.9.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:964b4dfb7c1c1965ac4c1978b0f755cc4bd698e8aa2b7667c575fb5f04ebe06b"}, + {file = "psycopg2_binary-2.9.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:afe64e9b8ea66866a771996f6ff14447e8082ea26e675a295ad3bdbffdd72afb"}, + {file = "psycopg2_binary-2.9.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:15e2ee79e7cf29582ef770de7dab3d286431b01c3bb598f8e05e09601b890081"}, + {file = "psycopg2_binary-2.9.6-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dfa74c903a3c1f0d9b1c7e7b53ed2d929a4910e272add6700c38f365a6002820"}, + {file = "psycopg2_binary-2.9.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b83456c2d4979e08ff56180a76429263ea254c3f6552cd14ada95cff1dec9bb8"}, + {file = "psycopg2_binary-2.9.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0645376d399bfd64da57148694d78e1f431b1e1ee1054872a5713125681cf1be"}, + {file = "psycopg2_binary-2.9.6-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e99e34c82309dd78959ba3c1590975b5d3c862d6f279f843d47d26ff89d7d7e1"}, + {file = "psycopg2_binary-2.9.6-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4ea29fc3ad9d91162c52b578f211ff1c931d8a38e1f58e684c45aa470adf19e2"}, + {file = "psycopg2_binary-2.9.6-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:4ac30da8b4f57187dbf449294d23b808f8f53cad6b1fc3623fa8a6c11d176dd0"}, + {file = "psycopg2_binary-2.9.6-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e78e6e2a00c223e164c417628572a90093c031ed724492c763721c2e0bc2a8df"}, + {file = "psycopg2_binary-2.9.6-cp311-cp311-win32.whl", hash = "sha256:1876843d8e31c89c399e31b97d4b9725a3575bb9c2af92038464231ec40f9edb"}, + {file = "psycopg2_binary-2.9.6-cp311-cp311-win_amd64.whl", hash = "sha256:b4b24f75d16a89cc6b4cdff0eb6a910a966ecd476d1e73f7ce5985ff1328e9a6"}, + {file = "psycopg2_binary-2.9.6-cp36-cp36m-win32.whl", hash = "sha256:498807b927ca2510baea1b05cc91d7da4718a0f53cb766c154c417a39f1820a0"}, + {file = "psycopg2_binary-2.9.6-cp36-cp36m-win_amd64.whl", hash = "sha256:0d236c2825fa656a2d98bbb0e52370a2e852e5a0ec45fc4f402977313329174d"}, + {file = "psycopg2_binary-2.9.6-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:34b9ccdf210cbbb1303c7c4db2905fa0319391bd5904d32689e6dd5c963d2ea8"}, + {file = "psycopg2_binary-2.9.6-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:84d2222e61f313c4848ff05353653bf5f5cf6ce34df540e4274516880d9c3763"}, + {file = "psycopg2_binary-2.9.6-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:30637a20623e2a2eacc420059be11527f4458ef54352d870b8181a4c3020ae6b"}, + {file = "psycopg2_binary-2.9.6-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8122cfc7cae0da9a3077216528b8bb3629c43b25053284cc868744bfe71eb141"}, + {file = "psycopg2_binary-2.9.6-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:38601cbbfe600362c43714482f43b7c110b20cb0f8172422c616b09b85a750c5"}, + {file = "psycopg2_binary-2.9.6-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c7e62ab8b332147a7593a385d4f368874d5fe4ad4e341770d4983442d89603e3"}, + {file = "psycopg2_binary-2.9.6-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2ab652e729ff4ad76d400df2624d223d6e265ef81bb8aa17fbd63607878ecbee"}, + {file = "psycopg2_binary-2.9.6-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:c83a74b68270028dc8ee74d38ecfaf9c90eed23c8959fca95bd703d25b82c88e"}, + {file = "psycopg2_binary-2.9.6-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d4e6036decf4b72d6425d5b29bbd3e8f0ff1059cda7ac7b96d6ac5ed34ffbacd"}, + {file = "psycopg2_binary-2.9.6-cp37-cp37m-win32.whl", hash = "sha256:a8c28fd40a4226b4a84bdf2d2b5b37d2c7bd49486b5adcc200e8c7ec991dfa7e"}, + {file = "psycopg2_binary-2.9.6-cp37-cp37m-win_amd64.whl", hash = "sha256:51537e3d299be0db9137b321dfb6a5022caaab275775680e0c3d281feefaca6b"}, + {file = "psycopg2_binary-2.9.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cf4499e0a83b7b7edcb8dabecbd8501d0d3a5ef66457200f77bde3d210d5debb"}, + {file = "psycopg2_binary-2.9.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7e13a5a2c01151f1208d5207e42f33ba86d561b7a89fca67c700b9486a06d0e2"}, + {file = "psycopg2_binary-2.9.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e0f754d27fddcfd74006455b6e04e6705d6c31a612ec69ddc040a5468e44b4e"}, + {file = "psycopg2_binary-2.9.6-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d57c3fd55d9058645d26ae37d76e61156a27722097229d32a9e73ed54819982a"}, + {file = "psycopg2_binary-2.9.6-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:71f14375d6f73b62800530b581aed3ada394039877818b2d5f7fc77e3bb6894d"}, + {file = "psycopg2_binary-2.9.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:441cc2f8869a4f0f4bb408475e5ae0ee1f3b55b33f350406150277f7f35384fc"}, + {file = "psycopg2_binary-2.9.6-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:65bee1e49fa6f9cf327ce0e01c4c10f39165ee76d35c846ade7cb0ec6683e303"}, + {file = "psycopg2_binary-2.9.6-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:af335bac6b666cc6aea16f11d486c3b794029d9df029967f9938a4bed59b6a19"}, + {file = "psycopg2_binary-2.9.6-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:cfec476887aa231b8548ece2e06d28edc87c1397ebd83922299af2e051cf2827"}, + {file = "psycopg2_binary-2.9.6-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:65c07febd1936d63bfde78948b76cd4c2a411572a44ac50719ead41947d0f26b"}, + {file = "psycopg2_binary-2.9.6-cp38-cp38-win32.whl", hash = "sha256:4dfb4be774c4436a4526d0c554af0cc2e02082c38303852a36f6456ece7b3503"}, + {file = "psycopg2_binary-2.9.6-cp38-cp38-win_amd64.whl", hash = "sha256:02c6e3cf3439e213e4ee930308dc122d6fb4d4bea9aef4a12535fbd605d1a2fe"}, + {file = "psycopg2_binary-2.9.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e9182eb20f41417ea1dd8e8f7888c4d7c6e805f8a7c98c1081778a3da2bee3e4"}, + {file = "psycopg2_binary-2.9.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8a6979cf527e2603d349a91060f428bcb135aea2be3201dff794813256c274f1"}, + {file = "psycopg2_binary-2.9.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8338a271cb71d8da40b023a35d9c1e919eba6cbd8fa20a54b748a332c355d896"}, + {file = "psycopg2_binary-2.9.6-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e3ed340d2b858d6e6fb5083f87c09996506af483227735de6964a6100b4e6a54"}, + {file = "psycopg2_binary-2.9.6-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f81e65376e52f03422e1fb475c9514185669943798ed019ac50410fb4c4df232"}, + {file = "psycopg2_binary-2.9.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bfb13af3c5dd3a9588000910178de17010ebcccd37b4f9794b00595e3a8ddad3"}, + {file = "psycopg2_binary-2.9.6-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:4c727b597c6444a16e9119386b59388f8a424223302d0c06c676ec8b4bc1f963"}, + {file = "psycopg2_binary-2.9.6-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:4d67fbdaf177da06374473ef6f7ed8cc0a9dc640b01abfe9e8a2ccb1b1402c1f"}, + {file = "psycopg2_binary-2.9.6-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:0892ef645c2fabb0c75ec32d79f4252542d0caec1d5d949630e7d242ca4681a3"}, + {file = "psycopg2_binary-2.9.6-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:02c0f3757a4300cf379eb49f543fb7ac527fb00144d39246ee40e1df684ab514"}, + {file = "psycopg2_binary-2.9.6-cp39-cp39-win32.whl", hash = "sha256:c3dba7dab16709a33a847e5cd756767271697041fbe3fe97c215b1fc1f5c9848"}, + {file = "psycopg2_binary-2.9.6-cp39-cp39-win_amd64.whl", hash = "sha256:f6a88f384335bb27812293fdb11ac6aee2ca3f51d3c7820fe03de0a304ab6249"}, +] + +[[package]] +name = "ptyprocess" +version = "0.7.0" +description = "Run a subprocess in a pseudo terminal" +optional = false +python-versions = "*" +files = [ + {file = "ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"}, + {file = "ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"}, +] + +[[package]] +name = "pure-eval" +version = "0.2.2" +description = "Safely evaluate AST nodes without side effects" +optional = false +python-versions = "*" +files = [ + {file = "pure_eval-0.2.2-py3-none-any.whl", hash = "sha256:01eaab343580944bc56080ebe0a674b39ec44a945e6d09ba7db3cb8cec289350"}, + {file = "pure_eval-0.2.2.tar.gz", hash = "sha256:2b45320af6dfaa1750f543d714b6d1c520a1688dec6fd24d339063ce0aaa9ac3"}, +] + +[package.extras] +tests = ["pytest"] + +[[package]] +name = "pyasn1" +version = "0.5.0" +description = "Pure-Python implementation of ASN.1 types and DER/BER/CER codecs (X.208)" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" +files = [ + {file = "pyasn1-0.5.0-py2.py3-none-any.whl", hash = "sha256:87a2121042a1ac9358cabcaf1d07680ff97ee6404333bacca15f76aa8ad01a57"}, + {file = "pyasn1-0.5.0.tar.gz", hash = "sha256:97b7290ca68e62a832558ec3976f15cbf911bf5d7c7039d8b861c2a0ece69fde"}, +] + +[[package]] +name = "pyasn1-modules" +version = "0.3.0" +description = "A collection of ASN.1-based protocols modules" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" +files = [ + {file = "pyasn1_modules-0.3.0-py2.py3-none-any.whl", hash = "sha256:d3ccd6ed470d9ffbc716be08bd90efbd44d0734bc9303818f7336070984a162d"}, + {file = "pyasn1_modules-0.3.0.tar.gz", hash = "sha256:5bd01446b736eb9d31512a30d46c1ac3395d676c6f3cafa4c03eb54b9925631c"}, +] + +[package.dependencies] +pyasn1 = ">=0.4.6,<0.6.0" + +[[package]] +name = "pycparser" +version = "2.21" +description = "C parser in Python" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "pycparser-2.21-py2.py3-none-any.whl", hash = "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9"}, + {file = "pycparser-2.21.tar.gz", hash = "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"}, +] + +[[package]] +name = "pycryptodome" +version = "3.18.0" +description = "Cryptographic library for Python" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "pycryptodome-3.18.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:d1497a8cd4728db0e0da3c304856cb37c0c4e3d0b36fcbabcc1600f18504fc54"}, + {file = "pycryptodome-3.18.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:928078c530da78ff08e10eb6cada6e0dff386bf3d9fa9871b4bbc9fbc1efe024"}, + {file = "pycryptodome-3.18.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:157c9b5ba5e21b375f052ca78152dd309a09ed04703fd3721dce3ff8ecced148"}, + {file = "pycryptodome-3.18.0-cp27-cp27m-manylinux2014_aarch64.whl", hash = "sha256:d20082bdac9218649f6abe0b885927be25a917e29ae0502eaf2b53f1233ce0c2"}, + {file = "pycryptodome-3.18.0-cp27-cp27m-musllinux_1_1_aarch64.whl", hash = "sha256:e8ad74044e5f5d2456c11ed4cfd3e34b8d4898c0cb201c4038fe41458a82ea27"}, + {file = "pycryptodome-3.18.0-cp27-cp27m-win32.whl", hash = "sha256:62a1e8847fabb5213ccde38915563140a5b338f0d0a0d363f996b51e4a6165cf"}, + {file = "pycryptodome-3.18.0-cp27-cp27m-win_amd64.whl", hash = "sha256:16bfd98dbe472c263ed2821284118d899c76968db1a6665ade0c46805e6b29a4"}, + {file = "pycryptodome-3.18.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:7a3d22c8ee63de22336679e021c7f2386f7fc465477d59675caa0e5706387944"}, + {file = "pycryptodome-3.18.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:78d863476e6bad2a592645072cc489bb90320972115d8995bcfbee2f8b209918"}, + {file = "pycryptodome-3.18.0-cp27-cp27mu-manylinux2014_aarch64.whl", hash = "sha256:b6a610f8bfe67eab980d6236fdc73bfcdae23c9ed5548192bb2d530e8a92780e"}, + {file = "pycryptodome-3.18.0-cp27-cp27mu-musllinux_1_1_aarch64.whl", hash = "sha256:422c89fd8df8a3bee09fb8d52aaa1e996120eafa565437392b781abec2a56e14"}, + {file = "pycryptodome-3.18.0-cp35-abi3-macosx_10_9_universal2.whl", hash = "sha256:9ad6f09f670c466aac94a40798e0e8d1ef2aa04589c29faa5b9b97566611d1d1"}, + {file = "pycryptodome-3.18.0-cp35-abi3-macosx_10_9_x86_64.whl", hash = "sha256:53aee6be8b9b6da25ccd9028caf17dcdce3604f2c7862f5167777b707fbfb6cb"}, + {file = "pycryptodome-3.18.0-cp35-abi3-manylinux2014_aarch64.whl", hash = "sha256:10da29526a2a927c7d64b8f34592f461d92ae55fc97981aab5bbcde8cb465bb6"}, + {file = "pycryptodome-3.18.0-cp35-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f21efb8438971aa16924790e1c3dba3a33164eb4000106a55baaed522c261acf"}, + {file = "pycryptodome-3.18.0-cp35-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4944defabe2ace4803f99543445c27dd1edbe86d7d4edb87b256476a91e9ffa4"}, + {file = "pycryptodome-3.18.0-cp35-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:51eae079ddb9c5f10376b4131be9589a6554f6fd84f7f655180937f611cd99a2"}, + {file = "pycryptodome-3.18.0-cp35-abi3-musllinux_1_1_i686.whl", hash = "sha256:83c75952dcf4a4cebaa850fa257d7a860644c70a7cd54262c237c9f2be26f76e"}, + {file = "pycryptodome-3.18.0-cp35-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:957b221d062d5752716923d14e0926f47670e95fead9d240fa4d4862214b9b2f"}, + {file = "pycryptodome-3.18.0-cp35-abi3-win32.whl", hash = "sha256:795bd1e4258a2c689c0b1f13ce9684fa0dd4c0e08680dcf597cf9516ed6bc0f3"}, + {file = "pycryptodome-3.18.0-cp35-abi3-win_amd64.whl", hash = "sha256:b1d9701d10303eec8d0bd33fa54d44e67b8be74ab449052a8372f12a66f93fb9"}, + {file = "pycryptodome-3.18.0-pp27-pypy_73-manylinux2010_x86_64.whl", hash = "sha256:cb1be4d5af7f355e7d41d36d8eec156ef1382a88638e8032215c215b82a4b8ec"}, + {file = "pycryptodome-3.18.0-pp27-pypy_73-win32.whl", hash = "sha256:fc0a73f4db1e31d4a6d71b672a48f3af458f548059aa05e83022d5f61aac9c08"}, + {file = "pycryptodome-3.18.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:f022a4fd2a5263a5c483a2bb165f9cb27f2be06f2f477113783efe3fe2ad887b"}, + {file = "pycryptodome-3.18.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:363dd6f21f848301c2dcdeb3c8ae5f0dee2286a5e952a0f04954b82076f23825"}, + {file = "pycryptodome-3.18.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:12600268763e6fec3cefe4c2dcdf79bde08d0b6dc1813887e789e495cb9f3403"}, + {file = "pycryptodome-3.18.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:4604816adebd4faf8810782f137f8426bf45fee97d8427fa8e1e49ea78a52e2c"}, + {file = "pycryptodome-3.18.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:01489bbdf709d993f3058e2996f8f40fee3f0ea4d995002e5968965fa2fe89fb"}, + {file = "pycryptodome-3.18.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3811e31e1ac3069988f7a1c9ee7331b942e605dfc0f27330a9ea5997e965efb2"}, + {file = "pycryptodome-3.18.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6f4b967bb11baea9128ec88c3d02f55a3e338361f5e4934f5240afcb667fdaec"}, + {file = "pycryptodome-3.18.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:9c8eda4f260072f7dbe42f473906c659dcbadd5ae6159dfb49af4da1293ae380"}, + {file = "pycryptodome-3.18.0.tar.gz", hash = "sha256:c9adee653fc882d98956e33ca2c1fb582e23a8af7ac82fee75bd6113c55a0413"}, +] + +[[package]] +name = "pycryptodomex" +version = "3.18.0" +description = "Cryptographic library for Python" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "pycryptodomex-3.18.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:160a39a708c36fa0b168ab79386dede588e62aec06eb505add870739329aecc6"}, + {file = "pycryptodomex-3.18.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:c2953afebf282a444c51bf4effe751706b4d0d63d7ca2cc51db21f902aa5b84e"}, + {file = "pycryptodomex-3.18.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:ba95abd563b0d1b88401658665a260852a8e6c647026ee6a0a65589287681df8"}, + {file = "pycryptodomex-3.18.0-cp27-cp27m-manylinux2014_aarch64.whl", hash = "sha256:192306cf881fe3467dda0e174a4f47bb3a8bb24b90c9cdfbdc248eec5fc0578c"}, + {file = "pycryptodomex-3.18.0-cp27-cp27m-musllinux_1_1_aarch64.whl", hash = "sha256:f9ab5ef0718f6a8716695dea16d83b671b22c45e9c0c78fd807c32c0192e54b5"}, + {file = "pycryptodomex-3.18.0-cp27-cp27m-win32.whl", hash = "sha256:50308fcdbf8345e5ec224a5502b4215178bdb5e95456ead8ab1a69ffd94779cb"}, + {file = "pycryptodomex-3.18.0-cp27-cp27m-win_amd64.whl", hash = "sha256:4d9379c684efea80fdab02a3eb0169372bca7db13f9332cb67483b8dc8b67c37"}, + {file = "pycryptodomex-3.18.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:5594a125dae30d60e94f37797fc67ce3c744522de7992c7c360d02fdb34918f8"}, + {file = "pycryptodomex-3.18.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:8ff129a5a0eb5ff16e45ca4fa70a6051da7f3de303c33b259063c19be0c43d35"}, + {file = "pycryptodomex-3.18.0-cp27-cp27mu-manylinux2014_aarch64.whl", hash = "sha256:3d9314ac785a5b75d5aaf924c5f21d6ca7e8df442e5cf4f0fefad4f6e284d422"}, + {file = "pycryptodomex-3.18.0-cp27-cp27mu-musllinux_1_1_aarch64.whl", hash = "sha256:f237278836dda412a325e9340ba2e6a84cb0f56b9244781e5b61f10b3905de88"}, + {file = "pycryptodomex-3.18.0-cp35-abi3-macosx_10_9_universal2.whl", hash = "sha256:ac614363a86cc53d8ba44b6c469831d1555947e69ab3276ae8d6edc219f570f7"}, + {file = "pycryptodomex-3.18.0-cp35-abi3-macosx_10_9_x86_64.whl", hash = "sha256:302a8f37c224e7b5d72017d462a2be058e28f7be627bdd854066e16722d0fc0c"}, + {file = "pycryptodomex-3.18.0-cp35-abi3-manylinux2014_aarch64.whl", hash = "sha256:6421d23d6a648e83ba2670a352bcd978542dad86829209f59d17a3f087f4afef"}, + {file = "pycryptodomex-3.18.0-cp35-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d84e105787f5e5d36ec6a581ff37a1048d12e638688074b2a00bcf402f9aa1c2"}, + {file = "pycryptodomex-3.18.0-cp35-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6875eb8666f68ddbd39097867325bd22771f595b4e2b0149739b5623c8bf899b"}, + {file = "pycryptodomex-3.18.0-cp35-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:27072a494ce621cc7a9096bbf60ed66826bb94db24b49b7359509e7951033e74"}, + {file = "pycryptodomex-3.18.0-cp35-abi3-musllinux_1_1_i686.whl", hash = "sha256:1949e09ea49b09c36d11a951b16ff2a05a0ffe969dda1846e4686ee342fe8646"}, + {file = "pycryptodomex-3.18.0-cp35-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:6ed3606832987018615f68e8ed716a7065c09a0fe94afd7c9ca1b6777f0ac6eb"}, + {file = "pycryptodomex-3.18.0-cp35-abi3-win32.whl", hash = "sha256:d56c9ec41258fd3734db9f5e4d2faeabe48644ba9ca23b18e1839b3bdf093222"}, + {file = "pycryptodomex-3.18.0-cp35-abi3-win_amd64.whl", hash = "sha256:e00a4bacb83a2627e8210cb353a2e31f04befc1155db2976e5e239dd66482278"}, + {file = "pycryptodomex-3.18.0-pp27-pypy_73-manylinux2010_x86_64.whl", hash = "sha256:2dc4eab20f4f04a2d00220fdc9258717b82d31913552e766d5f00282c031b70a"}, + {file = "pycryptodomex-3.18.0-pp27-pypy_73-win32.whl", hash = "sha256:75672205148bdea34669173366df005dbd52be05115e919551ee97171083423d"}, + {file = "pycryptodomex-3.18.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:bec6c80994d4e7a38312072f89458903b65ec99bed2d65aa4de96d997a53ea7a"}, + {file = "pycryptodomex-3.18.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d35a8ffdc8b05e4b353ba281217c8437f02c57d7233363824e9d794cf753c419"}, + {file = "pycryptodomex-3.18.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:76f0a46bee539dae4b3dfe37216f678769349576b0080fdbe431d19a02da42ff"}, + {file = "pycryptodomex-3.18.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:71687eed47df7e965f6e0bf3cadef98f368d5221f0fb89d2132effe1a3e6a194"}, + {file = "pycryptodomex-3.18.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:73d64b32d84cf48d9ec62106aa277dbe99ab5fbfd38c5100bc7bddd3beb569f7"}, + {file = "pycryptodomex-3.18.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbdcce0a226d9205560a5936b05208c709b01d493ed8307792075dedfaaffa5f"}, + {file = "pycryptodomex-3.18.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:58fc0aceb9c961b9897facec9da24c6a94c5db04597ec832060f53d4d6a07196"}, + {file = "pycryptodomex-3.18.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:215be2980a6b70704c10796dd7003eb4390e7be138ac6fb8344bf47e71a8d470"}, + {file = "pycryptodomex-3.18.0.tar.gz", hash = "sha256:3e3ecb5fe979e7c1bb0027e518340acf7ee60415d79295e5251d13c68dde576e"}, +] + +[[package]] +name = "pyexcel" +version = "0.7.0" +description = "A wrapper library that provides one API to read, manipulate and writedata in different excel formats" +optional = false +python-versions = ">=3.6" +files = [ + {file = "pyexcel-0.7.0-py2.py3-none-any.whl", hash = "sha256:ddc6904512bfa2ecda509fb3b58229bb30db14498632fd9e7a5ba7bbfb02ed1b"}, + {file = "pyexcel-0.7.0.tar.gz", hash = "sha256:fbf0eee5d93b96cef6f19a9f00703f22c0a64f19728d91b95428009a52129709"}, +] + +[package.dependencies] +chardet = "*" +lml = ">=0.0.4" +pyexcel-io = ">=0.6.2" +texttable = ">=0.8.2" + +[package.extras] +ods = ["pyexcel-ods3 (>=0.6.0)"] +xls = ["pyexcel-xls (>=0.6.0)"] +xlsx = ["pyexcel-xlsx (>=0.6.0)"] + +[[package]] +name = "pyexcel-io" +version = "0.6.6" +description = "A python library to read and write structured data in csv, zipped csvformat and to/from databases" +optional = false +python-versions = ">=3.6" +files = [ + {file = "pyexcel-io-0.6.6.tar.gz", hash = "sha256:f6084bf1afa5fbf4c61cf7df44370fa513821af188b02e3e19b5efb66d8a969f"}, + {file = "pyexcel_io-0.6.6-py2.py3-none-any.whl", hash = "sha256:19ff1d599a8a6c0982e4181ef86aa50e1f8d231410fa7e0e204d62e37551c1d6"}, +] + +[package.dependencies] +lml = ">=0.0.4" + +[package.extras] +ods = ["pyexcel-ods3 (>=0.6.0)"] +xls = ["pyexcel-xls (>=0.6.0)"] +xlsx = ["pyexcel-xlsx (>=0.6.0)"] + +[[package]] +name = "pyexcel-xlsx" +version = "0.6.0" +description = "A wrapper library to read, manipulate and write data in xlsx and xlsmformat" +optional = false +python-versions = ">=3.6" +files = [ + {file = "pyexcel-xlsx-0.6.0.tar.gz", hash = "sha256:55754f764252461aca6871db203f4bd1370ec877828e305e6be1de5f9aa6a79d"}, + {file = "pyexcel_xlsx-0.6.0-py2.py3-none-any.whl", hash = "sha256:16530f96a77c97ebcba7941517d2756ac52d3ce2903d81eecd7f300778d5242a"}, +] + +[package.dependencies] +openpyxl = ">=2.6.1" +pyexcel-io = ">=0.6.2" + +[[package]] +name = "pyfreerdp" +version = "0.0.1" +description = "" +optional = false +python-versions = "*" +files = [ + {file = "pyfreerdp-0.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:74b4e757d879b1d01c0bd7e1f91c17ddc007b941b92766f11077696546758490"}, + {file = "pyfreerdp-0.0.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2c73dc9c87c185cd009c00561102a4727bb0cdff69e69eeb9af02a87b1ed627a"}, + {file = "pyfreerdp-0.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:363a9caea1b56f82726eea42bc42f47750440867ce1958e3855f5a01aed3d23a"}, + {file = "pyfreerdp-0.0.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:310a8471afb533d0ab4ff1fdb10c54106884883ed727e1ad6b61491a7fed466f"}, + {file = "pyfreerdp-0.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c869ca101e7e262dfa536472e3ac192c89999351f682328bfbcf056daa98aa99"}, + {file = "pyfreerdp-0.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a48ac00d35a2c2fd7bacbbd93b9753995d7b80f3202b2cacd35e1ece3154cd9"}, + {file = "pyfreerdp-0.0.1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:f3c7c635316ab2ab8f0379f146b4fdec6636123ed45c0ef6edce6f9d615bcbba"}, + {file = "pyfreerdp-0.0.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2edc5d938f2bbb337b70c46413a3a578257daf852211a4fb71ad592c57870436"}, + {file = "pyfreerdp-0.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ee1439e6fc82ed5973ec098eb47c532abdb8de6d48f36b736cc39855f76df217"}, + {file = "pyfreerdp-0.0.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:0ea400aaff3c00fa6b2fdcdf52696b27cfe16ce83feeffc22969eabebacfde1d"}, + {file = "pyfreerdp-0.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:4d5f3340086956bedbf8cf0b43bb974e516df1730f80e63e4914fd0c6001e17f"}, + {file = "pyfreerdp-0.0.1-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f205f4d29da3bb118681bbc9ae732fb607fc86da210b04b4916a711fa1b67a9d"}, + {file = "pyfreerdp-0.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d424c70a36280f5445b6d213f947f3fffca1142a4414e5b3bb56c870f114397"}, + {file = "pyfreerdp-0.0.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:38eafc6a60759a25d97ae45f030a0c4e6c8c8a018541fc2076115cf302fd9475"}, + {file = "pyfreerdp-0.0.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:9b26a9ff4e25d04631330da16f3bdad2e805948edb3367f175b5db4cc6eed573"}, + {file = "pyfreerdp-0.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:414ede648e851be7fb0b8bd7b2f38390c5561ef73ea2f15bce2689fbbdaecb8b"}, + {file = "pyfreerdp-0.0.1-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5cec04cce9aa23268a0e8b1de78c65708b46a9fb8b7664f7bc00932761eed359"}, + {file = "pyfreerdp-0.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75f31d916bcadc015c775167895c823be8909aff8286847bc61f1162dd751fc0"}, + {file = "pyfreerdp-0.0.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:352d30fe3d7f4323b37f474faaed34b21ea3f230a53911e834ec5a51e9cc747b"}, + {file = "pyfreerdp-0.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:dd3e4cf7f24fb8a3eef4bf2e1147d92437e3298027280eef29a6d08c84b3e7dd"}, + {file = "pyfreerdp-0.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1ba8c23643746d9638469c7a8981f9d57a9bdf068d03fa2c32c28728011db7cc"}, + {file = "pyfreerdp-0.0.1-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:05f0f16dc1621cfbd3da6b3f8acd292dcf09ac2cde3a578aec7af359a65174b9"}, + {file = "pyfreerdp-0.0.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c4f577beba135c1b603e0cc3b1a71fbfc53bdb53a5aeedc7650f1120a5d52d14"}, + {file = "pyfreerdp-0.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c8311d355b54cdfadccc2dba7c9d8962aa8179f4c5a852ecb3a33bc9a6f0ee2"}, + {file = "pyfreerdp-0.0.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:51ecfecc1a8a40a2461a5b4ff105bc92ef86a57fd6364c3c309c6fe7c66fb5e7"}, + {file = "pyfreerdp-0.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:48cf5c73d98d3f8edaf229c78884828652242036484dff3e61974bf1bce852a3"}, + {file = "pyfreerdp-0.0.1-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e3adaaf7bb2e32c2288a4bb939130fa0a3afb5d87a11c46c2d6f882c051ee43e"}, + {file = "pyfreerdp-0.0.1-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:2127d10afa600d691e4b4795f3c6e70cf227e9a65b536bc0ec096f93eb92b4dd"}, + {file = "pyfreerdp-0.0.1-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8ed7f0413e4e5c0c03c01f9bcf24eb3fe2b0223fc84947917352421fbd548de5"}, + {file = "pyfreerdp-0.0.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40a91c509fe62ef74341e5ef66b3ac8530f989df87cf5477945de2eb8984522f"}, + {file = "pyfreerdp-0.0.1-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:509e1643fc87c597ec5bc1ab9505e2839b5e9ca049b5af95a3d70b828e8c4bfd"}, + {file = "pyfreerdp-0.0.1.tar.gz", hash = "sha256:946eca882741e6802794185cbdd47b49626c3181bce99dbd27c5746563c13d43"}, +] + +[[package]] +name = "pygments" +version = "2.15.1" +description = "Pygments is a syntax highlighting package written in Python." +optional = false +python-versions = ">=3.7" +files = [ + {file = "Pygments-2.15.1-py3-none-any.whl", hash = "sha256:db2db3deb4b4179f399a09054b023b6a586b76499d36965813c71aa8ed7b5fd1"}, + {file = "Pygments-2.15.1.tar.gz", hash = "sha256:8ace4d3c1dd481894b2005f560ead0f9f19ee64fe983366be1a21e171d12775c"}, +] + +[package.extras] +plugins = ["importlib-metadata"] + +[[package]] +name = "pyhcl" +version = "0.4.4" +description = "HCL configuration parser for python" +optional = false +python-versions = "*" +files = [ + {file = "pyhcl-0.4.4.tar.gz", hash = "sha256:2d9b9dcdf1023d812bfed561ba72c99104c5b3f52e558d595130a44ce081b003"}, +] + +[[package]] +name = "pyjwkest" +version = "1.4.2" +description = "Python implementation of JWT, JWE, JWS and JWK" +optional = false +python-versions = "*" +files = [ + {file = "pyjwkest-1.4.2.tar.gz", hash = "sha256:5560fd5ba08655f29ff6ad1df1e15dc05abc9d976fcbcec8d2b5167f49b70222"}, +] + +[package.dependencies] +future = "*" +pycryptodomex = "*" +requests = "*" +six = "*" + +[[package]] +name = "pyjwt" +version = "2.8.0" +description = "JSON Web Token implementation in Python" +optional = false +python-versions = ">=3.7" +files = [ + {file = "PyJWT-2.8.0-py3-none-any.whl", hash = "sha256:59127c392cc44c2da5bb3192169a91f429924e17aff6534d70fdc02ab3e04320"}, + {file = "PyJWT-2.8.0.tar.gz", hash = "sha256:57e28d156e3d5c10088e0c68abb90bfac3df82b40a71bd0daa20c65ccd5c23de"}, +] + +[package.dependencies] +cryptography = {version = ">=3.4.0", optional = true, markers = "extra == \"crypto\""} + +[package.extras] +crypto = ["cryptography (>=3.4.0)"] +dev = ["coverage[toml] (==5.0.4)", "cryptography (>=3.4.0)", "pre-commit", "pytest (>=6.0.0,<7.0.0)", "sphinx (>=4.5.0,<5.0.0)", "sphinx-rtd-theme", "zope.interface"] +docs = ["sphinx (>=4.5.0,<5.0.0)", "sphinx-rtd-theme", "zope.interface"] +tests = ["coverage[toml] (==5.0.4)", "pytest (>=6.0.0,<7.0.0)"] + +[[package]] +name = "pymongo" +version = "4.4.1" +description = "Python driver for MongoDB " +optional = false +python-versions = ">=3.7" +files = [ + {file = "pymongo-4.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:bbdd6c719cc2ea440d7245ba71ecdda507275071753c6ffe9c8232647246f575"}, + {file = "pymongo-4.4.1-cp310-cp310-manylinux1_i686.whl", hash = "sha256:a438508dd8007a4a724601c3790db46fe0edc3d7d172acafc5f148ceb4a07815"}, + {file = "pymongo-4.4.1-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:3a350d03959f9d5b7f2ea0621f5bb2eb3927b8fc1c4031d12cfd3949839d4f66"}, + {file = "pymongo-4.4.1-cp310-cp310-manylinux2014_i686.whl", hash = "sha256:e6d5d2c97c35f83dc65ccd5d64c7ed16eba6d9403e3744e847aee648c432f0bb"}, + {file = "pymongo-4.4.1-cp310-cp310-manylinux2014_ppc64le.whl", hash = "sha256:1944b16ffef3573ae064196460de43eb1c865a64fed23551b5eac1951d80acca"}, + {file = "pymongo-4.4.1-cp310-cp310-manylinux2014_s390x.whl", hash = "sha256:912b0fdc16500125dc1837be8b13c99d6782d93d6cd099d0e090e2aca0b6d100"}, + {file = "pymongo-4.4.1-cp310-cp310-manylinux2014_x86_64.whl", hash = "sha256:d1b1c8eb21de4cb5e296614e8b775d5ecf9c56b7d3c6000f4bfdb17f9e244e72"}, + {file = "pymongo-4.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e3b508e0de613b906267f2c484cb5e9afd3a64680e1af23386ca8f99a29c6145"}, + {file = "pymongo-4.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f41feb8cf429799ac43ed34504839954aa7d907f8bd9ecb52ed5ff0d2ea84245"}, + {file = "pymongo-4.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1897123c4bede1af0c264a3bc389a2505bae50d85e4f211288d352928c02d017"}, + {file = "pymongo-4.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b4c4bcd285bf0f5272d50628e4ea3989738e3af1251b2dd7bf50da2d593f3a56"}, + {file = "pymongo-4.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:995b868ccc9df8d36cb28142363e3911846fe9f43348d942951f60cdd7f62224"}, + {file = "pymongo-4.4.1-cp310-cp310-win32.whl", hash = "sha256:a5198beca36778f19a98b56f541a0529502046bc867b352dda5b6322e1ddc4fd"}, + {file = "pymongo-4.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:a86d20210c9805a032cda14225087ec483613aff0955327c7871a3c980562c5b"}, + {file = "pymongo-4.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5a2a1da505ea78787b0382c92dc21a45d19918014394b220c4734857e9c73694"}, + {file = "pymongo-4.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:35545583396684ea70a0b005034a469bf3f447732396e5b3d50bec94890b8d5c"}, + {file = "pymongo-4.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5248fdf7244a5e976279fe154d116c73f6206e0be71074ea9d9b1e73b5893dd5"}, + {file = "pymongo-4.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:44381b817eeb47a41bbfbd279594a7fb21017e0e3e15550eb0fd3758333097f3"}, + {file = "pymongo-4.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f0bd25de90b804cc95e548f55f430df2b47f242a4d7bbce486db62f3b3c981f"}, + {file = "pymongo-4.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d67f4029c57b36a0278aeae044ce382752c078c7625cef71b5e2cf3e576961f9"}, + {file = "pymongo-4.4.1-cp311-cp311-win32.whl", hash = "sha256:8082eef0d8c711c9c272906fa469965e52b44dbdb8a589b54857b1351dc2e511"}, + {file = "pymongo-4.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:980da627edc1275896d7d4670596433ec66e1f452ec244e07bbb2f91c955b581"}, + {file = "pymongo-4.4.1-cp37-cp37m-macosx_10_6_intel.whl", hash = "sha256:6cf08997d3ecf9a1eabe12c35aa82a5c588f53fac054ed46fe5c16a0a20ea43d"}, + {file = "pymongo-4.4.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:a6750449759f0a83adc9df3a469483a8c3eef077490b76f30c03dc8f7a4b1d66"}, + {file = "pymongo-4.4.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:efa67f46c1678df541e8f41247d22430905f80a3296d9c914aaa793f2c9fa1db"}, + {file = "pymongo-4.4.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:d9a5e16a32fb1000c72a8734ddd8ae291974deb5d38d40d1bdd01dbe4024eeb0"}, + {file = "pymongo-4.4.1-cp37-cp37m-manylinux2014_i686.whl", hash = "sha256:36b0b06c6e830d190215fced82872e5fd8239771063afa206f9adc09574018a3"}, + {file = "pymongo-4.4.1-cp37-cp37m-manylinux2014_ppc64le.whl", hash = "sha256:4ec9c6d4547c93cf39787c249969f7348ef6c4d36439af10d57b5ee65f3dfbf9"}, + {file = "pymongo-4.4.1-cp37-cp37m-manylinux2014_s390x.whl", hash = "sha256:5368801ca6b66aacc5cc013258f11899cd6a4c3bb28cec435dd67f835905e9d2"}, + {file = "pymongo-4.4.1-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:91848d555155ad4594de5e575b6452adc471bc7bc4b4d2b1f4f15a78a8af7843"}, + {file = "pymongo-4.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e0f08a2dba1469252462c414b66cb416c7f7295f2c85e50f735122a251fcb131"}, + {file = "pymongo-4.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2fe4bbf2b2c91e4690b5658b0fbb98ca6e0a8fba9ececd65b4e7d2d1df3e9b01"}, + {file = "pymongo-4.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7e307d67641d0e2f7e7d6ee3dad880d090dace96cc1d95c99d15bd9f545a1168"}, + {file = "pymongo-4.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d43634594f2486cc9bb604a1dc0914234878c4faf6604574a25260cb2faaa06"}, + {file = "pymongo-4.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ef0e3279e72cccc3dc7be75b12b1e54cc938d7ce13f5f22bea844b9d9d5fecd4"}, + {file = "pymongo-4.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:05935f5a4bbae0a99482147588351b7b17999f4a4e6e55abfb74367ac58c0634"}, + {file = "pymongo-4.4.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:854d92d2437e3496742e17342496e1f3d9efb22455501fd6010aa3658138e457"}, + {file = "pymongo-4.4.1-cp37-cp37m-win32.whl", hash = "sha256:ddffc0c6d0e92cf43dc6c47639d1ef9ab3c280db2998a33dbb9953bd864841e1"}, + {file = "pymongo-4.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:2259302d8ab51cd56c3d9d5cca325977e35a0bb3a15a297ec124d2da56c214f7"}, + {file = "pymongo-4.4.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:262a4073d2ee0654f0314ef4d9aab1d8c13dc8dae5c102312e152c02bfa7bdb7"}, + {file = "pymongo-4.4.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:022c91e2a41eefbcddc844c534520a13c6f613666c37b9fb9ed039eff47bd2e4"}, + {file = "pymongo-4.4.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:a0d326c3ba989091026fbc4827638dc169abdbb0c0bbe593716921543f530af6"}, + {file = "pymongo-4.4.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:5a1e5b931bf729b2eacd720a0e40201c2d5ed0e2bada60863f19b069bb5016c4"}, + {file = "pymongo-4.4.1-cp38-cp38-manylinux2014_i686.whl", hash = "sha256:54d0b8b6f2548e15b09232827d9ba8e03a599c9a30534f7f2c7bae79df2d1f91"}, + {file = "pymongo-4.4.1-cp38-cp38-manylinux2014_ppc64le.whl", hash = "sha256:e426e213ab07a73f8759ab8d69e87d05d7a60b3ecbf7673965948dcf8ebc1c9f"}, + {file = "pymongo-4.4.1-cp38-cp38-manylinux2014_s390x.whl", hash = "sha256:53831effe4dc0243231a944dfbd87896e42b1cf081776930de5cc74371405e3b"}, + {file = "pymongo-4.4.1-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:977c34b5b0b50bd169fbca1a4dd06fbfdfd8ac47734fdc3473532c10098e16ce"}, + {file = "pymongo-4.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fab52db4d3aa3b73bcf920fb375dbea63bf0df0cb4bdb38c5a0a69e16568cc21"}, + {file = "pymongo-4.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3bb935789276422d8875f051837356edfccdb886e673444d91e4941a8142bd48"}, + {file = "pymongo-4.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9d45243ff4800320c842c45e01c91037e281840e8c6ed2949ed82a70f55c0e6a"}, + {file = "pymongo-4.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:32d6d2b7e14bb6bc052f6cba0c1cf4d47a2b49c56ea1ed0f960a02bc9afaefb2"}, + {file = "pymongo-4.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:85b92b3828b2c923ed448f820c147ee51fa4566e35c9bf88415586eb0192ced2"}, + {file = "pymongo-4.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3f345380f6d6d6d1dc6db9fa5c8480c439ea79553b71a2cbe3030a1f20676595"}, + {file = "pymongo-4.4.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:0dcc64747b628a96bcfc6405c42acae3762c85d8ae8c1ce18834b8151cad7486"}, + {file = "pymongo-4.4.1-cp38-cp38-win32.whl", hash = "sha256:ebe1683ec85d8bca389183d01ecf4640c797d6f22e6dac3453a6c492920d5ec3"}, + {file = "pymongo-4.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:58c492e28057838792bed67875f982ffbd3c9ceb67341cc03811859fddb8efbf"}, + {file = "pymongo-4.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:aed21b3142311ad139629c4e101b54f25447ec40d6f42c72ad5c1a6f4f851f3a"}, + {file = "pymongo-4.4.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:98764ae13de0ab80ba824ca0b84177006dec51f48dfb7c944d8fa78ab645c67f"}, + {file = "pymongo-4.4.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:7b7127bb35f10d974ec1bd5573389e99054c558b821c9f23bb8ff94e7ae6e612"}, + {file = "pymongo-4.4.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:48409bac0f6a62825c306c9a124698df920afdc396132908a8e88b466925a248"}, + {file = "pymongo-4.4.1-cp39-cp39-manylinux2014_i686.whl", hash = "sha256:55b6ebeeabe32a9d2e38eeb90f07c020cb91098b34b5fca42ff3991cb6e6e621"}, + {file = "pymongo-4.4.1-cp39-cp39-manylinux2014_ppc64le.whl", hash = "sha256:4e6a70c9d437b043fb07eef1796060f476359e5b7d8e23baa49f1a70379d6543"}, + {file = "pymongo-4.4.1-cp39-cp39-manylinux2014_s390x.whl", hash = "sha256:0bdbbcc1ef3a56347630c57eda5cd9536bdbdb82754b3108c66cbc51b5233dfb"}, + {file = "pymongo-4.4.1-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:04ec1c5451ad358fdbff28ddc6e8a3d1b5f62178d38cd08007a251bc3f59445a"}, + {file = "pymongo-4.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a7739bcebdbeb5648edb15af00fd38f2ab5de20851a1341d229494a638284cc"}, + {file = "pymongo-4.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:02dba4ea2a6f22de4b50864d3957a0110b75d3eeb40aeab0b0ff64bcb5a063e6"}, + {file = "pymongo-4.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:884a35c0740744a48f67210692841581ab83a4608d3a031e7125022989ef65f8"}, + {file = "pymongo-4.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2aab6d1cff00d68212eca75d2260980202b14038d9298fed7d5c455fe3285c7c"}, + {file = "pymongo-4.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae1f85223193f249320f695eec4242cdcc311357f5f5064c2e72cfd18017e8ee"}, + {file = "pymongo-4.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b25d2ccdb2901655cc56c0fc978c5ddb35029c46bfd30d182d0e23fffd55b14b"}, + {file = "pymongo-4.4.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:334d41649f157c56a47fb289bae3b647a867c1a74f5f3a8a371fb361580bd9d3"}, + {file = "pymongo-4.4.1-cp39-cp39-win32.whl", hash = "sha256:c409e5888a94a3ff99783fffd9477128ffab8416e3f8b2c633993eecdcd5c267"}, + {file = "pymongo-4.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:3681caf37edbe05f72f0d351e4a6cb5874ec7ab5eeb99df3a277dbf110093739"}, + {file = "pymongo-4.4.1.tar.gz", hash = "sha256:a4df87dbbd03ac6372d24f2a8054b4dc33de497d5227b50ec649f436ad574284"}, +] + +[package.dependencies] +dnspython = ">=1.16.0,<3.0.0" + +[package.extras] +aws = ["pymongo-auth-aws (<2.0.0)"] +encryption = ["pymongo-auth-aws (<2.0.0)", "pymongocrypt (>=1.6.0,<2.0.0)"] +gssapi = ["pykerberos"] +ocsp = ["certifi", "pyopenssl (>=17.2.0)", "requests (<3.0.0)", "service-identity (>=18.1.0)"] +snappy = ["python-snappy"] +zstd = ["zstandard"] + +[[package]] +name = "pympler" +version = "1.0.1" +description = "A development tool to measure, monitor and analyze the memory behavior of Python objects." +optional = false +python-versions = ">=3.6" +files = [ + {file = "Pympler-1.0.1-py3-none-any.whl", hash = "sha256:d260dda9ae781e1eab6ea15bacb84015849833ba5555f141d2d9b7b7473b307d"}, + {file = "Pympler-1.0.1.tar.gz", hash = "sha256:993f1a3599ca3f4fcd7160c7545ad06310c9e12f70174ae7ae8d4e25f6c5d3fa"}, +] + +[[package]] +name = "pymssql" +version = "2.2.7" +description = "DB-API interface to Microsoft SQL Server for Python. (new Cython-based version)" +optional = false +python-versions = "*" +files = [ + {file = "pymssql-2.2.7-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:9a883def0ded86dc93cdb45dcbe924f79bd141e6bc39975d6077f88e156f3741"}, + {file = "pymssql-2.2.7-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:83ee4914bacecc715fcdb3cc22aedc8d9bf22f62e75802799fe9773b718fd41b"}, + {file = "pymssql-2.2.7-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2a8b1b903527f0f8c287582bfe01b28180f173583b8501914c1134659ead3c1d"}, + {file = "pymssql-2.2.7-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4aa12c836c307c80c1148eb190362bbbe178abc311e6715316b9950327af7a14"}, + {file = "pymssql-2.2.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70260e05717cd6d72a622ee29d06375fa44d58fe825d4964a63344ae34d80223"}, + {file = "pymssql-2.2.7-cp310-cp310-manylinux_2_24_i686.whl", hash = "sha256:c42a03cab7edd2bf6c4e075a9f1f7252151a4022216d7c85af4e4e4751f3bb14"}, + {file = "pymssql-2.2.7-cp310-cp310-manylinux_2_24_x86_64.whl", hash = "sha256:9bfb8f04b26d398f2fb7741733a33c7cfe418bbbf922703e5c4c409e86891785"}, + {file = "pymssql-2.2.7-cp310-cp310-win32.whl", hash = "sha256:0dbb905655f5976b94b6f899d4675ffdd460e7cb5516fba332cf0d77c15c2e9e"}, + {file = "pymssql-2.2.7-cp310-cp310-win_amd64.whl", hash = "sha256:2ce4f9fd604b9c7f9efad56afb3dcb2331c3c87bada172388f69d91297f20939"}, + {file = "pymssql-2.2.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8fe96bcbb26e7603ef63696f59fa19364c793aab25f2b606dc04d50917c7b35f"}, + {file = "pymssql-2.2.7-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:628611bc8cab379f8353ad29b93a07162254c9b75efb5fe5255ac855a8d3abe4"}, + {file = "pymssql-2.2.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:045029bed7cea6fcbc630e18f956f7ec6d1bde25c570019ff1f8f0e2b9abd5f0"}, + {file = "pymssql-2.2.7-cp311-cp311-manylinux_2_24_i686.whl", hash = "sha256:ad3c2e67fd04fb860ffb3affd068e109ef92488a74274347235df45664de4a27"}, + {file = "pymssql-2.2.7-cp311-cp311-manylinux_2_24_x86_64.whl", hash = "sha256:7099e45e91460ffec10e551830c722c27f207a41fd2267446a9b1a798e89d3bc"}, + {file = "pymssql-2.2.7-cp311-cp311-win32.whl", hash = "sha256:4dbe67d60472e18d01bcfba139f404f017ab9e9bd1b558d527befbb47dbd6486"}, + {file = "pymssql-2.2.7-cp311-cp311-win_amd64.whl", hash = "sha256:a9a40bf77792532fe643ee07ae0de930f6386c8593348baef07d76d1b2f48967"}, + {file = "pymssql-2.2.7-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:e6116a0389939bba789fb3fccdd976773cfce7d9cc48bf2eb933cdc2c8ce2b19"}, + {file = "pymssql-2.2.7-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:2b0415e6063b06234921d2d7d2b226cc68d197976f05b1547555ebfb3c446d01"}, + {file = "pymssql-2.2.7-cp36-cp36m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:d84a0fe84dda22dd50efd9ef9f68349a9df88edeb1c719e1545961e7bb74c27c"}, + {file = "pymssql-2.2.7-cp36-cp36m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9eeff70c3af730fee19406dda11a7cef0e70e397d53f7c2edb13bd11d8e3b1b5"}, + {file = "pymssql-2.2.7-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4dd8ae8b5bc7dd78af8b886721c9b586b5269fea4f0e425c64ee2444356cb292"}, + {file = "pymssql-2.2.7-cp36-cp36m-manylinux_2_24_i686.whl", hash = "sha256:a061af4df57863abee1a8a87cad357f660294e038ef9a3375e258c10f982164c"}, + {file = "pymssql-2.2.7-cp36-cp36m-manylinux_2_24_x86_64.whl", hash = "sha256:1b723fccf11caf57cb44051e83955f170d2cad8ad931cbb4ab97d263691c4bd5"}, + {file = "pymssql-2.2.7-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:016d1f903b0bd9a7f094712668bcf9fa86ef305fba4b933d182c152043706191"}, + {file = "pymssql-2.2.7-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:bf4640b04663e0296d8562ba835bd8636ca763495ece0fc023a2192adcfacdb2"}, + {file = "pymssql-2.2.7-cp36-cp36m-win32.whl", hash = "sha256:9a5a554af18e803a2532a8232817b0904cb7cb6d8c1a1cf716fe6a5f568a1111"}, + {file = "pymssql-2.2.7-cp36-cp36m-win_amd64.whl", hash = "sha256:1c0b7ed54b38ba2a59695dd9d0adba6a144ac37de459d514668b18e45f5a232d"}, + {file = "pymssql-2.2.7-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:f26de948303c2146089c1a5f8c4c5c46e6fd21b8b6b550c19c1f056d87ab112d"}, + {file = "pymssql-2.2.7-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:97760db6df17327ebedd58a93d7cd5c2c453faa517bc9bdfbe19ad1ff66b96a5"}, + {file = "pymssql-2.2.7-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:5ce2089b5b88a56eb599118b4f9a1b119e9056e85f8c6cb3002e44493181dd76"}, + {file = "pymssql-2.2.7-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:597563146e4ab088ee907c836075b9300541c16eef9791f4fbdfe6100894d512"}, + {file = "pymssql-2.2.7-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6cd3ee322daf8fcbb6e58deb21daa4adceea658e433eef3d3cae8c5be5049086"}, + {file = "pymssql-2.2.7-cp37-cp37m-manylinux_2_24_i686.whl", hash = "sha256:18b611ee72c5f4095cd8e942047982e92ab4d2d2ce5a457b85ef03bb8e385e7e"}, + {file = "pymssql-2.2.7-cp37-cp37m-manylinux_2_24_x86_64.whl", hash = "sha256:2d97127604bfde669cfc6e14f03536925e1a446d2bf4b7f3c7d671be07801361"}, + {file = "pymssql-2.2.7-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:16a281b556975d4c79cad6d41e902aba32017351aebfa4ede30581e00e89b1c1"}, + {file = "pymssql-2.2.7-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:7e9a277352a5a081a20107e112c7b820ecb76c2320779d1fc15b783110a2c1f5"}, + {file = "pymssql-2.2.7-cp37-cp37m-win32.whl", hash = "sha256:e06e6c189821fe259764dd8c61551ebcc2e5ec3752d06f850e79b520c2e92998"}, + {file = "pymssql-2.2.7-cp37-cp37m-win_amd64.whl", hash = "sha256:4306f74b4b19acc367b4bf6afb5ef961d35362f416622ae24a73035f75cfcdee"}, + {file = "pymssql-2.2.7-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:26eb3bb6f4b6a57e2f7e2639179914aa5c962522ccd68f5aecb0190e8d34893f"}, + {file = "pymssql-2.2.7-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:28151def07dc86e3b44dc0759ce130e56ebbab17b41c01458fc217678eccce31"}, + {file = "pymssql-2.2.7-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:51855d2f63e20f4d2ed6986d0f10cc03f341f959638e60d041a1ddb5a95d00fd"}, + {file = "pymssql-2.2.7-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bbf6717d85b62b95b9c96f3dd12166297dc9cef4f0887534d62c6a00c85bba4e"}, + {file = "pymssql-2.2.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:429491158fbee5309bd18b15d6fb29ad986b91afef4d05db5640fa7206d0d338"}, + {file = "pymssql-2.2.7-cp38-cp38-manylinux_2_24_i686.whl", hash = "sha256:3067423fb4cbf476c8d465fe5b7f081d3508524c1f4907b961a4c69af4280454"}, + {file = "pymssql-2.2.7-cp38-cp38-manylinux_2_24_x86_64.whl", hash = "sha256:1fc8a4b7d1a4146db70b5fbec3511bcfccb7b34d22a2aba89427bf55f8e44e23"}, + {file = "pymssql-2.2.7-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6f873e481f7175bed246f756e250778ca723e52ec14bd9cb2bb0cfaeea237868"}, + {file = "pymssql-2.2.7-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:0da65a89c95dc6336281c6a84f67abece9d50350dfd9b1c574b04aeb7148967d"}, + {file = "pymssql-2.2.7-cp38-cp38-win32.whl", hash = "sha256:4c9b337972377cabe4782e3cb4fae95b328305b0815392004a330314f3441fd8"}, + {file = "pymssql-2.2.7-cp38-cp38-win_amd64.whl", hash = "sha256:46271abb5a657004c220a4675f4365978e1b67e826de5b98a2c06855e9816e17"}, + {file = "pymssql-2.2.7-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:ec7889c696f2cc27d17af86e21062d032d795bf81e48802820a69cfeb740667c"}, + {file = "pymssql-2.2.7-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:25c330fab365174a29f7b5d77b03c05836ee3d39e135fad7d66380b5d5b99911"}, + {file = "pymssql-2.2.7-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c638398a023471ebde4774e2f8e5237bed07e7f934c4142c6d8e63ed42a86db1"}, + {file = "pymssql-2.2.7-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aa413e4fa34c53b6cfaaf294ca9070bbce1c52e5b284b35ce8e2bfbfaeae9d96"}, + {file = "pymssql-2.2.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:319e0dabd35ddb3e20798e4dc1ed6a8f8038101deafd7aabf531c0c6eaedeb5d"}, + {file = "pymssql-2.2.7-cp39-cp39-manylinux_2_24_i686.whl", hash = "sha256:8d8a13e89483891afabf67211453eab7c8d5f73379ed77c21160a672d3a818fb"}, + {file = "pymssql-2.2.7-cp39-cp39-manylinux_2_24_x86_64.whl", hash = "sha256:56916753f74ffa1e3b89483ce529ba13fd42944636558099b173b5343815fb0e"}, + {file = "pymssql-2.2.7-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:084a1573a5e4a10e7ad6e978f98ad3cc9704fc844beec4275aab1ff691533712"}, + {file = "pymssql-2.2.7-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6ed58a251e3aaffe4c731adad7d1468593dcd45f19375f1501f2bf8a54e1e355"}, + {file = "pymssql-2.2.7-cp39-cp39-win32.whl", hash = "sha256:78884588abfc44e99e3eaec46e19f5b08854af66eae9719a87a63b4645cf49b1"}, + {file = "pymssql-2.2.7-cp39-cp39-win_amd64.whl", hash = "sha256:cfa2bf7b8f7f462f72b2fa78b7753fc6c86a660dbea57d663993716afbb05072"}, + {file = "pymssql-2.2.7.tar.gz", hash = "sha256:ff95b910532ec7b02e4322231c117d3d6af0abab667e6fbf15442db873943045"}, +] + +[[package]] +name = "pymysql" +version = "1.1.0" +description = "Pure Python MySQL Driver" +optional = false +python-versions = ">=3.7" +files = [ + {file = "PyMySQL-1.1.0-py3-none-any.whl", hash = "sha256:8969ec6d763c856f7073c4c64662882675702efcb114b4bcbb955aea3a069fa7"}, + {file = "PyMySQL-1.1.0.tar.gz", hash = "sha256:4f13a7df8bf36a51e81dd9f3605fede45a4878fe02f9236349fd82a3f0612f96"}, +] + +[package.extras] +ed25519 = ["PyNaCl (>=1.4.0)"] +rsa = ["cryptography"] + +[[package]] +name = "pynacl" +version = "1.5.0" +description = "Python binding to the Networking and Cryptography (NaCl) library" +optional = false +python-versions = ">=3.6" +files = [ + {file = "PyNaCl-1.5.0-cp36-abi3-macosx_10_10_universal2.whl", hash = "sha256:401002a4aaa07c9414132aaed7f6836ff98f59277a234704ff66878c2ee4a0d1"}, + {file = "PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:52cb72a79269189d4e0dc537556f4740f7f0a9ec41c1322598799b0bdad4ef92"}, + {file = "PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a36d4a9dda1f19ce6e03c9a784a2921a4b726b02e1c736600ca9c22029474394"}, + {file = "PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:0c84947a22519e013607c9be43706dd42513f9e6ae5d39d3613ca1e142fba44d"}, + {file = "PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:06b8f6fa7f5de8d5d2f7573fe8c863c051225a27b61e6860fd047b1775807858"}, + {file = "PyNaCl-1.5.0-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:a422368fc821589c228f4c49438a368831cb5bbc0eab5ebe1d7fac9dded6567b"}, + {file = "PyNaCl-1.5.0-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:61f642bf2378713e2c2e1de73444a3778e5f0a38be6fee0fe532fe30060282ff"}, + {file = "PyNaCl-1.5.0-cp36-abi3-win32.whl", hash = "sha256:e46dae94e34b085175f8abb3b0aaa7da40767865ac82c928eeb9e57e1ea8a543"}, + {file = "PyNaCl-1.5.0-cp36-abi3-win_amd64.whl", hash = "sha256:20f42270d27e1b6a29f54032090b972d97f0a1b0948cc52392041ef7831fee93"}, + {file = "PyNaCl-1.5.0.tar.gz", hash = "sha256:8ac7448f09ab85811607bdd21ec2464495ac8b7c66d146bf545b0f08fb9220ba"}, +] + +[package.dependencies] +cffi = ">=1.4.1" + +[package.extras] +docs = ["sphinx (>=1.6.5)", "sphinx-rtd-theme"] +tests = ["hypothesis (>=3.27.0)", "pytest (>=3.2.1,!=3.3.0)"] + +[[package]] +name = "pyopenssl" +version = "23.2.0" +description = "Python wrapper module around the OpenSSL library" +optional = false +python-versions = ">=3.6" +files = [ + {file = "pyOpenSSL-23.2.0-py3-none-any.whl", hash = "sha256:24f0dc5227396b3e831f4c7f602b950a5e9833d292c8e4a2e06b709292806ae2"}, + {file = "pyOpenSSL-23.2.0.tar.gz", hash = "sha256:276f931f55a452e7dea69c7173e984eb2a4407ce413c918aa34b55f82f9b8bac"}, +] + +[package.dependencies] +cryptography = ">=38.0.0,<40.0.0 || >40.0.0,<40.0.1 || >40.0.1,<42" + +[package.extras] +docs = ["sphinx (!=5.2.0,!=5.2.0.post0)", "sphinx-rtd-theme"] +test = ["flaky", "pretend", "pytest (>=3.0.1)"] + +[[package]] +name = "pyotp" +version = "2.8.0" +description = "Python One Time Password Library" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pyotp-2.8.0-py3-none-any.whl", hash = "sha256:889d037fdde6accad28531fc62a790f089e5dfd5b638773e9ee004cce074a2e5"}, + {file = "pyotp-2.8.0.tar.gz", hash = "sha256:c2f5e17d9da92d8ec1f7de6331ab08116b9115adbabcba6e208d46fc49a98c5a"}, +] + +[[package]] +name = "pyparsing" +version = "3.1.1" +description = "pyparsing module - Classes and methods to define and execute parsing grammars" +optional = false +python-versions = ">=3.6.8" +files = [ + {file = "pyparsing-3.1.1-py3-none-any.whl", hash = "sha256:32c7c0b711493c72ff18a981d24f28aaf9c1fb7ed5e9667c9e84e3db623bdbfb"}, + {file = "pyparsing-3.1.1.tar.gz", hash = "sha256:ede28a1a32462f5a9705e07aea48001a08f7cf81a021585011deba701581a0db"}, +] + +[package.extras] +diagrams = ["jinja2", "railroad-diagrams"] + +[[package]] +name = "pyrad" +version = "2.4" +description = "RADIUS tools" +optional = false +python-versions = "*" +files = [ + {file = "pyrad-2.4-py3-none-any.whl", hash = "sha256:233de3aefa383875c5bddfdecfd4819d1b1fbac41aa43f6bebe4f81e63dca363"}, + {file = "pyrad-2.4.tar.gz", hash = "sha256:057de4b7e89d8da57ba782c1bde45c63ebee720ae2c0b0a69beaff15c47e30d9"}, +] + +[package.dependencies] +netaddr = "*" +six = "*" + +[[package]] +name = "pyspnego" +version = "0.9.1" +description = "Windows Negotiate Authentication Client and Server" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pyspnego-0.9.1-cp310-cp310-win32.whl", hash = "sha256:aa43f00ed1c3b8e16a658613e2557a3ff9bea26acef867705eb4ee7f5e469ac3"}, + {file = "pyspnego-0.9.1-cp310-cp310-win_amd64.whl", hash = "sha256:d031a7fa9c9ab3b67725e35affc90f8e6504518fb3ffe21573504e72b5a2fb5e"}, + {file = "pyspnego-0.9.1-cp311-cp311-win32.whl", hash = "sha256:58a17f7ba17f6cee72149911df6cc785ce7072744a386483957b74c62da654d8"}, + {file = "pyspnego-0.9.1-cp311-cp311-win_amd64.whl", hash = "sha256:e7a92321272e3613c30f55a3324ef6d780bba8b723be8d50c35aac8409fc4028"}, + {file = "pyspnego-0.9.1-cp37-cp37m-win32.whl", hash = "sha256:87a2c23e640f4f6ae3c391d1f56e287b72908080a0e6376f2f365da5a2117dca"}, + {file = "pyspnego-0.9.1-cp37-cp37m-win_amd64.whl", hash = "sha256:ff4fecf488369d6634afb20f9e56eb3b187fb3c883d6551601bbad4f4badab62"}, + {file = "pyspnego-0.9.1-cp38-cp38-win32.whl", hash = "sha256:7515f00418324809eb1adec0afac93da006c03baba6c6fd1a981b5401b798f56"}, + {file = "pyspnego-0.9.1-cp38-cp38-win_amd64.whl", hash = "sha256:6366e39ba251889e2573c7d037e7feec8af86aea6c3b32f22a8af33bf88265b6"}, + {file = "pyspnego-0.9.1-cp39-cp39-win32.whl", hash = "sha256:07417f90328fb57c19a383e59b65060d4fc101441b74c34dbe4ba860775b0a3a"}, + {file = "pyspnego-0.9.1-cp39-cp39-win_amd64.whl", hash = "sha256:4b79d5ba55ada38833d2421c44ed30a7313c00cbf34fa919dd106049616307d3"}, + {file = "pyspnego-0.9.1-py3-none-any.whl", hash = "sha256:c6aebe1fdc3990be2c137f3c3e041062243871b8161bc7adf4d269c3b6deda35"}, + {file = "pyspnego-0.9.1.tar.gz", hash = "sha256:6eea64f511bdfa192c2f80593ddf124258b0ea560327468953d18420e0ab3597"}, +] + +[package.dependencies] +cryptography = "*" + +[package.extras] +kerberos = ["gssapi (>=1.6.0)", "krb5 (>=0.3.0)"] +yaml = ["ruamel.yaml"] + +[[package]] +name = "python-cas" +version = "1.6.0" +description = "Python CAS client library" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "python-cas-1.6.0.tar.gz", hash = "sha256:b8f1dcb1b6c56b3ff4f86bbef47bcdfcf932061ccd4812ae35e3f63954dfdb28"}, + {file = "python_cas-1.6.0-py2.py3-none-any.whl", hash = "sha256:2abc0dae93c3b14097999fb7062f23cd09bc9f4e33d93f03c0cc040bd71ed50e"}, +] + +[package.dependencies] +lxml = ">=3.4" +requests = ">=2.11.1" +six = ">=1.10.0" + +[[package]] +name = "python-crontab" +version = "3.0.0" +description = "Python Crontab API" +optional = false +python-versions = "*" +files = [ + {file = "python-crontab-3.0.0.tar.gz", hash = "sha256:79fb7465039ddfd4fb93d072d6ee0d45c1ac8bf1597f0686ea14fd4361dba379"}, + {file = "python_crontab-3.0.0-py3-none-any.whl", hash = "sha256:6d5ba3c190ec76e4d252989a1644fcb233dbf53fbc8fceeb9febe1657b9fb1d4"}, +] + +[package.dependencies] +python-dateutil = "*" + +[package.extras] +cron-description = ["cron-descriptor"] +cron-schedule = ["croniter"] + +[[package]] +name = "python-daemon" +version = "3.0.1" +description = "Library to implement a well-behaved Unix daemon process." +optional = false +python-versions = ">=3" +files = [ + {file = "python-daemon-3.0.1.tar.gz", hash = "sha256:6c57452372f7eaff40934a1c03ad1826bf5e793558e87fef49131e6464b4dae5"}, + {file = "python_daemon-3.0.1-py3-none-any.whl", hash = "sha256:42bb848a3260a027fa71ad47ecd959e471327cb34da5965962edd5926229f341"}, +] + +[package.dependencies] +docutils = "*" +lockfile = ">=0.10" +setuptools = ">=62.4.0" + +[package.extras] +devel = ["coverage", "docutils", "isort", "testscenarios (>=0.4)", "testtools", "twine"] +test = ["coverage", "docutils", "testscenarios (>=0.4)", "testtools"] + +[[package]] +name = "python-dateutil" +version = "2.8.2" +description = "Extensions to the standard Python datetime module" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +files = [ + {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, + {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, +] + +[package.dependencies] +six = ">=1.5" + +[[package]] +name = "python-dotenv" +version = "1.0.0" +description = "Read key-value pairs from a .env file and set them as environment variables" +optional = false +python-versions = ">=3.8" +files = [ + {file = "python-dotenv-1.0.0.tar.gz", hash = "sha256:a8df96034aae6d2d50a4ebe8216326c61c3eb64836776504fcca410e5937a3ba"}, + {file = "python_dotenv-1.0.0-py3-none-any.whl", hash = "sha256:f5971a9226b701070a4bf2c38c89e5a3f0d64de8debda981d1db98583009122a"}, +] + +[package.extras] +cli = ["click (>=5.0)"] + +[[package]] +name = "python-keystoneclient" +version = "5.1.0" +description = "Client Library for OpenStack Identity" +optional = false +python-versions = ">=3.8" +files = [ + {file = "python-keystoneclient-5.1.0.tar.gz", hash = "sha256:ba09bdfeafa2a2196450a327cd3f46f2a8a9dd9d21b838f8cb9b17a99740c6a1"}, + {file = "python_keystoneclient-5.1.0-py3-none-any.whl", hash = "sha256:9c2e0b1700f553ca625e987f4cd8ef62d7a27ad88c5104e96e16904d2ae1d918"}, +] + +[package.dependencies] +debtcollector = ">=1.2.0" +keystoneauth1 = ">=3.4.0" +"oslo.config" = ">=5.2.0" +"oslo.i18n" = ">=3.15.3" +"oslo.serialization" = ">=2.18.0,<2.19.1 || >2.19.1" +"oslo.utils" = ">=3.33.0" +packaging = ">=20.4" +pbr = ">=2.0.0,<2.1.0 || >2.1.0" +requests = ">=2.14.2" +six = ">=1.10.0" +stevedore = ">=1.20.0" + +[[package]] +name = "python-ldap" +version = "3.4.3" +description = "Python modules for implementing LDAP clients" +optional = false +python-versions = ">=3.6" +files = [ + {file = "python-ldap-3.4.3.tar.gz", hash = "sha256:ab26c519a0ef2a443a2a10391fa3c5cb52d7871323399db949ebfaa9f25ee2a0"}, +] + +[package.dependencies] +pyasn1 = ">=0.3.7" +pyasn1_modules = ">=0.1.5" + +[[package]] +name = "python-nmap" +version = "0.7.1" +description = "This is a python class to use nmap and access scan results from python3" +optional = false +python-versions = "*" +files = [ + {file = "python-nmap-0.7.1.tar.gz", hash = "sha256:f75af6b91dd8e3b0c31f869db32163f62ada686945e5b7c25f84bc0f7fad3b64"}, +] + +[[package]] +name = "python-novaclient" +version = "18.3.0" +description = "Client library for OpenStack Compute API" +optional = false +python-versions = ">=3.8" +files = [ + {file = "python-novaclient-18.3.0.tar.gz", hash = "sha256:50f7587c7a2b2528f73505817f9437ac5c1d04d576e9be264d2deeffdb745a76"}, + {file = "python_novaclient-18.3.0-py3-none-any.whl", hash = "sha256:e5ed24feb6f8bd46ae60d8c6a258295bc0ba0f0f080308c995e96c882ca2e5e3"}, +] + +[package.dependencies] +iso8601 = ">=0.1.11" +keystoneauth1 = ">=3.5.0" +"oslo.i18n" = ">=3.15.3" +"oslo.serialization" = ">=2.18.0,<2.19.1 || >2.19.1" +"oslo.utils" = ">=3.33.0" +pbr = ">=2.0.0,<2.1.0 || >2.1.0" +PrettyTable = ">=0.7.2" +stevedore = ">=2.0.1" + +[[package]] +name = "python-redis-lock" +version = "4.0.0" +description = "Lock context manager implemented via redis SETNX/BLPOP." +optional = false +python-versions = ">=3.7" +files = [ + {file = "python-redis-lock-4.0.0.tar.gz", hash = "sha256:4abd0bcf49136acad66727bf5486dd2494078ca55e49efa693f794077319091a"}, + {file = "python_redis_lock-4.0.0-py3-none-any.whl", hash = "sha256:ff786e587569415f31e64ca9337fce47c4206e832776e9e42b83bfb9ee1af4bd"}, +] + +[package.dependencies] +redis = ">=2.10.0" + +[package.extras] +django = ["django-redis (>=3.8.0)"] + +[[package]] +name = "python3-saml" +version = "1.15.0" +description = "Saml Python Toolkit. Add SAML support to your Python software using this library" +optional = false +python-versions = "*" +files = [ + {file = "python3-saml-1.15.0.tar.gz", hash = "sha256:8c68b31739471faffb93dcdfe3bcab375b9d6a0459cab7fa9cb0d7d874ecf0b0"}, + {file = "python3_saml-1.15.0-py2-none-any.whl", hash = "sha256:3a76a17c6a2384313c5cdb450ea8b2e6d098f30836ee3dddbfe8e870903971d2"}, + {file = "python3_saml-1.15.0-py3-none-any.whl", hash = "sha256:cc0458351ddaa08270ebe29ffaf9e1a41dbd285ba43a176cbd70907af5944c66"}, +] + +[package.dependencies] +isodate = ">=0.6.1" +lxml = ">=4.6.5,<4.7.0 || >4.7.0" +xmlsec = ">=1.3.9" + +[package.extras] +test = ["coverage (>=4.5.2)", "flake8 (>=3.6.0,<=5.0.0)", "freezegun (>=0.3.11,<=1.1.0)", "pytest (>=4.6)"] + +[[package]] +name = "pytz" +version = "2023.3" +description = "World timezone definitions, modern and historical" +optional = false +python-versions = "*" +files = [ + {file = "pytz-2023.3-py2.py3-none-any.whl", hash = "sha256:a151b3abb88eda1d4e34a9814df37de2a80e301e68ba0fd856fb9b46bfbbbffb"}, + {file = "pytz-2023.3.tar.gz", hash = "sha256:1d8ce29db189191fb55338ee6d0387d82ab59f3d00eac103412d64e0ebd0c588"}, +] + +[[package]] +name = "pyvmomi" +version = "8.0.1.0.2" +description = "VMware vSphere Python SDK" +optional = false +python-versions = ">=2.7.9, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "pyvmomi-8.0.1.0.2.tar.gz", hash = "sha256:8aeccd9e4adbbecba2512d7a94488edec44ce481d7072000f5fc524e29c395f3"}, +] + +[package.dependencies] +six = ">=1.7.3" + +[package.extras] +sso = ["lxml", "pyOpenSSL", "pywin32"] + +[[package]] +name = "pywin32" +version = "306" +description = "Python for Window Extensions" +optional = false +python-versions = "*" +files = [ + {file = "pywin32-306-cp310-cp310-win32.whl", hash = "sha256:06d3420a5155ba65f0b72f2699b5bacf3109f36acbe8923765c22938a69dfc8d"}, + {file = "pywin32-306-cp310-cp310-win_amd64.whl", hash = "sha256:84f4471dbca1887ea3803d8848a1616429ac94a4a8d05f4bc9c5dcfd42ca99c8"}, + {file = "pywin32-306-cp311-cp311-win32.whl", hash = "sha256:e65028133d15b64d2ed8f06dd9fbc268352478d4f9289e69c190ecd6818b6407"}, + {file = "pywin32-306-cp311-cp311-win_amd64.whl", hash = "sha256:a7639f51c184c0272e93f244eb24dafca9b1855707d94c192d4a0b4c01e1100e"}, + {file = "pywin32-306-cp311-cp311-win_arm64.whl", hash = "sha256:70dba0c913d19f942a2db25217d9a1b726c278f483a919f1abfed79c9cf64d3a"}, + {file = "pywin32-306-cp312-cp312-win32.whl", hash = "sha256:383229d515657f4e3ed1343da8be101000562bf514591ff383ae940cad65458b"}, + {file = "pywin32-306-cp312-cp312-win_amd64.whl", hash = "sha256:37257794c1ad39ee9be652da0462dc2e394c8159dfd913a8a4e8eb6fd346da0e"}, + {file = "pywin32-306-cp312-cp312-win_arm64.whl", hash = "sha256:5821ec52f6d321aa59e2db7e0a35b997de60c201943557d108af9d4ae1ec7040"}, + {file = "pywin32-306-cp37-cp37m-win32.whl", hash = "sha256:1c73ea9a0d2283d889001998059f5eaaba3b6238f767c9cf2833b13e6a685f65"}, + {file = "pywin32-306-cp37-cp37m-win_amd64.whl", hash = "sha256:72c5f621542d7bdd4fdb716227be0dd3f8565c11b280be6315b06ace35487d36"}, + {file = "pywin32-306-cp38-cp38-win32.whl", hash = "sha256:e4c092e2589b5cf0d365849e73e02c391c1349958c5ac3e9d5ccb9a28e017b3a"}, + {file = "pywin32-306-cp38-cp38-win_amd64.whl", hash = "sha256:e8ac1ae3601bee6ca9f7cb4b5363bf1c0badb935ef243c4733ff9a393b1690c0"}, + {file = "pywin32-306-cp39-cp39-win32.whl", hash = "sha256:e25fd5b485b55ac9c057f67d94bc203f3f6595078d1fb3b458c9c28b7153a802"}, + {file = "pywin32-306-cp39-cp39-win_amd64.whl", hash = "sha256:39b61c15272833b5c329a2989999dcae836b1eed650252ab1b7bfbe1d59f30f4"}, +] + +[[package]] +name = "pywinrm" +version = "0.4.3" +description = "Python library for Windows Remote Management" +optional = false +python-versions = "*" +files = [ + {file = "pywinrm-0.4.3-py2.py3-none-any.whl", hash = "sha256:c476c1e20dd0875da6fe4684c4d8e242dd537025907c2f11e1990c5aee5c9526"}, + {file = "pywinrm-0.4.3.tar.gz", hash = "sha256:995674bf5ac64b2562c9c56540473109e530d36bde10c262d5a5296121ad5565"}, +] + +[package.dependencies] +requests = ">=2.9.1" +requests-ntlm = ">=1.1.0" +six = "*" +xmltodict = "*" + +[package.extras] +credssp = ["requests-credssp (>=1.0.0)"] +kerberos = ["pykerberos (>=1.2.1,<2.0.0)", "winkerberos (>=0.5.0)"] + +[[package]] +name = "pyyaml" +version = "6.0.1" +description = "YAML parser and emitter for Python" +optional = false +python-versions = ">=3.6" +files = [ + {file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"}, + {file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, + {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, + {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, + {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, + {file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, + {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, + {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, + {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"}, + {file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"}, + {file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"}, + {file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"}, + {file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"}, + {file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"}, + {file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, + {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, + {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, + {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, + {file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, + {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, + {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, + {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, +] + +[[package]] +name = "pyzipper" +version = "0.3.6" +description = "AES encryption for zipfile." +optional = false +python-versions = ">=3.4" +files = [ + {file = "pyzipper-0.3.6-py2.py3-none-any.whl", hash = "sha256:6d097f465bfa47796b1494e12ea65d1478107d38e13bc56f6e58eedc4f6c1a87"}, + {file = "pyzipper-0.3.6.tar.gz", hash = "sha256:0adca90a00c36a93fbe49bfa8c5add452bfe4ef85a1b8e3638739dd1c7b26bfc"}, +] + +[package.dependencies] +pycryptodomex = "*" + +[[package]] +name = "qingcloud-sdk" +version = "1.2.15" +description = "Software Development Kit for QingCloud." +optional = false +python-versions = "*" +files = [ + {file = "qingcloud-sdk-1.2.15.tar.gz", hash = "sha256:4e0cc3587cc4dea94313917c38334daabdbaa99ed9cbc7500a51485d21b6df78"}, + {file = "qingcloud_sdk-1.2.15-py2-none-any.whl", hash = "sha256:a4fffd8f8fcfe4fab2768a6157fff3170898be17e0387694bfe00b2731002d75"}, +] + +[package.dependencies] +future = "*" + +[[package]] +name = "redis" +version = "4.6.0" +description = "Python client for Redis database and key-value store" +optional = false +python-versions = ">=3.7" +files = [ + {file = "redis-4.6.0-py3-none-any.whl", hash = "sha256:e2b03db868160ee4591de3cb90d40ebb50a90dd302138775937f6a42b7ed183c"}, + {file = "redis-4.6.0.tar.gz", hash = "sha256:585dc516b9eb042a619ef0a39c3d7d55fe81bdb4df09a52c9cdde0d07bf1aa7d"}, +] + +[package.dependencies] +async-timeout = {version = ">=4.0.2", markers = "python_full_version <= \"3.11.2\""} + +[package.extras] +hiredis = ["hiredis (>=1.0.0)"] +ocsp = ["cryptography (>=36.0.1)", "pyopenssl (==20.0.1)", "requests (>=2.26.0)"] + +[[package]] +name = "requests" +version = "2.31.0" +description = "Python HTTP for Humans." +optional = false +python-versions = ">=3.7" +files = [ + {file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"}, + {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"}, +] + +[package.dependencies] +certifi = ">=2017.4.17" +charset-normalizer = ">=2,<4" +idna = ">=2.5,<4" +urllib3 = ">=1.21.1,<3" + +[package.extras] +socks = ["PySocks (>=1.5.6,!=1.5.7)"] +use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] + +[[package]] +name = "requests-ntlm" +version = "1.2.0" +description = "This package allows for HTTP NTLM authentication using the requests library." +optional = false +python-versions = ">=3.7" +files = [ + {file = "requests_ntlm-1.2.0-py3-none-any.whl", hash = "sha256:b7781090c647308a88b55fb530c7b3705cef45349e70a83b8d6731e7889272a6"}, + {file = "requests_ntlm-1.2.0.tar.gz", hash = "sha256:33c285f5074e317cbdd338d199afa46a7c01132e5c111d36bd415534e9b916a8"}, +] + +[package.dependencies] +cryptography = ">=1.3" +pyspnego = ">=0.1.6" +requests = ">=2.0.0" + +[[package]] +name = "requests-oauthlib" +version = "1.3.1" +description = "OAuthlib authentication support for Requests." +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "requests-oauthlib-1.3.1.tar.gz", hash = "sha256:75beac4a47881eeb94d5ea5d6ad31ef88856affe2332b9aafb52c6452ccf0d7a"}, + {file = "requests_oauthlib-1.3.1-py2.py3-none-any.whl", hash = "sha256:2577c501a2fb8d05a304c09d090d6e47c306fef15809d102b327cf8364bddab5"}, +] + +[package.dependencies] +oauthlib = ">=3.0.0" +requests = ">=2.0.0" + +[package.extras] +rsa = ["oauthlib[signedtoken] (>=3.0.0)"] + +[[package]] +name = "resolvelib" +version = "0.8.1" +description = "Resolve abstract dependencies into concrete ones" +optional = false +python-versions = "*" +files = [ + {file = "resolvelib-0.8.1-py2.py3-none-any.whl", hash = "sha256:d9b7907f055c3b3a2cfc56c914ffd940122915826ff5fb5b1de0c99778f4de98"}, + {file = "resolvelib-0.8.1.tar.gz", hash = "sha256:c6ea56732e9fb6fca1b2acc2ccc68a0b6b8c566d8f3e78e0443310ede61dbd37"}, +] + +[package.extras] +examples = ["html5lib", "packaging", "pygraphviz", "requests"] +lint = ["black", "flake8", "isort", "mypy", "types-requests"] +release = ["build", "towncrier", "twine"] +test = ["commentjson", "packaging", "pytest"] + +[[package]] +name = "rest-condition" +version = "1.0.3" +description = "Complex permissions flow for django-rest-framework" +optional = false +python-versions = "*" +files = [ + {file = "rest_condition-1.0.3.tar.gz", hash = "sha256:7f47ed11a6519260b3f6248a2b6d6bf127ea7d9e04155fcf1e546bb561295af8"}, +] + +[package.dependencies] +django = ">=1.3" +djangorestframework = "*" + +[[package]] +name = "rfc3986" +version = "2.0.0" +description = "Validating URI References per RFC 3986" +optional = false +python-versions = ">=3.7" +files = [ + {file = "rfc3986-2.0.0-py2.py3-none-any.whl", hash = "sha256:50b1502b60e289cb37883f3dfd34532b8873c7de9f49bb546641ce9cbd256ebd"}, + {file = "rfc3986-2.0.0.tar.gz", hash = "sha256:97aacf9dbd4bfd829baad6e6309fa6573aaf1be3f6fa735c8ab05e46cecb261c"}, +] + +[package.extras] +idna2008 = ["idna"] + +[[package]] +name = "rsa" +version = "4.9" +description = "Pure-Python RSA implementation" +optional = false +python-versions = ">=3.6,<4" +files = [ + {file = "rsa-4.9-py3-none-any.whl", hash = "sha256:90260d9058e514786967344d0ef75fa8727eed8a7d2e43ce9f4bcf1b536174f7"}, + {file = "rsa-4.9.tar.gz", hash = "sha256:e38464a49c6c85d7f1351b0126661487a7e0a14a50f1675ec50eb34d4f20ef21"}, +] + +[package.dependencies] +pyasn1 = ">=0.1.3" + +[[package]] +name = "s3transfer" +version = "0.6.1" +description = "An Amazon S3 Transfer Manager" +optional = false +python-versions = ">= 3.7" +files = [ + {file = "s3transfer-0.6.1-py3-none-any.whl", hash = "sha256:3c0da2d074bf35d6870ef157158641178a4204a6e689e82546083e31e0311346"}, + {file = "s3transfer-0.6.1.tar.gz", hash = "sha256:640bb492711f4c0c0905e1f62b6aaeb771881935ad27884852411f8e9cacbca9"}, +] + +[package.dependencies] +botocore = ">=1.12.36,<2.0a.0" + +[package.extras] +crt = ["botocore[crt] (>=1.20.29,<2.0a.0)"] + +[[package]] +name = "service-identity" +version = "23.1.0" +description = "Service identity verification for pyOpenSSL & cryptography." +optional = false +python-versions = ">=3.8" +files = [ + {file = "service_identity-23.1.0-py3-none-any.whl", hash = "sha256:87415a691d52fcad954a500cb81f424d0273f8e7e3ee7d766128f4575080f383"}, + {file = "service_identity-23.1.0.tar.gz", hash = "sha256:ecb33cd96307755041e978ab14f8b14e13b40f1fbd525a4dc78f46d2b986431d"}, +] + +[package.dependencies] +attrs = ">=19.1.0" +cryptography = "*" +pyasn1 = "*" +pyasn1-modules = "*" + +[package.extras] +dev = ["pyopenssl", "service-identity[docs,idna,mypy,tests]"] +docs = ["furo", "myst-parser", "pyopenssl", "sphinx", "sphinx-notfound-page"] +idna = ["idna"] +mypy = ["idna", "mypy", "types-pyopenssl"] +tests = ["coverage[toml] (>=5.0.2)", "pytest"] + +[[package]] +name = "setuptools" +version = "68.0.0" +description = "Easily download, build, install, upgrade, and uninstall Python packages" +optional = false +python-versions = ">=3.7" +files = [ + {file = "setuptools-68.0.0-py3-none-any.whl", hash = "sha256:11e52c67415a381d10d6b462ced9cfb97066179f0e871399e006c4ab101fc85f"}, + {file = "setuptools-68.0.0.tar.gz", hash = "sha256:baf1fdb41c6da4cd2eae722e135500da913332ab3f2f5c7d33af9b492acb5235"}, +] + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (==0.8.3)", "sphinx-reredirects", "sphinxcontrib-towncrier"] +testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] + +[[package]] +name = "simplejson" +version = "3.19.1" +description = "Simple, fast, extensible JSON encoder/decoder for Python" +optional = false +python-versions = ">=2.5, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ + {file = "simplejson-3.19.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:412e58997a30c5deb8cab5858b8e2e5b40ca007079f7010ee74565cc13d19665"}, + {file = "simplejson-3.19.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:e765b1f47293dedf77946f0427e03ee45def2862edacd8868c6cf9ab97c8afbd"}, + {file = "simplejson-3.19.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:3231100edee292da78948fa0a77dee4e5a94a0a60bcba9ed7a9dc77f4d4bb11e"}, + {file = "simplejson-3.19.1-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:081ea6305b3b5e84ae7417e7f45956db5ea3872ec497a584ec86c3260cda049e"}, + {file = "simplejson-3.19.1-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:f253edf694ce836631b350d758d00a8c4011243d58318fbfbe0dd54a6a839ab4"}, + {file = "simplejson-3.19.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:5db86bb82034e055257c8e45228ca3dbce85e38d7bfa84fa7b2838e032a3219c"}, + {file = "simplejson-3.19.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:69a8b10a4f81548bc1e06ded0c4a6c9042c0be0d947c53c1ed89703f7e613950"}, + {file = "simplejson-3.19.1-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:58ee5e24d6863b22194020eb62673cf8cc69945fcad6b283919490f6e359f7c5"}, + {file = "simplejson-3.19.1-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:73d0904c2471f317386d4ae5c665b16b5c50ab4f3ee7fd3d3b7651e564ad74b1"}, + {file = "simplejson-3.19.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:66d780047c31ff316ee305c3f7550f352d87257c756413632303fc59fef19eac"}, + {file = "simplejson-3.19.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:cd4d50a27b065447c9c399f0bf0a993bd0e6308db8bbbfbc3ea03b41c145775a"}, + {file = "simplejson-3.19.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0c16ec6a67a5f66ab004190829eeede01c633936375edcad7cbf06d3241e5865"}, + {file = "simplejson-3.19.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:17a963e8dd4d81061cc05b627677c1f6a12e81345111fbdc5708c9f088d752c9"}, + {file = "simplejson-3.19.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7e78d79b10aa92f40f54178ada2b635c960d24fc6141856b926d82f67e56d169"}, + {file = "simplejson-3.19.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ad071cd84a636195f35fa71de2186d717db775f94f985232775794d09f8d9061"}, + {file = "simplejson-3.19.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e7c70f19405e5f99168077b785fe15fcb5f9b3c0b70b0b5c2757ce294922c8c"}, + {file = "simplejson-3.19.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:54fca2b26bcd1c403146fd9461d1da76199442297160721b1d63def2a1b17799"}, + {file = "simplejson-3.19.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:48600a6e0032bed17c20319d91775f1797d39953ccfd68c27f83c8d7fc3b32cb"}, + {file = "simplejson-3.19.1-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:93f5ac30607157a0b2579af59a065bcfaa7fadeb4875bf927a8f8b6739c8d910"}, + {file = "simplejson-3.19.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6b79642a599740603ca86cf9df54f57a2013c47e1dd4dd2ae4769af0a6816900"}, + {file = "simplejson-3.19.1-cp310-cp310-win32.whl", hash = "sha256:d9f2c27f18a0b94107d57294aab3d06d6046ea843ed4a45cae8bd45756749f3a"}, + {file = "simplejson-3.19.1-cp310-cp310-win_amd64.whl", hash = "sha256:5673d27806085d2a413b3be5f85fad6fca4b7ffd31cfe510bbe65eea52fff571"}, + {file = "simplejson-3.19.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:79c748aa61fd8098d0472e776743de20fae2686edb80a24f0f6593a77f74fe86"}, + {file = "simplejson-3.19.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:390f4a8ca61d90bcf806c3ad644e05fa5890f5b9a72abdd4ca8430cdc1e386fa"}, + {file = "simplejson-3.19.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d61482b5d18181e6bb4810b4a6a24c63a490c3a20e9fbd7876639653e2b30a1a"}, + {file = "simplejson-3.19.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2541fdb7467ef9bfad1f55b6c52e8ea52b3ce4a0027d37aff094190a955daa9d"}, + {file = "simplejson-3.19.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:46133bc7dd45c9953e6ee4852e3de3d5a9a4a03b068bd238935a5c72f0a1ce34"}, + {file = "simplejson-3.19.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f96def94576f857abf58e031ce881b5a3fc25cbec64b2bc4824824a8a4367af9"}, + {file = "simplejson-3.19.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f14ecca970d825df0d29d5c6736ff27999ee7bdf5510e807f7ad8845f7760ce"}, + {file = "simplejson-3.19.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:66389b6b6ee46a94a493a933a26008a1bae0cfadeca176933e7ff6556c0ce998"}, + {file = "simplejson-3.19.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:22b867205cd258050c2625325fdd9a65f917a5aff22a23387e245ecae4098e78"}, + {file = "simplejson-3.19.1-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:c39fa911e4302eb79c804b221ddec775c3da08833c0a9120041dd322789824de"}, + {file = "simplejson-3.19.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:65dafe413b15e8895ad42e49210b74a955c9ae65564952b0243a18fb35b986cc"}, + {file = "simplejson-3.19.1-cp311-cp311-win32.whl", hash = "sha256:f05d05d99fce5537d8f7a0af6417a9afa9af3a6c4bb1ba7359c53b6257625fcb"}, + {file = "simplejson-3.19.1-cp311-cp311-win_amd64.whl", hash = "sha256:b46aaf0332a8a9c965310058cf3487d705bf672641d2c43a835625b326689cf4"}, + {file = "simplejson-3.19.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:b438e5eaa474365f4faaeeef1ec3e8d5b4e7030706e3e3d6b5bee6049732e0e6"}, + {file = "simplejson-3.19.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aa9d614a612ad02492f704fbac636f666fa89295a5d22b4facf2d665fc3b5ea9"}, + {file = "simplejson-3.19.1-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:46e89f58e4bed107626edce1cf098da3664a336d01fc78fddcfb1f397f553d44"}, + {file = "simplejson-3.19.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:96ade243fb6f3b57e7bd3b71e90c190cd0f93ec5dce6bf38734a73a2e5fa274f"}, + {file = "simplejson-3.19.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ed18728b90758d171f0c66c475c24a443ede815cf3f1a91e907b0db0ebc6e508"}, + {file = "simplejson-3.19.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:6a561320485017ddfc21bd2ed5de2d70184f754f1c9b1947c55f8e2b0163a268"}, + {file = "simplejson-3.19.1-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:2098811cd241429c08b7fc5c9e41fcc3f59f27c2e8d1da2ccdcf6c8e340ab507"}, + {file = "simplejson-3.19.1-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:8f8d179393e6f0cf6c7c950576892ea6acbcea0a320838c61968ac7046f59228"}, + {file = "simplejson-3.19.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:eff87c68058374e45225089e4538c26329a13499bc0104b52b77f8428eed36b2"}, + {file = "simplejson-3.19.1-cp36-cp36m-win32.whl", hash = "sha256:d300773b93eed82f6da138fd1d081dc96fbe53d96000a85e41460fe07c8d8b33"}, + {file = "simplejson-3.19.1-cp36-cp36m-win_amd64.whl", hash = "sha256:37724c634f93e5caaca04458f267836eb9505d897ab3947b52f33b191bf344f3"}, + {file = "simplejson-3.19.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:74bf802debe68627227ddb665c067eb8c73aa68b2476369237adf55c1161b728"}, + {file = "simplejson-3.19.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:70128fb92932524c89f373e17221cf9535d7d0c63794955cc3cd5868e19f5d38"}, + {file = "simplejson-3.19.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8090e75653ea7db75bc21fa5f7bcf5f7bdf64ea258cbbac45c7065f6324f1b50"}, + {file = "simplejson-3.19.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a755f7bfc8adcb94887710dc70cc12a69a454120c6adcc6f251c3f7b46ee6aac"}, + {file = "simplejson-3.19.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ccb2c1877bc9b25bc4f4687169caa925ffda605d7569c40e8e95186e9a5e58b"}, + {file = "simplejson-3.19.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:919bc5aa4d8094cf8f1371ea9119e5d952f741dc4162810ab714aec948a23fe5"}, + {file = "simplejson-3.19.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:e333c5b62e93949f5ac27e6758ba53ef6ee4f93e36cc977fe2e3df85c02f6dc4"}, + {file = "simplejson-3.19.1-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:3a4480e348000d89cf501b5606415f4d328484bbb431146c2971123d49fd8430"}, + {file = "simplejson-3.19.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:cb502cde018e93e75dc8fc7bb2d93477ce4f3ac10369f48866c61b5e031db1fd"}, + {file = "simplejson-3.19.1-cp37-cp37m-win32.whl", hash = "sha256:f41915a4e1f059dfad614b187bc06021fefb5fc5255bfe63abf8247d2f7a646a"}, + {file = "simplejson-3.19.1-cp37-cp37m-win_amd64.whl", hash = "sha256:3844305bc33d52c4975da07f75b480e17af3558c0d13085eaa6cc2f32882ccf7"}, + {file = "simplejson-3.19.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:1cb19eacb77adc5a9720244d8d0b5507421d117c7ed4f2f9461424a1829e0ceb"}, + {file = "simplejson-3.19.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:926957b278de22797bfc2f004b15297013843b595b3cd7ecd9e37ccb5fad0b72"}, + {file = "simplejson-3.19.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b0e9a5e66969f7a47dc500e3dba8edc3b45d4eb31efb855c8647700a3493dd8a"}, + {file = "simplejson-3.19.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79d46e7e33c3a4ef853a1307b2032cfb7220e1a079d0c65488fbd7118f44935a"}, + {file = "simplejson-3.19.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:344a5093b71c1b370968d0fbd14d55c9413cb6f0355fdefeb4a322d602d21776"}, + {file = "simplejson-3.19.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:23fbb7b46d44ed7cbcda689295862851105c7594ae5875dce2a70eeaa498ff86"}, + {file = "simplejson-3.19.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4d3025e7e9ddb48813aec2974e1a7e68e63eac911dd5e0a9568775de107ac79a"}, + {file = "simplejson-3.19.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:87b190e6ceec286219bd6b6f13547ca433f977d4600b4e81739e9ac23b5b9ba9"}, + {file = "simplejson-3.19.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:dc935d8322ba9bc7b84f99f40f111809b0473df167bf5b93b89fb719d2c4892b"}, + {file = "simplejson-3.19.1-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:3b652579c21af73879d99c8072c31476788c8c26b5565687fd9db154070d852a"}, + {file = "simplejson-3.19.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6aa7ca03f25b23b01629b1c7f78e1cd826a66bfb8809f8977a3635be2ec48f1a"}, + {file = "simplejson-3.19.1-cp38-cp38-win32.whl", hash = "sha256:08be5a241fdf67a8e05ac7edbd49b07b638ebe4846b560673e196b2a25c94b92"}, + {file = "simplejson-3.19.1-cp38-cp38-win_amd64.whl", hash = "sha256:ca56a6c8c8236d6fe19abb67ef08d76f3c3f46712c49a3b6a5352b6e43e8855f"}, + {file = "simplejson-3.19.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:6424d8229ba62e5dbbc377908cfee9b2edf25abd63b855c21f12ac596cd18e41"}, + {file = "simplejson-3.19.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:547ea86ca408a6735335c881a2e6208851027f5bfd678d8f2c92a0f02c7e7330"}, + {file = "simplejson-3.19.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:889328873c35cb0b2b4c83cbb83ec52efee5a05e75002e2c0c46c4e42790e83c"}, + {file = "simplejson-3.19.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:44cdb4e544134f305b033ad79ae5c6b9a32e7c58b46d9f55a64e2a883fbbba01"}, + {file = "simplejson-3.19.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc2b3f06430cbd4fac0dae5b2974d2bf14f71b415fb6de017f498950da8159b1"}, + {file = "simplejson-3.19.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d125e754d26c0298715bdc3f8a03a0658ecbe72330be247f4b328d229d8cf67f"}, + {file = "simplejson-3.19.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:476c8033abed7b1fd8db62a7600bf18501ce701c1a71179e4ce04ac92c1c5c3c"}, + {file = "simplejson-3.19.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:199a0bcd792811c252d71e3eabb3d4a132b3e85e43ebd93bfd053d5b59a7e78b"}, + {file = "simplejson-3.19.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:a79b439a6a77649bb8e2f2644e6c9cc0adb720fc55bed63546edea86e1d5c6c8"}, + {file = "simplejson-3.19.1-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:203412745fed916fc04566ecef3f2b6c872b52f1e7fb3a6a84451b800fb508c1"}, + {file = "simplejson-3.19.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5ca922c61d87b4c38f37aa706520328ffe22d7ac1553ef1cadc73f053a673553"}, + {file = "simplejson-3.19.1-cp39-cp39-win32.whl", hash = "sha256:3e0902c278243d6f7223ba3e6c5738614c971fd9a887fff8feaa8dcf7249c8d4"}, + {file = "simplejson-3.19.1-cp39-cp39-win_amd64.whl", hash = "sha256:d396b610e77b0c438846607cd56418bfc194973b9886550a98fd6724e8c6cfec"}, + {file = "simplejson-3.19.1-py3-none-any.whl", hash = "sha256:4710806eb75e87919b858af0cba4ffedc01b463edc3982ded7b55143f39e41e1"}, + {file = "simplejson-3.19.1.tar.gz", hash = "sha256:6277f60848a7d8319d27d2be767a7546bc965535b28070e310b3a9af90604a4c"}, +] + +[[package]] +name = "six" +version = "1.16.0" +description = "Python 2 and 3 compatibility utilities" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ + {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, + {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, +] + +[[package]] +name = "sniffio" +version = "1.3.0" +description = "Sniff out which async library your code is running under" +optional = false +python-versions = ">=3.7" +files = [ + {file = "sniffio-1.3.0-py3-none-any.whl", hash = "sha256:eecefdce1e5bbfb7ad2eeaabf7c1eeb404d7757c379bd1f7e5cce9d8bf425384"}, + {file = "sniffio-1.3.0.tar.gz", hash = "sha256:e60305c5e5d314f5389259b7f22aaa33d8f7dee49763119234af3755c55b9101"}, +] + +[[package]] +name = "soupsieve" +version = "2.4.1" +description = "A modern CSS selector implementation for Beautiful Soup." +optional = false +python-versions = ">=3.7" +files = [ + {file = "soupsieve-2.4.1-py3-none-any.whl", hash = "sha256:1c1bfee6819544a3447586c889157365a27e10d88cde3ad3da0cf0ddf646feb8"}, + {file = "soupsieve-2.4.1.tar.gz", hash = "sha256:89d12b2d5dfcd2c9e8c22326da9d9aa9cb3dfab0a83a024f05704076ee8d35ea"}, +] + +[[package]] +name = "sqlparse" +version = "0.4.4" +description = "A non-validating SQL parser." +optional = false +python-versions = ">=3.5" +files = [ + {file = "sqlparse-0.4.4-py3-none-any.whl", hash = "sha256:5430a4fe2ac7d0f93e66f1efc6e1338a41884b7ddf2a350cedd20ccc4d9d28f3"}, + {file = "sqlparse-0.4.4.tar.gz", hash = "sha256:d446183e84b8349fa3061f0fe7f06ca94ba65b426946ffebe6e3e8295332420c"}, +] + +[package.extras] +dev = ["build", "flake8"] +doc = ["sphinx"] +test = ["pytest", "pytest-cov"] + +[[package]] +name = "sshpubkeys" +version = "3.3.1" +description = "SSH public key parser" +optional = false +python-versions = ">=3" +files = [ + {file = "sshpubkeys-3.3.1-py2.py3-none-any.whl", hash = "sha256:946f76b8fe86704b0e7c56a00d80294e39bc2305999844f079a217885060b1ac"}, + {file = "sshpubkeys-3.3.1.tar.gz", hash = "sha256:3020ed4f8c846849299370fbe98ff4157b0ccc1accec105e07cfa9ae4bb55064"}, +] + +[package.dependencies] +cryptography = ">=2.1.4" +ecdsa = ">=0.13" + +[package.extras] +dev = ["twine", "wheel", "yapf"] + +[[package]] +name = "sshtunnel" +version = "0.4.0" +description = "Pure python SSH tunnels" +optional = false +python-versions = "*" +files = [ + {file = "sshtunnel-0.4.0-py2.py3-none-any.whl", hash = "sha256:98e54c26f726ab8bd42b47a3a21fca5c3e60f58956f0f70de2fb8ab0046d0606"}, + {file = "sshtunnel-0.4.0.tar.gz", hash = "sha256:e7cb0ea774db81bf91844db22de72a40aae8f7b0f9bb9ba0f666d474ef6bf9fc"}, +] + +[package.dependencies] +paramiko = ">=2.7.2" + +[package.extras] +build-sphinx = ["sphinx", "sphinxcontrib-napoleon"] +dev = ["check-manifest"] +test = ["tox (>=1.8.1)"] + +[[package]] +name = "stack-data" +version = "0.6.2" +description = "Extract data from python stack frames and tracebacks for informative displays" +optional = false +python-versions = "*" +files = [ + {file = "stack_data-0.6.2-py3-none-any.whl", hash = "sha256:cbb2a53eb64e5785878201a97ed7c7b94883f48b87bfb0bbe8b623c74679e4a8"}, + {file = "stack_data-0.6.2.tar.gz", hash = "sha256:32d2dd0376772d01b6cb9fc996f3c8b57a357089dec328ed4b6553d037eaf815"}, +] + +[package.dependencies] +asttokens = ">=2.1.0" +executing = ">=1.2.0" +pure-eval = "*" + +[package.extras] +tests = ["cython", "littleutils", "pygments", "pytest", "typeguard"] + +[[package]] +name = "stevedore" +version = "5.1.0" +description = "Manage dynamic plugins for Python applications" +optional = false +python-versions = ">=3.8" +files = [ + {file = "stevedore-5.1.0-py3-none-any.whl", hash = "sha256:8cc040628f3cea5d7128f2e76cf486b2251a4e543c7b938f58d9a377f6694a2d"}, + {file = "stevedore-5.1.0.tar.gz", hash = "sha256:a54534acf9b89bc7ed264807013b505bf07f74dbe4bcfa37d32bd063870b087c"}, +] + +[package.dependencies] +pbr = ">=2.0.0,<2.1.0 || >2.1.0" + +[[package]] +name = "tencentcloud-sdk-python" +version = "3.0.941" +description = "Tencent Cloud SDK for Python" +optional = false +python-versions = "*" +files = [ + {file = "tencentcloud-sdk-python-3.0.941.tar.gz", hash = "sha256:c0fc86ced60b11ff578c94567daaac841606d2414f53806d372b5284351cfe5b"}, + {file = "tencentcloud_sdk_python-3.0.941-py2.py3-none-any.whl", hash = "sha256:aa8a75ab54dcf04edf934bb2b08533b85316907fad3ebfd06571e5591cb8e98f"}, +] + +[package.dependencies] +requests = ">=2.16.0" + +[[package]] +name = "termcolor" +version = "2.3.0" +description = "ANSI color formatting for output in terminal" +optional = false +python-versions = ">=3.7" +files = [ + {file = "termcolor-2.3.0-py3-none-any.whl", hash = "sha256:3afb05607b89aed0ffe25202399ee0867ad4d3cb4180d98aaf8eefa6a5f7d475"}, + {file = "termcolor-2.3.0.tar.gz", hash = "sha256:b5b08f68937f138fe92f6c089b99f1e2da0ae56c52b78bf7075fd95420fd9a5a"}, +] + +[package.extras] +tests = ["pytest", "pytest-cov"] + +[[package]] +name = "texttable" +version = "1.6.7" +description = "module to create simple ASCII tables" +optional = false +python-versions = "*" +files = [ + {file = "texttable-1.6.7-py2.py3-none-any.whl", hash = "sha256:b7b68139aa8a6339d2c320ca8b1dc42d13a7831a346b446cb9eb385f0c76310c"}, + {file = "texttable-1.6.7.tar.gz", hash = "sha256:290348fb67f7746931bcdfd55ac7584ecd4e5b0846ab164333f0794b121760f2"}, +] + +[[package]] +name = "tornado" +version = "6.3.2" +description = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed." +optional = false +python-versions = ">= 3.8" +files = [ + {file = "tornado-6.3.2-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:c367ab6c0393d71171123ca5515c61ff62fe09024fa6bf299cd1339dc9456829"}, + {file = "tornado-6.3.2-cp38-abi3-macosx_10_9_x86_64.whl", hash = "sha256:b46a6ab20f5c7c1cb949c72c1994a4585d2eaa0be4853f50a03b5031e964fc7c"}, + {file = "tornado-6.3.2-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c2de14066c4a38b4ecbbcd55c5cc4b5340eb04f1c5e81da7451ef555859c833f"}, + {file = "tornado-6.3.2-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:05615096845cf50a895026f749195bf0b10b8909f9be672f50b0fe69cba368e4"}, + {file = "tornado-6.3.2-cp38-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5b17b1cf5f8354efa3d37c6e28fdfd9c1c1e5122f2cb56dac121ac61baa47cbe"}, + {file = "tornado-6.3.2-cp38-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:29e71c847a35f6e10ca3b5c2990a52ce38b233019d8e858b755ea6ce4dcdd19d"}, + {file = "tornado-6.3.2-cp38-abi3-musllinux_1_1_i686.whl", hash = "sha256:834ae7540ad3a83199a8da8f9f2d383e3c3d5130a328889e4cc991acc81e87a0"}, + {file = "tornado-6.3.2-cp38-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:6a0848f1aea0d196a7c4f6772197cbe2abc4266f836b0aac76947872cd29b411"}, + {file = "tornado-6.3.2-cp38-abi3-win32.whl", hash = "sha256:7efcbcc30b7c654eb6a8c9c9da787a851c18f8ccd4a5a3a95b05c7accfa068d2"}, + {file = "tornado-6.3.2-cp38-abi3-win_amd64.whl", hash = "sha256:0c325e66c8123c606eea33084976c832aa4e766b7dff8aedd7587ea44a604cdf"}, + {file = "tornado-6.3.2.tar.gz", hash = "sha256:4b927c4f19b71e627b13f3db2324e4ae660527143f9e1f2e2fb404f3a187e2ba"}, +] + +[[package]] +name = "traitlets" +version = "5.9.0" +description = "Traitlets Python configuration system" +optional = false +python-versions = ">=3.7" +files = [ + {file = "traitlets-5.9.0-py3-none-any.whl", hash = "sha256:9e6ec080259b9a5940c797d58b613b5e31441c2257b87c2e795c5228ae80d2d8"}, + {file = "traitlets-5.9.0.tar.gz", hash = "sha256:f6cde21a9c68cf756af02035f72d5a723bf607e862e7be33ece505abf4a3bad9"}, +] + +[package.extras] +docs = ["myst-parser", "pydata-sphinx-theme", "sphinx"] +test = ["argcomplete (>=2.0)", "pre-commit", "pytest", "pytest-mock"] + +[[package]] +name = "treelib" +version = "1.6.4" +description = "A Python 2/3 implementation of tree structure." +optional = false +python-versions = "*" +files = [ + {file = "treelib-1.6.4-py3-none-any.whl", hash = "sha256:4218f7dded2448dfa6a335888bf68a28430660163e7faf18c6128ec4477d34c0"}, + {file = "treelib-1.6.4.tar.gz", hash = "sha256:1a2e838f6b99e2690bc3d992d5a1f04cdb4af6564bd7688883c23d17257bbb2a"}, +] + +[package.dependencies] +six = "*" + +[[package]] +name = "twisted" +version = "22.10.0" +description = "An asynchronous networking framework written in Python" +optional = false +python-versions = ">=3.7.1" +files = [ + {file = "Twisted-22.10.0-py3-none-any.whl", hash = "sha256:86c55f712cc5ab6f6d64e02503352464f0400f66d4f079096d744080afcccbd0"}, + {file = "Twisted-22.10.0.tar.gz", hash = "sha256:32acbd40a94f5f46e7b42c109bfae2b302250945561783a8b7a059048f2d4d31"}, +] + +[package.dependencies] +attrs = ">=19.2.0" +Automat = ">=0.8.0" +constantly = ">=15.1" +hyperlink = ">=17.1.1" +idna = {version = ">=2.4", optional = true, markers = "extra == \"tls\""} +incremental = ">=21.3.0" +pyopenssl = {version = ">=21.0.0", optional = true, markers = "extra == \"tls\""} +service-identity = {version = ">=18.1.0", optional = true, markers = "extra == \"tls\""} +twisted-iocpsupport = {version = ">=1.0.2,<2", markers = "platform_system == \"Windows\""} +typing-extensions = ">=3.6.5" +"zope.interface" = ">=4.4.2" + +[package.extras] +all-non-platform = ["PyHamcrest (>=1.9.0)", "appdirs (>=1.4.0)", "bcrypt (>=3.0.0)", "contextvars (>=2.4,<3)", "cryptography (>=2.6)", "cython-test-exception-raiser (>=1.0.2,<2)", "h2 (>=3.0,<5.0)", "hypothesis (>=6.0,<7.0)", "idna (>=2.4)", "priority (>=1.1.0,<2.0)", "pyasn1", "pyopenssl (>=21.0.0)", "pyserial (>=3.0)", "pywin32 (!=226)", "service-identity (>=18.1.0)"] +conch = ["appdirs (>=1.4.0)", "bcrypt (>=3.0.0)", "cryptography (>=2.6)", "pyasn1"] +conch-nacl = ["PyNaCl", "appdirs (>=1.4.0)", "bcrypt (>=3.0.0)", "cryptography (>=2.6)", "pyasn1"] +contextvars = ["contextvars (>=2.4,<3)"] +dev = ["coverage (>=6b1,<7)", "pydoctor (>=22.9.0,<22.10.0)", "pyflakes (>=2.2,<3.0)", "python-subunit (>=1.4,<2.0)", "readthedocs-sphinx-ext (>=2.1,<3.0)", "sphinx (>=5.0,<6)", "sphinx-rtd-theme (>=1.0,<2.0)", "towncrier (>=22.8,<23.0)", "twistedchecker (>=0.7,<1.0)"] +dev-release = ["pydoctor (>=22.9.0,<22.10.0)", "readthedocs-sphinx-ext (>=2.1,<3.0)", "sphinx (>=5.0,<6)", "sphinx-rtd-theme (>=1.0,<2.0)", "towncrier (>=22.8,<23.0)"] +gtk-platform = ["PyHamcrest (>=1.9.0)", "appdirs (>=1.4.0)", "bcrypt (>=3.0.0)", "contextvars (>=2.4,<3)", "cryptography (>=2.6)", "cython-test-exception-raiser (>=1.0.2,<2)", "h2 (>=3.0,<5.0)", "hypothesis (>=6.0,<7.0)", "idna (>=2.4)", "priority (>=1.1.0,<2.0)", "pyasn1", "pygobject", "pyopenssl (>=21.0.0)", "pyserial (>=3.0)", "pywin32 (!=226)", "service-identity (>=18.1.0)"] +http2 = ["h2 (>=3.0,<5.0)", "priority (>=1.1.0,<2.0)"] +macos-platform = ["PyHamcrest (>=1.9.0)", "appdirs (>=1.4.0)", "bcrypt (>=3.0.0)", "contextvars (>=2.4,<3)", "cryptography (>=2.6)", "cython-test-exception-raiser (>=1.0.2,<2)", "h2 (>=3.0,<5.0)", "hypothesis (>=6.0,<7.0)", "idna (>=2.4)", "priority (>=1.1.0,<2.0)", "pyasn1", "pyobjc-core", "pyobjc-framework-CFNetwork", "pyobjc-framework-Cocoa", "pyopenssl (>=21.0.0)", "pyserial (>=3.0)", "pywin32 (!=226)", "service-identity (>=18.1.0)"] +mypy = ["PyHamcrest (>=1.9.0)", "PyNaCl", "appdirs (>=1.4.0)", "bcrypt (>=3.0.0)", "contextvars (>=2.4,<3)", "coverage (>=6b1,<7)", "cryptography (>=2.6)", "cython-test-exception-raiser (>=1.0.2,<2)", "h2 (>=3.0,<5.0)", "hypothesis (>=6.0,<7.0)", "idna (>=2.4)", "mypy (==0.930)", "mypy-zope (==0.3.4)", "priority (>=1.1.0,<2.0)", "pyasn1", "pydoctor (>=22.9.0,<22.10.0)", "pyflakes (>=2.2,<3.0)", "pyopenssl (>=21.0.0)", "pyserial (>=3.0)", "python-subunit (>=1.4,<2.0)", "pywin32 (!=226)", "readthedocs-sphinx-ext (>=2.1,<3.0)", "service-identity (>=18.1.0)", "sphinx (>=5.0,<6)", "sphinx-rtd-theme (>=1.0,<2.0)", "towncrier (>=22.8,<23.0)", "twistedchecker (>=0.7,<1.0)", "types-pyOpenSSL", "types-setuptools"] +osx-platform = ["PyHamcrest (>=1.9.0)", "appdirs (>=1.4.0)", "bcrypt (>=3.0.0)", "contextvars (>=2.4,<3)", "cryptography (>=2.6)", "cython-test-exception-raiser (>=1.0.2,<2)", "h2 (>=3.0,<5.0)", "hypothesis (>=6.0,<7.0)", "idna (>=2.4)", "priority (>=1.1.0,<2.0)", "pyasn1", "pyobjc-core", "pyobjc-framework-CFNetwork", "pyobjc-framework-Cocoa", "pyopenssl (>=21.0.0)", "pyserial (>=3.0)", "pywin32 (!=226)", "service-identity (>=18.1.0)"] +serial = ["pyserial (>=3.0)", "pywin32 (!=226)"] +test = ["PyHamcrest (>=1.9.0)", "cython-test-exception-raiser (>=1.0.2,<2)", "hypothesis (>=6.0,<7.0)"] +tls = ["idna (>=2.4)", "pyopenssl (>=21.0.0)", "service-identity (>=18.1.0)"] +windows-platform = ["PyHamcrest (>=1.9.0)", "appdirs (>=1.4.0)", "bcrypt (>=3.0.0)", "contextvars (>=2.4,<3)", "cryptography (>=2.6)", "cython-test-exception-raiser (>=1.0.2,<2)", "h2 (>=3.0,<5.0)", "hypothesis (>=6.0,<7.0)", "idna (>=2.4)", "priority (>=1.1.0,<2.0)", "pyasn1", "pyopenssl (>=21.0.0)", "pyserial (>=3.0)", "pywin32 (!=226)", "pywin32 (!=226)", "service-identity (>=18.1.0)"] + +[[package]] +name = "twisted-iocpsupport" +version = "1.0.3" +description = "An extension for use in the twisted I/O Completion Ports reactor." +optional = false +python-versions = "*" +files = [ + {file = "twisted-iocpsupport-1.0.3.tar.gz", hash = "sha256:afb00801fdfbaccf0d0173a722626500023d4a19719ac9f129d1347a32e2fc66"}, + {file = "twisted_iocpsupport-1.0.3-cp310-cp310-win32.whl", hash = "sha256:a379ef56a576c8090889f74441bc3822ca31ac82253cc61e8d50631bcb0c26d0"}, + {file = "twisted_iocpsupport-1.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:1ea2c3fbdb739c95cc8b3355305cd593d2c9ec56d709207aa1a05d4d98671e85"}, + {file = "twisted_iocpsupport-1.0.3-cp311-cp311-win32.whl", hash = "sha256:7efcdfafb377f32db90f42bd5fc5bb32cd1e3637ee936cdaf3aff4f4786ab3bf"}, + {file = "twisted_iocpsupport-1.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:1dbfac706972bf9ec5ce1ddbc735d2ebba406ad363345df8751ffd5252aa1618"}, + {file = "twisted_iocpsupport-1.0.3-cp36-cp36m-win32.whl", hash = "sha256:1ddfc5fa22ec6f913464b736b3f46e642237f17ac41be47eed6fa9bd52f5d0e0"}, + {file = "twisted_iocpsupport-1.0.3-cp36-cp36m-win_amd64.whl", hash = "sha256:1bdccbb22199fc69fd7744d6d2dfd22d073c028c8611d994b41d2d2ad0e0f40d"}, + {file = "twisted_iocpsupport-1.0.3-cp37-cp37m-win32.whl", hash = "sha256:db11c80054b52dbdea44d63d5474a44c9a6531882f0e2960268b15123088641a"}, + {file = "twisted_iocpsupport-1.0.3-cp37-cp37m-win_amd64.whl", hash = "sha256:67bec1716eb8f466ef366bbf262e1467ecc9e20940111207663ac24049785bad"}, + {file = "twisted_iocpsupport-1.0.3-cp38-cp38-win32.whl", hash = "sha256:98a6f16ab215f8c1446e9fc60aaed0ab7c746d566aa2f3492a23cea334e6bebb"}, + {file = "twisted_iocpsupport-1.0.3-cp38-cp38-win_amd64.whl", hash = "sha256:4f249d0baac836bb431d6fa0178be063a310136bc489465a831e3abd2d7acafd"}, + {file = "twisted_iocpsupport-1.0.3-cp39-cp39-win32.whl", hash = "sha256:aaca8f30c3b7c80d27a33fe9fe0d0bac42b1b012ddc60f677175c30e1becc1f3"}, + {file = "twisted_iocpsupport-1.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:dff43136c33665c2d117a73706aef6f7d6433e5c4560332a118fe066b16b8695"}, + {file = "twisted_iocpsupport-1.0.3-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:8faceae553cfadc42ad791b1790e7cdecb7751102608c405217f6a26e877e0c5"}, + {file = "twisted_iocpsupport-1.0.3-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:6f8c433faaad5d53d30d1da6968d5a3730df415e2efb6864847267a9b51290cd"}, + {file = "twisted_iocpsupport-1.0.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:3f39c41c0213a81a9ce0961e30d0d7650f371ad80f8d261007d15a2deb6d5be3"}, +] + +[[package]] +name = "txaio" +version = "23.1.1" +description = "Compatibility API between asyncio/Twisted/Trollius" +optional = false +python-versions = ">=3.7" +files = [ + {file = "txaio-23.1.1-py2.py3-none-any.whl", hash = "sha256:aaea42f8aad50e0ecfb976130ada140797e9dcb85fad2cf72b0f37f8cefcb490"}, + {file = "txaio-23.1.1.tar.gz", hash = "sha256:f9a9216e976e5e3246dfd112ad7ad55ca915606b60b84a757ac769bd404ff704"}, +] + +[package.extras] +all = ["twisted (>=20.3.0)", "zope.interface (>=5.2.0)"] +dev = ["pep8 (>=1.6.2)", "pyenchant (>=1.6.6)", "pytest (>=2.6.4)", "pytest-cov (>=1.8.1)", "sphinx (>=1.2.3)", "sphinx-rtd-theme (>=0.1.9)", "sphinxcontrib-spelling (>=2.1.2)", "tox (>=2.1.1)", "tox-gh-actions (>=2.2.0)", "twine (>=1.6.5)", "wheel"] +twisted = ["twisted (>=20.3.0)", "zope.interface (>=5.2.0)"] + +[[package]] +name = "typing-extensions" +version = "4.7.1" +description = "Backported and Experimental Type Hints for Python 3.7+" +optional = false +python-versions = ">=3.7" +files = [ + {file = "typing_extensions-4.7.1-py3-none-any.whl", hash = "sha256:440d5dd3af93b060174bf433bccd69b0babc3b15b1a8dca43789fd7f61514b36"}, + {file = "typing_extensions-4.7.1.tar.gz", hash = "sha256:b75ddc264f0ba5615db7ba217daeb99701ad295353c45f9e95963337ceeeffb2"}, +] + +[[package]] +name = "tzdata" +version = "2023.3" +description = "Provider of IANA time zone data" +optional = false +python-versions = ">=2" +files = [ + {file = "tzdata-2023.3-py2.py3-none-any.whl", hash = "sha256:7e65763eef3120314099b6939b5546db7adce1e7d6f2e179e3df563c70511eda"}, + {file = "tzdata-2023.3.tar.gz", hash = "sha256:11ef1e08e54acb0d4f95bdb1be05da659673de4acbd21bf9c69e94cc5e907a3a"}, +] + +[[package]] +name = "ucloud-sdk-python3" +version = "0.11.50" +description = "UCloud Service Development Kit - Python" +optional = false +python-versions = ">=3.5" +files = [ + {file = "ucloud-sdk-python3-0.11.50.tar.gz", hash = "sha256:6e0ed984d6a07489889597c0db5f2d05b3605057c2667dde4f55686f13682866"}, + {file = "ucloud_sdk_python3-0.11.50-py3-none-any.whl", hash = "sha256:e759ebc11e8f782d79dcea10a2597a3a3a7bdf258c6bcf2571ea962bf9c6b7a8"}, +] + +[package.dependencies] +requests = "*" + +[package.extras] +ci = ["flake8 (>=3.6.0)", "pytest (>=4.6)", "pytest-cov", "requests", "requests-mock", "sphinx"] +dev = ["black", "flake8 (>=3.6.0)", "pytest (>=4.6)", "pytest-cov", "requests", "requests-mock", "sphinx"] +doc = ["requests", "sphinx"] +test = ["flake8 (>=3.6.0)", "pytest (>=4.6)", "pytest-cov", "requests", "requests-mock"] + +[[package]] +name = "unicodecsv" +version = "0.14.1" +description = "Python2's stdlib csv module is nice, but it doesn't support unicode. This module is a drop-in replacement which *does*." +optional = false +python-versions = "*" +files = [ + {file = "unicodecsv-0.14.1.tar.gz", hash = "sha256:018c08037d48649a0412063ff4eda26eaa81eff1546dbffa51fa5293276ff7fc"}, +] + +[[package]] +name = "uritemplate" +version = "4.1.1" +description = "Implementation of RFC 6570 URI Templates" +optional = false +python-versions = ">=3.6" +files = [ + {file = "uritemplate-4.1.1-py2.py3-none-any.whl", hash = "sha256:830c08b8d99bdd312ea4ead05994a38e8936266f84b9a7878232db50b044e02e"}, + {file = "uritemplate-4.1.1.tar.gz", hash = "sha256:4346edfc5c3b79f694bccd6d6099a322bbeb628dbf2cd86eea55a456ce5124f0"}, +] + +[[package]] +name = "urllib3" +version = "1.26.16" +description = "HTTP library with thread-safe connection pooling, file post, and more." +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" +files = [ + {file = "urllib3-1.26.16-py2.py3-none-any.whl", hash = "sha256:8d36afa7616d8ab714608411b4a3b13e58f463aee519024578e062e141dce20f"}, + {file = "urllib3-1.26.16.tar.gz", hash = "sha256:8f135f6502756bde6b2a9b28989df5fbe87c9970cecaa69041edcce7f0589b14"}, +] + +[package.extras] +brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)", "brotlipy (>=0.6.0)"] +secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "ipaddress", "pyOpenSSL (>=0.14)", "urllib3-secure-extra"] +socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] + +[[package]] +name = "uvicorn" +version = "0.22.0" +description = "The lightning-fast ASGI server." +optional = false +python-versions = ">=3.7" +files = [ + {file = "uvicorn-0.22.0-py3-none-any.whl", hash = "sha256:e9434d3bbf05f310e762147f769c9f21235ee118ba2d2bf1155a7196448bd996"}, + {file = "uvicorn-0.22.0.tar.gz", hash = "sha256:79277ae03db57ce7d9aa0567830bbb51d7a612f54d6e1e3e92da3ef24c2c8ed8"}, +] + +[package.dependencies] +click = ">=7.0" +colorama = {version = ">=0.4", optional = true, markers = "sys_platform == \"win32\" and extra == \"standard\""} +h11 = ">=0.8" +httptools = {version = ">=0.5.0", optional = true, markers = "extra == \"standard\""} +python-dotenv = {version = ">=0.13", optional = true, markers = "extra == \"standard\""} +pyyaml = {version = ">=5.1", optional = true, markers = "extra == \"standard\""} +uvloop = {version = ">=0.14.0,<0.15.0 || >0.15.0,<0.15.1 || >0.15.1", optional = true, markers = "(sys_platform != \"win32\" and sys_platform != \"cygwin\") and platform_python_implementation != \"PyPy\" and extra == \"standard\""} +watchfiles = {version = ">=0.13", optional = true, markers = "extra == \"standard\""} +websockets = {version = ">=10.4", optional = true, markers = "extra == \"standard\""} + +[package.extras] +standard = ["colorama (>=0.4)", "httptools (>=0.5.0)", "python-dotenv (>=0.13)", "pyyaml (>=5.1)", "uvloop (>=0.14.0,!=0.15.0,!=0.15.1)", "watchfiles (>=0.13)", "websockets (>=10.4)"] + +[[package]] +name = "uvloop" +version = "0.17.0" +description = "Fast implementation of asyncio event loop on top of libuv" +optional = false +python-versions = ">=3.7" +files = [ + {file = "uvloop-0.17.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ce9f61938d7155f79d3cb2ffa663147d4a76d16e08f65e2c66b77bd41b356718"}, + {file = "uvloop-0.17.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:68532f4349fd3900b839f588972b3392ee56042e440dd5873dfbbcd2cc67617c"}, + {file = "uvloop-0.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0949caf774b9fcefc7c5756bacbbbd3fc4c05a6b7eebc7c7ad6f825b23998d6d"}, + {file = "uvloop-0.17.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ff3d00b70ce95adce264462c930fbaecb29718ba6563db354608f37e49e09024"}, + {file = "uvloop-0.17.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:a5abddb3558d3f0a78949c750644a67be31e47936042d4f6c888dd6f3c95f4aa"}, + {file = "uvloop-0.17.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8efcadc5a0003d3a6e887ccc1fb44dec25594f117a94e3127954c05cf144d811"}, + {file = "uvloop-0.17.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:3378eb62c63bf336ae2070599e49089005771cc651c8769aaad72d1bd9385a7c"}, + {file = "uvloop-0.17.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6aafa5a78b9e62493539456f8b646f85abc7093dd997f4976bb105537cf2635e"}, + {file = "uvloop-0.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c686a47d57ca910a2572fddfe9912819880b8765e2f01dc0dd12a9bf8573e539"}, + {file = "uvloop-0.17.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:864e1197139d651a76c81757db5eb199db8866e13acb0dfe96e6fc5d1cf45fc4"}, + {file = "uvloop-0.17.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:2a6149e1defac0faf505406259561bc14b034cdf1d4711a3ddcdfbaa8d825a05"}, + {file = "uvloop-0.17.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:6708f30db9117f115eadc4f125c2a10c1a50d711461699a0cbfaa45b9a78e376"}, + {file = "uvloop-0.17.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:23609ca361a7fc587031429fa25ad2ed7242941adec948f9d10c045bfecab06b"}, + {file = "uvloop-0.17.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2deae0b0fb00a6af41fe60a675cec079615b01d68beb4cc7b722424406b126a8"}, + {file = "uvloop-0.17.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45cea33b208971e87a31c17622e4b440cac231766ec11e5d22c76fab3bf9df62"}, + {file = "uvloop-0.17.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:9b09e0f0ac29eee0451d71798878eae5a4e6a91aa275e114037b27f7db72702d"}, + {file = "uvloop-0.17.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:dbbaf9da2ee98ee2531e0c780455f2841e4675ff580ecf93fe5c48fe733b5667"}, + {file = "uvloop-0.17.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:a4aee22ece20958888eedbad20e4dbb03c37533e010fb824161b4f05e641f738"}, + {file = "uvloop-0.17.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:307958f9fc5c8bb01fad752d1345168c0abc5d62c1b72a4a8c6c06f042b45b20"}, + {file = "uvloop-0.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ebeeec6a6641d0adb2ea71dcfb76017602ee2bfd8213e3fcc18d8f699c5104f"}, + {file = "uvloop-0.17.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1436c8673c1563422213ac6907789ecb2b070f5939b9cbff9ef7113f2b531595"}, + {file = "uvloop-0.17.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:8887d675a64cfc59f4ecd34382e5b4f0ef4ae1da37ed665adba0c2badf0d6578"}, + {file = "uvloop-0.17.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:3db8de10ed684995a7f34a001f15b374c230f7655ae840964d51496e2f8a8474"}, + {file = "uvloop-0.17.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7d37dccc7ae63e61f7b96ee2e19c40f153ba6ce730d8ba4d3b4e9738c1dccc1b"}, + {file = "uvloop-0.17.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:cbbe908fda687e39afd6ea2a2f14c2c3e43f2ca88e3a11964b297822358d0e6c"}, + {file = "uvloop-0.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3d97672dc709fa4447ab83276f344a165075fd9f366a97b712bdd3fee05efae8"}, + {file = "uvloop-0.17.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f1e507c9ee39c61bfddd79714e4f85900656db1aec4d40c6de55648e85c2799c"}, + {file = "uvloop-0.17.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:c092a2c1e736086d59ac8e41f9c98f26bbf9b9222a76f21af9dfe949b99b2eb9"}, + {file = "uvloop-0.17.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:30babd84706115626ea78ea5dbc7dd8d0d01a2e9f9b306d24ca4ed5796c66ded"}, + {file = "uvloop-0.17.0.tar.gz", hash = "sha256:0ddf6baf9cf11a1a22c71487f39f15b2cf78eb5bde7e5b45fbb99e8a9d91b9e1"}, +] + +[package.extras] +dev = ["Cython (>=0.29.32,<0.30.0)", "Sphinx (>=4.1.2,<4.2.0)", "aiohttp", "flake8 (>=3.9.2,<3.10.0)", "mypy (>=0.800)", "psutil", "pyOpenSSL (>=22.0.0,<22.1.0)", "pycodestyle (>=2.7.0,<2.8.0)", "pytest (>=3.6.0)", "sphinx-rtd-theme (>=0.5.2,<0.6.0)", "sphinxcontrib-asyncio (>=0.3.0,<0.4.0)"] +docs = ["Sphinx (>=4.1.2,<4.2.0)", "sphinx-rtd-theme (>=0.5.2,<0.6.0)", "sphinxcontrib-asyncio (>=0.3.0,<0.4.0)"] +test = ["Cython (>=0.29.32,<0.30.0)", "aiohttp", "flake8 (>=3.9.2,<3.10.0)", "mypy (>=0.800)", "psutil", "pyOpenSSL (>=22.0.0,<22.1.0)", "pycodestyle (>=2.7.0,<2.8.0)"] + +[[package]] +name = "vine" +version = "5.0.0" +description = "Promises, promises, promises." +optional = false +python-versions = ">=3.6" +files = [ + {file = "vine-5.0.0-py2.py3-none-any.whl", hash = "sha256:4c9dceab6f76ed92105027c49c823800dd33cacce13bdedc5b914e3514b7fb30"}, + {file = "vine-5.0.0.tar.gz", hash = "sha256:7d3b1624a953da82ef63462013bbd271d3eb75751489f9807598e8f340bd637e"}, +] + +[[package]] +name = "watchfiles" +version = "0.19.0" +description = "Simple, modern and high performance file watching and code reload in python." +optional = false +python-versions = ">=3.7" +files = [ + {file = "watchfiles-0.19.0-cp37-abi3-macosx_10_7_x86_64.whl", hash = "sha256:91633e64712df3051ca454ca7d1b976baf842d7a3640b87622b323c55f3345e7"}, + {file = "watchfiles-0.19.0-cp37-abi3-macosx_11_0_arm64.whl", hash = "sha256:b6577b8c6c8701ba8642ea9335a129836347894b666dd1ec2226830e263909d3"}, + {file = "watchfiles-0.19.0-cp37-abi3-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:18b28f6ad871b82df9542ff958d0c86bb0d8310bb09eb8e87d97318a3b5273af"}, + {file = "watchfiles-0.19.0-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fac19dc9cbc34052394dbe81e149411a62e71999c0a19e1e09ce537867f95ae0"}, + {file = "watchfiles-0.19.0-cp37-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:09ea3397aecbc81c19ed7f025e051a7387feefdb789cf768ff994c1228182fda"}, + {file = "watchfiles-0.19.0-cp37-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c0376deac92377817e4fb8f347bf559b7d44ff556d9bc6f6208dd3f79f104aaf"}, + {file = "watchfiles-0.19.0-cp37-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c75eff897786ee262c9f17a48886f4e98e6cfd335e011c591c305e5d083c056"}, + {file = "watchfiles-0.19.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cb5d45c4143c1dd60f98a16187fd123eda7248f84ef22244818c18d531a249d1"}, + {file = "watchfiles-0.19.0-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:79c533ff593db861ae23436541f481ec896ee3da4e5db8962429b441bbaae16e"}, + {file = "watchfiles-0.19.0-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:3d7d267d27aceeeaa3de0dd161a0d64f0a282264d592e335fff7958cc0cbae7c"}, + {file = "watchfiles-0.19.0-cp37-abi3-win32.whl", hash = "sha256:176a9a7641ec2c97b24455135d58012a5be5c6217fc4d5fef0b2b9f75dbf5154"}, + {file = "watchfiles-0.19.0-cp37-abi3-win_amd64.whl", hash = "sha256:945be0baa3e2440151eb3718fd8846751e8b51d8de7b884c90b17d271d34cae8"}, + {file = "watchfiles-0.19.0-cp37-abi3-win_arm64.whl", hash = "sha256:0089c6dc24d436b373c3c57657bf4f9a453b13767150d17284fc6162b2791911"}, + {file = "watchfiles-0.19.0-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:cae3dde0b4b2078f31527acff6f486e23abed307ba4d3932466ba7cdd5ecec79"}, + {file = "watchfiles-0.19.0-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:7f3920b1285a7d3ce898e303d84791b7bf40d57b7695ad549dc04e6a44c9f120"}, + {file = "watchfiles-0.19.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9afd0d69429172c796164fd7fe8e821ade9be983f51c659a38da3faaaaac44dc"}, + {file = "watchfiles-0.19.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:68dce92b29575dda0f8d30c11742a8e2b9b8ec768ae414b54f7453f27bdf9545"}, + {file = "watchfiles-0.19.0-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:5569fc7f967429d4bc87e355cdfdcee6aabe4b620801e2cf5805ea245c06097c"}, + {file = "watchfiles-0.19.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:5471582658ea56fca122c0f0d0116a36807c63fefd6fdc92c71ca9a4491b6b48"}, + {file = "watchfiles-0.19.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b538014a87f94d92f98f34d3e6d2635478e6be6423a9ea53e4dd96210065e193"}, + {file = "watchfiles-0.19.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:20b44221764955b1e703f012c74015306fb7e79a00c15370785f309b1ed9aa8d"}, + {file = "watchfiles-0.19.0.tar.gz", hash = "sha256:d9b073073e048081e502b6c6b0b88714c026a1a4c890569238d04aca5f9ca74b"}, +] + +[package.dependencies] +anyio = ">=3.0.0" + +[[package]] +name = "wcwidth" +version = "0.2.6" +description = "Measures the displayed width of unicode strings in a terminal" +optional = false +python-versions = "*" +files = [ + {file = "wcwidth-0.2.6-py2.py3-none-any.whl", hash = "sha256:795b138f6875577cd91bba52baf9e445cd5118fd32723b460e30a0af30ea230e"}, + {file = "wcwidth-0.2.6.tar.gz", hash = "sha256:a5220780a404dbe3353789870978e472cfe477761f06ee55077256e509b156d0"}, +] + +[[package]] +name = "websocket-client" +version = "1.6.1" +description = "WebSocket client for Python with low level API options" +optional = false +python-versions = ">=3.7" +files = [ + {file = "websocket-client-1.6.1.tar.gz", hash = "sha256:c951af98631d24f8df89ab1019fc365f2227c0892f12fd150e935607c79dd0dd"}, + {file = "websocket_client-1.6.1-py3-none-any.whl", hash = "sha256:f1f9f2ad5291f0225a49efad77abf9e700b6fef553900623060dad6e26503b9d"}, +] + +[package.extras] +docs = ["Sphinx (>=3.4)", "sphinx-rtd-theme (>=0.5)"] +optional = ["python-socks", "wsaccel"] +test = ["websockets"] + +[[package]] +name = "websockets" +version = "11.0.3" +description = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)" +optional = false +python-versions = ">=3.7" +files = [ + {file = "websockets-11.0.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3ccc8a0c387629aec40f2fc9fdcb4b9d5431954f934da3eaf16cdc94f67dbfac"}, + {file = "websockets-11.0.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d67ac60a307f760c6e65dad586f556dde58e683fab03323221a4e530ead6f74d"}, + {file = "websockets-11.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:84d27a4832cc1a0ee07cdcf2b0629a8a72db73f4cf6de6f0904f6661227f256f"}, + {file = "websockets-11.0.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffd7dcaf744f25f82190856bc26ed81721508fc5cbf2a330751e135ff1283564"}, + {file = "websockets-11.0.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7622a89d696fc87af8e8d280d9b421db5133ef5b29d3f7a1ce9f1a7bf7fcfa11"}, + {file = "websockets-11.0.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bceab846bac555aff6427d060f2fcfff71042dba6f5fca7dc4f75cac815e57ca"}, + {file = "websockets-11.0.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:54c6e5b3d3a8936a4ab6870d46bdd6ec500ad62bde9e44462c32d18f1e9a8e54"}, + {file = "websockets-11.0.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:41f696ba95cd92dc047e46b41b26dd24518384749ed0d99bea0a941ca87404c4"}, + {file = "websockets-11.0.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:86d2a77fd490ae3ff6fae1c6ceaecad063d3cc2320b44377efdde79880e11526"}, + {file = "websockets-11.0.3-cp310-cp310-win32.whl", hash = "sha256:2d903ad4419f5b472de90cd2d40384573b25da71e33519a67797de17ef849b69"}, + {file = "websockets-11.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:1d2256283fa4b7f4c7d7d3e84dc2ece74d341bce57d5b9bf385df109c2a1a82f"}, + {file = "websockets-11.0.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e848f46a58b9fcf3d06061d17be388caf70ea5b8cc3466251963c8345e13f7eb"}, + {file = "websockets-11.0.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:aa5003845cdd21ac0dc6c9bf661c5beddd01116f6eb9eb3c8e272353d45b3288"}, + {file = "websockets-11.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b58cbf0697721120866820b89f93659abc31c1e876bf20d0b3d03cef14faf84d"}, + {file = "websockets-11.0.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:660e2d9068d2bedc0912af508f30bbeb505bbbf9774d98def45f68278cea20d3"}, + {file = "websockets-11.0.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c1f0524f203e3bd35149f12157438f406eff2e4fb30f71221c8a5eceb3617b6b"}, + {file = "websockets-11.0.3-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:def07915168ac8f7853812cc593c71185a16216e9e4fa886358a17ed0fd9fcf6"}, + {file = "websockets-11.0.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:b30c6590146e53149f04e85a6e4fcae068df4289e31e4aee1fdf56a0dead8f97"}, + {file = "websockets-11.0.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:619d9f06372b3a42bc29d0cd0354c9bb9fb39c2cbc1a9c5025b4538738dbffaf"}, + {file = "websockets-11.0.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:01f5567d9cf6f502d655151645d4e8b72b453413d3819d2b6f1185abc23e82dd"}, + {file = "websockets-11.0.3-cp311-cp311-win32.whl", hash = "sha256:e1459677e5d12be8bbc7584c35b992eea142911a6236a3278b9b5ce3326f282c"}, + {file = "websockets-11.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:e7837cb169eca3b3ae94cc5787c4fed99eef74c0ab9506756eea335e0d6f3ed8"}, + {file = "websockets-11.0.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:9f59a3c656fef341a99e3d63189852be7084c0e54b75734cde571182c087b152"}, + {file = "websockets-11.0.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2529338a6ff0eb0b50c7be33dc3d0e456381157a31eefc561771ee431134a97f"}, + {file = "websockets-11.0.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:34fd59a4ac42dff6d4681d8843217137f6bc85ed29722f2f7222bd619d15e95b"}, + {file = "websockets-11.0.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:332d126167ddddec94597c2365537baf9ff62dfcc9db4266f263d455f2f031cb"}, + {file = "websockets-11.0.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:6505c1b31274723ccaf5f515c1824a4ad2f0d191cec942666b3d0f3aa4cb4007"}, + {file = "websockets-11.0.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:f467ba0050b7de85016b43f5a22b46383ef004c4f672148a8abf32bc999a87f0"}, + {file = "websockets-11.0.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:9d9acd80072abcc98bd2c86c3c9cd4ac2347b5a5a0cae7ed5c0ee5675f86d9af"}, + {file = "websockets-11.0.3-cp37-cp37m-win32.whl", hash = "sha256:e590228200fcfc7e9109509e4d9125eace2042fd52b595dd22bbc34bb282307f"}, + {file = "websockets-11.0.3-cp37-cp37m-win_amd64.whl", hash = "sha256:b16fff62b45eccb9c7abb18e60e7e446998093cdcb50fed33134b9b6878836de"}, + {file = "websockets-11.0.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:fb06eea71a00a7af0ae6aefbb932fb8a7df3cb390cc217d51a9ad7343de1b8d0"}, + {file = "websockets-11.0.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8a34e13a62a59c871064dfd8ffb150867e54291e46d4a7cf11d02c94a5275bae"}, + {file = "websockets-11.0.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4841ed00f1026dfbced6fca7d963c4e7043aa832648671b5138008dc5a8f6d99"}, + {file = "websockets-11.0.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a073fc9ab1c8aff37c99f11f1641e16da517770e31a37265d2755282a5d28aa"}, + {file = "websockets-11.0.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:68b977f21ce443d6d378dbd5ca38621755f2063d6fdb3335bda981d552cfff86"}, + {file = "websockets-11.0.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e1a99a7a71631f0efe727c10edfba09ea6bee4166a6f9c19aafb6c0b5917d09c"}, + {file = "websockets-11.0.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:bee9fcb41db2a23bed96c6b6ead6489702c12334ea20a297aa095ce6d31370d0"}, + {file = "websockets-11.0.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:4b253869ea05a5a073ebfdcb5cb3b0266a57c3764cf6fe114e4cd90f4bfa5f5e"}, + {file = "websockets-11.0.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:1553cb82942b2a74dd9b15a018dce645d4e68674de2ca31ff13ebc2d9f283788"}, + {file = "websockets-11.0.3-cp38-cp38-win32.whl", hash = "sha256:f61bdb1df43dc9c131791fbc2355535f9024b9a04398d3bd0684fc16ab07df74"}, + {file = "websockets-11.0.3-cp38-cp38-win_amd64.whl", hash = "sha256:03aae4edc0b1c68498f41a6772d80ac7c1e33c06c6ffa2ac1c27a07653e79d6f"}, + {file = "websockets-11.0.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:777354ee16f02f643a4c7f2b3eff8027a33c9861edc691a2003531f5da4f6bc8"}, + {file = "websockets-11.0.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8c82f11964f010053e13daafdc7154ce7385ecc538989a354ccc7067fd7028fd"}, + {file = "websockets-11.0.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3580dd9c1ad0701169e4d6fc41e878ffe05e6bdcaf3c412f9d559389d0c9e016"}, + {file = "websockets-11.0.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f1a3f10f836fab6ca6efa97bb952300b20ae56b409414ca85bff2ad241d2a61"}, + {file = "websockets-11.0.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:df41b9bc27c2c25b486bae7cf42fccdc52ff181c8c387bfd026624a491c2671b"}, + {file = "websockets-11.0.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:279e5de4671e79a9ac877427f4ac4ce93751b8823f276b681d04b2156713b9dd"}, + {file = "websockets-11.0.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:1fdf26fa8a6a592f8f9235285b8affa72748dc12e964a5518c6c5e8f916716f7"}, + {file = "websockets-11.0.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:69269f3a0b472e91125b503d3c0b3566bda26da0a3261c49f0027eb6075086d1"}, + {file = "websockets-11.0.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:97b52894d948d2f6ea480171a27122d77af14ced35f62e5c892ca2fae9344311"}, + {file = "websockets-11.0.3-cp39-cp39-win32.whl", hash = "sha256:c7f3cb904cce8e1be667c7e6fef4516b98d1a6a0635a58a57528d577ac18a128"}, + {file = "websockets-11.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:c792ea4eabc0159535608fc5658a74d1a81020eb35195dd63214dcf07556f67e"}, + {file = "websockets-11.0.3-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:f2e58f2c36cc52d41f2659e4c0cbf7353e28c8c9e63e30d8c6d3494dc9fdedcf"}, + {file = "websockets-11.0.3-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:de36fe9c02995c7e6ae6efe2e205816f5f00c22fd1fbf343d4d18c3d5ceac2f5"}, + {file = "websockets-11.0.3-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0ac56b661e60edd453585f4bd68eb6a29ae25b5184fd5ba51e97652580458998"}, + {file = "websockets-11.0.3-pp37-pypy37_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e052b8467dd07d4943936009f46ae5ce7b908ddcac3fda581656b1b19c083d9b"}, + {file = "websockets-11.0.3-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:42cc5452a54a8e46a032521d7365da775823e21bfba2895fb7b77633cce031bb"}, + {file = "websockets-11.0.3-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:e6316827e3e79b7b8e7d8e3b08f4e331af91a48e794d5d8b099928b6f0b85f20"}, + {file = "websockets-11.0.3-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8531fdcad636d82c517b26a448dcfe62f720e1922b33c81ce695d0edb91eb931"}, + {file = "websockets-11.0.3-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c114e8da9b475739dde229fd3bc6b05a6537a88a578358bc8eb29b4030fac9c9"}, + {file = "websockets-11.0.3-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e063b1865974611313a3849d43f2c3f5368093691349cf3c7c8f8f75ad7cb280"}, + {file = "websockets-11.0.3-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:92b2065d642bf8c0a82d59e59053dd2fdde64d4ed44efe4870fa816c1232647b"}, + {file = "websockets-11.0.3-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:0ee68fe502f9031f19d495dae2c268830df2760c0524cbac5d759921ba8c8e82"}, + {file = "websockets-11.0.3-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dcacf2c7a6c3a84e720d1bb2b543c675bf6c40e460300b628bab1b1efc7c034c"}, + {file = "websockets-11.0.3-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b67c6f5e5a401fc56394f191f00f9b3811fe843ee93f4a70df3c389d1adf857d"}, + {file = "websockets-11.0.3-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1d5023a4b6a5b183dc838808087033ec5df77580485fc533e7dab2567851b0a4"}, + {file = "websockets-11.0.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:ed058398f55163a79bb9f06a90ef9ccc063b204bb346c4de78efc5d15abfe602"}, + {file = "websockets-11.0.3-py3-none-any.whl", hash = "sha256:6681ba9e7f8f3b19440921e99efbb40fc89f26cd71bf539e45d8c8a25c976dc6"}, + {file = "websockets-11.0.3.tar.gz", hash = "sha256:88fc51d9a26b10fc331be344f1781224a375b78488fc343620184e95a4b27016"}, +] + +[[package]] +name = "werkzeug" +version = "2.3.6" +description = "The comprehensive WSGI web application library." +optional = false +python-versions = ">=3.8" +files = [ + {file = "Werkzeug-2.3.6-py3-none-any.whl", hash = "sha256:935539fa1413afbb9195b24880778422ed620c0fc09670945185cce4d91a8890"}, + {file = "Werkzeug-2.3.6.tar.gz", hash = "sha256:98c774df2f91b05550078891dee5f0eb0cb797a522c757a2452b9cee5b202330"}, +] + +[package.dependencies] +MarkupSafe = ">=2.1.1" + +[package.extras] +watchdog = ["watchdog (>=2.3)"] + +[[package]] +name = "wrapt" +version = "1.15.0" +description = "Module for decorators, wrappers and monkey patching." +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" +files = [ + {file = "wrapt-1.15.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:ca1cccf838cd28d5a0883b342474c630ac48cac5df0ee6eacc9c7290f76b11c1"}, + {file = "wrapt-1.15.0-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:e826aadda3cae59295b95343db8f3d965fb31059da7de01ee8d1c40a60398b29"}, + {file = "wrapt-1.15.0-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:5fc8e02f5984a55d2c653f5fea93531e9836abbd84342c1d1e17abc4a15084c2"}, + {file = "wrapt-1.15.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:96e25c8603a155559231c19c0349245eeb4ac0096fe3c1d0be5c47e075bd4f46"}, + {file = "wrapt-1.15.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:40737a081d7497efea35ab9304b829b857f21558acfc7b3272f908d33b0d9d4c"}, + {file = "wrapt-1.15.0-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:f87ec75864c37c4c6cb908d282e1969e79763e0d9becdfe9fe5473b7bb1e5f09"}, + {file = "wrapt-1.15.0-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:1286eb30261894e4c70d124d44b7fd07825340869945c79d05bda53a40caa079"}, + {file = "wrapt-1.15.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:493d389a2b63c88ad56cdc35d0fa5752daac56ca755805b1b0c530f785767d5e"}, + {file = "wrapt-1.15.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:58d7a75d731e8c63614222bcb21dd992b4ab01a399f1f09dd82af17bbfc2368a"}, + {file = "wrapt-1.15.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:21f6d9a0d5b3a207cdf7acf8e58d7d13d463e639f0c7e01d82cdb671e6cb7923"}, + {file = "wrapt-1.15.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ce42618f67741d4697684e501ef02f29e758a123aa2d669e2d964ff734ee00ee"}, + {file = "wrapt-1.15.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41d07d029dd4157ae27beab04d22b8e261eddfc6ecd64ff7000b10dc8b3a5727"}, + {file = "wrapt-1.15.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:54accd4b8bc202966bafafd16e69da9d5640ff92389d33d28555c5fd4f25ccb7"}, + {file = "wrapt-1.15.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2fbfbca668dd15b744418265a9607baa970c347eefd0db6a518aaf0cfbd153c0"}, + {file = "wrapt-1.15.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:76e9c727a874b4856d11a32fb0b389afc61ce8aaf281ada613713ddeadd1cfec"}, + {file = "wrapt-1.15.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e20076a211cd6f9b44a6be58f7eeafa7ab5720eb796975d0c03f05b47d89eb90"}, + {file = "wrapt-1.15.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a74d56552ddbde46c246b5b89199cb3fd182f9c346c784e1a93e4dc3f5ec9975"}, + {file = "wrapt-1.15.0-cp310-cp310-win32.whl", hash = "sha256:26458da5653aa5b3d8dc8b24192f574a58984c749401f98fff994d41d3f08da1"}, + {file = "wrapt-1.15.0-cp310-cp310-win_amd64.whl", hash = "sha256:75760a47c06b5974aa5e01949bf7e66d2af4d08cb8c1d6516af5e39595397f5e"}, + {file = "wrapt-1.15.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ba1711cda2d30634a7e452fc79eabcadaffedf241ff206db2ee93dd2c89a60e7"}, + {file = "wrapt-1.15.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:56374914b132c702aa9aa9959c550004b8847148f95e1b824772d453ac204a72"}, + {file = "wrapt-1.15.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a89ce3fd220ff144bd9d54da333ec0de0399b52c9ac3d2ce34b569cf1a5748fb"}, + {file = "wrapt-1.15.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3bbe623731d03b186b3d6b0d6f51865bf598587c38d6f7b0be2e27414f7f214e"}, + {file = "wrapt-1.15.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3abbe948c3cbde2689370a262a8d04e32ec2dd4f27103669a45c6929bcdbfe7c"}, + {file = "wrapt-1.15.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:b67b819628e3b748fd3c2192c15fb951f549d0f47c0449af0764d7647302fda3"}, + {file = "wrapt-1.15.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:7eebcdbe3677e58dd4c0e03b4f2cfa346ed4049687d839adad68cc38bb559c92"}, + {file = "wrapt-1.15.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:74934ebd71950e3db69960a7da29204f89624dde411afbfb3b4858c1409b1e98"}, + {file = "wrapt-1.15.0-cp311-cp311-win32.whl", hash = "sha256:bd84395aab8e4d36263cd1b9308cd504f6cf713b7d6d3ce25ea55670baec5416"}, + {file = "wrapt-1.15.0-cp311-cp311-win_amd64.whl", hash = "sha256:a487f72a25904e2b4bbc0817ce7a8de94363bd7e79890510174da9d901c38705"}, + {file = "wrapt-1.15.0-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:4ff0d20f2e670800d3ed2b220d40984162089a6e2c9646fdb09b85e6f9a8fc29"}, + {file = "wrapt-1.15.0-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:9ed6aa0726b9b60911f4aed8ec5b8dd7bf3491476015819f56473ffaef8959bd"}, + {file = "wrapt-1.15.0-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:896689fddba4f23ef7c718279e42f8834041a21342d95e56922e1c10c0cc7afb"}, + {file = "wrapt-1.15.0-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:75669d77bb2c071333417617a235324a1618dba66f82a750362eccbe5b61d248"}, + {file = "wrapt-1.15.0-cp35-cp35m-win32.whl", hash = "sha256:fbec11614dba0424ca72f4e8ba3c420dba07b4a7c206c8c8e4e73f2e98f4c559"}, + {file = "wrapt-1.15.0-cp35-cp35m-win_amd64.whl", hash = "sha256:fd69666217b62fa5d7c6aa88e507493a34dec4fa20c5bd925e4bc12fce586639"}, + {file = "wrapt-1.15.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:b0724f05c396b0a4c36a3226c31648385deb6a65d8992644c12a4963c70326ba"}, + {file = "wrapt-1.15.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bbeccb1aa40ab88cd29e6c7d8585582c99548f55f9b2581dfc5ba68c59a85752"}, + {file = "wrapt-1.15.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:38adf7198f8f154502883242f9fe7333ab05a5b02de7d83aa2d88ea621f13364"}, + {file = "wrapt-1.15.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:578383d740457fa790fdf85e6d346fda1416a40549fe8db08e5e9bd281c6a475"}, + {file = "wrapt-1.15.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:a4cbb9ff5795cd66f0066bdf5947f170f5d63a9274f99bdbca02fd973adcf2a8"}, + {file = "wrapt-1.15.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:af5bd9ccb188f6a5fdda9f1f09d9f4c86cc8a539bd48a0bfdc97723970348418"}, + {file = "wrapt-1.15.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:b56d5519e470d3f2fe4aa7585f0632b060d532d0696c5bdfb5e8319e1d0f69a2"}, + {file = "wrapt-1.15.0-cp36-cp36m-win32.whl", hash = "sha256:77d4c1b881076c3ba173484dfa53d3582c1c8ff1f914c6461ab70c8428b796c1"}, + {file = "wrapt-1.15.0-cp36-cp36m-win_amd64.whl", hash = "sha256:077ff0d1f9d9e4ce6476c1a924a3332452c1406e59d90a2cf24aeb29eeac9420"}, + {file = "wrapt-1.15.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:5c5aa28df055697d7c37d2099a7bc09f559d5053c3349b1ad0c39000e611d317"}, + {file = "wrapt-1.15.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3a8564f283394634a7a7054b7983e47dbf39c07712d7b177b37e03f2467a024e"}, + {file = "wrapt-1.15.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:780c82a41dc493b62fc5884fb1d3a3b81106642c5c5c78d6a0d4cbe96d62ba7e"}, + {file = "wrapt-1.15.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e169e957c33576f47e21864cf3fc9ff47c223a4ebca8960079b8bd36cb014fd0"}, + {file = "wrapt-1.15.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:b02f21c1e2074943312d03d243ac4388319f2456576b2c6023041c4d57cd7019"}, + {file = "wrapt-1.15.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:f2e69b3ed24544b0d3dbe2c5c0ba5153ce50dcebb576fdc4696d52aa22db6034"}, + {file = "wrapt-1.15.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d787272ed958a05b2c86311d3a4135d3c2aeea4fc655705f074130aa57d71653"}, + {file = "wrapt-1.15.0-cp37-cp37m-win32.whl", hash = "sha256:02fce1852f755f44f95af51f69d22e45080102e9d00258053b79367d07af39c0"}, + {file = "wrapt-1.15.0-cp37-cp37m-win_amd64.whl", hash = "sha256:abd52a09d03adf9c763d706df707c343293d5d106aea53483e0ec8d9e310ad5e"}, + {file = "wrapt-1.15.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cdb4f085756c96a3af04e6eca7f08b1345e94b53af8921b25c72f096e704e145"}, + {file = "wrapt-1.15.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:230ae493696a371f1dbffaad3dafbb742a4d27a0afd2b1aecebe52b740167e7f"}, + {file = "wrapt-1.15.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63424c681923b9f3bfbc5e3205aafe790904053d42ddcc08542181a30a7a51bd"}, + {file = "wrapt-1.15.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d6bcbfc99f55655c3d93feb7ef3800bd5bbe963a755687cbf1f490a71fb7794b"}, + {file = "wrapt-1.15.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c99f4309f5145b93eca6e35ac1a988f0dc0a7ccf9ccdcd78d3c0adf57224e62f"}, + {file = "wrapt-1.15.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b130fe77361d6771ecf5a219d8e0817d61b236b7d8b37cc045172e574ed219e6"}, + {file = "wrapt-1.15.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:96177eb5645b1c6985f5c11d03fc2dbda9ad24ec0f3a46dcce91445747e15094"}, + {file = "wrapt-1.15.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5fe3e099cf07d0fb5a1e23d399e5d4d1ca3e6dfcbe5c8570ccff3e9208274f7"}, + {file = "wrapt-1.15.0-cp38-cp38-win32.whl", hash = "sha256:abd8f36c99512755b8456047b7be10372fca271bf1467a1caa88db991e7c421b"}, + {file = "wrapt-1.15.0-cp38-cp38-win_amd64.whl", hash = "sha256:b06fa97478a5f478fb05e1980980a7cdf2712015493b44d0c87606c1513ed5b1"}, + {file = "wrapt-1.15.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2e51de54d4fb8fb50d6ee8327f9828306a959ae394d3e01a1ba8b2f937747d86"}, + {file = "wrapt-1.15.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0970ddb69bba00670e58955f8019bec4a42d1785db3faa043c33d81de2bf843c"}, + {file = "wrapt-1.15.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76407ab327158c510f44ded207e2f76b657303e17cb7a572ffe2f5a8a48aa04d"}, + {file = "wrapt-1.15.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cd525e0e52a5ff16653a3fc9e3dd827981917d34996600bbc34c05d048ca35cc"}, + {file = "wrapt-1.15.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d37ac69edc5614b90516807de32d08cb8e7b12260a285ee330955604ed9dd29"}, + {file = "wrapt-1.15.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:078e2a1a86544e644a68422f881c48b84fef6d18f8c7a957ffd3f2e0a74a0d4a"}, + {file = "wrapt-1.15.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:2cf56d0e237280baed46f0b5316661da892565ff58309d4d2ed7dba763d984b8"}, + {file = "wrapt-1.15.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7dc0713bf81287a00516ef43137273b23ee414fe41a3c14be10dd95ed98a2df9"}, + {file = "wrapt-1.15.0-cp39-cp39-win32.whl", hash = "sha256:46ed616d5fb42f98630ed70c3529541408166c22cdfd4540b88d5f21006b0eff"}, + {file = "wrapt-1.15.0-cp39-cp39-win_amd64.whl", hash = "sha256:eef4d64c650f33347c1f9266fa5ae001440b232ad9b98f1f43dfe7a79435c0a6"}, + {file = "wrapt-1.15.0-py3-none-any.whl", hash = "sha256:64b1df0f83706b4ef4cfb4fb0e4c2669100fd7ecacfb59e091fad300d4e04640"}, + {file = "wrapt-1.15.0.tar.gz", hash = "sha256:d06730c6aed78cee4126234cf2d071e01b44b915e725a6cb439a879ec9754a3a"}, +] + +[[package]] +name = "xmlsec" +version = "1.3.13" +description = "Python bindings for the XML Security Library" +optional = false +python-versions = ">=3.5" +files = [ + {file = "xmlsec-1.3.13-cp310-cp310-win32.whl", hash = "sha256:2174e8c88555383322d8b7d3927490a92ef72ad72a6ddaf4fa1b96a3f27c3e90"}, + {file = "xmlsec-1.3.13-cp310-cp310-win_amd64.whl", hash = "sha256:46d1daf16a8f4430efca5bb9c6a15776f2671f69f48a1941d6bb335e6f8cb29d"}, + {file = "xmlsec-1.3.13-cp35-cp35m-win32.whl", hash = "sha256:d47062c42775a025aa94fb8b15de97c1db86e301e549d3168157e0b1223d51b1"}, + {file = "xmlsec-1.3.13-cp35-cp35m-win_amd64.whl", hash = "sha256:7c7e8ef52688ddaf5b66750cc8d901f61716f46727014ff012f41d8858cedeb0"}, + {file = "xmlsec-1.3.13-cp36-cp36m-win32.whl", hash = "sha256:1725d70ee2bb2cd8dd66c7a7451be02bb59dc8280103db4f68e731f00135b1e0"}, + {file = "xmlsec-1.3.13-cp36-cp36m-win_amd64.whl", hash = "sha256:1f8c41162152d7086fd459926e61bc7cb2d52ffc829e760bf8b2c221a645d568"}, + {file = "xmlsec-1.3.13-cp37-cp37m-win32.whl", hash = "sha256:ff1c61f296e75cba5bac802d0000bfde09143eed946ced1a5162211867c335f8"}, + {file = "xmlsec-1.3.13-cp37-cp37m-win_amd64.whl", hash = "sha256:d249c0a2bf3ff13a231bca6a588e7d276b3f1e2cf09316b542f470a63855799e"}, + {file = "xmlsec-1.3.13-cp38-cp38-win32.whl", hash = "sha256:56cfcf3487b6ad269eb1fb543c04dee2c101f1bc91e06d6cf7bfab9ac486efd8"}, + {file = "xmlsec-1.3.13-cp38-cp38-win_amd64.whl", hash = "sha256:e6626bece0e97a8598b5df28c27bc6f2ae1e97d29dca3c1a4910a7598a4d1d0f"}, + {file = "xmlsec-1.3.13-cp39-cp39-win32.whl", hash = "sha256:091f23765729df6f3b3a55c8a6a96f9c713fa86e76b86a19cdb756aaa6dc0646"}, + {file = "xmlsec-1.3.13-cp39-cp39-win_amd64.whl", hash = "sha256:5162f416179350587c4ff64737af68a846a9b86f95fd465df4e68b589ce56618"}, + {file = "xmlsec-1.3.13.tar.gz", hash = "sha256:916f5d78e8041f6cd9391abba659da8c94a4fef7196d126d40af1ff417f2cf86"}, +] + +[package.dependencies] +lxml = ">=3.8" + +[[package]] +name = "xmltodict" +version = "0.13.0" +description = "Makes working with XML feel like you are working with JSON" +optional = false +python-versions = ">=3.4" +files = [ + {file = "xmltodict-0.13.0-py2.py3-none-any.whl", hash = "sha256:aa89e8fd76320154a40d19a0df04a4695fb9dc5ba977cbb68ab3e4eb225e7852"}, + {file = "xmltodict-0.13.0.tar.gz", hash = "sha256:341595a488e3e01a85a9d8911d8912fd922ede5fecc4dce437eb4b6c8d037e56"}, +] + +[[package]] +name = "yarl" +version = "1.9.2" +description = "Yet another URL library" +optional = false +python-versions = ">=3.7" +files = [ + {file = "yarl-1.9.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8c2ad583743d16ddbdf6bb14b5cd76bf43b0d0006e918809d5d4ddf7bde8dd82"}, + {file = "yarl-1.9.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:82aa6264b36c50acfb2424ad5ca537a2060ab6de158a5bd2a72a032cc75b9eb8"}, + {file = "yarl-1.9.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c0c77533b5ed4bcc38e943178ccae29b9bcf48ffd1063f5821192f23a1bd27b9"}, + {file = "yarl-1.9.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ee4afac41415d52d53a9833ebae7e32b344be72835bbb589018c9e938045a560"}, + {file = "yarl-1.9.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9bf345c3a4f5ba7f766430f97f9cc1320786f19584acc7086491f45524a551ac"}, + {file = "yarl-1.9.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2a96c19c52ff442a808c105901d0bdfd2e28575b3d5f82e2f5fd67e20dc5f4ea"}, + {file = "yarl-1.9.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:891c0e3ec5ec881541f6c5113d8df0315ce5440e244a716b95f2525b7b9f3608"}, + {file = "yarl-1.9.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c3a53ba34a636a256d767c086ceb111358876e1fb6b50dfc4d3f4951d40133d5"}, + {file = "yarl-1.9.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:566185e8ebc0898b11f8026447eacd02e46226716229cea8db37496c8cdd26e0"}, + {file = "yarl-1.9.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:2b0738fb871812722a0ac2154be1f049c6223b9f6f22eec352996b69775b36d4"}, + {file = "yarl-1.9.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:32f1d071b3f362c80f1a7d322bfd7b2d11e33d2adf395cc1dd4df36c9c243095"}, + {file = "yarl-1.9.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:e9fdc7ac0d42bc3ea78818557fab03af6181e076a2944f43c38684b4b6bed8e3"}, + {file = "yarl-1.9.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:56ff08ab5df8429901ebdc5d15941b59f6253393cb5da07b4170beefcf1b2528"}, + {file = "yarl-1.9.2-cp310-cp310-win32.whl", hash = "sha256:8ea48e0a2f931064469bdabca50c2f578b565fc446f302a79ba6cc0ee7f384d3"}, + {file = "yarl-1.9.2-cp310-cp310-win_amd64.whl", hash = "sha256:50f33040f3836e912ed16d212f6cc1efb3231a8a60526a407aeb66c1c1956dde"}, + {file = "yarl-1.9.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:646d663eb2232d7909e6601f1a9107e66f9791f290a1b3dc7057818fe44fc2b6"}, + {file = "yarl-1.9.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:aff634b15beff8902d1f918012fc2a42e0dbae6f469fce134c8a0dc51ca423bb"}, + {file = "yarl-1.9.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a83503934c6273806aed765035716216cc9ab4e0364f7f066227e1aaea90b8d0"}, + {file = "yarl-1.9.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b25322201585c69abc7b0e89e72790469f7dad90d26754717f3310bfe30331c2"}, + {file = "yarl-1.9.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:22a94666751778629f1ec4280b08eb11815783c63f52092a5953faf73be24191"}, + {file = "yarl-1.9.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ec53a0ea2a80c5cd1ab397925f94bff59222aa3cf9c6da938ce05c9ec20428d"}, + {file = "yarl-1.9.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:159d81f22d7a43e6eabc36d7194cb53f2f15f498dbbfa8edc8a3239350f59fe7"}, + {file = "yarl-1.9.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:832b7e711027c114d79dffb92576acd1bd2decc467dec60e1cac96912602d0e6"}, + {file = "yarl-1.9.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:95d2ecefbcf4e744ea952d073c6922e72ee650ffc79028eb1e320e732898d7e8"}, + {file = "yarl-1.9.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:d4e2c6d555e77b37288eaf45b8f60f0737c9efa3452c6c44626a5455aeb250b9"}, + {file = "yarl-1.9.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:783185c75c12a017cc345015ea359cc801c3b29a2966c2655cd12b233bf5a2be"}, + {file = "yarl-1.9.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:b8cc1863402472f16c600e3e93d542b7e7542a540f95c30afd472e8e549fc3f7"}, + {file = "yarl-1.9.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:822b30a0f22e588b32d3120f6d41e4ed021806418b4c9f0bc3048b8c8cb3f92a"}, + {file = "yarl-1.9.2-cp311-cp311-win32.whl", hash = "sha256:a60347f234c2212a9f0361955007fcf4033a75bf600a33c88a0a8e91af77c0e8"}, + {file = "yarl-1.9.2-cp311-cp311-win_amd64.whl", hash = "sha256:be6b3fdec5c62f2a67cb3f8c6dbf56bbf3f61c0f046f84645cd1ca73532ea051"}, + {file = "yarl-1.9.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:38a3928ae37558bc1b559f67410df446d1fbfa87318b124bf5032c31e3447b74"}, + {file = "yarl-1.9.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac9bb4c5ce3975aeac288cfcb5061ce60e0d14d92209e780c93954076c7c4367"}, + {file = "yarl-1.9.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3da8a678ca8b96c8606bbb8bfacd99a12ad5dd288bc6f7979baddd62f71c63ef"}, + {file = "yarl-1.9.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:13414591ff516e04fcdee8dc051c13fd3db13b673c7a4cb1350e6b2ad9639ad3"}, + {file = "yarl-1.9.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf74d08542c3a9ea97bb8f343d4fcbd4d8f91bba5ec9d5d7f792dbe727f88938"}, + {file = "yarl-1.9.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6e7221580dc1db478464cfeef9b03b95c5852cc22894e418562997df0d074ccc"}, + {file = "yarl-1.9.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:494053246b119b041960ddcd20fd76224149cfea8ed8777b687358727911dd33"}, + {file = "yarl-1.9.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:52a25809fcbecfc63ac9ba0c0fb586f90837f5425edfd1ec9f3372b119585e45"}, + {file = "yarl-1.9.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:e65610c5792870d45d7b68c677681376fcf9cc1c289f23e8e8b39c1485384185"}, + {file = "yarl-1.9.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:1b1bba902cba32cdec51fca038fd53f8beee88b77efc373968d1ed021024cc04"}, + {file = "yarl-1.9.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:662e6016409828ee910f5d9602a2729a8a57d74b163c89a837de3fea050c7582"}, + {file = "yarl-1.9.2-cp37-cp37m-win32.whl", hash = "sha256:f364d3480bffd3aa566e886587eaca7c8c04d74f6e8933f3f2c996b7f09bee1b"}, + {file = "yarl-1.9.2-cp37-cp37m-win_amd64.whl", hash = "sha256:6a5883464143ab3ae9ba68daae8e7c5c95b969462bbe42e2464d60e7e2698368"}, + {file = "yarl-1.9.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5610f80cf43b6202e2c33ba3ec2ee0a2884f8f423c8f4f62906731d876ef4fac"}, + {file = "yarl-1.9.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b9a4e67ad7b646cd6f0938c7ebfd60e481b7410f574c560e455e938d2da8e0f4"}, + {file = "yarl-1.9.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:83fcc480d7549ccebe9415d96d9263e2d4226798c37ebd18c930fce43dfb9574"}, + {file = "yarl-1.9.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5fcd436ea16fee7d4207c045b1e340020e58a2597301cfbcfdbe5abd2356c2fb"}, + {file = "yarl-1.9.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:84e0b1599334b1e1478db01b756e55937d4614f8654311eb26012091be109d59"}, + {file = "yarl-1.9.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3458a24e4ea3fd8930e934c129b676c27452e4ebda80fbe47b56d8c6c7a63a9e"}, + {file = "yarl-1.9.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:838162460b3a08987546e881a2bfa573960bb559dfa739e7800ceeec92e64417"}, + {file = "yarl-1.9.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f4e2d08f07a3d7d3e12549052eb5ad3eab1c349c53ac51c209a0e5991bbada78"}, + {file = "yarl-1.9.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:de119f56f3c5f0e2fb4dee508531a32b069a5f2c6e827b272d1e0ff5ac040333"}, + {file = "yarl-1.9.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:149ddea5abf329752ea5051b61bd6c1d979e13fbf122d3a1f9f0c8be6cb6f63c"}, + {file = "yarl-1.9.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:674ca19cbee4a82c9f54e0d1eee28116e63bc6fd1e96c43031d11cbab8b2afd5"}, + {file = "yarl-1.9.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:9b3152f2f5677b997ae6c804b73da05a39daa6a9e85a512e0e6823d81cdad7cc"}, + {file = "yarl-1.9.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5415d5a4b080dc9612b1b63cba008db84e908b95848369aa1da3686ae27b6d2b"}, + {file = "yarl-1.9.2-cp38-cp38-win32.whl", hash = "sha256:f7a3d8146575e08c29ed1cd287068e6d02f1c7bdff8970db96683b9591b86ee7"}, + {file = "yarl-1.9.2-cp38-cp38-win_amd64.whl", hash = "sha256:63c48f6cef34e6319a74c727376e95626f84ea091f92c0250a98e53e62c77c72"}, + {file = "yarl-1.9.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:75df5ef94c3fdc393c6b19d80e6ef1ecc9ae2f4263c09cacb178d871c02a5ba9"}, + {file = "yarl-1.9.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c027a6e96ef77d401d8d5a5c8d6bc478e8042f1e448272e8d9752cb0aff8b5c8"}, + {file = "yarl-1.9.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f3b078dbe227f79be488ffcfc7a9edb3409d018e0952cf13f15fd6512847f3f7"}, + {file = "yarl-1.9.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:59723a029760079b7d991a401386390c4be5bfec1e7dd83e25a6a0881859e716"}, + {file = "yarl-1.9.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b03917871bf859a81ccb180c9a2e6c1e04d2f6a51d953e6a5cdd70c93d4e5a2a"}, + {file = "yarl-1.9.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c1012fa63eb6c032f3ce5d2171c267992ae0c00b9e164efe4d73db818465fac3"}, + {file = "yarl-1.9.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a74dcbfe780e62f4b5a062714576f16c2f3493a0394e555ab141bf0d746bb955"}, + {file = "yarl-1.9.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8c56986609b057b4839968ba901944af91b8e92f1725d1a2d77cbac6972b9ed1"}, + {file = "yarl-1.9.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:2c315df3293cd521033533d242d15eab26583360b58f7ee5d9565f15fee1bef4"}, + {file = "yarl-1.9.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:b7232f8dfbd225d57340e441d8caf8652a6acd06b389ea2d3222b8bc89cbfca6"}, + {file = "yarl-1.9.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:53338749febd28935d55b41bf0bcc79d634881195a39f6b2f767870b72514caf"}, + {file = "yarl-1.9.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:066c163aec9d3d073dc9ffe5dd3ad05069bcb03fcaab8d221290ba99f9f69ee3"}, + {file = "yarl-1.9.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8288d7cd28f8119b07dd49b7230d6b4562f9b61ee9a4ab02221060d21136be80"}, + {file = "yarl-1.9.2-cp39-cp39-win32.whl", hash = "sha256:b124e2a6d223b65ba8768d5706d103280914d61f5cae3afbc50fc3dfcc016623"}, + {file = "yarl-1.9.2-cp39-cp39-win_amd64.whl", hash = "sha256:61016e7d582bc46a5378ffdd02cd0314fb8ba52f40f9cf4d9a5e7dbef88dee18"}, + {file = "yarl-1.9.2.tar.gz", hash = "sha256:04ab9d4b9f587c06d801c2abfe9317b77cdf996c65a90d5e84ecc45010823571"}, +] + +[package.dependencies] +idna = ">=2.0" +multidict = ">=4.0" + +[[package]] +name = "zope-interface" +version = "6.0" +description = "Interfaces for Python" +optional = false +python-versions = ">=3.7" +files = [ + {file = "zope.interface-6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f299c020c6679cb389814a3b81200fe55d428012c5e76da7e722491f5d205990"}, + {file = "zope.interface-6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ee4b43f35f5dc15e1fec55ccb53c130adb1d11e8ad8263d68b1284b66a04190d"}, + {file = "zope.interface-6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5a158846d0fca0a908c1afb281ddba88744d403f2550dc34405c3691769cdd85"}, + {file = "zope.interface-6.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f72f23bab1848edb7472309e9898603141644faec9fd57a823ea6b4d1c4c8995"}, + {file = "zope.interface-6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:48f4d38cf4b462e75fac78b6f11ad47b06b1c568eb59896db5b6ec1094eb467f"}, + {file = "zope.interface-6.0-cp310-cp310-win_amd64.whl", hash = "sha256:87b690bbee9876163210fd3f500ee59f5803e4a6607d1b1238833b8885ebd410"}, + {file = "zope.interface-6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f2363e5fd81afb650085c6686f2ee3706975c54f331b426800b53531191fdf28"}, + {file = "zope.interface-6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:af169ba897692e9cd984a81cb0f02e46dacdc07d6cf9fd5c91e81f8efaf93d52"}, + {file = "zope.interface-6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fa90bac61c9dc3e1a563e5babb3fd2c0c1c80567e815442ddbe561eadc803b30"}, + {file = "zope.interface-6.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:89086c9d3490a0f265a3c4b794037a84541ff5ffa28bb9c24cc9f66566968464"}, + {file = "zope.interface-6.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:809fe3bf1a91393abc7e92d607976bbb8586512913a79f2bf7d7ec15bd8ea518"}, + {file = "zope.interface-6.0-cp311-cp311-win_amd64.whl", hash = "sha256:0ec9653825f837fbddc4e4b603d90269b501486c11800d7c761eee7ce46d1bbb"}, + {file = "zope.interface-6.0-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:790c1d9d8f9c92819c31ea660cd43c3d5451df1df61e2e814a6f99cebb292788"}, + {file = "zope.interface-6.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b39b8711578dcfd45fc0140993403b8a81e879ec25d53189f3faa1f006087dca"}, + {file = "zope.interface-6.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eba51599370c87088d8882ab74f637de0c4f04a6d08a312dce49368ba9ed5c2a"}, + {file = "zope.interface-6.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6ee934f023f875ec2cfd2b05a937bd817efcc6c4c3f55c5778cbf78e58362ddc"}, + {file = "zope.interface-6.0-cp37-cp37m-win_amd64.whl", hash = "sha256:042f2381118b093714081fd82c98e3b189b68db38ee7d35b63c327c470ef8373"}, + {file = "zope.interface-6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:dfbbbf0809a3606046a41f8561c3eada9db811be94138f42d9135a5c47e75f6f"}, + {file = "zope.interface-6.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:424d23b97fa1542d7be882eae0c0fc3d6827784105264a8169a26ce16db260d8"}, + {file = "zope.interface-6.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e538f2d4a6ffb6edfb303ce70ae7e88629ac6e5581870e66c306d9ad7b564a58"}, + {file = "zope.interface-6.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:12175ca6b4db7621aedd7c30aa7cfa0a2d65ea3a0105393e05482d7a2d367446"}, + {file = "zope.interface-6.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c3d7dfd897a588ec27e391edbe3dd320a03684457470415870254e714126b1f"}, + {file = "zope.interface-6.0-cp38-cp38-win_amd64.whl", hash = "sha256:b3f543ae9d3408549a9900720f18c0194ac0fe810cecda2a584fd4dca2eb3bb8"}, + {file = "zope.interface-6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d0583b75f2e70ec93f100931660328965bb9ff65ae54695fb3fa0a1255daa6f2"}, + {file = "zope.interface-6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:23ac41d52fd15dd8be77e3257bc51bbb82469cf7f5e9a30b75e903e21439d16c"}, + {file = "zope.interface-6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:99856d6c98a326abbcc2363827e16bd6044f70f2ef42f453c0bd5440c4ce24e5"}, + {file = "zope.interface-6.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1592f68ae11e557b9ff2bc96ac8fc30b187e77c45a3c9cd876e3368c53dc5ba8"}, + {file = "zope.interface-6.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4407b1435572e3e1610797c9203ad2753666c62883b921318c5403fb7139dec2"}, + {file = "zope.interface-6.0-cp39-cp39-win_amd64.whl", hash = "sha256:5171eb073474a5038321409a630904fd61f12dd1856dd7e9d19cd6fe092cbbc5"}, + {file = "zope.interface-6.0.tar.gz", hash = "sha256:aab584725afd10c710b8f1e6e208dbee2d0ad009f57d674cb9d1b3964037275d"}, +] + +[package.dependencies] +setuptools = "*" + +[package.extras] +docs = ["Sphinx", "repoze.sphinx.autointerface"] +test = ["coverage (>=5.0.3)", "zope.event", "zope.testing"] +testing = ["coverage (>=5.0.3)", "zope.event", "zope.testing"] + +[metadata] +lock-version = "2.0" +python-versions = "^3.11" +content-hash = "4e3668a1a46b631b9ff2304162a1e5d06f76e4e31c6316c3b8c322af58077673" diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 000000000..2f3e86628 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,171 @@ +[tool.poetry] +name = "jumpserver" +version = "v3.5" +description = "广受欢迎的开源堡垒机" +authors = ["ibuler "] +license = "GPLv3" +readme = "README.md" + +[tool.poetry.dependencies] +python = "^3.11" +cython = "3.0.0" +aiofiles = "23.1.0" +amqp = "5.1.1" +ansible-core = { url = "https://github.com/jumpserver/ansible/releases/download/v2.14.1.2/ansible-2.14.1.2.zip" } +ansible = "7.1.0" +ansible-runner = "2.3.3" +asn1crypto = "1.5.1" +bcrypt = "4.0.1" +billiard = "4.1.0" +certifi = "2023.7.22" +cffi = "1.15.1" +chardet = "5.1.0" +configparser = "6.0.0" +decorator = "5.1.1" +docutils = "0.20.1" +ecdsa = "0.18.0" +enum-compat = "0.0.3" +ephem = "4.1.4" +future = "0.18.3" +idna = "3.4" +itypes = "1.2.0" +jinja2 = "3.1.2" +markupsafe = "2.1.3" +olefile = "0.46" +paramiko = "3.2.0" +passlib = "1.7.4" +pyasn1 = "0.5.0" +pycparser = "2.21" +cryptography = "41.0.2" +pycryptodome = "3.18.0" +pycryptodomex = "3.18.0" +phonenumbers = "8.13.17" +gmssl = "3.2.2" +itsdangerous = "1.1.0" +pyotp = "2.8.0" +pynacl = "1.5.0" +python-dateutil = "2.8.2" +pyyaml = "6.0.1" +requests = "2.31.0" +jms-storage = "0.0.50" +simplejson = "3.19.1" +six = "1.16.0" +sshtunnel = "0.4.0" +sshpubkeys = "3.3.1" +uritemplate = "4.1.1" +urllib3 = "1.26.16" +vine = "5.0.0" +werkzeug = "2.3.6" +unicodecsv = "0.14.1" +httpsig = "1.3.0" +treelib = "1.6.4" +psutil = "5.9.5" +msrestazure = "0.6.4" +adal = "1.2.7" +openpyxl = "3.0.10" +pyexcel = "0.7.0" +pyexcel-xlsx = "0.6.0" +data-tree = "0.0.1" +pyvmomi = "8.0.1.0.2" +termcolor = "2.3.0" +html2text = "2020.1.16" +pyzipper = "0.3.6" +python3-saml = "1.15.0" +websocket-client = "1.6.1" +pyjwkest = "1.4.2" +jsonfield2 = "4.0.0.post0" +geoip2 = "4.7.0" +ipip-ipdb = "1.6.1" +pywinrm = "0.4.3" +python-nmap = "0.7.1" +django = "4.1.10" +django-bootstrap3 = "23.4" +django-filter = "23.2" +django-formtools = "2.4.1" +django-ranged-response = "0.2.0" +django-rest-swagger = "2.2.0" +django-simple-captcha = "0.5.18" +django-timezone-field = "5.1" +djangorestframework = "3.14.0" +djangorestframework-bulk = "0.2.1" +django-simple-history = "3.3.0" +django-private-storage = "3.1" +drf-nested-routers = "0.93.4" +drf-writable-nested = "0.7.0" +rest-condition = "1.0.3" +drf-yasg = "1.21.7" +coreapi = "2.3.3" +coreschema = "0.0.4" +openapi-codec = "1.3.2" +pillow = "10.0.0" +pytz = "2023.3" +django-proxy = "1.2.2" +channels-redis = "4.1.0" +python-daemon = "3.0.1" +eventlet = "0.33.3" +greenlet = "2.0.2" +gunicorn = "21.2.0" +celery = "5.3.1" +flower = "2.0.0" +django-celery-beat = "2.5.0" +kombu = "5.3.1" +uvicorn = { version = "0.22.0", extras = ["standard"] } +websockets = "11.0.3" +python-ldap = "3.4.3" +ldap3 = "2.9.1" +django-radius = { url = "https://github.com/ibuler/django-radius/archive/refs/tags/1.5.0.zip" } +django-cas-ng = { url = "https://github.com/ibuler/django-cas-ng/releases/download/v4.3.1/django-cas-ng-4.3.1.zip" } +python-cas = "1.6.0" +django-auth-ldap = "4.4.0" +boto3 = "1.28.9" +botocore = "1.31.9" +s3transfer = "0.6.1" +kubernetes = "27.2.0" +mysqlclient = "2.2.0" +pymysql = "1.1.0" +django-redis = "5.3.0" +python-redis-lock = "4.0.0" +pyopenssl = "23.2.0" +redis = "4.6.0" +pymongo = "4.4.1" +pyfreerdp = "0.0.1" +ipython = "8.14.0" +forgerypy3 = "0.3.1" +django-debug-toolbar = "4.1.0" +pympler = "1.0.1" +hvac = "1.1.1" +pyhcl = "0.4.4" +ipy = "1.1" + + +[tool.poetry.group.dev.dependencies] +daphne = "4.0.0" +channels = "^4.0.0" +channels-redis = "^4.1.0" + + +[tool.poetry.group.xpack.dependencies] +qingcloud-sdk = "1.2.15" +azure-mgmt-subscription = "3.1.1" +azure-identity = "1.13.0" +azure-mgmt-compute = "30.0.0" +azure-mgmt-network = "23.1.0" +google-cloud-compute = "1.13.0" +grpcio = "1.56.2" +alibabacloud-dysmsapi20170525 = "2.0.24" +python-novaclient = "18.3.0" +python-keystoneclient = "5.1.0" +bce-python-sdk = "0.8.87" +tencentcloud-sdk-python = "3.0.941" +aliyun-python-sdk-core-v3 = "2.13.33" +aliyun-python-sdk-ecs = "4.24.64" +keystoneauth1 = "5.2.1" +oracledb = "1.3.2" +psycopg2-binary = "2.9.6" +pymssql = "2.2.7" +psycopg2 = "2.9.6" +ucloud-sdk-python3 = "0.11.50" + +[build-system] +requires = ["poetry-core"] +build-backend = "poetry.core.masonry.api" diff --git a/requirements/mac_pkg.sh b/requirements/mac_pkg.sh index 05033572a..4caf8dd1a 100644 --- a/requirements/mac_pkg.sh +++ b/requirements/mac_pkg.sh @@ -6,7 +6,7 @@ echo "1. 安装依赖" brew install libtiff libjpeg webp little-cms2 openssl gettext git \ git-lfs libxml2 libxmlsec1 pkg-config postgresql freetds openssl \ libffi freerdp -pip install daphne channels channel-redis +pip install daphne==4.0.0 channels channels-redis echo "2. 下载 IP 数据库" ip_db_path="${PROJECT_DIR}/apps/common/utils/geoip/GeoLite2-City.mmdb" diff --git a/requirements/requirements.txt b/requirements/requirements.txt index cb47071f7..3bb7cbee4 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -68,6 +68,7 @@ pyjwkest==1.4.2 jsonfield2==4.0.0.post0 geoip2==4.7.0 ipip-ipdb==1.6.1 +IPy==1.1 pywinrm==0.4.3 python-nmap==0.7.1 # Django environment diff --git a/requirements/requirements_xpack.txt b/requirements/requirements_xpack.txt index f7644fb05..253ea793b 100644 --- a/requirements/requirements_xpack.txt +++ b/requirements/requirements_xpack.txt @@ -19,6 +19,5 @@ keystoneauth1==5.2.1 oracledb==1.3.2 psycopg2-binary==2.9.6 pymssql==2.2.7 -IPy==1.1 psycopg2==2.9.6 ucloud-sdk-python3==0.11.50 From ef4f1ddb7487e3b9f80be3fad31c36feeef25c41 Mon Sep 17 00:00:00 2001 From: ibuler Date: Wed, 2 Aug 2023 14:52:12 +0800 Subject: [PATCH 080/177] perf: using mirror --- Dockerfile | 3 +- poetry.lock | 1383 +++++++++++++++++++++++++++++++++++++++++++++++- pyproject.toml | 5 + 3 files changed, 1387 insertions(+), 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index 75db8b6a2..346dfbe5f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -88,8 +88,7 @@ ARG PIP_MIRROR=https://pypi.douban.com/simple RUN --mount=type=cache,target=/root/.cache/pip \ set -ex \ - && pip config set global.index-url ${PIP_MIRROR} \ - && pip install poetry==1.5.1 \ + && pip install poetry==1.5.1 -i ${PIP_MIRROR} \ && poetry install --only=main COPY --from=stage-build /opt/jumpserver/release/jumpserver /opt/jumpserver diff --git a/poetry.lock b/poetry.lock index 73b9958d4..30075ac44 100644 --- a/poetry.lock +++ b/poetry.lock @@ -17,6 +17,11 @@ PyJWT = ">=1.0.0,<3" python-dateutil = ">=2.1.0,<3" requests = ">=2.0.0,<3" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "aiofiles" version = "23.1.0" @@ -28,6 +33,11 @@ files = [ {file = "aiofiles-23.1.0.tar.gz", hash = "sha256:edd247df9a19e0db16534d4baaf536d6609a43e1de5401d7a4c1c148753a1635"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "aiohttp" version = "3.8.5" @@ -136,6 +146,11 @@ yarl = ">=1.0,<2.0" [package.extras] speedups = ["Brotli", "aiodns", "cchardet"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "aiosignal" version = "1.3.1" @@ -150,6 +165,11 @@ files = [ [package.dependencies] frozenlist = ">=1.1.0" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "alibabacloud-credentials" version = "0.3.2" @@ -163,6 +183,11 @@ files = [ [package.dependencies] alibabacloud-tea = "*" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "alibabacloud-dysmsapi20170525" version = "2.0.24" @@ -180,6 +205,11 @@ alibabacloud-openapi-util = ">=0.2.1,<1.0.0" alibabacloud-tea-openapi = ">=0.3.6,<1.0.0" alibabacloud-tea-util = ">=0.3.9,<1.0.0" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "alibabacloud-endpoint-util" version = "0.0.3" @@ -193,6 +223,11 @@ files = [ [package.dependencies] alibabacloud-tea = ">=0.0.1" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "alibabacloud-gateway-spi" version = "0.0.1" @@ -206,6 +241,11 @@ files = [ [package.dependencies] alibabacloud_credentials = ">=0.2.0,<1.0.0" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "alibabacloud-openapi-util" version = "0.2.1" @@ -220,6 +260,11 @@ files = [ alibabacloud_tea_util = ">=0.0.2" cryptography = ">=3.0.0" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "alibabacloud-tea" version = "0.3.3" @@ -235,6 +280,11 @@ aiohttp = ">=3.7.0,<4.0.0" requests = ">=2.21.0,<3.0.0" urllib3 = "<2.0.0" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "alibabacloud-tea-openapi" version = "0.3.7" @@ -252,6 +302,11 @@ alibabacloud_openapi_util = ">=0.2.1,<1.0.0" alibabacloud_tea_util = ">=0.3.8,<1.0.0" alibabacloud_tea_xml = ">=0.0.2,<1.0.0" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "alibabacloud-tea-util" version = "0.3.11" @@ -265,6 +320,11 @@ files = [ [package.dependencies] alibabacloud-tea = ">=0.3.3" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "alibabacloud-tea-xml" version = "0.0.2" @@ -278,6 +338,11 @@ files = [ [package.dependencies] alibabacloud-tea = ">=0.0.1" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "aliyun-python-sdk-core" version = "2.13.36" @@ -292,6 +357,11 @@ files = [ cryptography = ">=2.6.0" jmespath = ">=0.9.3,<1.0.0" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "aliyun-python-sdk-core-v3" version = "2.13.33" @@ -306,6 +376,11 @@ files = [ cryptography = ">=2.6.0" jmespath = ">=0.9.3,<1.0.0" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "aliyun-python-sdk-ecs" version = "4.24.64" @@ -320,6 +395,11 @@ files = [ [package.dependencies] aliyun-python-sdk-core = ">=2.11.5" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "aliyun-python-sdk-kms" version = "2.16.1" @@ -334,6 +414,11 @@ files = [ [package.dependencies] aliyun-python-sdk-core = ">=2.11.5" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "amqp" version = "5.1.1" @@ -348,6 +433,11 @@ files = [ [package.dependencies] vine = ">=5.0.0" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "ansible" version = "7.1.0" @@ -362,6 +452,11 @@ files = [ [package.dependencies] ansible-core = ">=2.14.1,<2.15.0" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "ansible-core" version = "2.14.1" @@ -401,6 +496,11 @@ python-daemon = "*" pyyaml = "*" six = "*" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "anyio" version = "3.7.1" @@ -421,6 +521,11 @@ doc = ["Sphinx", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd- test = ["anyio[trio]", "coverage[toml] (>=4.5)", "hypothesis (>=4.0)", "mock (>=4)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"] trio = ["trio (<0.22)"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "appnope" version = "0.1.3" @@ -432,6 +537,11 @@ files = [ {file = "appnope-0.1.3.tar.gz", hash = "sha256:02bd91c4de869fbb1e1c50aafc4098827a7a54ab2f39d9dcba6c9547ed920e24"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "asgiref" version = "3.7.2" @@ -446,6 +556,11 @@ files = [ [package.extras] tests = ["mypy (>=0.800)", "pytest", "pytest-asyncio"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "asn1crypto" version = "1.5.1" @@ -457,6 +572,11 @@ files = [ {file = "asn1crypto-1.5.1.tar.gz", hash = "sha256:13ae38502be632115abf8a24cbe5f4da52e3b5231990aff31123c805306ccb9c"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "asttokens" version = "2.2.1" @@ -474,6 +594,11 @@ six = "*" [package.extras] test = ["astroid", "pytest"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "async-timeout" version = "4.0.2" @@ -485,6 +610,11 @@ files = [ {file = "async_timeout-4.0.2-py3-none-any.whl", hash = "sha256:8ca1e4fcf50d07413d66d1a5e416e42cfdf5851c981d679a09851a6853383b3c"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "attrs" version = "23.1.0" @@ -503,6 +633,11 @@ docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib- tests = ["attrs[tests-no-zope]", "zope-interface"] tests-no-zope = ["cloudpickle", "hypothesis", "mypy (>=1.1.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "autobahn" version = "23.6.2" @@ -531,6 +666,11 @@ twisted = ["attrs (>=20.3.0)", "twisted (>=20.3.0)", "zope.interface (>=5.2.0)"] ui = ["PyGObject (>=3.40.0)"] xbr = ["base58 (>=2.1.0)", "bitarray (>=2.7.5)", "cbor2 (>=5.2.0)", "click (>=8.1.2)", "ecdsa (>=0.16.1)", "eth-abi (>=4.0.0)", "hkdf (>=0.0.3)", "jinja2 (>=2.11.3)", "mnemonic (>=0.19)", "py-ecc (>=5.1.0)", "py-eth-sig-utils (>=0.4.0)", "py-multihash (>=2.0.1)", "rlp (>=2.0.1)", "spake2 (>=0.8)", "twisted (>=20.3.0)", "web3[ipfs] (>=6.0.0)", "xbr (>=21.2.1)", "yapf (==0.29.0)", "zlmdb (>=21.2.1)"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "automat" version = "22.10.0" @@ -549,6 +689,11 @@ six = "*" [package.extras] visualize = ["Twisted (>=16.1.1)", "graphviz (>0.5.1)"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "azure-common" version = "1.1.28" @@ -560,6 +705,11 @@ files = [ {file = "azure_common-1.1.28-py2.py3-none-any.whl", hash = "sha256:5c12d3dcf4ec20599ca6b0d3e09e86e146353d443e7fcc050c9a19c1f9df20ad"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "azure-core" version = "1.28.0" @@ -579,6 +729,11 @@ typing-extensions = ">=4.3.0" [package.extras] aio = ["aiohttp (>=3.0)"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "azure-identity" version = "1.13.0" @@ -597,6 +752,11 @@ msal = ">=1.20.0,<2.0.0" msal-extensions = ">=0.3.0,<2.0.0" six = ">=1.12.0" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "azure-mgmt-compute" version = "30.0.0" @@ -613,6 +773,11 @@ azure-common = ">=1.1,<2.0" azure-mgmt-core = ">=1.3.2,<2.0.0" isodate = ">=0.6.1,<1.0.0" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "azure-mgmt-core" version = "1.4.0" @@ -627,6 +792,11 @@ files = [ [package.dependencies] azure-core = ">=1.26.2,<2.0.0" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "azure-mgmt-network" version = "23.1.0" @@ -643,6 +813,11 @@ azure-common = ">=1.1,<2.0" azure-mgmt-core = ">=1.3.2,<2.0.0" isodate = ">=0.6.1,<1.0.0" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "azure-mgmt-subscription" version = "3.1.1" @@ -659,6 +834,11 @@ azure-common = ">=1.1,<2.0" azure-mgmt-core = ">=1.3.2,<2.0.0" msrest = ">=0.7.1" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "azure-storage-blob" version = "12.17.0" @@ -679,6 +859,11 @@ typing-extensions = ">=4.3.0" [package.extras] aio = ["azure-core[aio] (>=1.28.0,<2.0.0)"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "backcall" version = "0.2.0" @@ -690,6 +875,11 @@ files = [ {file = "backcall-0.2.0.tar.gz", hash = "sha256:5cbdbf27be5e7cfadb448baf0aa95508f91f2bbc6c6437cd9cd06e2a4c215e1e"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "bce-python-sdk" version = "0.8.87" @@ -706,6 +896,11 @@ future = ">=0.6.0" pycryptodome = ">=3.8.0" six = ">=1.4.0" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "bcrypt" version = "4.0.1" @@ -740,6 +935,11 @@ files = [ tests = ["pytest (>=3.2.1,!=3.3.0)"] typecheck = ["mypy"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "beautifulsoup4" version = "4.12.2" @@ -758,6 +958,11 @@ soupsieve = ">1.2" html5lib = ["html5lib"] lxml = ["lxml"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "billiard" version = "4.1.0" @@ -769,6 +974,11 @@ files = [ {file = "billiard-4.1.0.tar.gz", hash = "sha256:1ad2eeae8e28053d729ba3373d34d9d6e210f6e4d8bf0a9c64f92bd053f1edf5"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "boto" version = "2.49.0" @@ -780,6 +990,11 @@ files = [ {file = "boto-2.49.0.tar.gz", hash = "sha256:ea0d3b40a2d852767be77ca343b58a9e3a4b00d9db440efb8da74b4e58025e5a"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "boto3" version = "1.28.9" @@ -799,6 +1014,11 @@ s3transfer = ">=0.6.0,<0.7.0" [package.extras] crt = ["botocore[crt] (>=1.21.0,<2.0a0)"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "botocore" version = "1.31.9" @@ -818,6 +1038,11 @@ urllib3 = ">=1.25.4,<1.27" [package.extras] crt = ["awscrt (==0.16.26)"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "cachetools" version = "5.3.1" @@ -829,6 +1054,11 @@ files = [ {file = "cachetools-5.3.1.tar.gz", hash = "sha256:dce83f2d9b4e1f732a8cd44af8e8fab2dbe46201467fc98b3ef8f269092bf62b"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "celery" version = "5.3.1" @@ -884,6 +1114,11 @@ yaml = ["PyYAML (>=3.10)"] zookeeper = ["kazoo (>=1.3.1)"] zstd = ["zstandard (==0.21.0)"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "certifi" version = "2023.7.22" @@ -895,6 +1130,11 @@ files = [ {file = "certifi-2023.7.22.tar.gz", hash = "sha256:539cc1d13202e33ca466e88b2807e29f4c13049d6d87031a3c110744495cb082"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "cffi" version = "1.15.1" @@ -971,6 +1211,11 @@ files = [ [package.dependencies] pycparser = "*" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "channels" version = "4.0.0" @@ -990,6 +1235,11 @@ Django = ">=3.2" daphne = ["daphne (>=4.0.0)"] tests = ["async-timeout", "coverage (>=4.5,<5.0)", "pytest", "pytest-asyncio", "pytest-django"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "channels-redis" version = "4.1.0" @@ -1011,6 +1261,11 @@ redis = ">=4.5.3" cryptography = ["cryptography (>=1.3.0)"] tests = ["async-timeout", "cryptography (>=1.3.0)", "pytest", "pytest-asyncio", "pytest-timeout"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "chardet" version = "5.1.0" @@ -1022,6 +1277,11 @@ files = [ {file = "chardet-5.1.0.tar.gz", hash = "sha256:0d62712b956bc154f85fb0a266e2a3c5913c2967e00348701b32411d6def31e5"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "charset-normalizer" version = "3.2.0" @@ -1106,6 +1366,11 @@ files = [ {file = "charset_normalizer-3.2.0-py3-none-any.whl", hash = "sha256:8e098148dd37b4ce3baca71fb394c81dc5d9c7728c95df695d2dca218edf40e6"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "click" version = "8.1.6" @@ -1120,6 +1385,11 @@ files = [ [package.dependencies] colorama = {version = "*", markers = "platform_system == \"Windows\""} +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "click-didyoumean" version = "0.3.0" @@ -1134,6 +1404,11 @@ files = [ [package.dependencies] click = ">=7" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "click-plugins" version = "1.1.1" @@ -1151,6 +1426,11 @@ click = ">=4.0" [package.extras] dev = ["coveralls", "pytest (>=3.6)", "pytest-cov", "wheel"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "click-repl" version = "0.3.0" @@ -1169,6 +1449,11 @@ prompt-toolkit = ">=3.0.36" [package.extras] testing = ["pytest (>=7.2.1)", "pytest-cov (>=4.0.0)", "tox (>=4.4.3)"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "colorama" version = "0.4.6" @@ -1180,6 +1465,11 @@ files = [ {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "configparser" version = "6.0.0" @@ -1195,6 +1485,11 @@ files = [ docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] testing = ["pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-ruff", "types-backports"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "constantly" version = "15.1.0" @@ -1206,6 +1501,11 @@ files = [ {file = "constantly-15.1.0.tar.gz", hash = "sha256:586372eb92059873e29eba4f9dec8381541b4d3834660707faf8ba59146dfc35"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "coreapi" version = "2.3.3" @@ -1223,6 +1523,11 @@ itypes = "*" requests = "*" uritemplate = "*" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "coreschema" version = "0.0.4" @@ -1237,6 +1542,11 @@ files = [ [package.dependencies] jinja2 = "*" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "crcmod" version = "1.7" @@ -1247,6 +1557,11 @@ files = [ {file = "crcmod-1.7.tar.gz", hash = "sha256:dc7051a0db5f2bd48665a990d3ec1cc305a466a77358ca4492826f41f283601e"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "cron-descriptor" version = "1.4.0" @@ -1260,6 +1575,11 @@ files = [ [package.extras] dev = ["polib"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "cryptography" version = "41.0.2" @@ -1305,6 +1625,11 @@ ssh = ["bcrypt (>=3.1.5)"] test = ["pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] test-randomorder = ["pytest-randomly"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "cython" version = "3.0.0" @@ -1372,6 +1697,11 @@ files = [ {file = "Cython-3.0.0.tar.gz", hash = "sha256:350b18f9673e63101dbbfcf774ee2f57c20ac4636d255741d76ca79016b1bd82"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "daphne" version = "4.0.0" @@ -1391,6 +1721,11 @@ twisted = {version = ">=22.4", extras = ["tls"]} [package.extras] tests = ["django", "hypothesis", "pytest", "pytest-asyncio"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "data-tree" version = "0.0.1" @@ -1402,6 +1737,11 @@ files = [ {file = "data_tree-0.0.1.tar.gz", hash = "sha256:06f2a18b372cf2451166d426591f6e6fc73a7aabcad97255d50927aa3c3d5a0e"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "debtcollector" version = "2.5.0" @@ -1416,6 +1756,11 @@ files = [ [package.dependencies] wrapt = ">=1.7.0" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "decorator" version = "5.1.1" @@ -1427,6 +1772,11 @@ files = [ {file = "decorator-5.1.1.tar.gz", hash = "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "django" version = "4.1.10" @@ -1447,6 +1797,11 @@ tzdata = {version = "*", markers = "sys_platform == \"win32\""} argon2 = ["argon2-cffi (>=19.1.0)"] bcrypt = ["bcrypt"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "django-auth-ldap" version = "4.4.0" @@ -1462,6 +1817,11 @@ files = [ Django = ">=3.2" python-ldap = ">=3.1" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "django-bootstrap3" version = "23.4" @@ -1477,6 +1837,11 @@ files = [ beautifulsoup4 = ">=4.8.0" django = ">=3.2" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "django-cas-ng" version = "4.3.0" @@ -1514,6 +1879,11 @@ django-timezone-field = ">=5.0" python-crontab = ">=2.3.4" tzdata = "*" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "django-debug-toolbar" version = "4.1.0" @@ -1529,6 +1899,11 @@ files = [ django = ">=3.2.4" sqlparse = ">=0.2" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "django-filter" version = "23.2" @@ -1543,6 +1918,11 @@ files = [ [package.dependencies] Django = ">=3.2" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "django-formtools" version = "2.4.1" @@ -1557,6 +1937,11 @@ files = [ [package.dependencies] Django = ">=3.2" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "django-private-storage" version = "3.1" @@ -1568,6 +1953,11 @@ files = [ {file = "django_private_storage-3.1-py3-none-any.whl", hash = "sha256:cd11fa3c40e15bf902b3566dde8082c86f1cbb2900115f15c63e4b5278d96fe7"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "django-proxy" version = "1.2.2" @@ -1581,6 +1971,11 @@ files = [ [package.dependencies] requests = "*" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "django-radius" version = "1.4.0" @@ -1611,6 +2006,11 @@ files = [ [package.dependencies] django = "*" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "django-redis" version = "5.3.0" @@ -1629,6 +2029,11 @@ redis = ">=3,<4.0.0 || >4.0.0,<4.0.1 || >4.0.1" [package.extras] hiredis = ["redis[hiredis] (>=3,!=4.0.0,!=4.0.1)"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "django-rest-swagger" version = "2.2.0" @@ -1646,6 +2051,11 @@ djangorestframework = ">=3.5.4" openapi-codec = ">=1.3.1" simplejson = "*" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "django-simple-captcha" version = "0.5.18" @@ -1665,6 +2075,11 @@ Pillow = ">=6.2.0" [package.extras] test = ["testfixtures"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "django-simple-history" version = "3.3.0" @@ -1676,6 +2091,11 @@ files = [ {file = "django_simple_history-3.3.0-py3-none-any.whl", hash = "sha256:dc1f98e558a0a1e0b6371c3b8efb85f86e02a6db56e83d0ec198343b7408d00a"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "django-timezone-field" version = "5.1" @@ -1691,6 +2111,11 @@ files = [ Django = ">=2.2,<3.0.dev0 || >=3.2.dev0,<5.0" pytz = "*" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "djangorestframework" version = "3.14.0" @@ -1706,6 +2131,11 @@ files = [ django = ">=3.0" pytz = "*" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "djangorestframework-bulk" version = "0.2.1" @@ -1721,6 +2151,11 @@ django = "*" djangorestframework = "*" setuptools = "*" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "dnspython" version = "2.4.1" @@ -1740,6 +2175,11 @@ idna = ["idna (>=2.1,<4.0)"] trio = ["trio (>=0.14,<0.23)"] wmi = ["wmi (>=1.5.1,<2.0.0)"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "docutils" version = "0.20.1" @@ -1751,6 +2191,11 @@ files = [ {file = "docutils-0.20.1.tar.gz", hash = "sha256:f08a4e276c3a1583a86dce3e34aba3fe04d02bba2dd51ed16106244e8a923e3b"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "drf-nested-routers" version = "0.93.4" @@ -1766,6 +2211,11 @@ files = [ Django = ">=1.11" djangorestframework = ">=3.6.0" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "drf-writable-nested" version = "0.7.0" @@ -1776,6 +2226,11 @@ files = [ {file = "drf_writable_nested-0.7.0-py3-none-any.whl", hash = "sha256:154c0381e8a3a477e0fd539d5e1caf8ff4c1097a9c0c0fe741d4858b11b0455b"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "drf-yasg" version = "1.21.7" @@ -1800,6 +2255,11 @@ uritemplate = ">=3.0.0" coreapi = ["coreapi (>=2.3.3)", "coreschema (>=0.0.4)"] validation = ["swagger-spec-validator (>=2.1.0)"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "ecdsa" version = "0.18.0" @@ -1818,6 +2278,11 @@ six = ">=1.9.0" gmpy = ["gmpy"] gmpy2 = ["gmpy2"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "elastic-transport" version = "8.4.0" @@ -1836,6 +2301,11 @@ urllib3 = ">=1.26.2,<2" [package.extras] develop = ["aiohttp", "mock", "pytest", "pytest-asyncio", "pytest-cov", "pytest-httpserver", "pytest-mock", "requests", "trustme"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "elasticsearch" version = "8.8.2" @@ -1854,6 +2324,11 @@ elastic-transport = ">=8,<9" async = ["aiohttp (>=3,<4)"] requests = ["requests (>=2.4.0,<3.0.0)"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "enum-compat" version = "0.0.3" @@ -1865,6 +2340,11 @@ files = [ {file = "enum_compat-0.0.3-py3-none-any.whl", hash = "sha256:88091b617c7fc3bbbceae50db5958023c48dc40b50520005aa3bf27f8f7ea157"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "ephem" version = "4.1.4" @@ -1941,6 +2421,11 @@ files = [ {file = "ephem-4.1.4.tar.gz", hash = "sha256:73a59f0d2162d1624535c3c3b75f956556bdbb2055eaf554a7bef147d3f9c760"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "esdk-obs-python" version = "3.21.4" @@ -1951,6 +2436,11 @@ files = [ {file = "esdk-obs-python-3.21.4.tar.gz", hash = "sha256:a3b2a01b0a10768b5b02812abe239048feaae199256cbde67315870121d8ab1e"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "et-xmlfile" version = "1.1.0" @@ -1962,6 +2452,11 @@ files = [ {file = "et_xmlfile-1.1.0.tar.gz", hash = "sha256:8eb9e2bc2f8c97e37a2dc85a09ecdcdec9d8a396530a6d5a33b30b9a92da0c5c"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "eventlet" version = "0.33.3" @@ -1978,6 +2473,11 @@ dnspython = ">=1.15.0" greenlet = ">=0.3" six = ">=1.10.0" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "executing" version = "1.2.0" @@ -1992,6 +2492,11 @@ files = [ [package.extras] tests = ["asttokens", "littleutils", "pytest", "rich"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "flower" version = "2.0.0" @@ -2010,6 +2515,11 @@ prometheus-client = ">=0.8.0" pytz = "*" tornado = ">=5.0.0,<7.0.0" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "forgerypy3" version = "0.3.1" @@ -2020,6 +2530,11 @@ files = [ {file = "ForgeryPy3-0.3.1.tar.gz", hash = "sha256:03db26b2129252dc8c8c91aa5661171725a64707773c03c3ca0251b1dd173c93"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "frozenlist" version = "1.4.0" @@ -2090,6 +2605,11 @@ files = [ {file = "frozenlist-1.4.0.tar.gz", hash = "sha256:09163bdf0b2907454042edb19f887c6d33806adc71fbd54afc14908bfdc22251"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "future" version = "0.18.3" @@ -2100,6 +2620,11 @@ files = [ {file = "future-0.18.3.tar.gz", hash = "sha256:34a17436ed1e96697a86f9de3d15a3b0be01d8bc8de9c1dffd59fb8234ed5307"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "geoip2" version = "4.7.0" @@ -2116,6 +2641,11 @@ aiohttp = ">=3.6.2,<4.0.0" maxminddb = ">=2.3.0,<3.0.0" requests = ">=2.24.0,<3.0.0" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "gmssl" version = "3.2.2" @@ -2124,12 +2654,16 @@ optional = false python-versions = "*" files = [ {file = "gmssl-3.2.2-py3-none-any.whl", hash = "sha256:59f069a91eb19ef59b9e7be4d436ed01c92ce064d3d7d45a8778fc07fd2cd068"}, - {file = "gmssl-3.2.2.linux-x86_64.tar.gz", hash = "sha256:f3d8c8c75dd34cd169f129c017f67fdd80cce2c67a13f9a0e3b1c58f8de6351e"}, ] [package.dependencies] pycryptodomex = "*" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "google-api-core" version = "2.11.1" @@ -2160,6 +2694,11 @@ grpc = ["grpcio (>=1.33.2,<2.0dev)", "grpcio (>=1.49.1,<2.0dev)", "grpcio-status grpcgcp = ["grpcio-gcp (>=0.2.2,<1.0.dev0)"] grpcio-gcp = ["grpcio-gcp (>=0.2.2,<1.0.dev0)"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "google-auth" version = "2.22.0" @@ -2185,6 +2724,11 @@ pyopenssl = ["cryptography (>=38.0.3)", "pyopenssl (>=20.0.0)"] reauth = ["pyu2f (>=0.1.5)"] requests = ["requests (>=2.20.0,<3.0.0.dev0)"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "google-cloud-compute" version = "1.13.0" @@ -2201,6 +2745,11 @@ google-api-core = {version = ">=1.34.0,<2.0.dev0 || >=2.11.dev0,<3.0.0dev", extr proto-plus = {version = ">=1.22.2,<2.0.0dev", markers = "python_version >= \"3.11\""} protobuf = ">=3.19.5,<3.20.0 || >3.20.0,<3.20.1 || >3.20.1,<4.21.0 || >4.21.0,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<5.0.0dev" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "googleapis-common-protos" version = "1.60.0" @@ -2218,6 +2767,11 @@ protobuf = ">=3.19.5,<3.20.0 || >3.20.0,<3.20.1 || >3.20.1,<4.21.1 || >4.21.1,<4 [package.extras] grpc = ["grpcio (>=1.44.0,<2.0.0.dev0)"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "greenlet" version = "2.0.2" @@ -2291,6 +2845,11 @@ files = [ docs = ["Sphinx", "docutils (<0.18)"] test = ["objgraph", "psutil"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "grpcio" version = "1.56.2" @@ -2348,6 +2907,11 @@ files = [ [package.extras] protobuf = ["grpcio-tools (>=1.56.2)"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "grpcio-status" version = "1.56.2" @@ -2364,6 +2928,11 @@ googleapis-common-protos = ">=1.5.5" grpcio = ">=1.56.2" protobuf = ">=4.21.6" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "gunicorn" version = "21.2.0" @@ -2384,6 +2953,11 @@ gevent = ["gevent (>=1.4.0)"] setproctitle = ["setproctitle"] tornado = ["tornado (>=0.2)"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "h11" version = "0.14.0" @@ -2395,6 +2969,11 @@ files = [ {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "html2text" version = "2020.1.16" @@ -2406,6 +2985,11 @@ files = [ {file = "html2text-2020.1.16.tar.gz", hash = "sha256:e296318e16b059ddb97f7a8a1d6a5c1d7af4544049a01e261731d2d5cc277bbb"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "httpsig" version = "1.3.0" @@ -2421,6 +3005,11 @@ files = [ pycryptodome = ">=3,<4" six = "*" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "httptools" version = "0.6.0" @@ -2468,6 +3057,11 @@ files = [ [package.extras] test = ["Cython (>=0.29.24,<0.30.0)"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "humanize" version = "4.7.0" @@ -2482,6 +3076,11 @@ files = [ [package.extras] tests = ["freezegun", "pytest", "pytest-cov"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "hvac" version = "1.1.1" @@ -2497,6 +3096,11 @@ files = [ pyhcl = ">=0.4.4,<0.5.0" requests = ">=2.27.1,<3.0.0" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "hyperlink" version = "21.0.0" @@ -2511,6 +3115,11 @@ files = [ [package.dependencies] idna = ">=2.5" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "idna" version = "3.4" @@ -2522,6 +3131,11 @@ files = [ {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "incremental" version = "22.10.0" @@ -2537,6 +3151,11 @@ files = [ mypy = ["click (>=6.0)", "mypy (==0.812)", "twisted (>=16.4.0)"] scripts = ["click (>=6.0)", "twisted (>=16.4.0)"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "inflection" version = "0.5.1" @@ -2548,6 +3167,11 @@ files = [ {file = "inflection-0.5.1.tar.gz", hash = "sha256:1a29730d366e996aaacffb2f1f1cb9593dc38e2ddd30c91250c6dde09ea9b417"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "ipip-ipdb" version = "1.6.1" @@ -2558,6 +3182,11 @@ files = [ {file = "ipip-ipdb-1.6.1.tar.gz", hash = "sha256:4f396f8f8b1a2fc7fe3c41e1b05b479aac9aa1bc310b5b0182dbaa5376dc0bb9"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "ipy" version = "1.01" @@ -2568,6 +3197,11 @@ files = [ {file = "IPy-1.01.tar.gz", hash = "sha256:edeca741dea2d54aca568fa23740288c3fe86c0f3ea700344571e9ef14a7cc1a"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "ipython" version = "8.14.0" @@ -2606,6 +3240,11 @@ qtconsole = ["qtconsole"] test = ["pytest (<7.1)", "pytest-asyncio", "testpath"] test-extra = ["curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.21)", "pandas", "pytest (<7.1)", "pytest-asyncio", "testpath", "trio"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "iso8601" version = "2.0.0" @@ -2617,6 +3256,11 @@ files = [ {file = "iso8601-2.0.0.tar.gz", hash = "sha256:739960d37c74c77bd9bd546a76562ccb581fe3d4820ff5c3141eb49c839fda8f"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "isodate" version = "0.6.1" @@ -2631,6 +3275,11 @@ files = [ [package.dependencies] six = "*" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "itsdangerous" version = "1.1.0" @@ -2642,6 +3291,11 @@ files = [ {file = "itsdangerous-1.1.0.tar.gz", hash = "sha256:321b033d07f2a4136d3ec762eac9f16a10ccd60f53c0c91af90217ace7ba1f19"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "itypes" version = "1.2.0" @@ -2653,6 +3307,11 @@ files = [ {file = "itypes-1.2.0.tar.gz", hash = "sha256:af886f129dea4a2a1e3d36595a2d139589e4dd287f5cab0b40e799ee81570ff1"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "jedi" version = "0.19.0" @@ -2672,6 +3331,11 @@ docs = ["Jinja2 (==2.11.3)", "MarkupSafe (==1.1.1)", "Pygments (==2.8.1)", "alab qa = ["flake8 (==5.0.4)", "mypy (==0.971)", "types-setuptools (==67.2.0.1)"] testing = ["Django (<3.1)", "attrs", "colorama", "docopt", "pytest (<7.0.0)"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "jinja2" version = "3.1.2" @@ -2689,6 +3353,11 @@ MarkupSafe = ">=2.0" [package.extras] i18n = ["Babel (>=2.7)"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "jmespath" version = "0.10.0" @@ -2700,6 +3369,11 @@ files = [ {file = "jmespath-0.10.0.tar.gz", hash = "sha256:b85d0567b8666149a93172712e68920734333c0ce7e89b78b3e987f71e5ed4f9"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "jms-storage" version = "0.0.50" @@ -2729,6 +3403,11 @@ requests = "2.31.0" s3transfer = "0.6.1" six = "1.16.0" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "jsonfield2" version = "4.0.0.post0" @@ -2743,6 +3422,11 @@ files = [ [package.dependencies] Django = ">=2.2" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "keystoneauth1" version = "5.2.1" @@ -2768,6 +3452,11 @@ oauth1 = ["oauthlib (>=0.6.2)"] saml2 = ["lxml (>=4.2.0)"] test = ["PyYAML (>=3.12)", "bandit (>=1.1.0,<1.6.0)", "betamax (>=0.7.0)", "coverage (>=4.0,!=4.4)", "fixtures (>=3.0.0)", "flake8-docstrings (>=1.6.0,<1.7.0)", "flake8-import-order (>=0.17.1)", "hacking (>=4.1.0,<4.2.0)", "lxml (>=4.2.0)", "oauthlib (>=0.6.2)", "oslo.config (>=5.2.0)", "oslo.utils (>=3.33.0)", "oslotest (>=3.2.0)", "reno (>=3.1.0)", "requests-kerberos (>=0.8.0)", "requests-mock (>=1.2.0)", "stestr (>=1.0.0)", "testresources (>=2.0.0)", "testtools (>=2.2.0)"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "kombu" version = "5.3.1" @@ -2800,6 +3489,11 @@ sqs = ["boto3 (>=1.26.143)", "pycurl (>=7.43.0.5)", "urllib3 (>=1.26.16)"] yaml = ["PyYAML (>=3.10)"] zookeeper = ["kazoo (>=2.8.0)"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "kubernetes" version = "27.2.0" @@ -2826,6 +3520,11 @@ websocket-client = ">=0.32.0,<0.40.0 || >0.40.0,<0.41.dev0 || >=0.43.dev0" [package.extras] adal = ["adal (>=1.0.2)"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "ldap3" version = "2.9.1" @@ -2840,6 +3539,11 @@ files = [ [package.dependencies] pyasn1 = ">=0.4.6" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "lml" version = "0.1.0" @@ -2851,6 +3555,11 @@ files = [ {file = "lml-0.1.0.tar.gz", hash = "sha256:57a085a29bb7991d70d41c6c3144c560a8e35b4c1030ffb36d85fa058773bcc5"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "lockfile" version = "0.12.2" @@ -2862,6 +3571,11 @@ files = [ {file = "lockfile-0.12.2.tar.gz", hash = "sha256:6aed02de03cba24efabcd600b30540140634fc06cfa603822d508d5361e9f799"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "lxml" version = "4.9.3" @@ -2969,6 +3683,11 @@ html5 = ["html5lib"] htmlsoup = ["BeautifulSoup4"] source = ["Cython (>=0.29.35)"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "markupsafe" version = "2.1.3" @@ -3028,6 +3747,11 @@ files = [ {file = "MarkupSafe-2.1.3.tar.gz", hash = "sha256:af598ed32d6ae86f1b747b82783958b1a4ab8f617b06fe68795c7f026abbdcad"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "matplotlib-inline" version = "0.1.6" @@ -3042,6 +3766,11 @@ files = [ [package.dependencies] traitlets = "*" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "maxminddb" version = "2.4.0" @@ -3052,6 +3781,11 @@ files = [ {file = "maxminddb-2.4.0.tar.gz", hash = "sha256:81e54e53408bd502650e5969ccba16780af659ec1db1c44b2c997e4330a5ed96"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "msal" version = "1.23.0" @@ -3071,6 +3805,11 @@ requests = ">=2.0.0,<3" [package.extras] broker = ["pymsalruntime (>=0.13.2,<0.14)"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "msal-extensions" version = "1.0.0" @@ -3089,6 +3828,11 @@ portalocker = [ {version = ">=1.6,<3", markers = "python_version >= \"3.5\" and platform_system == \"Windows\""}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "msgpack" version = "1.0.5" @@ -3161,6 +3905,11 @@ files = [ {file = "msgpack-1.0.5.tar.gz", hash = "sha256:c075544284eadc5cddc70f4757331d99dcbc16b2bbd4849d15f8aae4cf36d31c"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "msrest" version = "0.7.1" @@ -3182,6 +3931,11 @@ requests-oauthlib = ">=0.5.0" [package.extras] async = ["aiodns", "aiohttp (>=3.0)"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "msrestazure" version = "0.6.4" @@ -3198,6 +3952,11 @@ adal = ">=0.6.0,<2.0.0" msrest = ">=0.6.0,<2.0.0" six = "*" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "multidict" version = "6.0.4" @@ -3281,6 +4040,11 @@ files = [ {file = "multidict-6.0.4.tar.gz", hash = "sha256:3666906492efb76453c0e7b97f2cf459b0682e7402c0489a95484965dbc1da49"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "mysqlclient" version = "2.2.0" @@ -3297,6 +4061,11 @@ files = [ {file = "mysqlclient-2.2.0.tar.gz", hash = "sha256:04368445f9c487d8abb7a878e3d23e923e6072c04a6c320f9e0dc8a82efba14e"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "netaddr" version = "0.8.0" @@ -3308,6 +4077,11 @@ files = [ {file = "netaddr-0.8.0.tar.gz", hash = "sha256:d6cc57c7a07b1d9d2e917aa8b36ae8ce61c35ba3fcd1b83ca31c5a0ee2b5a243"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "netifaces" version = "0.11.0" @@ -3347,6 +4121,11 @@ files = [ {file = "netifaces-0.11.0.tar.gz", hash = "sha256:043a79146eb2907edf439899f262b3dfe41717d34124298ed281139a8b93ca32"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "oauthlib" version = "3.2.2" @@ -3363,6 +4142,11 @@ rsa = ["cryptography (>=3.0.0)"] signals = ["blinker (>=1.4.0)"] signedtoken = ["cryptography (>=3.0.0)", "pyjwt (>=2.0.0,<3)"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "olefile" version = "0.46" @@ -3373,6 +4157,11 @@ files = [ {file = "olefile-0.46.zip", hash = "sha256:133b031eaf8fd2c9399b78b8bc5b8fcbe4c31e85295749bb17a87cba8f3c3964"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "openapi-codec" version = "1.3.2" @@ -3386,6 +4175,11 @@ files = [ [package.dependencies] coreapi = ">=2.2.0" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "openpyxl" version = "3.0.10" @@ -3400,6 +4194,11 @@ files = [ [package.dependencies] et-xmlfile = "*" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "oracledb" version = "1.3.2" @@ -3440,6 +4239,11 @@ files = [ [package.dependencies] cryptography = ">=3.2.1" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "os-service-types" version = "1.7.0" @@ -3454,6 +4258,11 @@ files = [ [package.dependencies] pbr = ">=2.0.0,<2.1.0 || >2.1.0" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "oslo-config" version = "9.1.1" @@ -3478,6 +4287,11 @@ stevedore = ">=1.20.0" rst-generator = ["rst2txt (>=1.1.0)", "sphinx (>=1.8.0,!=2.1.0)"] test = ["bandit (>=1.6.0,<1.7.0)", "coverage (>=4.0,!=4.4)", "fixtures (>=3.0.0)", "hacking (>=3.0.1,<3.1.0)", "mypy (>=0.720)", "oslo.log (>=3.36.0)", "oslotest (>=3.2.0)", "pre-commit (>=2.6.0)", "requests-mock (>=1.5.0)", "stestr (>=2.1.0)", "testscenarios (>=0.4)", "testtools (>=2.2.0)"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "oslo-i18n" version = "6.0.0" @@ -3492,6 +4306,11 @@ files = [ [package.dependencies] pbr = ">=2.0.0,<2.1.0 || >2.1.0" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "oslo-serialization" version = "5.1.1" @@ -3509,6 +4328,11 @@ msgpack = ">=0.5.2" pbr = ">=2.0.0,<2.1.0 || >2.1.0" pytz = ">=2013.6" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "oslo-utils" version = "6.2.0" @@ -3531,6 +4355,11 @@ pyparsing = ">=2.1.0" pytz = ">=2013.6" tzdata = ">=2022.4" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "oss2" version = "2.18.1" @@ -3549,6 +4378,11 @@ pycryptodome = ">=3.4.7" requests = "!=2.9.0" six = "*" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "packaging" version = "23.1" @@ -3560,6 +4394,11 @@ files = [ {file = "packaging-23.1.tar.gz", hash = "sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "paramiko" version = "3.2.0" @@ -3581,6 +4420,11 @@ all = ["gssapi (>=1.4.1)", "invoke (>=2.0)", "pyasn1 (>=0.1.7)", "pywin32 (>=2.1 gssapi = ["gssapi (>=1.4.1)", "pyasn1 (>=0.1.7)", "pywin32 (>=2.1.8)"] invoke = ["invoke (>=2.0)"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "parso" version = "0.8.3" @@ -3596,6 +4440,11 @@ files = [ qa = ["flake8 (==3.8.3)", "mypy (==0.782)"] testing = ["docopt", "pytest (<6.0.0)"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "passlib" version = "1.7.4" @@ -3613,6 +4462,11 @@ bcrypt = ["bcrypt (>=3.1.0)"] build-docs = ["cloud-sptheme (>=1.10.1)", "sphinx (>=1.6)", "sphinxcontrib-fulltoc (>=1.2.0)"] totp = ["cryptography"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "pbr" version = "5.11.1" @@ -3624,6 +4478,11 @@ files = [ {file = "pbr-5.11.1.tar.gz", hash = "sha256:aefc51675b0b533d56bb5fd1c8c6c0522fe31896679882e1c4c63d5e4a0fccb3"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "pexpect" version = "4.8.0" @@ -3638,6 +4497,11 @@ files = [ [package.dependencies] ptyprocess = ">=0.5" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "phonenumbers" version = "8.13.17" @@ -3649,6 +4513,11 @@ files = [ {file = "phonenumbers-8.13.17.tar.gz", hash = "sha256:89671217c706cbaa3ced101deefafa779836feac3e059434d886ac31f09f32c0"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "pickleshare" version = "0.7.5" @@ -3660,6 +4529,11 @@ files = [ {file = "pickleshare-0.7.5.tar.gz", hash = "sha256:87683d47965c1da65cdacaf31c8441d12b8044cdec9aca500cd78fc2c683afca"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "pillow" version = "10.0.0" @@ -3729,6 +4603,11 @@ files = [ docs = ["furo", "olefile", "sphinx (>=2.4)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinx-removed-in", "sphinxext-opengraph"] tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "portalocker" version = "2.7.0" @@ -3748,6 +4627,11 @@ docs = ["sphinx (>=1.7.1)"] redis = ["redis"] tests = ["pytest (>=5.4.1)", "pytest-cov (>=2.8.1)", "pytest-mypy (>=0.8.0)", "pytest-timeout (>=2.1.0)", "redis", "sphinx (>=6.0.0)"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "prettytable" version = "3.8.0" @@ -3765,6 +4649,11 @@ wcwidth = "*" [package.extras] tests = ["pytest", "pytest-cov", "pytest-lazy-fixture"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "prometheus-client" version = "0.17.1" @@ -3779,6 +4668,11 @@ files = [ [package.extras] twisted = ["twisted"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "prompt-toolkit" version = "3.0.39" @@ -3793,6 +4687,11 @@ files = [ [package.dependencies] wcwidth = "*" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "proto-plus" version = "1.22.3" @@ -3810,6 +4709,11 @@ protobuf = ">=3.19.0,<5.0.0dev" [package.extras] testing = ["google-api-core[grpc] (>=1.31.5)"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "protobuf" version = "4.23.4" @@ -3832,6 +4736,11 @@ files = [ {file = "protobuf-4.23.4.tar.gz", hash = "sha256:ccd9430c0719dce806b93f89c91de7977304729e55377f872a92465d548329a9"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "psutil" version = "5.9.5" @@ -3858,6 +4767,11 @@ files = [ [package.extras] test = ["enum34", "ipaddress", "mock", "pywin32", "wmi"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "psycopg2" version = "2.9.6" @@ -3880,6 +4794,11 @@ files = [ {file = "psycopg2-2.9.6.tar.gz", hash = "sha256:f15158418fd826831b28585e2ab48ed8df2d0d98f502a2b4fe619e7d5ca29011"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "psycopg2-binary" version = "2.9.6" @@ -3951,6 +4870,11 @@ files = [ {file = "psycopg2_binary-2.9.6-cp39-cp39-win_amd64.whl", hash = "sha256:f6a88f384335bb27812293fdb11ac6aee2ca3f51d3c7820fe03de0a304ab6249"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "ptyprocess" version = "0.7.0" @@ -3962,6 +4886,11 @@ files = [ {file = "ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "pure-eval" version = "0.2.2" @@ -3976,6 +4905,11 @@ files = [ [package.extras] tests = ["pytest"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "pyasn1" version = "0.5.0" @@ -3987,6 +4921,11 @@ files = [ {file = "pyasn1-0.5.0.tar.gz", hash = "sha256:97b7290ca68e62a832558ec3976f15cbf911bf5d7c7039d8b861c2a0ece69fde"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "pyasn1-modules" version = "0.3.0" @@ -4001,6 +4940,11 @@ files = [ [package.dependencies] pyasn1 = ">=0.4.6,<0.6.0" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "pycparser" version = "2.21" @@ -4012,6 +4956,11 @@ files = [ {file = "pycparser-2.21.tar.gz", hash = "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "pycryptodome" version = "3.18.0" @@ -4053,6 +5002,11 @@ files = [ {file = "pycryptodome-3.18.0.tar.gz", hash = "sha256:c9adee653fc882d98956e33ca2c1fb582e23a8af7ac82fee75bd6113c55a0413"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "pycryptodomex" version = "3.18.0" @@ -4094,6 +5048,11 @@ files = [ {file = "pycryptodomex-3.18.0.tar.gz", hash = "sha256:3e3ecb5fe979e7c1bb0027e518340acf7ee60415d79295e5251d13c68dde576e"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "pyexcel" version = "0.7.0" @@ -4116,6 +5075,11 @@ ods = ["pyexcel-ods3 (>=0.6.0)"] xls = ["pyexcel-xls (>=0.6.0)"] xlsx = ["pyexcel-xlsx (>=0.6.0)"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "pyexcel-io" version = "0.6.6" @@ -4135,6 +5099,11 @@ ods = ["pyexcel-ods3 (>=0.6.0)"] xls = ["pyexcel-xls (>=0.6.0)"] xlsx = ["pyexcel-xlsx (>=0.6.0)"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "pyexcel-xlsx" version = "0.6.0" @@ -4150,6 +5119,11 @@ files = [ openpyxl = ">=2.6.1" pyexcel-io = ">=0.6.2" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "pyfreerdp" version = "0.0.1" @@ -4191,6 +5165,11 @@ files = [ {file = "pyfreerdp-0.0.1.tar.gz", hash = "sha256:946eca882741e6802794185cbdd47b49626c3181bce99dbd27c5746563c13d43"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "pygments" version = "2.15.1" @@ -4205,6 +5184,11 @@ files = [ [package.extras] plugins = ["importlib-metadata"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "pyhcl" version = "0.4.4" @@ -4215,6 +5199,11 @@ files = [ {file = "pyhcl-0.4.4.tar.gz", hash = "sha256:2d9b9dcdf1023d812bfed561ba72c99104c5b3f52e558d595130a44ce081b003"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "pyjwkest" version = "1.4.2" @@ -4231,6 +5220,11 @@ pycryptodomex = "*" requests = "*" six = "*" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "pyjwt" version = "2.8.0" @@ -4251,6 +5245,11 @@ dev = ["coverage[toml] (==5.0.4)", "cryptography (>=3.4.0)", "pre-commit", "pyte docs = ["sphinx (>=4.5.0,<5.0.0)", "sphinx-rtd-theme", "zope.interface"] tests = ["coverage[toml] (==5.0.4)", "pytest (>=6.0.0,<7.0.0)"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "pymongo" version = "4.4.1" @@ -4345,6 +5344,11 @@ ocsp = ["certifi", "pyopenssl (>=17.2.0)", "requests (<3.0.0)", "service-identit snappy = ["python-snappy"] zstd = ["zstandard"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "pympler" version = "1.0.1" @@ -4356,6 +5360,11 @@ files = [ {file = "Pympler-1.0.1.tar.gz", hash = "sha256:993f1a3599ca3f4fcd7160c7545ad06310c9e12f70174ae7ae8d4e25f6c5d3fa"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "pymssql" version = "2.2.7" @@ -4426,6 +5435,11 @@ files = [ {file = "pymssql-2.2.7.tar.gz", hash = "sha256:ff95b910532ec7b02e4322231c117d3d6af0abab667e6fbf15442db873943045"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "pymysql" version = "1.1.0" @@ -4441,6 +5455,11 @@ files = [ ed25519 = ["PyNaCl (>=1.4.0)"] rsa = ["cryptography"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "pynacl" version = "1.5.0" @@ -4467,6 +5486,11 @@ cffi = ">=1.4.1" docs = ["sphinx (>=1.6.5)", "sphinx-rtd-theme"] tests = ["hypothesis (>=3.27.0)", "pytest (>=3.2.1,!=3.3.0)"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "pyopenssl" version = "23.2.0" @@ -4485,6 +5509,11 @@ cryptography = ">=38.0.0,<40.0.0 || >40.0.0,<40.0.1 || >40.0.1,<42" docs = ["sphinx (!=5.2.0,!=5.2.0.post0)", "sphinx-rtd-theme"] test = ["flaky", "pretend", "pytest (>=3.0.1)"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "pyotp" version = "2.8.0" @@ -4496,6 +5525,11 @@ files = [ {file = "pyotp-2.8.0.tar.gz", hash = "sha256:c2f5e17d9da92d8ec1f7de6331ab08116b9115adbabcba6e208d46fc49a98c5a"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "pyparsing" version = "3.1.1" @@ -4510,6 +5544,11 @@ files = [ [package.extras] diagrams = ["jinja2", "railroad-diagrams"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "pyrad" version = "2.4" @@ -4525,6 +5564,11 @@ files = [ netaddr = "*" six = "*" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "pyspnego" version = "0.9.1" @@ -4553,6 +5597,11 @@ cryptography = "*" kerberos = ["gssapi (>=1.6.0)", "krb5 (>=0.3.0)"] yaml = ["ruamel.yaml"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "python-cas" version = "1.6.0" @@ -4569,6 +5618,11 @@ lxml = ">=3.4" requests = ">=2.11.1" six = ">=1.10.0" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "python-crontab" version = "3.0.0" @@ -4587,6 +5641,11 @@ python-dateutil = "*" cron-description = ["cron-descriptor"] cron-schedule = ["croniter"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "python-daemon" version = "3.0.1" @@ -4607,6 +5666,11 @@ setuptools = ">=62.4.0" devel = ["coverage", "docutils", "isort", "testscenarios (>=0.4)", "testtools", "twine"] test = ["coverage", "docutils", "testscenarios (>=0.4)", "testtools"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "python-dateutil" version = "2.8.2" @@ -4621,6 +5685,11 @@ files = [ [package.dependencies] six = ">=1.5" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "python-dotenv" version = "1.0.0" @@ -4635,6 +5704,11 @@ files = [ [package.extras] cli = ["click (>=5.0)"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "python-keystoneclient" version = "5.1.0" @@ -4659,6 +5733,11 @@ requests = ">=2.14.2" six = ">=1.10.0" stevedore = ">=1.20.0" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "python-ldap" version = "3.4.3" @@ -4673,6 +5752,11 @@ files = [ pyasn1 = ">=0.3.7" pyasn1_modules = ">=0.1.5" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "python-nmap" version = "0.7.1" @@ -4683,6 +5767,11 @@ files = [ {file = "python-nmap-0.7.1.tar.gz", hash = "sha256:f75af6b91dd8e3b0c31f869db32163f62ada686945e5b7c25f84bc0f7fad3b64"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "python-novaclient" version = "18.3.0" @@ -4704,6 +5793,11 @@ pbr = ">=2.0.0,<2.1.0 || >2.1.0" PrettyTable = ">=0.7.2" stevedore = ">=2.0.1" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "python-redis-lock" version = "4.0.0" @@ -4721,6 +5815,11 @@ redis = ">=2.10.0" [package.extras] django = ["django-redis (>=3.8.0)"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "python3-saml" version = "1.15.0" @@ -4741,6 +5840,11 @@ xmlsec = ">=1.3.9" [package.extras] test = ["coverage (>=4.5.2)", "flake8 (>=3.6.0,<=5.0.0)", "freezegun (>=0.3.11,<=1.1.0)", "pytest (>=4.6)"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "pytz" version = "2023.3" @@ -4752,6 +5856,11 @@ files = [ {file = "pytz-2023.3.tar.gz", hash = "sha256:1d8ce29db189191fb55338ee6d0387d82ab59f3d00eac103412d64e0ebd0c588"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "pyvmomi" version = "8.0.1.0.2" @@ -4768,6 +5877,11 @@ six = ">=1.7.3" [package.extras] sso = ["lxml", "pyOpenSSL", "pywin32"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "pywin32" version = "306" @@ -4791,6 +5905,11 @@ files = [ {file = "pywin32-306-cp39-cp39-win_amd64.whl", hash = "sha256:39b61c15272833b5c329a2989999dcae836b1eed650252ab1b7bfbe1d59f30f4"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "pywinrm" version = "0.4.3" @@ -4812,6 +5931,11 @@ xmltodict = "*" credssp = ["requests-credssp (>=1.0.0)"] kerberos = ["pykerberos (>=1.2.1,<2.0.0)", "winkerberos (>=0.5.0)"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "pyyaml" version = "6.0.1" @@ -4861,6 +5985,11 @@ files = [ {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "pyzipper" version = "0.3.6" @@ -4875,6 +6004,11 @@ files = [ [package.dependencies] pycryptodomex = "*" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "qingcloud-sdk" version = "1.2.15" @@ -4889,6 +6023,11 @@ files = [ [package.dependencies] future = "*" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "redis" version = "4.6.0" @@ -4907,6 +6046,11 @@ async-timeout = {version = ">=4.0.2", markers = "python_full_version <= \"3.11.2 hiredis = ["hiredis (>=1.0.0)"] ocsp = ["cryptography (>=36.0.1)", "pyopenssl (==20.0.1)", "requests (>=2.26.0)"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "requests" version = "2.31.0" @@ -4928,6 +6072,11 @@ urllib3 = ">=1.21.1,<3" socks = ["PySocks (>=1.5.6,!=1.5.7)"] use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "requests-ntlm" version = "1.2.0" @@ -4944,6 +6093,11 @@ cryptography = ">=1.3" pyspnego = ">=0.1.6" requests = ">=2.0.0" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "requests-oauthlib" version = "1.3.1" @@ -4962,6 +6116,11 @@ requests = ">=2.0.0" [package.extras] rsa = ["oauthlib[signedtoken] (>=3.0.0)"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "resolvelib" version = "0.8.1" @@ -4979,6 +6138,11 @@ lint = ["black", "flake8", "isort", "mypy", "types-requests"] release = ["build", "towncrier", "twine"] test = ["commentjson", "packaging", "pytest"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "rest-condition" version = "1.0.3" @@ -4993,6 +6157,11 @@ files = [ django = ">=1.3" djangorestframework = "*" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "rfc3986" version = "2.0.0" @@ -5007,6 +6176,11 @@ files = [ [package.extras] idna2008 = ["idna"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "rsa" version = "4.9" @@ -5021,6 +6195,11 @@ files = [ [package.dependencies] pyasn1 = ">=0.1.3" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "s3transfer" version = "0.6.1" @@ -5038,6 +6217,11 @@ botocore = ">=1.12.36,<2.0a.0" [package.extras] crt = ["botocore[crt] (>=1.20.29,<2.0a.0)"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "service-identity" version = "23.1.0" @@ -5062,6 +6246,11 @@ idna = ["idna"] mypy = ["idna", "mypy", "types-pyopenssl"] tests = ["coverage[toml] (>=5.0.2)", "pytest"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "setuptools" version = "68.0.0" @@ -5078,6 +6267,11 @@ docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "pygments-g testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "simplejson" version = "3.19.1" @@ -5172,6 +6366,11 @@ files = [ {file = "simplejson-3.19.1.tar.gz", hash = "sha256:6277f60848a7d8319d27d2be767a7546bc965535b28070e310b3a9af90604a4c"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "six" version = "1.16.0" @@ -5183,6 +6382,11 @@ files = [ {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "sniffio" version = "1.3.0" @@ -5194,6 +6398,11 @@ files = [ {file = "sniffio-1.3.0.tar.gz", hash = "sha256:e60305c5e5d314f5389259b7f22aaa33d8f7dee49763119234af3755c55b9101"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "soupsieve" version = "2.4.1" @@ -5205,6 +6414,11 @@ files = [ {file = "soupsieve-2.4.1.tar.gz", hash = "sha256:89d12b2d5dfcd2c9e8c22326da9d9aa9cb3dfab0a83a024f05704076ee8d35ea"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "sqlparse" version = "0.4.4" @@ -5221,6 +6435,11 @@ dev = ["build", "flake8"] doc = ["sphinx"] test = ["pytest", "pytest-cov"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "sshpubkeys" version = "3.3.1" @@ -5239,6 +6458,11 @@ ecdsa = ">=0.13" [package.extras] dev = ["twine", "wheel", "yapf"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "sshtunnel" version = "0.4.0" @@ -5258,6 +6482,11 @@ build-sphinx = ["sphinx", "sphinxcontrib-napoleon"] dev = ["check-manifest"] test = ["tox (>=1.8.1)"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "stack-data" version = "0.6.2" @@ -5277,6 +6506,11 @@ pure-eval = "*" [package.extras] tests = ["cython", "littleutils", "pygments", "pytest", "typeguard"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "stevedore" version = "5.1.0" @@ -5291,6 +6525,11 @@ files = [ [package.dependencies] pbr = ">=2.0.0,<2.1.0 || >2.1.0" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "tencentcloud-sdk-python" version = "3.0.941" @@ -5305,6 +6544,11 @@ files = [ [package.dependencies] requests = ">=2.16.0" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "termcolor" version = "2.3.0" @@ -5319,6 +6563,11 @@ files = [ [package.extras] tests = ["pytest", "pytest-cov"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "texttable" version = "1.6.7" @@ -5330,6 +6579,11 @@ files = [ {file = "texttable-1.6.7.tar.gz", hash = "sha256:290348fb67f7746931bcdfd55ac7584ecd4e5b0846ab164333f0794b121760f2"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "tornado" version = "6.3.2" @@ -5350,6 +6604,11 @@ files = [ {file = "tornado-6.3.2.tar.gz", hash = "sha256:4b927c4f19b71e627b13f3db2324e4ae660527143f9e1f2e2fb404f3a187e2ba"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "traitlets" version = "5.9.0" @@ -5365,6 +6624,11 @@ files = [ docs = ["myst-parser", "pydata-sphinx-theme", "sphinx"] test = ["argcomplete (>=2.0)", "pre-commit", "pytest", "pytest-mock"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "treelib" version = "1.6.4" @@ -5379,6 +6643,11 @@ files = [ [package.dependencies] six = "*" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "twisted" version = "22.10.0" @@ -5420,6 +6689,11 @@ test = ["PyHamcrest (>=1.9.0)", "cython-test-exception-raiser (>=1.0.2,<2)", "hy tls = ["idna (>=2.4)", "pyopenssl (>=21.0.0)", "service-identity (>=18.1.0)"] windows-platform = ["PyHamcrest (>=1.9.0)", "appdirs (>=1.4.0)", "bcrypt (>=3.0.0)", "contextvars (>=2.4,<3)", "cryptography (>=2.6)", "cython-test-exception-raiser (>=1.0.2,<2)", "h2 (>=3.0,<5.0)", "hypothesis (>=6.0,<7.0)", "idna (>=2.4)", "priority (>=1.1.0,<2.0)", "pyasn1", "pyopenssl (>=21.0.0)", "pyserial (>=3.0)", "pywin32 (!=226)", "pywin32 (!=226)", "service-identity (>=18.1.0)"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "twisted-iocpsupport" version = "1.0.3" @@ -5445,6 +6719,11 @@ files = [ {file = "twisted_iocpsupport-1.0.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:3f39c41c0213a81a9ce0961e30d0d7650f371ad80f8d261007d15a2deb6d5be3"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "txaio" version = "23.1.1" @@ -5461,6 +6740,11 @@ all = ["twisted (>=20.3.0)", "zope.interface (>=5.2.0)"] dev = ["pep8 (>=1.6.2)", "pyenchant (>=1.6.6)", "pytest (>=2.6.4)", "pytest-cov (>=1.8.1)", "sphinx (>=1.2.3)", "sphinx-rtd-theme (>=0.1.9)", "sphinxcontrib-spelling (>=2.1.2)", "tox (>=2.1.1)", "tox-gh-actions (>=2.2.0)", "twine (>=1.6.5)", "wheel"] twisted = ["twisted (>=20.3.0)", "zope.interface (>=5.2.0)"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "typing-extensions" version = "4.7.1" @@ -5472,6 +6756,11 @@ files = [ {file = "typing_extensions-4.7.1.tar.gz", hash = "sha256:b75ddc264f0ba5615db7ba217daeb99701ad295353c45f9e95963337ceeeffb2"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "tzdata" version = "2023.3" @@ -5483,6 +6772,11 @@ files = [ {file = "tzdata-2023.3.tar.gz", hash = "sha256:11ef1e08e54acb0d4f95bdb1be05da659673de4acbd21bf9c69e94cc5e907a3a"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "ucloud-sdk-python3" version = "0.11.50" @@ -5503,6 +6797,11 @@ dev = ["black", "flake8 (>=3.6.0)", "pytest (>=4.6)", "pytest-cov", "requests", doc = ["requests", "sphinx"] test = ["flake8 (>=3.6.0)", "pytest (>=4.6)", "pytest-cov", "requests", "requests-mock"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "unicodecsv" version = "0.14.1" @@ -5513,6 +6812,11 @@ files = [ {file = "unicodecsv-0.14.1.tar.gz", hash = "sha256:018c08037d48649a0412063ff4eda26eaa81eff1546dbffa51fa5293276ff7fc"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "uritemplate" version = "4.1.1" @@ -5524,6 +6828,11 @@ files = [ {file = "uritemplate-4.1.1.tar.gz", hash = "sha256:4346edfc5c3b79f694bccd6d6099a322bbeb628dbf2cd86eea55a456ce5124f0"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "urllib3" version = "1.26.16" @@ -5540,6 +6849,11 @@ brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)", "brotlipy (>=0.6.0)"] secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "ipaddress", "pyOpenSSL (>=0.14)", "urllib3-secure-extra"] socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "uvicorn" version = "0.22.0" @@ -5565,6 +6879,11 @@ websockets = {version = ">=10.4", optional = true, markers = "extra == \"standar [package.extras] standard = ["colorama (>=0.4)", "httptools (>=0.5.0)", "python-dotenv (>=0.13)", "pyyaml (>=5.1)", "uvloop (>=0.14.0,!=0.15.0,!=0.15.1)", "watchfiles (>=0.13)", "websockets (>=10.4)"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "uvloop" version = "0.17.0" @@ -5609,6 +6928,11 @@ dev = ["Cython (>=0.29.32,<0.30.0)", "Sphinx (>=4.1.2,<4.2.0)", "aiohttp", "flak docs = ["Sphinx (>=4.1.2,<4.2.0)", "sphinx-rtd-theme (>=0.5.2,<0.6.0)", "sphinxcontrib-asyncio (>=0.3.0,<0.4.0)"] test = ["Cython (>=0.29.32,<0.30.0)", "aiohttp", "flake8 (>=3.9.2,<3.10.0)", "mypy (>=0.800)", "psutil", "pyOpenSSL (>=22.0.0,<22.1.0)", "pycodestyle (>=2.7.0,<2.8.0)"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "vine" version = "5.0.0" @@ -5620,6 +6944,11 @@ files = [ {file = "vine-5.0.0.tar.gz", hash = "sha256:7d3b1624a953da82ef63462013bbd271d3eb75751489f9807598e8f340bd637e"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "watchfiles" version = "0.19.0" @@ -5654,6 +6983,11 @@ files = [ [package.dependencies] anyio = ">=3.0.0" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "wcwidth" version = "0.2.6" @@ -5665,6 +6999,11 @@ files = [ {file = "wcwidth-0.2.6.tar.gz", hash = "sha256:a5220780a404dbe3353789870978e472cfe477761f06ee55077256e509b156d0"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "websocket-client" version = "1.6.1" @@ -5681,6 +7020,11 @@ docs = ["Sphinx (>=3.4)", "sphinx-rtd-theme (>=0.5)"] optional = ["python-socks", "wsaccel"] test = ["websockets"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "websockets" version = "11.0.3" @@ -5760,6 +7104,11 @@ files = [ {file = "websockets-11.0.3.tar.gz", hash = "sha256:88fc51d9a26b10fc331be344f1781224a375b78488fc343620184e95a4b27016"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "werkzeug" version = "2.3.6" @@ -5777,6 +7126,11 @@ MarkupSafe = ">=2.1.1" [package.extras] watchdog = ["watchdog (>=2.3)"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "wrapt" version = "1.15.0" @@ -5861,6 +7215,11 @@ files = [ {file = "wrapt-1.15.0.tar.gz", hash = "sha256:d06730c6aed78cee4126234cf2d071e01b44b915e725a6cb439a879ec9754a3a"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "xmlsec" version = "1.3.13" @@ -5886,6 +7245,11 @@ files = [ [package.dependencies] lxml = ">=3.8" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "xmltodict" version = "0.13.0" @@ -5897,6 +7261,11 @@ files = [ {file = "xmltodict-0.13.0.tar.gz", hash = "sha256:341595a488e3e01a85a9d8911d8912fd922ede5fecc4dce437eb4b6c8d037e56"}, ] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "yarl" version = "1.9.2" @@ -5984,6 +7353,11 @@ files = [ idna = ">=2.0" multidict = ">=4.0" +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "zope-interface" version = "6.0" @@ -6031,7 +7405,12 @@ docs = ["Sphinx", "repoze.sphinx.autointerface"] test = ["coverage (>=5.0.3)", "zope.event", "zope.testing"] testing = ["coverage (>=5.0.3)", "zope.event", "zope.testing"] +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "4e3668a1a46b631b9ff2304162a1e5d06f76e4e31c6316c3b8c322af58077673" +content-hash = "3dc9498476fdd72f17898b76a31f029099e2224c78028d919dfeb964e14df5e8" diff --git a/pyproject.toml b/pyproject.toml index 2f3e86628..a09355113 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -166,6 +166,11 @@ pymssql = "2.2.7" psycopg2 = "2.9.6" ucloud-sdk-python3 = "0.11.50" +[[tool.poetry.source]] +name = "tsinghua" +url = "https://pypi.tuna.tsinghua.edu.cn/simple/" +priority = "primary" + [build-system] requires = ["poetry-core"] build-backend = "poetry.core.masonry.api" From 6d758bdb597482e592a496e03e9f9d2e82cdd603 Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Wed, 2 Aug 2023 15:07:22 +0800 Subject: [PATCH 081/177] =?UTF-8?q?fix:=20k8s=20=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E7=BD=91=E5=85=B3=20(#11171)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: feng <1304903146@qq.com> --- apps/assets/utils/k8s.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/apps/assets/utils/k8s.py b/apps/assets/utils/k8s.py index a281bfe80..35fe4fd18 100644 --- a/apps/assets/utils/k8s.py +++ b/apps/assets/utils/k8s.py @@ -22,7 +22,12 @@ class KubernetesClient: @property def api(self): configuration = client.Configuration() - configuration.host = self.url + scheme = urlparse(self.url).scheme + if not self.server: + host = self.url + else: + host = f'{scheme}://127.0.0.1:{self.server.local_bind_port}' + configuration.host = host configuration.verify_ssl = False configuration.api_key = {"authorization": "Bearer " + self.token} c = api_client.ApiClient(configuration=configuration) From 89c4a8d5c4419d0b9b92c93b4a9558359b070cd1 Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Wed, 2 Aug 2023 15:17:21 +0800 Subject: [PATCH 082/177] =?UTF-8?q?perf:=20=E5=8E=BB=E6=8E=89=20lock=20?= =?UTF-8?q?=E4=B8=AD=E7=9A=84=20source=20(#11173)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * perf: 去掉 lock 中的 source * perf: 去掉格式化 --------- Co-authored-by: ibuler --- poetry.lock | 1380 +++++++++++---------------------------------------- 1 file changed, 276 insertions(+), 1104 deletions(-) diff --git a/poetry.lock b/poetry.lock index 30075ac44..ffb442f91 100644 --- a/poetry.lock +++ b/poetry.lock @@ -17,10 +17,7 @@ PyJWT = ">=1.0.0,<3" python-dateutil = ">=2.1.0,<3" requests = ">=2.0.0,<3" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "aiofiles" @@ -33,10 +30,7 @@ files = [ {file = "aiofiles-23.1.0.tar.gz", hash = "sha256:edd247df9a19e0db16534d4baaf536d6609a43e1de5401d7a4c1c148753a1635"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "aiohttp" @@ -146,10 +140,7 @@ yarl = ">=1.0,<2.0" [package.extras] speedups = ["Brotli", "aiodns", "cchardet"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "aiosignal" @@ -165,10 +156,7 @@ files = [ [package.dependencies] frozenlist = ">=1.1.0" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "alibabacloud-credentials" @@ -183,10 +171,7 @@ files = [ [package.dependencies] alibabacloud-tea = "*" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "alibabacloud-dysmsapi20170525" @@ -205,10 +190,7 @@ alibabacloud-openapi-util = ">=0.2.1,<1.0.0" alibabacloud-tea-openapi = ">=0.3.6,<1.0.0" alibabacloud-tea-util = ">=0.3.9,<1.0.0" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "alibabacloud-endpoint-util" @@ -223,10 +205,7 @@ files = [ [package.dependencies] alibabacloud-tea = ">=0.0.1" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "alibabacloud-gateway-spi" @@ -241,10 +220,7 @@ files = [ [package.dependencies] alibabacloud_credentials = ">=0.2.0,<1.0.0" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "alibabacloud-openapi-util" @@ -260,10 +236,7 @@ files = [ alibabacloud_tea_util = ">=0.0.2" cryptography = ">=3.0.0" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "alibabacloud-tea" @@ -280,10 +253,7 @@ aiohttp = ">=3.7.0,<4.0.0" requests = ">=2.21.0,<3.0.0" urllib3 = "<2.0.0" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "alibabacloud-tea-openapi" @@ -302,10 +272,7 @@ alibabacloud_openapi_util = ">=0.2.1,<1.0.0" alibabacloud_tea_util = ">=0.3.8,<1.0.0" alibabacloud_tea_xml = ">=0.0.2,<1.0.0" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "alibabacloud-tea-util" @@ -320,10 +287,7 @@ files = [ [package.dependencies] alibabacloud-tea = ">=0.3.3" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "alibabacloud-tea-xml" @@ -338,10 +302,7 @@ files = [ [package.dependencies] alibabacloud-tea = ">=0.0.1" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "aliyun-python-sdk-core" @@ -357,10 +318,7 @@ files = [ cryptography = ">=2.6.0" jmespath = ">=0.9.3,<1.0.0" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "aliyun-python-sdk-core-v3" @@ -376,10 +334,7 @@ files = [ cryptography = ">=2.6.0" jmespath = ">=0.9.3,<1.0.0" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "aliyun-python-sdk-ecs" @@ -395,10 +350,7 @@ files = [ [package.dependencies] aliyun-python-sdk-core = ">=2.11.5" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "aliyun-python-sdk-kms" @@ -414,10 +366,7 @@ files = [ [package.dependencies] aliyun-python-sdk-core = ">=2.11.5" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "amqp" @@ -433,10 +382,7 @@ files = [ [package.dependencies] vine = ">=5.0.0" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "ansible" @@ -452,10 +398,7 @@ files = [ [package.dependencies] ansible-core = ">=2.14.1,<2.15.0" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "ansible-core" @@ -496,10 +439,7 @@ python-daemon = "*" pyyaml = "*" six = "*" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "anyio" @@ -521,10 +461,7 @@ doc = ["Sphinx", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd- test = ["anyio[trio]", "coverage[toml] (>=4.5)", "hypothesis (>=4.0)", "mock (>=4)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"] trio = ["trio (<0.22)"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "appnope" @@ -537,10 +474,7 @@ files = [ {file = "appnope-0.1.3.tar.gz", hash = "sha256:02bd91c4de869fbb1e1c50aafc4098827a7a54ab2f39d9dcba6c9547ed920e24"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "asgiref" @@ -556,10 +490,7 @@ files = [ [package.extras] tests = ["mypy (>=0.800)", "pytest", "pytest-asyncio"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "asn1crypto" @@ -572,10 +503,7 @@ files = [ {file = "asn1crypto-1.5.1.tar.gz", hash = "sha256:13ae38502be632115abf8a24cbe5f4da52e3b5231990aff31123c805306ccb9c"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "asttokens" @@ -594,10 +522,7 @@ six = "*" [package.extras] test = ["astroid", "pytest"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "async-timeout" @@ -610,10 +535,7 @@ files = [ {file = "async_timeout-4.0.2-py3-none-any.whl", hash = "sha256:8ca1e4fcf50d07413d66d1a5e416e42cfdf5851c981d679a09851a6853383b3c"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "attrs" @@ -633,10 +555,7 @@ docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib- tests = ["attrs[tests-no-zope]", "zope-interface"] tests-no-zope = ["cloudpickle", "hypothesis", "mypy (>=1.1.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "autobahn" @@ -666,10 +585,7 @@ twisted = ["attrs (>=20.3.0)", "twisted (>=20.3.0)", "zope.interface (>=5.2.0)"] ui = ["PyGObject (>=3.40.0)"] xbr = ["base58 (>=2.1.0)", "bitarray (>=2.7.5)", "cbor2 (>=5.2.0)", "click (>=8.1.2)", "ecdsa (>=0.16.1)", "eth-abi (>=4.0.0)", "hkdf (>=0.0.3)", "jinja2 (>=2.11.3)", "mnemonic (>=0.19)", "py-ecc (>=5.1.0)", "py-eth-sig-utils (>=0.4.0)", "py-multihash (>=2.0.1)", "rlp (>=2.0.1)", "spake2 (>=0.8)", "twisted (>=20.3.0)", "web3[ipfs] (>=6.0.0)", "xbr (>=21.2.1)", "yapf (==0.29.0)", "zlmdb (>=21.2.1)"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "automat" @@ -689,10 +605,7 @@ six = "*" [package.extras] visualize = ["Twisted (>=16.1.1)", "graphviz (>0.5.1)"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "azure-common" @@ -705,10 +618,7 @@ files = [ {file = "azure_common-1.1.28-py2.py3-none-any.whl", hash = "sha256:5c12d3dcf4ec20599ca6b0d3e09e86e146353d443e7fcc050c9a19c1f9df20ad"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "azure-core" @@ -729,10 +639,7 @@ typing-extensions = ">=4.3.0" [package.extras] aio = ["aiohttp (>=3.0)"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "azure-identity" @@ -752,10 +659,7 @@ msal = ">=1.20.0,<2.0.0" msal-extensions = ">=0.3.0,<2.0.0" six = ">=1.12.0" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "azure-mgmt-compute" @@ -773,10 +677,7 @@ azure-common = ">=1.1,<2.0" azure-mgmt-core = ">=1.3.2,<2.0.0" isodate = ">=0.6.1,<1.0.0" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "azure-mgmt-core" @@ -792,10 +693,7 @@ files = [ [package.dependencies] azure-core = ">=1.26.2,<2.0.0" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "azure-mgmt-network" @@ -813,10 +711,7 @@ azure-common = ">=1.1,<2.0" azure-mgmt-core = ">=1.3.2,<2.0.0" isodate = ">=0.6.1,<1.0.0" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "azure-mgmt-subscription" @@ -834,10 +729,7 @@ azure-common = ">=1.1,<2.0" azure-mgmt-core = ">=1.3.2,<2.0.0" msrest = ">=0.7.1" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "azure-storage-blob" @@ -859,10 +751,7 @@ typing-extensions = ">=4.3.0" [package.extras] aio = ["azure-core[aio] (>=1.28.0,<2.0.0)"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "backcall" @@ -875,10 +764,7 @@ files = [ {file = "backcall-0.2.0.tar.gz", hash = "sha256:5cbdbf27be5e7cfadb448baf0aa95508f91f2bbc6c6437cd9cd06e2a4c215e1e"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "bce-python-sdk" @@ -896,10 +782,7 @@ future = ">=0.6.0" pycryptodome = ">=3.8.0" six = ">=1.4.0" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "bcrypt" @@ -935,10 +818,7 @@ files = [ tests = ["pytest (>=3.2.1,!=3.3.0)"] typecheck = ["mypy"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "beautifulsoup4" @@ -958,10 +838,7 @@ soupsieve = ">1.2" html5lib = ["html5lib"] lxml = ["lxml"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "billiard" @@ -974,10 +851,7 @@ files = [ {file = "billiard-4.1.0.tar.gz", hash = "sha256:1ad2eeae8e28053d729ba3373d34d9d6e210f6e4d8bf0a9c64f92bd053f1edf5"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "boto" @@ -990,10 +864,7 @@ files = [ {file = "boto-2.49.0.tar.gz", hash = "sha256:ea0d3b40a2d852767be77ca343b58a9e3a4b00d9db440efb8da74b4e58025e5a"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "boto3" @@ -1014,10 +885,7 @@ s3transfer = ">=0.6.0,<0.7.0" [package.extras] crt = ["botocore[crt] (>=1.21.0,<2.0a0)"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "botocore" @@ -1038,10 +906,7 @@ urllib3 = ">=1.25.4,<1.27" [package.extras] crt = ["awscrt (==0.16.26)"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "cachetools" @@ -1054,10 +919,7 @@ files = [ {file = "cachetools-5.3.1.tar.gz", hash = "sha256:dce83f2d9b4e1f732a8cd44af8e8fab2dbe46201467fc98b3ef8f269092bf62b"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "celery" @@ -1114,10 +976,7 @@ yaml = ["PyYAML (>=3.10)"] zookeeper = ["kazoo (>=1.3.1)"] zstd = ["zstandard (==0.21.0)"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "certifi" @@ -1130,10 +989,7 @@ files = [ {file = "certifi-2023.7.22.tar.gz", hash = "sha256:539cc1d13202e33ca466e88b2807e29f4c13049d6d87031a3c110744495cb082"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "cffi" @@ -1211,10 +1067,7 @@ files = [ [package.dependencies] pycparser = "*" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "channels" @@ -1235,10 +1088,7 @@ Django = ">=3.2" daphne = ["daphne (>=4.0.0)"] tests = ["async-timeout", "coverage (>=4.5,<5.0)", "pytest", "pytest-asyncio", "pytest-django"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "channels-redis" @@ -1261,10 +1111,7 @@ redis = ">=4.5.3" cryptography = ["cryptography (>=1.3.0)"] tests = ["async-timeout", "cryptography (>=1.3.0)", "pytest", "pytest-asyncio", "pytest-timeout"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "chardet" @@ -1277,10 +1124,7 @@ files = [ {file = "chardet-5.1.0.tar.gz", hash = "sha256:0d62712b956bc154f85fb0a266e2a3c5913c2967e00348701b32411d6def31e5"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "charset-normalizer" @@ -1366,10 +1210,7 @@ files = [ {file = "charset_normalizer-3.2.0-py3-none-any.whl", hash = "sha256:8e098148dd37b4ce3baca71fb394c81dc5d9c7728c95df695d2dca218edf40e6"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "click" @@ -1385,10 +1226,7 @@ files = [ [package.dependencies] colorama = {version = "*", markers = "platform_system == \"Windows\""} -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "click-didyoumean" @@ -1404,10 +1242,7 @@ files = [ [package.dependencies] click = ">=7" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "click-plugins" @@ -1426,10 +1261,7 @@ click = ">=4.0" [package.extras] dev = ["coveralls", "pytest (>=3.6)", "pytest-cov", "wheel"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "click-repl" @@ -1449,10 +1281,7 @@ prompt-toolkit = ">=3.0.36" [package.extras] testing = ["pytest (>=7.2.1)", "pytest-cov (>=4.0.0)", "tox (>=4.4.3)"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "colorama" @@ -1465,10 +1294,7 @@ files = [ {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "configparser" @@ -1485,10 +1311,7 @@ files = [ docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] testing = ["pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-ruff", "types-backports"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "constantly" @@ -1501,10 +1324,7 @@ files = [ {file = "constantly-15.1.0.tar.gz", hash = "sha256:586372eb92059873e29eba4f9dec8381541b4d3834660707faf8ba59146dfc35"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "coreapi" @@ -1523,10 +1343,7 @@ itypes = "*" requests = "*" uritemplate = "*" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "coreschema" @@ -1542,10 +1359,7 @@ files = [ [package.dependencies] jinja2 = "*" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "crcmod" @@ -1557,10 +1371,7 @@ files = [ {file = "crcmod-1.7.tar.gz", hash = "sha256:dc7051a0db5f2bd48665a990d3ec1cc305a466a77358ca4492826f41f283601e"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "cron-descriptor" @@ -1575,10 +1386,7 @@ files = [ [package.extras] dev = ["polib"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "cryptography" @@ -1625,10 +1433,7 @@ ssh = ["bcrypt (>=3.1.5)"] test = ["pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] test-randomorder = ["pytest-randomly"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "cython" @@ -1697,10 +1502,7 @@ files = [ {file = "Cython-3.0.0.tar.gz", hash = "sha256:350b18f9673e63101dbbfcf774ee2f57c20ac4636d255741d76ca79016b1bd82"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "daphne" @@ -1721,10 +1523,7 @@ twisted = {version = ">=22.4", extras = ["tls"]} [package.extras] tests = ["django", "hypothesis", "pytest", "pytest-asyncio"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "data-tree" @@ -1737,10 +1536,7 @@ files = [ {file = "data_tree-0.0.1.tar.gz", hash = "sha256:06f2a18b372cf2451166d426591f6e6fc73a7aabcad97255d50927aa3c3d5a0e"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "debtcollector" @@ -1756,10 +1552,7 @@ files = [ [package.dependencies] wrapt = ">=1.7.0" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "decorator" @@ -1772,10 +1565,7 @@ files = [ {file = "decorator-5.1.1.tar.gz", hash = "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "django" @@ -1797,10 +1587,7 @@ tzdata = {version = "*", markers = "sys_platform == \"win32\""} argon2 = ["argon2-cffi (>=19.1.0)"] bcrypt = ["bcrypt"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "django-auth-ldap" @@ -1817,10 +1604,7 @@ files = [ Django = ">=3.2" python-ldap = ">=3.1" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "django-bootstrap3" @@ -1837,10 +1621,7 @@ files = [ beautifulsoup4 = ">=4.8.0" django = ">=3.2" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "django-cas-ng" @@ -1879,10 +1660,7 @@ django-timezone-field = ">=5.0" python-crontab = ">=2.3.4" tzdata = "*" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "django-debug-toolbar" @@ -1899,10 +1677,7 @@ files = [ django = ">=3.2.4" sqlparse = ">=0.2" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "django-filter" @@ -1918,10 +1693,7 @@ files = [ [package.dependencies] Django = ">=3.2" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "django-formtools" @@ -1937,10 +1709,7 @@ files = [ [package.dependencies] Django = ">=3.2" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "django-private-storage" @@ -1953,10 +1722,7 @@ files = [ {file = "django_private_storage-3.1-py3-none-any.whl", hash = "sha256:cd11fa3c40e15bf902b3566dde8082c86f1cbb2900115f15c63e4b5278d96fe7"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "django-proxy" @@ -1971,10 +1737,7 @@ files = [ [package.dependencies] requests = "*" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "django-radius" @@ -2006,10 +1769,7 @@ files = [ [package.dependencies] django = "*" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "django-redis" @@ -2029,10 +1789,7 @@ redis = ">=3,<4.0.0 || >4.0.0,<4.0.1 || >4.0.1" [package.extras] hiredis = ["redis[hiredis] (>=3,!=4.0.0,!=4.0.1)"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "django-rest-swagger" @@ -2051,10 +1808,7 @@ djangorestframework = ">=3.5.4" openapi-codec = ">=1.3.1" simplejson = "*" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "django-simple-captcha" @@ -2075,10 +1829,7 @@ Pillow = ">=6.2.0" [package.extras] test = ["testfixtures"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "django-simple-history" @@ -2091,10 +1842,7 @@ files = [ {file = "django_simple_history-3.3.0-py3-none-any.whl", hash = "sha256:dc1f98e558a0a1e0b6371c3b8efb85f86e02a6db56e83d0ec198343b7408d00a"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "django-timezone-field" @@ -2111,10 +1859,7 @@ files = [ Django = ">=2.2,<3.0.dev0 || >=3.2.dev0,<5.0" pytz = "*" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "djangorestframework" @@ -2131,10 +1876,7 @@ files = [ django = ">=3.0" pytz = "*" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "djangorestframework-bulk" @@ -2151,10 +1893,7 @@ django = "*" djangorestframework = "*" setuptools = "*" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "dnspython" @@ -2175,10 +1914,7 @@ idna = ["idna (>=2.1,<4.0)"] trio = ["trio (>=0.14,<0.23)"] wmi = ["wmi (>=1.5.1,<2.0.0)"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "docutils" @@ -2191,10 +1927,7 @@ files = [ {file = "docutils-0.20.1.tar.gz", hash = "sha256:f08a4e276c3a1583a86dce3e34aba3fe04d02bba2dd51ed16106244e8a923e3b"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "drf-nested-routers" @@ -2211,10 +1944,7 @@ files = [ Django = ">=1.11" djangorestframework = ">=3.6.0" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "drf-writable-nested" @@ -2226,10 +1956,7 @@ files = [ {file = "drf_writable_nested-0.7.0-py3-none-any.whl", hash = "sha256:154c0381e8a3a477e0fd539d5e1caf8ff4c1097a9c0c0fe741d4858b11b0455b"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "drf-yasg" @@ -2255,10 +1982,7 @@ uritemplate = ">=3.0.0" coreapi = ["coreapi (>=2.3.3)", "coreschema (>=0.0.4)"] validation = ["swagger-spec-validator (>=2.1.0)"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "ecdsa" @@ -2278,10 +2002,7 @@ six = ">=1.9.0" gmpy = ["gmpy"] gmpy2 = ["gmpy2"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "elastic-transport" @@ -2301,10 +2022,7 @@ urllib3 = ">=1.26.2,<2" [package.extras] develop = ["aiohttp", "mock", "pytest", "pytest-asyncio", "pytest-cov", "pytest-httpserver", "pytest-mock", "requests", "trustme"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "elasticsearch" @@ -2324,10 +2042,7 @@ elastic-transport = ">=8,<9" async = ["aiohttp (>=3,<4)"] requests = ["requests (>=2.4.0,<3.0.0)"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "enum-compat" @@ -2340,10 +2055,7 @@ files = [ {file = "enum_compat-0.0.3-py3-none-any.whl", hash = "sha256:88091b617c7fc3bbbceae50db5958023c48dc40b50520005aa3bf27f8f7ea157"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "ephem" @@ -2421,10 +2133,7 @@ files = [ {file = "ephem-4.1.4.tar.gz", hash = "sha256:73a59f0d2162d1624535c3c3b75f956556bdbb2055eaf554a7bef147d3f9c760"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "esdk-obs-python" @@ -2436,10 +2145,7 @@ files = [ {file = "esdk-obs-python-3.21.4.tar.gz", hash = "sha256:a3b2a01b0a10768b5b02812abe239048feaae199256cbde67315870121d8ab1e"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "et-xmlfile" @@ -2452,10 +2158,7 @@ files = [ {file = "et_xmlfile-1.1.0.tar.gz", hash = "sha256:8eb9e2bc2f8c97e37a2dc85a09ecdcdec9d8a396530a6d5a33b30b9a92da0c5c"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "eventlet" @@ -2473,10 +2176,7 @@ dnspython = ">=1.15.0" greenlet = ">=0.3" six = ">=1.10.0" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "executing" @@ -2492,10 +2192,7 @@ files = [ [package.extras] tests = ["asttokens", "littleutils", "pytest", "rich"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "flower" @@ -2515,10 +2212,7 @@ prometheus-client = ">=0.8.0" pytz = "*" tornado = ">=5.0.0,<7.0.0" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "forgerypy3" @@ -2530,10 +2224,7 @@ files = [ {file = "ForgeryPy3-0.3.1.tar.gz", hash = "sha256:03db26b2129252dc8c8c91aa5661171725a64707773c03c3ca0251b1dd173c93"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "frozenlist" @@ -2605,10 +2296,7 @@ files = [ {file = "frozenlist-1.4.0.tar.gz", hash = "sha256:09163bdf0b2907454042edb19f887c6d33806adc71fbd54afc14908bfdc22251"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "future" @@ -2620,10 +2308,7 @@ files = [ {file = "future-0.18.3.tar.gz", hash = "sha256:34a17436ed1e96697a86f9de3d15a3b0be01d8bc8de9c1dffd59fb8234ed5307"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "geoip2" @@ -2641,10 +2326,7 @@ aiohttp = ">=3.6.2,<4.0.0" maxminddb = ">=2.3.0,<3.0.0" requests = ">=2.24.0,<3.0.0" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "gmssl" @@ -2659,10 +2341,7 @@ files = [ [package.dependencies] pycryptodomex = "*" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "google-api-core" @@ -2694,10 +2373,7 @@ grpc = ["grpcio (>=1.33.2,<2.0dev)", "grpcio (>=1.49.1,<2.0dev)", "grpcio-status grpcgcp = ["grpcio-gcp (>=0.2.2,<1.0.dev0)"] grpcio-gcp = ["grpcio-gcp (>=0.2.2,<1.0.dev0)"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "google-auth" @@ -2724,10 +2400,7 @@ pyopenssl = ["cryptography (>=38.0.3)", "pyopenssl (>=20.0.0)"] reauth = ["pyu2f (>=0.1.5)"] requests = ["requests (>=2.20.0,<3.0.0.dev0)"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "google-cloud-compute" @@ -2745,10 +2418,7 @@ google-api-core = {version = ">=1.34.0,<2.0.dev0 || >=2.11.dev0,<3.0.0dev", extr proto-plus = {version = ">=1.22.2,<2.0.0dev", markers = "python_version >= \"3.11\""} protobuf = ">=3.19.5,<3.20.0 || >3.20.0,<3.20.1 || >3.20.1,<4.21.0 || >4.21.0,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<5.0.0dev" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "googleapis-common-protos" @@ -2767,10 +2437,7 @@ protobuf = ">=3.19.5,<3.20.0 || >3.20.0,<3.20.1 || >3.20.1,<4.21.1 || >4.21.1,<4 [package.extras] grpc = ["grpcio (>=1.44.0,<2.0.0.dev0)"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "greenlet" @@ -2845,10 +2512,7 @@ files = [ docs = ["Sphinx", "docutils (<0.18)"] test = ["objgraph", "psutil"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "grpcio" @@ -2907,10 +2571,7 @@ files = [ [package.extras] protobuf = ["grpcio-tools (>=1.56.2)"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "grpcio-status" @@ -2928,10 +2589,7 @@ googleapis-common-protos = ">=1.5.5" grpcio = ">=1.56.2" protobuf = ">=4.21.6" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "gunicorn" @@ -2953,10 +2611,7 @@ gevent = ["gevent (>=1.4.0)"] setproctitle = ["setproctitle"] tornado = ["tornado (>=0.2)"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "h11" @@ -2969,10 +2624,7 @@ files = [ {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "html2text" @@ -2985,10 +2637,7 @@ files = [ {file = "html2text-2020.1.16.tar.gz", hash = "sha256:e296318e16b059ddb97f7a8a1d6a5c1d7af4544049a01e261731d2d5cc277bbb"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "httpsig" @@ -3005,10 +2654,7 @@ files = [ pycryptodome = ">=3,<4" six = "*" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "httptools" @@ -3057,10 +2703,7 @@ files = [ [package.extras] test = ["Cython (>=0.29.24,<0.30.0)"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "humanize" @@ -3076,10 +2719,7 @@ files = [ [package.extras] tests = ["freezegun", "pytest", "pytest-cov"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "hvac" @@ -3096,10 +2736,7 @@ files = [ pyhcl = ">=0.4.4,<0.5.0" requests = ">=2.27.1,<3.0.0" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "hyperlink" @@ -3115,10 +2752,7 @@ files = [ [package.dependencies] idna = ">=2.5" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "idna" @@ -3131,10 +2765,7 @@ files = [ {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "incremental" @@ -3151,10 +2782,7 @@ files = [ mypy = ["click (>=6.0)", "mypy (==0.812)", "twisted (>=16.4.0)"] scripts = ["click (>=6.0)", "twisted (>=16.4.0)"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "inflection" @@ -3167,10 +2795,7 @@ files = [ {file = "inflection-0.5.1.tar.gz", hash = "sha256:1a29730d366e996aaacffb2f1f1cb9593dc38e2ddd30c91250c6dde09ea9b417"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "ipip-ipdb" @@ -3182,10 +2807,7 @@ files = [ {file = "ipip-ipdb-1.6.1.tar.gz", hash = "sha256:4f396f8f8b1a2fc7fe3c41e1b05b479aac9aa1bc310b5b0182dbaa5376dc0bb9"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "ipy" @@ -3197,10 +2819,7 @@ files = [ {file = "IPy-1.01.tar.gz", hash = "sha256:edeca741dea2d54aca568fa23740288c3fe86c0f3ea700344571e9ef14a7cc1a"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "ipython" @@ -3240,10 +2859,7 @@ qtconsole = ["qtconsole"] test = ["pytest (<7.1)", "pytest-asyncio", "testpath"] test-extra = ["curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.21)", "pandas", "pytest (<7.1)", "pytest-asyncio", "testpath", "trio"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "iso8601" @@ -3256,10 +2872,7 @@ files = [ {file = "iso8601-2.0.0.tar.gz", hash = "sha256:739960d37c74c77bd9bd546a76562ccb581fe3d4820ff5c3141eb49c839fda8f"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "isodate" @@ -3275,10 +2888,7 @@ files = [ [package.dependencies] six = "*" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "itsdangerous" @@ -3291,10 +2901,7 @@ files = [ {file = "itsdangerous-1.1.0.tar.gz", hash = "sha256:321b033d07f2a4136d3ec762eac9f16a10ccd60f53c0c91af90217ace7ba1f19"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "itypes" @@ -3307,10 +2914,7 @@ files = [ {file = "itypes-1.2.0.tar.gz", hash = "sha256:af886f129dea4a2a1e3d36595a2d139589e4dd287f5cab0b40e799ee81570ff1"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "jedi" @@ -3331,10 +2935,7 @@ docs = ["Jinja2 (==2.11.3)", "MarkupSafe (==1.1.1)", "Pygments (==2.8.1)", "alab qa = ["flake8 (==5.0.4)", "mypy (==0.971)", "types-setuptools (==67.2.0.1)"] testing = ["Django (<3.1)", "attrs", "colorama", "docopt", "pytest (<7.0.0)"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "jinja2" @@ -3353,10 +2954,7 @@ MarkupSafe = ">=2.0" [package.extras] i18n = ["Babel (>=2.7)"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "jmespath" @@ -3369,10 +2967,7 @@ files = [ {file = "jmespath-0.10.0.tar.gz", hash = "sha256:b85d0567b8666149a93172712e68920734333c0ce7e89b78b3e987f71e5ed4f9"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "jms-storage" @@ -3403,10 +2998,7 @@ requests = "2.31.0" s3transfer = "0.6.1" six = "1.16.0" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "jsonfield2" @@ -3422,10 +3014,7 @@ files = [ [package.dependencies] Django = ">=2.2" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "keystoneauth1" @@ -3452,10 +3041,7 @@ oauth1 = ["oauthlib (>=0.6.2)"] saml2 = ["lxml (>=4.2.0)"] test = ["PyYAML (>=3.12)", "bandit (>=1.1.0,<1.6.0)", "betamax (>=0.7.0)", "coverage (>=4.0,!=4.4)", "fixtures (>=3.0.0)", "flake8-docstrings (>=1.6.0,<1.7.0)", "flake8-import-order (>=0.17.1)", "hacking (>=4.1.0,<4.2.0)", "lxml (>=4.2.0)", "oauthlib (>=0.6.2)", "oslo.config (>=5.2.0)", "oslo.utils (>=3.33.0)", "oslotest (>=3.2.0)", "reno (>=3.1.0)", "requests-kerberos (>=0.8.0)", "requests-mock (>=1.2.0)", "stestr (>=1.0.0)", "testresources (>=2.0.0)", "testtools (>=2.2.0)"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "kombu" @@ -3489,10 +3075,7 @@ sqs = ["boto3 (>=1.26.143)", "pycurl (>=7.43.0.5)", "urllib3 (>=1.26.16)"] yaml = ["PyYAML (>=3.10)"] zookeeper = ["kazoo (>=2.8.0)"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "kubernetes" @@ -3520,10 +3103,7 @@ websocket-client = ">=0.32.0,<0.40.0 || >0.40.0,<0.41.dev0 || >=0.43.dev0" [package.extras] adal = ["adal (>=1.0.2)"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "ldap3" @@ -3539,10 +3119,7 @@ files = [ [package.dependencies] pyasn1 = ">=0.4.6" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "lml" @@ -3555,10 +3132,7 @@ files = [ {file = "lml-0.1.0.tar.gz", hash = "sha256:57a085a29bb7991d70d41c6c3144c560a8e35b4c1030ffb36d85fa058773bcc5"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "lockfile" @@ -3571,10 +3145,7 @@ files = [ {file = "lockfile-0.12.2.tar.gz", hash = "sha256:6aed02de03cba24efabcd600b30540140634fc06cfa603822d508d5361e9f799"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "lxml" @@ -3683,10 +3254,7 @@ html5 = ["html5lib"] htmlsoup = ["BeautifulSoup4"] source = ["Cython (>=0.29.35)"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "markupsafe" @@ -3747,10 +3315,7 @@ files = [ {file = "MarkupSafe-2.1.3.tar.gz", hash = "sha256:af598ed32d6ae86f1b747b82783958b1a4ab8f617b06fe68795c7f026abbdcad"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "matplotlib-inline" @@ -3766,10 +3331,7 @@ files = [ [package.dependencies] traitlets = "*" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "maxminddb" @@ -3781,10 +3343,7 @@ files = [ {file = "maxminddb-2.4.0.tar.gz", hash = "sha256:81e54e53408bd502650e5969ccba16780af659ec1db1c44b2c997e4330a5ed96"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "msal" @@ -3805,10 +3364,7 @@ requests = ">=2.0.0,<3" [package.extras] broker = ["pymsalruntime (>=0.13.2,<0.14)"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "msal-extensions" @@ -3828,10 +3384,7 @@ portalocker = [ {version = ">=1.6,<3", markers = "python_version >= \"3.5\" and platform_system == \"Windows\""}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "msgpack" @@ -3905,10 +3458,7 @@ files = [ {file = "msgpack-1.0.5.tar.gz", hash = "sha256:c075544284eadc5cddc70f4757331d99dcbc16b2bbd4849d15f8aae4cf36d31c"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "msrest" @@ -3931,10 +3481,7 @@ requests-oauthlib = ">=0.5.0" [package.extras] async = ["aiodns", "aiohttp (>=3.0)"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "msrestazure" @@ -3952,10 +3499,7 @@ adal = ">=0.6.0,<2.0.0" msrest = ">=0.6.0,<2.0.0" six = "*" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "multidict" @@ -4040,10 +3584,7 @@ files = [ {file = "multidict-6.0.4.tar.gz", hash = "sha256:3666906492efb76453c0e7b97f2cf459b0682e7402c0489a95484965dbc1da49"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "mysqlclient" @@ -4061,10 +3602,7 @@ files = [ {file = "mysqlclient-2.2.0.tar.gz", hash = "sha256:04368445f9c487d8abb7a878e3d23e923e6072c04a6c320f9e0dc8a82efba14e"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "netaddr" @@ -4077,10 +3615,7 @@ files = [ {file = "netaddr-0.8.0.tar.gz", hash = "sha256:d6cc57c7a07b1d9d2e917aa8b36ae8ce61c35ba3fcd1b83ca31c5a0ee2b5a243"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "netifaces" @@ -4121,10 +3656,7 @@ files = [ {file = "netifaces-0.11.0.tar.gz", hash = "sha256:043a79146eb2907edf439899f262b3dfe41717d34124298ed281139a8b93ca32"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "oauthlib" @@ -4142,10 +3674,7 @@ rsa = ["cryptography (>=3.0.0)"] signals = ["blinker (>=1.4.0)"] signedtoken = ["cryptography (>=3.0.0)", "pyjwt (>=2.0.0,<3)"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "olefile" @@ -4157,10 +3686,7 @@ files = [ {file = "olefile-0.46.zip", hash = "sha256:133b031eaf8fd2c9399b78b8bc5b8fcbe4c31e85295749bb17a87cba8f3c3964"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "openapi-codec" @@ -4175,10 +3701,7 @@ files = [ [package.dependencies] coreapi = ">=2.2.0" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "openpyxl" @@ -4194,10 +3717,7 @@ files = [ [package.dependencies] et-xmlfile = "*" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "oracledb" @@ -4239,10 +3759,7 @@ files = [ [package.dependencies] cryptography = ">=3.2.1" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "os-service-types" @@ -4258,10 +3775,7 @@ files = [ [package.dependencies] pbr = ">=2.0.0,<2.1.0 || >2.1.0" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "oslo-config" @@ -4287,10 +3801,7 @@ stevedore = ">=1.20.0" rst-generator = ["rst2txt (>=1.1.0)", "sphinx (>=1.8.0,!=2.1.0)"] test = ["bandit (>=1.6.0,<1.7.0)", "coverage (>=4.0,!=4.4)", "fixtures (>=3.0.0)", "hacking (>=3.0.1,<3.1.0)", "mypy (>=0.720)", "oslo.log (>=3.36.0)", "oslotest (>=3.2.0)", "pre-commit (>=2.6.0)", "requests-mock (>=1.5.0)", "stestr (>=2.1.0)", "testscenarios (>=0.4)", "testtools (>=2.2.0)"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "oslo-i18n" @@ -4306,10 +3817,7 @@ files = [ [package.dependencies] pbr = ">=2.0.0,<2.1.0 || >2.1.0" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "oslo-serialization" @@ -4328,10 +3836,7 @@ msgpack = ">=0.5.2" pbr = ">=2.0.0,<2.1.0 || >2.1.0" pytz = ">=2013.6" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "oslo-utils" @@ -4355,10 +3860,7 @@ pyparsing = ">=2.1.0" pytz = ">=2013.6" tzdata = ">=2022.4" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "oss2" @@ -4378,10 +3880,7 @@ pycryptodome = ">=3.4.7" requests = "!=2.9.0" six = "*" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "packaging" @@ -4394,10 +3893,7 @@ files = [ {file = "packaging-23.1.tar.gz", hash = "sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "paramiko" @@ -4420,10 +3916,7 @@ all = ["gssapi (>=1.4.1)", "invoke (>=2.0)", "pyasn1 (>=0.1.7)", "pywin32 (>=2.1 gssapi = ["gssapi (>=1.4.1)", "pyasn1 (>=0.1.7)", "pywin32 (>=2.1.8)"] invoke = ["invoke (>=2.0)"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "parso" @@ -4440,10 +3933,7 @@ files = [ qa = ["flake8 (==3.8.3)", "mypy (==0.782)"] testing = ["docopt", "pytest (<6.0.0)"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "passlib" @@ -4462,10 +3952,7 @@ bcrypt = ["bcrypt (>=3.1.0)"] build-docs = ["cloud-sptheme (>=1.10.1)", "sphinx (>=1.6)", "sphinxcontrib-fulltoc (>=1.2.0)"] totp = ["cryptography"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "pbr" @@ -4478,10 +3965,7 @@ files = [ {file = "pbr-5.11.1.tar.gz", hash = "sha256:aefc51675b0b533d56bb5fd1c8c6c0522fe31896679882e1c4c63d5e4a0fccb3"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "pexpect" @@ -4497,10 +3981,7 @@ files = [ [package.dependencies] ptyprocess = ">=0.5" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "phonenumbers" @@ -4513,10 +3994,7 @@ files = [ {file = "phonenumbers-8.13.17.tar.gz", hash = "sha256:89671217c706cbaa3ced101deefafa779836feac3e059434d886ac31f09f32c0"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "pickleshare" @@ -4529,10 +4007,7 @@ files = [ {file = "pickleshare-0.7.5.tar.gz", hash = "sha256:87683d47965c1da65cdacaf31c8441d12b8044cdec9aca500cd78fc2c683afca"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "pillow" @@ -4603,10 +4078,7 @@ files = [ docs = ["furo", "olefile", "sphinx (>=2.4)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinx-removed-in", "sphinxext-opengraph"] tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "portalocker" @@ -4627,10 +4099,7 @@ docs = ["sphinx (>=1.7.1)"] redis = ["redis"] tests = ["pytest (>=5.4.1)", "pytest-cov (>=2.8.1)", "pytest-mypy (>=0.8.0)", "pytest-timeout (>=2.1.0)", "redis", "sphinx (>=6.0.0)"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "prettytable" @@ -4649,10 +4118,7 @@ wcwidth = "*" [package.extras] tests = ["pytest", "pytest-cov", "pytest-lazy-fixture"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "prometheus-client" @@ -4668,10 +4134,7 @@ files = [ [package.extras] twisted = ["twisted"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "prompt-toolkit" @@ -4687,10 +4150,7 @@ files = [ [package.dependencies] wcwidth = "*" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "proto-plus" @@ -4709,10 +4169,7 @@ protobuf = ">=3.19.0,<5.0.0dev" [package.extras] testing = ["google-api-core[grpc] (>=1.31.5)"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "protobuf" @@ -4736,10 +4193,7 @@ files = [ {file = "protobuf-4.23.4.tar.gz", hash = "sha256:ccd9430c0719dce806b93f89c91de7977304729e55377f872a92465d548329a9"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "psutil" @@ -4767,10 +4221,7 @@ files = [ [package.extras] test = ["enum34", "ipaddress", "mock", "pywin32", "wmi"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "psycopg2" @@ -4794,10 +4245,7 @@ files = [ {file = "psycopg2-2.9.6.tar.gz", hash = "sha256:f15158418fd826831b28585e2ab48ed8df2d0d98f502a2b4fe619e7d5ca29011"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "psycopg2-binary" @@ -4870,10 +4318,7 @@ files = [ {file = "psycopg2_binary-2.9.6-cp39-cp39-win_amd64.whl", hash = "sha256:f6a88f384335bb27812293fdb11ac6aee2ca3f51d3c7820fe03de0a304ab6249"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "ptyprocess" @@ -4886,10 +4331,7 @@ files = [ {file = "ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "pure-eval" @@ -4905,10 +4347,7 @@ files = [ [package.extras] tests = ["pytest"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "pyasn1" @@ -4921,10 +4360,7 @@ files = [ {file = "pyasn1-0.5.0.tar.gz", hash = "sha256:97b7290ca68e62a832558ec3976f15cbf911bf5d7c7039d8b861c2a0ece69fde"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "pyasn1-modules" @@ -4940,10 +4376,7 @@ files = [ [package.dependencies] pyasn1 = ">=0.4.6,<0.6.0" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "pycparser" @@ -4956,10 +4389,7 @@ files = [ {file = "pycparser-2.21.tar.gz", hash = "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "pycryptodome" @@ -5002,10 +4432,7 @@ files = [ {file = "pycryptodome-3.18.0.tar.gz", hash = "sha256:c9adee653fc882d98956e33ca2c1fb582e23a8af7ac82fee75bd6113c55a0413"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "pycryptodomex" @@ -5048,10 +4475,7 @@ files = [ {file = "pycryptodomex-3.18.0.tar.gz", hash = "sha256:3e3ecb5fe979e7c1bb0027e518340acf7ee60415d79295e5251d13c68dde576e"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "pyexcel" @@ -5075,10 +4499,7 @@ ods = ["pyexcel-ods3 (>=0.6.0)"] xls = ["pyexcel-xls (>=0.6.0)"] xlsx = ["pyexcel-xlsx (>=0.6.0)"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "pyexcel-io" @@ -5099,10 +4520,7 @@ ods = ["pyexcel-ods3 (>=0.6.0)"] xls = ["pyexcel-xls (>=0.6.0)"] xlsx = ["pyexcel-xlsx (>=0.6.0)"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "pyexcel-xlsx" @@ -5119,10 +4537,7 @@ files = [ openpyxl = ">=2.6.1" pyexcel-io = ">=0.6.2" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "pyfreerdp" @@ -5165,10 +4580,7 @@ files = [ {file = "pyfreerdp-0.0.1.tar.gz", hash = "sha256:946eca882741e6802794185cbdd47b49626c3181bce99dbd27c5746563c13d43"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "pygments" @@ -5184,10 +4596,7 @@ files = [ [package.extras] plugins = ["importlib-metadata"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "pyhcl" @@ -5199,10 +4608,7 @@ files = [ {file = "pyhcl-0.4.4.tar.gz", hash = "sha256:2d9b9dcdf1023d812bfed561ba72c99104c5b3f52e558d595130a44ce081b003"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "pyjwkest" @@ -5220,10 +4626,7 @@ pycryptodomex = "*" requests = "*" six = "*" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "pyjwt" @@ -5245,10 +4648,7 @@ dev = ["coverage[toml] (==5.0.4)", "cryptography (>=3.4.0)", "pre-commit", "pyte docs = ["sphinx (>=4.5.0,<5.0.0)", "sphinx-rtd-theme", "zope.interface"] tests = ["coverage[toml] (==5.0.4)", "pytest (>=6.0.0,<7.0.0)"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "pymongo" @@ -5344,10 +4744,7 @@ ocsp = ["certifi", "pyopenssl (>=17.2.0)", "requests (<3.0.0)", "service-identit snappy = ["python-snappy"] zstd = ["zstandard"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "pympler" @@ -5360,10 +4757,7 @@ files = [ {file = "Pympler-1.0.1.tar.gz", hash = "sha256:993f1a3599ca3f4fcd7160c7545ad06310c9e12f70174ae7ae8d4e25f6c5d3fa"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "pymssql" @@ -5435,10 +4829,7 @@ files = [ {file = "pymssql-2.2.7.tar.gz", hash = "sha256:ff95b910532ec7b02e4322231c117d3d6af0abab667e6fbf15442db873943045"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "pymysql" @@ -5455,10 +4846,7 @@ files = [ ed25519 = ["PyNaCl (>=1.4.0)"] rsa = ["cryptography"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "pynacl" @@ -5486,10 +4874,7 @@ cffi = ">=1.4.1" docs = ["sphinx (>=1.6.5)", "sphinx-rtd-theme"] tests = ["hypothesis (>=3.27.0)", "pytest (>=3.2.1,!=3.3.0)"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "pyopenssl" @@ -5509,10 +4894,7 @@ cryptography = ">=38.0.0,<40.0.0 || >40.0.0,<40.0.1 || >40.0.1,<42" docs = ["sphinx (!=5.2.0,!=5.2.0.post0)", "sphinx-rtd-theme"] test = ["flaky", "pretend", "pytest (>=3.0.1)"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "pyotp" @@ -5525,10 +4907,7 @@ files = [ {file = "pyotp-2.8.0.tar.gz", hash = "sha256:c2f5e17d9da92d8ec1f7de6331ab08116b9115adbabcba6e208d46fc49a98c5a"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "pyparsing" @@ -5544,10 +4923,7 @@ files = [ [package.extras] diagrams = ["jinja2", "railroad-diagrams"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "pyrad" @@ -5564,10 +4940,7 @@ files = [ netaddr = "*" six = "*" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "pyspnego" @@ -5597,10 +4970,7 @@ cryptography = "*" kerberos = ["gssapi (>=1.6.0)", "krb5 (>=0.3.0)"] yaml = ["ruamel.yaml"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "python-cas" @@ -5618,10 +4988,7 @@ lxml = ">=3.4" requests = ">=2.11.1" six = ">=1.10.0" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "python-crontab" @@ -5641,10 +5008,7 @@ python-dateutil = "*" cron-description = ["cron-descriptor"] cron-schedule = ["croniter"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "python-daemon" @@ -5666,10 +5030,7 @@ setuptools = ">=62.4.0" devel = ["coverage", "docutils", "isort", "testscenarios (>=0.4)", "testtools", "twine"] test = ["coverage", "docutils", "testscenarios (>=0.4)", "testtools"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "python-dateutil" @@ -5685,10 +5046,7 @@ files = [ [package.dependencies] six = ">=1.5" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "python-dotenv" @@ -5704,10 +5062,7 @@ files = [ [package.extras] cli = ["click (>=5.0)"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "python-keystoneclient" @@ -5733,10 +5088,7 @@ requests = ">=2.14.2" six = ">=1.10.0" stevedore = ">=1.20.0" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "python-ldap" @@ -5752,10 +5104,7 @@ files = [ pyasn1 = ">=0.3.7" pyasn1_modules = ">=0.1.5" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "python-nmap" @@ -5767,10 +5116,7 @@ files = [ {file = "python-nmap-0.7.1.tar.gz", hash = "sha256:f75af6b91dd8e3b0c31f869db32163f62ada686945e5b7c25f84bc0f7fad3b64"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "python-novaclient" @@ -5793,10 +5139,7 @@ pbr = ">=2.0.0,<2.1.0 || >2.1.0" PrettyTable = ">=0.7.2" stevedore = ">=2.0.1" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "python-redis-lock" @@ -5815,10 +5158,7 @@ redis = ">=2.10.0" [package.extras] django = ["django-redis (>=3.8.0)"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "python3-saml" @@ -5840,10 +5180,7 @@ xmlsec = ">=1.3.9" [package.extras] test = ["coverage (>=4.5.2)", "flake8 (>=3.6.0,<=5.0.0)", "freezegun (>=0.3.11,<=1.1.0)", "pytest (>=4.6)"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "pytz" @@ -5856,10 +5193,7 @@ files = [ {file = "pytz-2023.3.tar.gz", hash = "sha256:1d8ce29db189191fb55338ee6d0387d82ab59f3d00eac103412d64e0ebd0c588"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "pyvmomi" @@ -5877,10 +5211,7 @@ six = ">=1.7.3" [package.extras] sso = ["lxml", "pyOpenSSL", "pywin32"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "pywin32" @@ -5905,10 +5236,7 @@ files = [ {file = "pywin32-306-cp39-cp39-win_amd64.whl", hash = "sha256:39b61c15272833b5c329a2989999dcae836b1eed650252ab1b7bfbe1d59f30f4"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "pywinrm" @@ -5931,10 +5259,7 @@ xmltodict = "*" credssp = ["requests-credssp (>=1.0.0)"] kerberos = ["pykerberos (>=1.2.1,<2.0.0)", "winkerberos (>=0.5.0)"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "pyyaml" @@ -5985,10 +5310,7 @@ files = [ {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "pyzipper" @@ -6004,10 +5326,7 @@ files = [ [package.dependencies] pycryptodomex = "*" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "qingcloud-sdk" @@ -6023,10 +5342,7 @@ files = [ [package.dependencies] future = "*" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "redis" @@ -6046,10 +5362,7 @@ async-timeout = {version = ">=4.0.2", markers = "python_full_version <= \"3.11.2 hiredis = ["hiredis (>=1.0.0)"] ocsp = ["cryptography (>=36.0.1)", "pyopenssl (==20.0.1)", "requests (>=2.26.0)"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "requests" @@ -6072,10 +5385,7 @@ urllib3 = ">=1.21.1,<3" socks = ["PySocks (>=1.5.6,!=1.5.7)"] use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "requests-ntlm" @@ -6093,10 +5403,7 @@ cryptography = ">=1.3" pyspnego = ">=0.1.6" requests = ">=2.0.0" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "requests-oauthlib" @@ -6116,10 +5423,7 @@ requests = ">=2.0.0" [package.extras] rsa = ["oauthlib[signedtoken] (>=3.0.0)"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "resolvelib" @@ -6138,10 +5442,7 @@ lint = ["black", "flake8", "isort", "mypy", "types-requests"] release = ["build", "towncrier", "twine"] test = ["commentjson", "packaging", "pytest"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "rest-condition" @@ -6157,10 +5458,7 @@ files = [ django = ">=1.3" djangorestframework = "*" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "rfc3986" @@ -6176,10 +5474,7 @@ files = [ [package.extras] idna2008 = ["idna"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "rsa" @@ -6195,10 +5490,7 @@ files = [ [package.dependencies] pyasn1 = ">=0.1.3" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "s3transfer" @@ -6217,10 +5509,7 @@ botocore = ">=1.12.36,<2.0a.0" [package.extras] crt = ["botocore[crt] (>=1.20.29,<2.0a.0)"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "service-identity" @@ -6246,10 +5535,7 @@ idna = ["idna"] mypy = ["idna", "mypy", "types-pyopenssl"] tests = ["coverage[toml] (>=5.0.2)", "pytest"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "setuptools" @@ -6267,10 +5553,7 @@ docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "pygments-g testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "simplejson" @@ -6366,10 +5649,7 @@ files = [ {file = "simplejson-3.19.1.tar.gz", hash = "sha256:6277f60848a7d8319d27d2be767a7546bc965535b28070e310b3a9af90604a4c"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "six" @@ -6382,10 +5662,7 @@ files = [ {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "sniffio" @@ -6398,10 +5675,7 @@ files = [ {file = "sniffio-1.3.0.tar.gz", hash = "sha256:e60305c5e5d314f5389259b7f22aaa33d8f7dee49763119234af3755c55b9101"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "soupsieve" @@ -6414,10 +5688,7 @@ files = [ {file = "soupsieve-2.4.1.tar.gz", hash = "sha256:89d12b2d5dfcd2c9e8c22326da9d9aa9cb3dfab0a83a024f05704076ee8d35ea"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "sqlparse" @@ -6435,10 +5706,7 @@ dev = ["build", "flake8"] doc = ["sphinx"] test = ["pytest", "pytest-cov"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "sshpubkeys" @@ -6458,10 +5726,7 @@ ecdsa = ">=0.13" [package.extras] dev = ["twine", "wheel", "yapf"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "sshtunnel" @@ -6482,10 +5747,7 @@ build-sphinx = ["sphinx", "sphinxcontrib-napoleon"] dev = ["check-manifest"] test = ["tox (>=1.8.1)"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "stack-data" @@ -6506,10 +5768,7 @@ pure-eval = "*" [package.extras] tests = ["cython", "littleutils", "pygments", "pytest", "typeguard"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "stevedore" @@ -6525,10 +5784,7 @@ files = [ [package.dependencies] pbr = ">=2.0.0,<2.1.0 || >2.1.0" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "tencentcloud-sdk-python" @@ -6544,10 +5800,7 @@ files = [ [package.dependencies] requests = ">=2.16.0" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "termcolor" @@ -6563,10 +5816,7 @@ files = [ [package.extras] tests = ["pytest", "pytest-cov"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "texttable" @@ -6579,10 +5829,7 @@ files = [ {file = "texttable-1.6.7.tar.gz", hash = "sha256:290348fb67f7746931bcdfd55ac7584ecd4e5b0846ab164333f0794b121760f2"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "tornado" @@ -6604,10 +5851,7 @@ files = [ {file = "tornado-6.3.2.tar.gz", hash = "sha256:4b927c4f19b71e627b13f3db2324e4ae660527143f9e1f2e2fb404f3a187e2ba"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "traitlets" @@ -6624,10 +5868,7 @@ files = [ docs = ["myst-parser", "pydata-sphinx-theme", "sphinx"] test = ["argcomplete (>=2.0)", "pre-commit", "pytest", "pytest-mock"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "treelib" @@ -6643,10 +5884,7 @@ files = [ [package.dependencies] six = "*" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "twisted" @@ -6689,10 +5927,7 @@ test = ["PyHamcrest (>=1.9.0)", "cython-test-exception-raiser (>=1.0.2,<2)", "hy tls = ["idna (>=2.4)", "pyopenssl (>=21.0.0)", "service-identity (>=18.1.0)"] windows-platform = ["PyHamcrest (>=1.9.0)", "appdirs (>=1.4.0)", "bcrypt (>=3.0.0)", "contextvars (>=2.4,<3)", "cryptography (>=2.6)", "cython-test-exception-raiser (>=1.0.2,<2)", "h2 (>=3.0,<5.0)", "hypothesis (>=6.0,<7.0)", "idna (>=2.4)", "priority (>=1.1.0,<2.0)", "pyasn1", "pyopenssl (>=21.0.0)", "pyserial (>=3.0)", "pywin32 (!=226)", "pywin32 (!=226)", "service-identity (>=18.1.0)"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "twisted-iocpsupport" @@ -6719,10 +5954,7 @@ files = [ {file = "twisted_iocpsupport-1.0.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:3f39c41c0213a81a9ce0961e30d0d7650f371ad80f8d261007d15a2deb6d5be3"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "txaio" @@ -6740,10 +5972,7 @@ all = ["twisted (>=20.3.0)", "zope.interface (>=5.2.0)"] dev = ["pep8 (>=1.6.2)", "pyenchant (>=1.6.6)", "pytest (>=2.6.4)", "pytest-cov (>=1.8.1)", "sphinx (>=1.2.3)", "sphinx-rtd-theme (>=0.1.9)", "sphinxcontrib-spelling (>=2.1.2)", "tox (>=2.1.1)", "tox-gh-actions (>=2.2.0)", "twine (>=1.6.5)", "wheel"] twisted = ["twisted (>=20.3.0)", "zope.interface (>=5.2.0)"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "typing-extensions" @@ -6756,10 +5985,7 @@ files = [ {file = "typing_extensions-4.7.1.tar.gz", hash = "sha256:b75ddc264f0ba5615db7ba217daeb99701ad295353c45f9e95963337ceeeffb2"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "tzdata" @@ -6772,10 +5998,7 @@ files = [ {file = "tzdata-2023.3.tar.gz", hash = "sha256:11ef1e08e54acb0d4f95bdb1be05da659673de4acbd21bf9c69e94cc5e907a3a"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "ucloud-sdk-python3" @@ -6797,10 +6020,7 @@ dev = ["black", "flake8 (>=3.6.0)", "pytest (>=4.6)", "pytest-cov", "requests", doc = ["requests", "sphinx"] test = ["flake8 (>=3.6.0)", "pytest (>=4.6)", "pytest-cov", "requests", "requests-mock"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "unicodecsv" @@ -6812,10 +6032,7 @@ files = [ {file = "unicodecsv-0.14.1.tar.gz", hash = "sha256:018c08037d48649a0412063ff4eda26eaa81eff1546dbffa51fa5293276ff7fc"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "uritemplate" @@ -6828,10 +6045,7 @@ files = [ {file = "uritemplate-4.1.1.tar.gz", hash = "sha256:4346edfc5c3b79f694bccd6d6099a322bbeb628dbf2cd86eea55a456ce5124f0"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "urllib3" @@ -6849,10 +6063,7 @@ brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)", "brotlipy (>=0.6.0)"] secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "ipaddress", "pyOpenSSL (>=0.14)", "urllib3-secure-extra"] socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "uvicorn" @@ -6879,10 +6090,7 @@ websockets = {version = ">=10.4", optional = true, markers = "extra == \"standar [package.extras] standard = ["colorama (>=0.4)", "httptools (>=0.5.0)", "python-dotenv (>=0.13)", "pyyaml (>=5.1)", "uvloop (>=0.14.0,!=0.15.0,!=0.15.1)", "watchfiles (>=0.13)", "websockets (>=10.4)"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "uvloop" @@ -6928,10 +6136,7 @@ dev = ["Cython (>=0.29.32,<0.30.0)", "Sphinx (>=4.1.2,<4.2.0)", "aiohttp", "flak docs = ["Sphinx (>=4.1.2,<4.2.0)", "sphinx-rtd-theme (>=0.5.2,<0.6.0)", "sphinxcontrib-asyncio (>=0.3.0,<0.4.0)"] test = ["Cython (>=0.29.32,<0.30.0)", "aiohttp", "flake8 (>=3.9.2,<3.10.0)", "mypy (>=0.800)", "psutil", "pyOpenSSL (>=22.0.0,<22.1.0)", "pycodestyle (>=2.7.0,<2.8.0)"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "vine" @@ -6944,10 +6149,7 @@ files = [ {file = "vine-5.0.0.tar.gz", hash = "sha256:7d3b1624a953da82ef63462013bbd271d3eb75751489f9807598e8f340bd637e"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "watchfiles" @@ -6983,10 +6185,7 @@ files = [ [package.dependencies] anyio = ">=3.0.0" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "wcwidth" @@ -6999,10 +6198,7 @@ files = [ {file = "wcwidth-0.2.6.tar.gz", hash = "sha256:a5220780a404dbe3353789870978e472cfe477761f06ee55077256e509b156d0"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "websocket-client" @@ -7020,10 +6216,7 @@ docs = ["Sphinx (>=3.4)", "sphinx-rtd-theme (>=0.5)"] optional = ["python-socks", "wsaccel"] test = ["websockets"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "websockets" @@ -7104,10 +6297,7 @@ files = [ {file = "websockets-11.0.3.tar.gz", hash = "sha256:88fc51d9a26b10fc331be344f1781224a375b78488fc343620184e95a4b27016"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "werkzeug" @@ -7126,10 +6316,7 @@ MarkupSafe = ">=2.1.1" [package.extras] watchdog = ["watchdog (>=2.3)"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "wrapt" @@ -7215,10 +6402,7 @@ files = [ {file = "wrapt-1.15.0.tar.gz", hash = "sha256:d06730c6aed78cee4126234cf2d071e01b44b915e725a6cb439a879ec9754a3a"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "xmlsec" @@ -7245,10 +6429,7 @@ files = [ [package.dependencies] lxml = ">=3.8" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "xmltodict" @@ -7261,10 +6442,7 @@ files = [ {file = "xmltodict-0.13.0.tar.gz", hash = "sha256:341595a488e3e01a85a9d8911d8912fd922ede5fecc4dce437eb4b6c8d037e56"}, ] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "yarl" @@ -7353,10 +6531,7 @@ files = [ idna = ">=2.0" multidict = ">=4.0" -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [[package]] name = "zope-interface" @@ -7405,10 +6580,7 @@ docs = ["Sphinx", "repoze.sphinx.autointerface"] test = ["coverage (>=5.0.3)", "zope.event", "zope.testing"] testing = ["coverage (>=5.0.3)", "zope.event", "zope.testing"] -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" + [metadata] lock-version = "2.0" From ba128e99f90957436d58007cc38d0c4e1fbc4f5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=80=81=E5=B9=BF?= Date: Wed, 2 Aug 2023 15:30:20 +0800 Subject: [PATCH 083/177] =?UTF-8?q?perf:=20=E6=B7=BB=E5=8A=A0=E6=B8=85?= =?UTF-8?q?=E5=8D=8E=E6=BA=90=20(#11174)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- poetry.lock | 1380 ++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 1104 insertions(+), 276 deletions(-) diff --git a/poetry.lock b/poetry.lock index ffb442f91..30075ac44 100644 --- a/poetry.lock +++ b/poetry.lock @@ -17,7 +17,10 @@ PyJWT = ">=1.0.0,<3" python-dateutil = ">=2.1.0,<3" requests = ">=2.0.0,<3" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "aiofiles" @@ -30,7 +33,10 @@ files = [ {file = "aiofiles-23.1.0.tar.gz", hash = "sha256:edd247df9a19e0db16534d4baaf536d6609a43e1de5401d7a4c1c148753a1635"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "aiohttp" @@ -140,7 +146,10 @@ yarl = ">=1.0,<2.0" [package.extras] speedups = ["Brotli", "aiodns", "cchardet"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "aiosignal" @@ -156,7 +165,10 @@ files = [ [package.dependencies] frozenlist = ">=1.1.0" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "alibabacloud-credentials" @@ -171,7 +183,10 @@ files = [ [package.dependencies] alibabacloud-tea = "*" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "alibabacloud-dysmsapi20170525" @@ -190,7 +205,10 @@ alibabacloud-openapi-util = ">=0.2.1,<1.0.0" alibabacloud-tea-openapi = ">=0.3.6,<1.0.0" alibabacloud-tea-util = ">=0.3.9,<1.0.0" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "alibabacloud-endpoint-util" @@ -205,7 +223,10 @@ files = [ [package.dependencies] alibabacloud-tea = ">=0.0.1" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "alibabacloud-gateway-spi" @@ -220,7 +241,10 @@ files = [ [package.dependencies] alibabacloud_credentials = ">=0.2.0,<1.0.0" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "alibabacloud-openapi-util" @@ -236,7 +260,10 @@ files = [ alibabacloud_tea_util = ">=0.0.2" cryptography = ">=3.0.0" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "alibabacloud-tea" @@ -253,7 +280,10 @@ aiohttp = ">=3.7.0,<4.0.0" requests = ">=2.21.0,<3.0.0" urllib3 = "<2.0.0" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "alibabacloud-tea-openapi" @@ -272,7 +302,10 @@ alibabacloud_openapi_util = ">=0.2.1,<1.0.0" alibabacloud_tea_util = ">=0.3.8,<1.0.0" alibabacloud_tea_xml = ">=0.0.2,<1.0.0" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "alibabacloud-tea-util" @@ -287,7 +320,10 @@ files = [ [package.dependencies] alibabacloud-tea = ">=0.3.3" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "alibabacloud-tea-xml" @@ -302,7 +338,10 @@ files = [ [package.dependencies] alibabacloud-tea = ">=0.0.1" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "aliyun-python-sdk-core" @@ -318,7 +357,10 @@ files = [ cryptography = ">=2.6.0" jmespath = ">=0.9.3,<1.0.0" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "aliyun-python-sdk-core-v3" @@ -334,7 +376,10 @@ files = [ cryptography = ">=2.6.0" jmespath = ">=0.9.3,<1.0.0" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "aliyun-python-sdk-ecs" @@ -350,7 +395,10 @@ files = [ [package.dependencies] aliyun-python-sdk-core = ">=2.11.5" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "aliyun-python-sdk-kms" @@ -366,7 +414,10 @@ files = [ [package.dependencies] aliyun-python-sdk-core = ">=2.11.5" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "amqp" @@ -382,7 +433,10 @@ files = [ [package.dependencies] vine = ">=5.0.0" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "ansible" @@ -398,7 +452,10 @@ files = [ [package.dependencies] ansible-core = ">=2.14.1,<2.15.0" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "ansible-core" @@ -439,7 +496,10 @@ python-daemon = "*" pyyaml = "*" six = "*" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "anyio" @@ -461,7 +521,10 @@ doc = ["Sphinx", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd- test = ["anyio[trio]", "coverage[toml] (>=4.5)", "hypothesis (>=4.0)", "mock (>=4)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"] trio = ["trio (<0.22)"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "appnope" @@ -474,7 +537,10 @@ files = [ {file = "appnope-0.1.3.tar.gz", hash = "sha256:02bd91c4de869fbb1e1c50aafc4098827a7a54ab2f39d9dcba6c9547ed920e24"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "asgiref" @@ -490,7 +556,10 @@ files = [ [package.extras] tests = ["mypy (>=0.800)", "pytest", "pytest-asyncio"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "asn1crypto" @@ -503,7 +572,10 @@ files = [ {file = "asn1crypto-1.5.1.tar.gz", hash = "sha256:13ae38502be632115abf8a24cbe5f4da52e3b5231990aff31123c805306ccb9c"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "asttokens" @@ -522,7 +594,10 @@ six = "*" [package.extras] test = ["astroid", "pytest"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "async-timeout" @@ -535,7 +610,10 @@ files = [ {file = "async_timeout-4.0.2-py3-none-any.whl", hash = "sha256:8ca1e4fcf50d07413d66d1a5e416e42cfdf5851c981d679a09851a6853383b3c"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "attrs" @@ -555,7 +633,10 @@ docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib- tests = ["attrs[tests-no-zope]", "zope-interface"] tests-no-zope = ["cloudpickle", "hypothesis", "mypy (>=1.1.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "autobahn" @@ -585,7 +666,10 @@ twisted = ["attrs (>=20.3.0)", "twisted (>=20.3.0)", "zope.interface (>=5.2.0)"] ui = ["PyGObject (>=3.40.0)"] xbr = ["base58 (>=2.1.0)", "bitarray (>=2.7.5)", "cbor2 (>=5.2.0)", "click (>=8.1.2)", "ecdsa (>=0.16.1)", "eth-abi (>=4.0.0)", "hkdf (>=0.0.3)", "jinja2 (>=2.11.3)", "mnemonic (>=0.19)", "py-ecc (>=5.1.0)", "py-eth-sig-utils (>=0.4.0)", "py-multihash (>=2.0.1)", "rlp (>=2.0.1)", "spake2 (>=0.8)", "twisted (>=20.3.0)", "web3[ipfs] (>=6.0.0)", "xbr (>=21.2.1)", "yapf (==0.29.0)", "zlmdb (>=21.2.1)"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "automat" @@ -605,7 +689,10 @@ six = "*" [package.extras] visualize = ["Twisted (>=16.1.1)", "graphviz (>0.5.1)"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "azure-common" @@ -618,7 +705,10 @@ files = [ {file = "azure_common-1.1.28-py2.py3-none-any.whl", hash = "sha256:5c12d3dcf4ec20599ca6b0d3e09e86e146353d443e7fcc050c9a19c1f9df20ad"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "azure-core" @@ -639,7 +729,10 @@ typing-extensions = ">=4.3.0" [package.extras] aio = ["aiohttp (>=3.0)"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "azure-identity" @@ -659,7 +752,10 @@ msal = ">=1.20.0,<2.0.0" msal-extensions = ">=0.3.0,<2.0.0" six = ">=1.12.0" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "azure-mgmt-compute" @@ -677,7 +773,10 @@ azure-common = ">=1.1,<2.0" azure-mgmt-core = ">=1.3.2,<2.0.0" isodate = ">=0.6.1,<1.0.0" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "azure-mgmt-core" @@ -693,7 +792,10 @@ files = [ [package.dependencies] azure-core = ">=1.26.2,<2.0.0" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "azure-mgmt-network" @@ -711,7 +813,10 @@ azure-common = ">=1.1,<2.0" azure-mgmt-core = ">=1.3.2,<2.0.0" isodate = ">=0.6.1,<1.0.0" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "azure-mgmt-subscription" @@ -729,7 +834,10 @@ azure-common = ">=1.1,<2.0" azure-mgmt-core = ">=1.3.2,<2.0.0" msrest = ">=0.7.1" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "azure-storage-blob" @@ -751,7 +859,10 @@ typing-extensions = ">=4.3.0" [package.extras] aio = ["azure-core[aio] (>=1.28.0,<2.0.0)"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "backcall" @@ -764,7 +875,10 @@ files = [ {file = "backcall-0.2.0.tar.gz", hash = "sha256:5cbdbf27be5e7cfadb448baf0aa95508f91f2bbc6c6437cd9cd06e2a4c215e1e"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "bce-python-sdk" @@ -782,7 +896,10 @@ future = ">=0.6.0" pycryptodome = ">=3.8.0" six = ">=1.4.0" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "bcrypt" @@ -818,7 +935,10 @@ files = [ tests = ["pytest (>=3.2.1,!=3.3.0)"] typecheck = ["mypy"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "beautifulsoup4" @@ -838,7 +958,10 @@ soupsieve = ">1.2" html5lib = ["html5lib"] lxml = ["lxml"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "billiard" @@ -851,7 +974,10 @@ files = [ {file = "billiard-4.1.0.tar.gz", hash = "sha256:1ad2eeae8e28053d729ba3373d34d9d6e210f6e4d8bf0a9c64f92bd053f1edf5"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "boto" @@ -864,7 +990,10 @@ files = [ {file = "boto-2.49.0.tar.gz", hash = "sha256:ea0d3b40a2d852767be77ca343b58a9e3a4b00d9db440efb8da74b4e58025e5a"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "boto3" @@ -885,7 +1014,10 @@ s3transfer = ">=0.6.0,<0.7.0" [package.extras] crt = ["botocore[crt] (>=1.21.0,<2.0a0)"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "botocore" @@ -906,7 +1038,10 @@ urllib3 = ">=1.25.4,<1.27" [package.extras] crt = ["awscrt (==0.16.26)"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "cachetools" @@ -919,7 +1054,10 @@ files = [ {file = "cachetools-5.3.1.tar.gz", hash = "sha256:dce83f2d9b4e1f732a8cd44af8e8fab2dbe46201467fc98b3ef8f269092bf62b"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "celery" @@ -976,7 +1114,10 @@ yaml = ["PyYAML (>=3.10)"] zookeeper = ["kazoo (>=1.3.1)"] zstd = ["zstandard (==0.21.0)"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "certifi" @@ -989,7 +1130,10 @@ files = [ {file = "certifi-2023.7.22.tar.gz", hash = "sha256:539cc1d13202e33ca466e88b2807e29f4c13049d6d87031a3c110744495cb082"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "cffi" @@ -1067,7 +1211,10 @@ files = [ [package.dependencies] pycparser = "*" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "channels" @@ -1088,7 +1235,10 @@ Django = ">=3.2" daphne = ["daphne (>=4.0.0)"] tests = ["async-timeout", "coverage (>=4.5,<5.0)", "pytest", "pytest-asyncio", "pytest-django"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "channels-redis" @@ -1111,7 +1261,10 @@ redis = ">=4.5.3" cryptography = ["cryptography (>=1.3.0)"] tests = ["async-timeout", "cryptography (>=1.3.0)", "pytest", "pytest-asyncio", "pytest-timeout"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "chardet" @@ -1124,7 +1277,10 @@ files = [ {file = "chardet-5.1.0.tar.gz", hash = "sha256:0d62712b956bc154f85fb0a266e2a3c5913c2967e00348701b32411d6def31e5"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "charset-normalizer" @@ -1210,7 +1366,10 @@ files = [ {file = "charset_normalizer-3.2.0-py3-none-any.whl", hash = "sha256:8e098148dd37b4ce3baca71fb394c81dc5d9c7728c95df695d2dca218edf40e6"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "click" @@ -1226,7 +1385,10 @@ files = [ [package.dependencies] colorama = {version = "*", markers = "platform_system == \"Windows\""} - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "click-didyoumean" @@ -1242,7 +1404,10 @@ files = [ [package.dependencies] click = ">=7" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "click-plugins" @@ -1261,7 +1426,10 @@ click = ">=4.0" [package.extras] dev = ["coveralls", "pytest (>=3.6)", "pytest-cov", "wheel"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "click-repl" @@ -1281,7 +1449,10 @@ prompt-toolkit = ">=3.0.36" [package.extras] testing = ["pytest (>=7.2.1)", "pytest-cov (>=4.0.0)", "tox (>=4.4.3)"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "colorama" @@ -1294,7 +1465,10 @@ files = [ {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "configparser" @@ -1311,7 +1485,10 @@ files = [ docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] testing = ["pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-ruff", "types-backports"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "constantly" @@ -1324,7 +1501,10 @@ files = [ {file = "constantly-15.1.0.tar.gz", hash = "sha256:586372eb92059873e29eba4f9dec8381541b4d3834660707faf8ba59146dfc35"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "coreapi" @@ -1343,7 +1523,10 @@ itypes = "*" requests = "*" uritemplate = "*" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "coreschema" @@ -1359,7 +1542,10 @@ files = [ [package.dependencies] jinja2 = "*" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "crcmod" @@ -1371,7 +1557,10 @@ files = [ {file = "crcmod-1.7.tar.gz", hash = "sha256:dc7051a0db5f2bd48665a990d3ec1cc305a466a77358ca4492826f41f283601e"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "cron-descriptor" @@ -1386,7 +1575,10 @@ files = [ [package.extras] dev = ["polib"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "cryptography" @@ -1433,7 +1625,10 @@ ssh = ["bcrypt (>=3.1.5)"] test = ["pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] test-randomorder = ["pytest-randomly"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "cython" @@ -1502,7 +1697,10 @@ files = [ {file = "Cython-3.0.0.tar.gz", hash = "sha256:350b18f9673e63101dbbfcf774ee2f57c20ac4636d255741d76ca79016b1bd82"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "daphne" @@ -1523,7 +1721,10 @@ twisted = {version = ">=22.4", extras = ["tls"]} [package.extras] tests = ["django", "hypothesis", "pytest", "pytest-asyncio"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "data-tree" @@ -1536,7 +1737,10 @@ files = [ {file = "data_tree-0.0.1.tar.gz", hash = "sha256:06f2a18b372cf2451166d426591f6e6fc73a7aabcad97255d50927aa3c3d5a0e"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "debtcollector" @@ -1552,7 +1756,10 @@ files = [ [package.dependencies] wrapt = ">=1.7.0" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "decorator" @@ -1565,7 +1772,10 @@ files = [ {file = "decorator-5.1.1.tar.gz", hash = "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "django" @@ -1587,7 +1797,10 @@ tzdata = {version = "*", markers = "sys_platform == \"win32\""} argon2 = ["argon2-cffi (>=19.1.0)"] bcrypt = ["bcrypt"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "django-auth-ldap" @@ -1604,7 +1817,10 @@ files = [ Django = ">=3.2" python-ldap = ">=3.1" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "django-bootstrap3" @@ -1621,7 +1837,10 @@ files = [ beautifulsoup4 = ">=4.8.0" django = ">=3.2" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "django-cas-ng" @@ -1660,7 +1879,10 @@ django-timezone-field = ">=5.0" python-crontab = ">=2.3.4" tzdata = "*" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "django-debug-toolbar" @@ -1677,7 +1899,10 @@ files = [ django = ">=3.2.4" sqlparse = ">=0.2" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "django-filter" @@ -1693,7 +1918,10 @@ files = [ [package.dependencies] Django = ">=3.2" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "django-formtools" @@ -1709,7 +1937,10 @@ files = [ [package.dependencies] Django = ">=3.2" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "django-private-storage" @@ -1722,7 +1953,10 @@ files = [ {file = "django_private_storage-3.1-py3-none-any.whl", hash = "sha256:cd11fa3c40e15bf902b3566dde8082c86f1cbb2900115f15c63e4b5278d96fe7"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "django-proxy" @@ -1737,7 +1971,10 @@ files = [ [package.dependencies] requests = "*" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "django-radius" @@ -1769,7 +2006,10 @@ files = [ [package.dependencies] django = "*" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "django-redis" @@ -1789,7 +2029,10 @@ redis = ">=3,<4.0.0 || >4.0.0,<4.0.1 || >4.0.1" [package.extras] hiredis = ["redis[hiredis] (>=3,!=4.0.0,!=4.0.1)"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "django-rest-swagger" @@ -1808,7 +2051,10 @@ djangorestframework = ">=3.5.4" openapi-codec = ">=1.3.1" simplejson = "*" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "django-simple-captcha" @@ -1829,7 +2075,10 @@ Pillow = ">=6.2.0" [package.extras] test = ["testfixtures"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "django-simple-history" @@ -1842,7 +2091,10 @@ files = [ {file = "django_simple_history-3.3.0-py3-none-any.whl", hash = "sha256:dc1f98e558a0a1e0b6371c3b8efb85f86e02a6db56e83d0ec198343b7408d00a"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "django-timezone-field" @@ -1859,7 +2111,10 @@ files = [ Django = ">=2.2,<3.0.dev0 || >=3.2.dev0,<5.0" pytz = "*" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "djangorestframework" @@ -1876,7 +2131,10 @@ files = [ django = ">=3.0" pytz = "*" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "djangorestframework-bulk" @@ -1893,7 +2151,10 @@ django = "*" djangorestframework = "*" setuptools = "*" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "dnspython" @@ -1914,7 +2175,10 @@ idna = ["idna (>=2.1,<4.0)"] trio = ["trio (>=0.14,<0.23)"] wmi = ["wmi (>=1.5.1,<2.0.0)"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "docutils" @@ -1927,7 +2191,10 @@ files = [ {file = "docutils-0.20.1.tar.gz", hash = "sha256:f08a4e276c3a1583a86dce3e34aba3fe04d02bba2dd51ed16106244e8a923e3b"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "drf-nested-routers" @@ -1944,7 +2211,10 @@ files = [ Django = ">=1.11" djangorestframework = ">=3.6.0" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "drf-writable-nested" @@ -1956,7 +2226,10 @@ files = [ {file = "drf_writable_nested-0.7.0-py3-none-any.whl", hash = "sha256:154c0381e8a3a477e0fd539d5e1caf8ff4c1097a9c0c0fe741d4858b11b0455b"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "drf-yasg" @@ -1982,7 +2255,10 @@ uritemplate = ">=3.0.0" coreapi = ["coreapi (>=2.3.3)", "coreschema (>=0.0.4)"] validation = ["swagger-spec-validator (>=2.1.0)"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "ecdsa" @@ -2002,7 +2278,10 @@ six = ">=1.9.0" gmpy = ["gmpy"] gmpy2 = ["gmpy2"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "elastic-transport" @@ -2022,7 +2301,10 @@ urllib3 = ">=1.26.2,<2" [package.extras] develop = ["aiohttp", "mock", "pytest", "pytest-asyncio", "pytest-cov", "pytest-httpserver", "pytest-mock", "requests", "trustme"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "elasticsearch" @@ -2042,7 +2324,10 @@ elastic-transport = ">=8,<9" async = ["aiohttp (>=3,<4)"] requests = ["requests (>=2.4.0,<3.0.0)"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "enum-compat" @@ -2055,7 +2340,10 @@ files = [ {file = "enum_compat-0.0.3-py3-none-any.whl", hash = "sha256:88091b617c7fc3bbbceae50db5958023c48dc40b50520005aa3bf27f8f7ea157"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "ephem" @@ -2133,7 +2421,10 @@ files = [ {file = "ephem-4.1.4.tar.gz", hash = "sha256:73a59f0d2162d1624535c3c3b75f956556bdbb2055eaf554a7bef147d3f9c760"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "esdk-obs-python" @@ -2145,7 +2436,10 @@ files = [ {file = "esdk-obs-python-3.21.4.tar.gz", hash = "sha256:a3b2a01b0a10768b5b02812abe239048feaae199256cbde67315870121d8ab1e"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "et-xmlfile" @@ -2158,7 +2452,10 @@ files = [ {file = "et_xmlfile-1.1.0.tar.gz", hash = "sha256:8eb9e2bc2f8c97e37a2dc85a09ecdcdec9d8a396530a6d5a33b30b9a92da0c5c"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "eventlet" @@ -2176,7 +2473,10 @@ dnspython = ">=1.15.0" greenlet = ">=0.3" six = ">=1.10.0" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "executing" @@ -2192,7 +2492,10 @@ files = [ [package.extras] tests = ["asttokens", "littleutils", "pytest", "rich"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "flower" @@ -2212,7 +2515,10 @@ prometheus-client = ">=0.8.0" pytz = "*" tornado = ">=5.0.0,<7.0.0" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "forgerypy3" @@ -2224,7 +2530,10 @@ files = [ {file = "ForgeryPy3-0.3.1.tar.gz", hash = "sha256:03db26b2129252dc8c8c91aa5661171725a64707773c03c3ca0251b1dd173c93"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "frozenlist" @@ -2296,7 +2605,10 @@ files = [ {file = "frozenlist-1.4.0.tar.gz", hash = "sha256:09163bdf0b2907454042edb19f887c6d33806adc71fbd54afc14908bfdc22251"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "future" @@ -2308,7 +2620,10 @@ files = [ {file = "future-0.18.3.tar.gz", hash = "sha256:34a17436ed1e96697a86f9de3d15a3b0be01d8bc8de9c1dffd59fb8234ed5307"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "geoip2" @@ -2326,7 +2641,10 @@ aiohttp = ">=3.6.2,<4.0.0" maxminddb = ">=2.3.0,<3.0.0" requests = ">=2.24.0,<3.0.0" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "gmssl" @@ -2341,7 +2659,10 @@ files = [ [package.dependencies] pycryptodomex = "*" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "google-api-core" @@ -2373,7 +2694,10 @@ grpc = ["grpcio (>=1.33.2,<2.0dev)", "grpcio (>=1.49.1,<2.0dev)", "grpcio-status grpcgcp = ["grpcio-gcp (>=0.2.2,<1.0.dev0)"] grpcio-gcp = ["grpcio-gcp (>=0.2.2,<1.0.dev0)"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "google-auth" @@ -2400,7 +2724,10 @@ pyopenssl = ["cryptography (>=38.0.3)", "pyopenssl (>=20.0.0)"] reauth = ["pyu2f (>=0.1.5)"] requests = ["requests (>=2.20.0,<3.0.0.dev0)"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "google-cloud-compute" @@ -2418,7 +2745,10 @@ google-api-core = {version = ">=1.34.0,<2.0.dev0 || >=2.11.dev0,<3.0.0dev", extr proto-plus = {version = ">=1.22.2,<2.0.0dev", markers = "python_version >= \"3.11\""} protobuf = ">=3.19.5,<3.20.0 || >3.20.0,<3.20.1 || >3.20.1,<4.21.0 || >4.21.0,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<5.0.0dev" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "googleapis-common-protos" @@ -2437,7 +2767,10 @@ protobuf = ">=3.19.5,<3.20.0 || >3.20.0,<3.20.1 || >3.20.1,<4.21.1 || >4.21.1,<4 [package.extras] grpc = ["grpcio (>=1.44.0,<2.0.0.dev0)"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "greenlet" @@ -2512,7 +2845,10 @@ files = [ docs = ["Sphinx", "docutils (<0.18)"] test = ["objgraph", "psutil"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "grpcio" @@ -2571,7 +2907,10 @@ files = [ [package.extras] protobuf = ["grpcio-tools (>=1.56.2)"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "grpcio-status" @@ -2589,7 +2928,10 @@ googleapis-common-protos = ">=1.5.5" grpcio = ">=1.56.2" protobuf = ">=4.21.6" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "gunicorn" @@ -2611,7 +2953,10 @@ gevent = ["gevent (>=1.4.0)"] setproctitle = ["setproctitle"] tornado = ["tornado (>=0.2)"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "h11" @@ -2624,7 +2969,10 @@ files = [ {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "html2text" @@ -2637,7 +2985,10 @@ files = [ {file = "html2text-2020.1.16.tar.gz", hash = "sha256:e296318e16b059ddb97f7a8a1d6a5c1d7af4544049a01e261731d2d5cc277bbb"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "httpsig" @@ -2654,7 +3005,10 @@ files = [ pycryptodome = ">=3,<4" six = "*" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "httptools" @@ -2703,7 +3057,10 @@ files = [ [package.extras] test = ["Cython (>=0.29.24,<0.30.0)"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "humanize" @@ -2719,7 +3076,10 @@ files = [ [package.extras] tests = ["freezegun", "pytest", "pytest-cov"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "hvac" @@ -2736,7 +3096,10 @@ files = [ pyhcl = ">=0.4.4,<0.5.0" requests = ">=2.27.1,<3.0.0" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "hyperlink" @@ -2752,7 +3115,10 @@ files = [ [package.dependencies] idna = ">=2.5" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "idna" @@ -2765,7 +3131,10 @@ files = [ {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "incremental" @@ -2782,7 +3151,10 @@ files = [ mypy = ["click (>=6.0)", "mypy (==0.812)", "twisted (>=16.4.0)"] scripts = ["click (>=6.0)", "twisted (>=16.4.0)"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "inflection" @@ -2795,7 +3167,10 @@ files = [ {file = "inflection-0.5.1.tar.gz", hash = "sha256:1a29730d366e996aaacffb2f1f1cb9593dc38e2ddd30c91250c6dde09ea9b417"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "ipip-ipdb" @@ -2807,7 +3182,10 @@ files = [ {file = "ipip-ipdb-1.6.1.tar.gz", hash = "sha256:4f396f8f8b1a2fc7fe3c41e1b05b479aac9aa1bc310b5b0182dbaa5376dc0bb9"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "ipy" @@ -2819,7 +3197,10 @@ files = [ {file = "IPy-1.01.tar.gz", hash = "sha256:edeca741dea2d54aca568fa23740288c3fe86c0f3ea700344571e9ef14a7cc1a"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "ipython" @@ -2859,7 +3240,10 @@ qtconsole = ["qtconsole"] test = ["pytest (<7.1)", "pytest-asyncio", "testpath"] test-extra = ["curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.21)", "pandas", "pytest (<7.1)", "pytest-asyncio", "testpath", "trio"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "iso8601" @@ -2872,7 +3256,10 @@ files = [ {file = "iso8601-2.0.0.tar.gz", hash = "sha256:739960d37c74c77bd9bd546a76562ccb581fe3d4820ff5c3141eb49c839fda8f"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "isodate" @@ -2888,7 +3275,10 @@ files = [ [package.dependencies] six = "*" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "itsdangerous" @@ -2901,7 +3291,10 @@ files = [ {file = "itsdangerous-1.1.0.tar.gz", hash = "sha256:321b033d07f2a4136d3ec762eac9f16a10ccd60f53c0c91af90217ace7ba1f19"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "itypes" @@ -2914,7 +3307,10 @@ files = [ {file = "itypes-1.2.0.tar.gz", hash = "sha256:af886f129dea4a2a1e3d36595a2d139589e4dd287f5cab0b40e799ee81570ff1"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "jedi" @@ -2935,7 +3331,10 @@ docs = ["Jinja2 (==2.11.3)", "MarkupSafe (==1.1.1)", "Pygments (==2.8.1)", "alab qa = ["flake8 (==5.0.4)", "mypy (==0.971)", "types-setuptools (==67.2.0.1)"] testing = ["Django (<3.1)", "attrs", "colorama", "docopt", "pytest (<7.0.0)"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "jinja2" @@ -2954,7 +3353,10 @@ MarkupSafe = ">=2.0" [package.extras] i18n = ["Babel (>=2.7)"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "jmespath" @@ -2967,7 +3369,10 @@ files = [ {file = "jmespath-0.10.0.tar.gz", hash = "sha256:b85d0567b8666149a93172712e68920734333c0ce7e89b78b3e987f71e5ed4f9"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "jms-storage" @@ -2998,7 +3403,10 @@ requests = "2.31.0" s3transfer = "0.6.1" six = "1.16.0" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "jsonfield2" @@ -3014,7 +3422,10 @@ files = [ [package.dependencies] Django = ">=2.2" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "keystoneauth1" @@ -3041,7 +3452,10 @@ oauth1 = ["oauthlib (>=0.6.2)"] saml2 = ["lxml (>=4.2.0)"] test = ["PyYAML (>=3.12)", "bandit (>=1.1.0,<1.6.0)", "betamax (>=0.7.0)", "coverage (>=4.0,!=4.4)", "fixtures (>=3.0.0)", "flake8-docstrings (>=1.6.0,<1.7.0)", "flake8-import-order (>=0.17.1)", "hacking (>=4.1.0,<4.2.0)", "lxml (>=4.2.0)", "oauthlib (>=0.6.2)", "oslo.config (>=5.2.0)", "oslo.utils (>=3.33.0)", "oslotest (>=3.2.0)", "reno (>=3.1.0)", "requests-kerberos (>=0.8.0)", "requests-mock (>=1.2.0)", "stestr (>=1.0.0)", "testresources (>=2.0.0)", "testtools (>=2.2.0)"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "kombu" @@ -3075,7 +3489,10 @@ sqs = ["boto3 (>=1.26.143)", "pycurl (>=7.43.0.5)", "urllib3 (>=1.26.16)"] yaml = ["PyYAML (>=3.10)"] zookeeper = ["kazoo (>=2.8.0)"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "kubernetes" @@ -3103,7 +3520,10 @@ websocket-client = ">=0.32.0,<0.40.0 || >0.40.0,<0.41.dev0 || >=0.43.dev0" [package.extras] adal = ["adal (>=1.0.2)"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "ldap3" @@ -3119,7 +3539,10 @@ files = [ [package.dependencies] pyasn1 = ">=0.4.6" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "lml" @@ -3132,7 +3555,10 @@ files = [ {file = "lml-0.1.0.tar.gz", hash = "sha256:57a085a29bb7991d70d41c6c3144c560a8e35b4c1030ffb36d85fa058773bcc5"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "lockfile" @@ -3145,7 +3571,10 @@ files = [ {file = "lockfile-0.12.2.tar.gz", hash = "sha256:6aed02de03cba24efabcd600b30540140634fc06cfa603822d508d5361e9f799"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "lxml" @@ -3254,7 +3683,10 @@ html5 = ["html5lib"] htmlsoup = ["BeautifulSoup4"] source = ["Cython (>=0.29.35)"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "markupsafe" @@ -3315,7 +3747,10 @@ files = [ {file = "MarkupSafe-2.1.3.tar.gz", hash = "sha256:af598ed32d6ae86f1b747b82783958b1a4ab8f617b06fe68795c7f026abbdcad"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "matplotlib-inline" @@ -3331,7 +3766,10 @@ files = [ [package.dependencies] traitlets = "*" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "maxminddb" @@ -3343,7 +3781,10 @@ files = [ {file = "maxminddb-2.4.0.tar.gz", hash = "sha256:81e54e53408bd502650e5969ccba16780af659ec1db1c44b2c997e4330a5ed96"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "msal" @@ -3364,7 +3805,10 @@ requests = ">=2.0.0,<3" [package.extras] broker = ["pymsalruntime (>=0.13.2,<0.14)"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "msal-extensions" @@ -3384,7 +3828,10 @@ portalocker = [ {version = ">=1.6,<3", markers = "python_version >= \"3.5\" and platform_system == \"Windows\""}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "msgpack" @@ -3458,7 +3905,10 @@ files = [ {file = "msgpack-1.0.5.tar.gz", hash = "sha256:c075544284eadc5cddc70f4757331d99dcbc16b2bbd4849d15f8aae4cf36d31c"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "msrest" @@ -3481,7 +3931,10 @@ requests-oauthlib = ">=0.5.0" [package.extras] async = ["aiodns", "aiohttp (>=3.0)"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "msrestazure" @@ -3499,7 +3952,10 @@ adal = ">=0.6.0,<2.0.0" msrest = ">=0.6.0,<2.0.0" six = "*" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "multidict" @@ -3584,7 +4040,10 @@ files = [ {file = "multidict-6.0.4.tar.gz", hash = "sha256:3666906492efb76453c0e7b97f2cf459b0682e7402c0489a95484965dbc1da49"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "mysqlclient" @@ -3602,7 +4061,10 @@ files = [ {file = "mysqlclient-2.2.0.tar.gz", hash = "sha256:04368445f9c487d8abb7a878e3d23e923e6072c04a6c320f9e0dc8a82efba14e"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "netaddr" @@ -3615,7 +4077,10 @@ files = [ {file = "netaddr-0.8.0.tar.gz", hash = "sha256:d6cc57c7a07b1d9d2e917aa8b36ae8ce61c35ba3fcd1b83ca31c5a0ee2b5a243"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "netifaces" @@ -3656,7 +4121,10 @@ files = [ {file = "netifaces-0.11.0.tar.gz", hash = "sha256:043a79146eb2907edf439899f262b3dfe41717d34124298ed281139a8b93ca32"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "oauthlib" @@ -3674,7 +4142,10 @@ rsa = ["cryptography (>=3.0.0)"] signals = ["blinker (>=1.4.0)"] signedtoken = ["cryptography (>=3.0.0)", "pyjwt (>=2.0.0,<3)"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "olefile" @@ -3686,7 +4157,10 @@ files = [ {file = "olefile-0.46.zip", hash = "sha256:133b031eaf8fd2c9399b78b8bc5b8fcbe4c31e85295749bb17a87cba8f3c3964"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "openapi-codec" @@ -3701,7 +4175,10 @@ files = [ [package.dependencies] coreapi = ">=2.2.0" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "openpyxl" @@ -3717,7 +4194,10 @@ files = [ [package.dependencies] et-xmlfile = "*" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "oracledb" @@ -3759,7 +4239,10 @@ files = [ [package.dependencies] cryptography = ">=3.2.1" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "os-service-types" @@ -3775,7 +4258,10 @@ files = [ [package.dependencies] pbr = ">=2.0.0,<2.1.0 || >2.1.0" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "oslo-config" @@ -3801,7 +4287,10 @@ stevedore = ">=1.20.0" rst-generator = ["rst2txt (>=1.1.0)", "sphinx (>=1.8.0,!=2.1.0)"] test = ["bandit (>=1.6.0,<1.7.0)", "coverage (>=4.0,!=4.4)", "fixtures (>=3.0.0)", "hacking (>=3.0.1,<3.1.0)", "mypy (>=0.720)", "oslo.log (>=3.36.0)", "oslotest (>=3.2.0)", "pre-commit (>=2.6.0)", "requests-mock (>=1.5.0)", "stestr (>=2.1.0)", "testscenarios (>=0.4)", "testtools (>=2.2.0)"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "oslo-i18n" @@ -3817,7 +4306,10 @@ files = [ [package.dependencies] pbr = ">=2.0.0,<2.1.0 || >2.1.0" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "oslo-serialization" @@ -3836,7 +4328,10 @@ msgpack = ">=0.5.2" pbr = ">=2.0.0,<2.1.0 || >2.1.0" pytz = ">=2013.6" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "oslo-utils" @@ -3860,7 +4355,10 @@ pyparsing = ">=2.1.0" pytz = ">=2013.6" tzdata = ">=2022.4" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "oss2" @@ -3880,7 +4378,10 @@ pycryptodome = ">=3.4.7" requests = "!=2.9.0" six = "*" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "packaging" @@ -3893,7 +4394,10 @@ files = [ {file = "packaging-23.1.tar.gz", hash = "sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "paramiko" @@ -3916,7 +4420,10 @@ all = ["gssapi (>=1.4.1)", "invoke (>=2.0)", "pyasn1 (>=0.1.7)", "pywin32 (>=2.1 gssapi = ["gssapi (>=1.4.1)", "pyasn1 (>=0.1.7)", "pywin32 (>=2.1.8)"] invoke = ["invoke (>=2.0)"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "parso" @@ -3933,7 +4440,10 @@ files = [ qa = ["flake8 (==3.8.3)", "mypy (==0.782)"] testing = ["docopt", "pytest (<6.0.0)"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "passlib" @@ -3952,7 +4462,10 @@ bcrypt = ["bcrypt (>=3.1.0)"] build-docs = ["cloud-sptheme (>=1.10.1)", "sphinx (>=1.6)", "sphinxcontrib-fulltoc (>=1.2.0)"] totp = ["cryptography"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "pbr" @@ -3965,7 +4478,10 @@ files = [ {file = "pbr-5.11.1.tar.gz", hash = "sha256:aefc51675b0b533d56bb5fd1c8c6c0522fe31896679882e1c4c63d5e4a0fccb3"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "pexpect" @@ -3981,7 +4497,10 @@ files = [ [package.dependencies] ptyprocess = ">=0.5" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "phonenumbers" @@ -3994,7 +4513,10 @@ files = [ {file = "phonenumbers-8.13.17.tar.gz", hash = "sha256:89671217c706cbaa3ced101deefafa779836feac3e059434d886ac31f09f32c0"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "pickleshare" @@ -4007,7 +4529,10 @@ files = [ {file = "pickleshare-0.7.5.tar.gz", hash = "sha256:87683d47965c1da65cdacaf31c8441d12b8044cdec9aca500cd78fc2c683afca"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "pillow" @@ -4078,7 +4603,10 @@ files = [ docs = ["furo", "olefile", "sphinx (>=2.4)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinx-removed-in", "sphinxext-opengraph"] tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "portalocker" @@ -4099,7 +4627,10 @@ docs = ["sphinx (>=1.7.1)"] redis = ["redis"] tests = ["pytest (>=5.4.1)", "pytest-cov (>=2.8.1)", "pytest-mypy (>=0.8.0)", "pytest-timeout (>=2.1.0)", "redis", "sphinx (>=6.0.0)"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "prettytable" @@ -4118,7 +4649,10 @@ wcwidth = "*" [package.extras] tests = ["pytest", "pytest-cov", "pytest-lazy-fixture"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "prometheus-client" @@ -4134,7 +4668,10 @@ files = [ [package.extras] twisted = ["twisted"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "prompt-toolkit" @@ -4150,7 +4687,10 @@ files = [ [package.dependencies] wcwidth = "*" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "proto-plus" @@ -4169,7 +4709,10 @@ protobuf = ">=3.19.0,<5.0.0dev" [package.extras] testing = ["google-api-core[grpc] (>=1.31.5)"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "protobuf" @@ -4193,7 +4736,10 @@ files = [ {file = "protobuf-4.23.4.tar.gz", hash = "sha256:ccd9430c0719dce806b93f89c91de7977304729e55377f872a92465d548329a9"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "psutil" @@ -4221,7 +4767,10 @@ files = [ [package.extras] test = ["enum34", "ipaddress", "mock", "pywin32", "wmi"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "psycopg2" @@ -4245,7 +4794,10 @@ files = [ {file = "psycopg2-2.9.6.tar.gz", hash = "sha256:f15158418fd826831b28585e2ab48ed8df2d0d98f502a2b4fe619e7d5ca29011"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "psycopg2-binary" @@ -4318,7 +4870,10 @@ files = [ {file = "psycopg2_binary-2.9.6-cp39-cp39-win_amd64.whl", hash = "sha256:f6a88f384335bb27812293fdb11ac6aee2ca3f51d3c7820fe03de0a304ab6249"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "ptyprocess" @@ -4331,7 +4886,10 @@ files = [ {file = "ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "pure-eval" @@ -4347,7 +4905,10 @@ files = [ [package.extras] tests = ["pytest"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "pyasn1" @@ -4360,7 +4921,10 @@ files = [ {file = "pyasn1-0.5.0.tar.gz", hash = "sha256:97b7290ca68e62a832558ec3976f15cbf911bf5d7c7039d8b861c2a0ece69fde"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "pyasn1-modules" @@ -4376,7 +4940,10 @@ files = [ [package.dependencies] pyasn1 = ">=0.4.6,<0.6.0" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "pycparser" @@ -4389,7 +4956,10 @@ files = [ {file = "pycparser-2.21.tar.gz", hash = "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "pycryptodome" @@ -4432,7 +5002,10 @@ files = [ {file = "pycryptodome-3.18.0.tar.gz", hash = "sha256:c9adee653fc882d98956e33ca2c1fb582e23a8af7ac82fee75bd6113c55a0413"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "pycryptodomex" @@ -4475,7 +5048,10 @@ files = [ {file = "pycryptodomex-3.18.0.tar.gz", hash = "sha256:3e3ecb5fe979e7c1bb0027e518340acf7ee60415d79295e5251d13c68dde576e"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "pyexcel" @@ -4499,7 +5075,10 @@ ods = ["pyexcel-ods3 (>=0.6.0)"] xls = ["pyexcel-xls (>=0.6.0)"] xlsx = ["pyexcel-xlsx (>=0.6.0)"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "pyexcel-io" @@ -4520,7 +5099,10 @@ ods = ["pyexcel-ods3 (>=0.6.0)"] xls = ["pyexcel-xls (>=0.6.0)"] xlsx = ["pyexcel-xlsx (>=0.6.0)"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "pyexcel-xlsx" @@ -4537,7 +5119,10 @@ files = [ openpyxl = ">=2.6.1" pyexcel-io = ">=0.6.2" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "pyfreerdp" @@ -4580,7 +5165,10 @@ files = [ {file = "pyfreerdp-0.0.1.tar.gz", hash = "sha256:946eca882741e6802794185cbdd47b49626c3181bce99dbd27c5746563c13d43"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "pygments" @@ -4596,7 +5184,10 @@ files = [ [package.extras] plugins = ["importlib-metadata"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "pyhcl" @@ -4608,7 +5199,10 @@ files = [ {file = "pyhcl-0.4.4.tar.gz", hash = "sha256:2d9b9dcdf1023d812bfed561ba72c99104c5b3f52e558d595130a44ce081b003"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "pyjwkest" @@ -4626,7 +5220,10 @@ pycryptodomex = "*" requests = "*" six = "*" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "pyjwt" @@ -4648,7 +5245,10 @@ dev = ["coverage[toml] (==5.0.4)", "cryptography (>=3.4.0)", "pre-commit", "pyte docs = ["sphinx (>=4.5.0,<5.0.0)", "sphinx-rtd-theme", "zope.interface"] tests = ["coverage[toml] (==5.0.4)", "pytest (>=6.0.0,<7.0.0)"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "pymongo" @@ -4744,7 +5344,10 @@ ocsp = ["certifi", "pyopenssl (>=17.2.0)", "requests (<3.0.0)", "service-identit snappy = ["python-snappy"] zstd = ["zstandard"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "pympler" @@ -4757,7 +5360,10 @@ files = [ {file = "Pympler-1.0.1.tar.gz", hash = "sha256:993f1a3599ca3f4fcd7160c7545ad06310c9e12f70174ae7ae8d4e25f6c5d3fa"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "pymssql" @@ -4829,7 +5435,10 @@ files = [ {file = "pymssql-2.2.7.tar.gz", hash = "sha256:ff95b910532ec7b02e4322231c117d3d6af0abab667e6fbf15442db873943045"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "pymysql" @@ -4846,7 +5455,10 @@ files = [ ed25519 = ["PyNaCl (>=1.4.0)"] rsa = ["cryptography"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "pynacl" @@ -4874,7 +5486,10 @@ cffi = ">=1.4.1" docs = ["sphinx (>=1.6.5)", "sphinx-rtd-theme"] tests = ["hypothesis (>=3.27.0)", "pytest (>=3.2.1,!=3.3.0)"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "pyopenssl" @@ -4894,7 +5509,10 @@ cryptography = ">=38.0.0,<40.0.0 || >40.0.0,<40.0.1 || >40.0.1,<42" docs = ["sphinx (!=5.2.0,!=5.2.0.post0)", "sphinx-rtd-theme"] test = ["flaky", "pretend", "pytest (>=3.0.1)"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "pyotp" @@ -4907,7 +5525,10 @@ files = [ {file = "pyotp-2.8.0.tar.gz", hash = "sha256:c2f5e17d9da92d8ec1f7de6331ab08116b9115adbabcba6e208d46fc49a98c5a"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "pyparsing" @@ -4923,7 +5544,10 @@ files = [ [package.extras] diagrams = ["jinja2", "railroad-diagrams"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "pyrad" @@ -4940,7 +5564,10 @@ files = [ netaddr = "*" six = "*" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "pyspnego" @@ -4970,7 +5597,10 @@ cryptography = "*" kerberos = ["gssapi (>=1.6.0)", "krb5 (>=0.3.0)"] yaml = ["ruamel.yaml"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "python-cas" @@ -4988,7 +5618,10 @@ lxml = ">=3.4" requests = ">=2.11.1" six = ">=1.10.0" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "python-crontab" @@ -5008,7 +5641,10 @@ python-dateutil = "*" cron-description = ["cron-descriptor"] cron-schedule = ["croniter"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "python-daemon" @@ -5030,7 +5666,10 @@ setuptools = ">=62.4.0" devel = ["coverage", "docutils", "isort", "testscenarios (>=0.4)", "testtools", "twine"] test = ["coverage", "docutils", "testscenarios (>=0.4)", "testtools"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "python-dateutil" @@ -5046,7 +5685,10 @@ files = [ [package.dependencies] six = ">=1.5" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "python-dotenv" @@ -5062,7 +5704,10 @@ files = [ [package.extras] cli = ["click (>=5.0)"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "python-keystoneclient" @@ -5088,7 +5733,10 @@ requests = ">=2.14.2" six = ">=1.10.0" stevedore = ">=1.20.0" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "python-ldap" @@ -5104,7 +5752,10 @@ files = [ pyasn1 = ">=0.3.7" pyasn1_modules = ">=0.1.5" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "python-nmap" @@ -5116,7 +5767,10 @@ files = [ {file = "python-nmap-0.7.1.tar.gz", hash = "sha256:f75af6b91dd8e3b0c31f869db32163f62ada686945e5b7c25f84bc0f7fad3b64"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "python-novaclient" @@ -5139,7 +5793,10 @@ pbr = ">=2.0.0,<2.1.0 || >2.1.0" PrettyTable = ">=0.7.2" stevedore = ">=2.0.1" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "python-redis-lock" @@ -5158,7 +5815,10 @@ redis = ">=2.10.0" [package.extras] django = ["django-redis (>=3.8.0)"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "python3-saml" @@ -5180,7 +5840,10 @@ xmlsec = ">=1.3.9" [package.extras] test = ["coverage (>=4.5.2)", "flake8 (>=3.6.0,<=5.0.0)", "freezegun (>=0.3.11,<=1.1.0)", "pytest (>=4.6)"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "pytz" @@ -5193,7 +5856,10 @@ files = [ {file = "pytz-2023.3.tar.gz", hash = "sha256:1d8ce29db189191fb55338ee6d0387d82ab59f3d00eac103412d64e0ebd0c588"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "pyvmomi" @@ -5211,7 +5877,10 @@ six = ">=1.7.3" [package.extras] sso = ["lxml", "pyOpenSSL", "pywin32"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "pywin32" @@ -5236,7 +5905,10 @@ files = [ {file = "pywin32-306-cp39-cp39-win_amd64.whl", hash = "sha256:39b61c15272833b5c329a2989999dcae836b1eed650252ab1b7bfbe1d59f30f4"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "pywinrm" @@ -5259,7 +5931,10 @@ xmltodict = "*" credssp = ["requests-credssp (>=1.0.0)"] kerberos = ["pykerberos (>=1.2.1,<2.0.0)", "winkerberos (>=0.5.0)"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "pyyaml" @@ -5310,7 +5985,10 @@ files = [ {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "pyzipper" @@ -5326,7 +6004,10 @@ files = [ [package.dependencies] pycryptodomex = "*" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "qingcloud-sdk" @@ -5342,7 +6023,10 @@ files = [ [package.dependencies] future = "*" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "redis" @@ -5362,7 +6046,10 @@ async-timeout = {version = ">=4.0.2", markers = "python_full_version <= \"3.11.2 hiredis = ["hiredis (>=1.0.0)"] ocsp = ["cryptography (>=36.0.1)", "pyopenssl (==20.0.1)", "requests (>=2.26.0)"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "requests" @@ -5385,7 +6072,10 @@ urllib3 = ">=1.21.1,<3" socks = ["PySocks (>=1.5.6,!=1.5.7)"] use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "requests-ntlm" @@ -5403,7 +6093,10 @@ cryptography = ">=1.3" pyspnego = ">=0.1.6" requests = ">=2.0.0" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "requests-oauthlib" @@ -5423,7 +6116,10 @@ requests = ">=2.0.0" [package.extras] rsa = ["oauthlib[signedtoken] (>=3.0.0)"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "resolvelib" @@ -5442,7 +6138,10 @@ lint = ["black", "flake8", "isort", "mypy", "types-requests"] release = ["build", "towncrier", "twine"] test = ["commentjson", "packaging", "pytest"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "rest-condition" @@ -5458,7 +6157,10 @@ files = [ django = ">=1.3" djangorestframework = "*" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "rfc3986" @@ -5474,7 +6176,10 @@ files = [ [package.extras] idna2008 = ["idna"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "rsa" @@ -5490,7 +6195,10 @@ files = [ [package.dependencies] pyasn1 = ">=0.1.3" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "s3transfer" @@ -5509,7 +6217,10 @@ botocore = ">=1.12.36,<2.0a.0" [package.extras] crt = ["botocore[crt] (>=1.20.29,<2.0a.0)"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "service-identity" @@ -5535,7 +6246,10 @@ idna = ["idna"] mypy = ["idna", "mypy", "types-pyopenssl"] tests = ["coverage[toml] (>=5.0.2)", "pytest"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "setuptools" @@ -5553,7 +6267,10 @@ docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "pygments-g testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "simplejson" @@ -5649,7 +6366,10 @@ files = [ {file = "simplejson-3.19.1.tar.gz", hash = "sha256:6277f60848a7d8319d27d2be767a7546bc965535b28070e310b3a9af90604a4c"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "six" @@ -5662,7 +6382,10 @@ files = [ {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "sniffio" @@ -5675,7 +6398,10 @@ files = [ {file = "sniffio-1.3.0.tar.gz", hash = "sha256:e60305c5e5d314f5389259b7f22aaa33d8f7dee49763119234af3755c55b9101"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "soupsieve" @@ -5688,7 +6414,10 @@ files = [ {file = "soupsieve-2.4.1.tar.gz", hash = "sha256:89d12b2d5dfcd2c9e8c22326da9d9aa9cb3dfab0a83a024f05704076ee8d35ea"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "sqlparse" @@ -5706,7 +6435,10 @@ dev = ["build", "flake8"] doc = ["sphinx"] test = ["pytest", "pytest-cov"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "sshpubkeys" @@ -5726,7 +6458,10 @@ ecdsa = ">=0.13" [package.extras] dev = ["twine", "wheel", "yapf"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "sshtunnel" @@ -5747,7 +6482,10 @@ build-sphinx = ["sphinx", "sphinxcontrib-napoleon"] dev = ["check-manifest"] test = ["tox (>=1.8.1)"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "stack-data" @@ -5768,7 +6506,10 @@ pure-eval = "*" [package.extras] tests = ["cython", "littleutils", "pygments", "pytest", "typeguard"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "stevedore" @@ -5784,7 +6525,10 @@ files = [ [package.dependencies] pbr = ">=2.0.0,<2.1.0 || >2.1.0" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "tencentcloud-sdk-python" @@ -5800,7 +6544,10 @@ files = [ [package.dependencies] requests = ">=2.16.0" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "termcolor" @@ -5816,7 +6563,10 @@ files = [ [package.extras] tests = ["pytest", "pytest-cov"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "texttable" @@ -5829,7 +6579,10 @@ files = [ {file = "texttable-1.6.7.tar.gz", hash = "sha256:290348fb67f7746931bcdfd55ac7584ecd4e5b0846ab164333f0794b121760f2"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "tornado" @@ -5851,7 +6604,10 @@ files = [ {file = "tornado-6.3.2.tar.gz", hash = "sha256:4b927c4f19b71e627b13f3db2324e4ae660527143f9e1f2e2fb404f3a187e2ba"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "traitlets" @@ -5868,7 +6624,10 @@ files = [ docs = ["myst-parser", "pydata-sphinx-theme", "sphinx"] test = ["argcomplete (>=2.0)", "pre-commit", "pytest", "pytest-mock"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "treelib" @@ -5884,7 +6643,10 @@ files = [ [package.dependencies] six = "*" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "twisted" @@ -5927,7 +6689,10 @@ test = ["PyHamcrest (>=1.9.0)", "cython-test-exception-raiser (>=1.0.2,<2)", "hy tls = ["idna (>=2.4)", "pyopenssl (>=21.0.0)", "service-identity (>=18.1.0)"] windows-platform = ["PyHamcrest (>=1.9.0)", "appdirs (>=1.4.0)", "bcrypt (>=3.0.0)", "contextvars (>=2.4,<3)", "cryptography (>=2.6)", "cython-test-exception-raiser (>=1.0.2,<2)", "h2 (>=3.0,<5.0)", "hypothesis (>=6.0,<7.0)", "idna (>=2.4)", "priority (>=1.1.0,<2.0)", "pyasn1", "pyopenssl (>=21.0.0)", "pyserial (>=3.0)", "pywin32 (!=226)", "pywin32 (!=226)", "service-identity (>=18.1.0)"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "twisted-iocpsupport" @@ -5954,7 +6719,10 @@ files = [ {file = "twisted_iocpsupport-1.0.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:3f39c41c0213a81a9ce0961e30d0d7650f371ad80f8d261007d15a2deb6d5be3"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "txaio" @@ -5972,7 +6740,10 @@ all = ["twisted (>=20.3.0)", "zope.interface (>=5.2.0)"] dev = ["pep8 (>=1.6.2)", "pyenchant (>=1.6.6)", "pytest (>=2.6.4)", "pytest-cov (>=1.8.1)", "sphinx (>=1.2.3)", "sphinx-rtd-theme (>=0.1.9)", "sphinxcontrib-spelling (>=2.1.2)", "tox (>=2.1.1)", "tox-gh-actions (>=2.2.0)", "twine (>=1.6.5)", "wheel"] twisted = ["twisted (>=20.3.0)", "zope.interface (>=5.2.0)"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "typing-extensions" @@ -5985,7 +6756,10 @@ files = [ {file = "typing_extensions-4.7.1.tar.gz", hash = "sha256:b75ddc264f0ba5615db7ba217daeb99701ad295353c45f9e95963337ceeeffb2"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "tzdata" @@ -5998,7 +6772,10 @@ files = [ {file = "tzdata-2023.3.tar.gz", hash = "sha256:11ef1e08e54acb0d4f95bdb1be05da659673de4acbd21bf9c69e94cc5e907a3a"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "ucloud-sdk-python3" @@ -6020,7 +6797,10 @@ dev = ["black", "flake8 (>=3.6.0)", "pytest (>=4.6)", "pytest-cov", "requests", doc = ["requests", "sphinx"] test = ["flake8 (>=3.6.0)", "pytest (>=4.6)", "pytest-cov", "requests", "requests-mock"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "unicodecsv" @@ -6032,7 +6812,10 @@ files = [ {file = "unicodecsv-0.14.1.tar.gz", hash = "sha256:018c08037d48649a0412063ff4eda26eaa81eff1546dbffa51fa5293276ff7fc"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "uritemplate" @@ -6045,7 +6828,10 @@ files = [ {file = "uritemplate-4.1.1.tar.gz", hash = "sha256:4346edfc5c3b79f694bccd6d6099a322bbeb628dbf2cd86eea55a456ce5124f0"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "urllib3" @@ -6063,7 +6849,10 @@ brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)", "brotlipy (>=0.6.0)"] secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "ipaddress", "pyOpenSSL (>=0.14)", "urllib3-secure-extra"] socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "uvicorn" @@ -6090,7 +6879,10 @@ websockets = {version = ">=10.4", optional = true, markers = "extra == \"standar [package.extras] standard = ["colorama (>=0.4)", "httptools (>=0.5.0)", "python-dotenv (>=0.13)", "pyyaml (>=5.1)", "uvloop (>=0.14.0,!=0.15.0,!=0.15.1)", "watchfiles (>=0.13)", "websockets (>=10.4)"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "uvloop" @@ -6136,7 +6928,10 @@ dev = ["Cython (>=0.29.32,<0.30.0)", "Sphinx (>=4.1.2,<4.2.0)", "aiohttp", "flak docs = ["Sphinx (>=4.1.2,<4.2.0)", "sphinx-rtd-theme (>=0.5.2,<0.6.0)", "sphinxcontrib-asyncio (>=0.3.0,<0.4.0)"] test = ["Cython (>=0.29.32,<0.30.0)", "aiohttp", "flake8 (>=3.9.2,<3.10.0)", "mypy (>=0.800)", "psutil", "pyOpenSSL (>=22.0.0,<22.1.0)", "pycodestyle (>=2.7.0,<2.8.0)"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "vine" @@ -6149,7 +6944,10 @@ files = [ {file = "vine-5.0.0.tar.gz", hash = "sha256:7d3b1624a953da82ef63462013bbd271d3eb75751489f9807598e8f340bd637e"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "watchfiles" @@ -6185,7 +6983,10 @@ files = [ [package.dependencies] anyio = ">=3.0.0" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "wcwidth" @@ -6198,7 +6999,10 @@ files = [ {file = "wcwidth-0.2.6.tar.gz", hash = "sha256:a5220780a404dbe3353789870978e472cfe477761f06ee55077256e509b156d0"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "websocket-client" @@ -6216,7 +7020,10 @@ docs = ["Sphinx (>=3.4)", "sphinx-rtd-theme (>=0.5)"] optional = ["python-socks", "wsaccel"] test = ["websockets"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "websockets" @@ -6297,7 +7104,10 @@ files = [ {file = "websockets-11.0.3.tar.gz", hash = "sha256:88fc51d9a26b10fc331be344f1781224a375b78488fc343620184e95a4b27016"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "werkzeug" @@ -6316,7 +7126,10 @@ MarkupSafe = ">=2.1.1" [package.extras] watchdog = ["watchdog (>=2.3)"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "wrapt" @@ -6402,7 +7215,10 @@ files = [ {file = "wrapt-1.15.0.tar.gz", hash = "sha256:d06730c6aed78cee4126234cf2d071e01b44b915e725a6cb439a879ec9754a3a"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "xmlsec" @@ -6429,7 +7245,10 @@ files = [ [package.dependencies] lxml = ">=3.8" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "xmltodict" @@ -6442,7 +7261,10 @@ files = [ {file = "xmltodict-0.13.0.tar.gz", hash = "sha256:341595a488e3e01a85a9d8911d8912fd922ede5fecc4dce437eb4b6c8d037e56"}, ] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "yarl" @@ -6531,7 +7353,10 @@ files = [ idna = ">=2.0" multidict = ">=4.0" - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "zope-interface" @@ -6580,7 +7405,10 @@ docs = ["Sphinx", "repoze.sphinx.autointerface"] test = ["coverage (>=5.0.3)", "zope.event", "zope.testing"] testing = ["coverage (>=5.0.3)", "zope.event", "zope.testing"] - +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [metadata] lock-version = "2.0" From 958290529a0ca291a041a083116a94b0a2dbfaba Mon Sep 17 00:00:00 2001 From: ibuler Date: Wed, 2 Aug 2023 15:37:30 +0800 Subject: [PATCH 084/177] =?UTF-8?q?perf:=20=E4=B8=8D=E5=88=9B=E5=BB=BA=20v?= =?UTF-8?q?env?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 346dfbe5f..08da9f7a8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -89,7 +89,9 @@ ARG PIP_MIRROR=https://pypi.douban.com/simple RUN --mount=type=cache,target=/root/.cache/pip \ set -ex \ && pip install poetry==1.5.1 -i ${PIP_MIRROR} \ - && poetry install --only=main + && poetry config virtualenvs.create false \ + && poetry install --only=main \ + && rm -rf /root/.cache/pip COPY --from=stage-build /opt/jumpserver/release/jumpserver /opt/jumpserver RUN echo > /opt/jumpserver/config.yml \ From 85058f8599fe0a184738e3fb2427d5fe1cf20263 Mon Sep 17 00:00:00 2001 From: ibuler Date: Wed, 2 Aug 2023 15:45:13 +0800 Subject: [PATCH 085/177] =?UTF-8?q?perf:=20=E4=B8=8D=E8=83=BD=20remove?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index 08da9f7a8..4df68fa31 100644 --- a/Dockerfile +++ b/Dockerfile @@ -86,12 +86,11 @@ COPY ./poetry.lock ./poetry.lock ARG PIP_MIRROR=https://pypi.douban.com/simple -RUN --mount=type=cache,target=/root/.cache/pip \ +RUN --mount=type=cache,target=/root/.cache/poetry \ set -ex \ && pip install poetry==1.5.1 -i ${PIP_MIRROR} \ && poetry config virtualenvs.create false \ - && poetry install --only=main \ - && rm -rf /root/.cache/pip + && poetry install --only=main COPY --from=stage-build /opt/jumpserver/release/jumpserver /opt/jumpserver RUN echo > /opt/jumpserver/config.yml \ From 4ef05a1cd430e06079709b4b4630dc0d42f3947c Mon Sep 17 00:00:00 2001 From: ibuler Date: Wed, 2 Aug 2023 16:53:47 +0800 Subject: [PATCH 086/177] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=20telnet=20?= =?UTF-8?q?=E5=B9=B3=E5=8F=B0=EF=BC=8C=E6=94=AF=E6=8C=81=E8=87=AA=E5=AE=9A?= =?UTF-8?q?=E4=B9=89=20prompt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/assets/const/protocol.py | 20 ++ apps/locale/ja/LC_MESSAGES/django.po | 312 ++++++++++++++++----------- apps/locale/zh/LC_MESSAGES/django.po | 308 +++++++++++++++----------- 3 files changed, 384 insertions(+), 256 deletions(-) diff --git a/apps/assets/const/protocol.py b/apps/assets/const/protocol.py index 9588149ad..6886cbc4d 100644 --- a/apps/assets/const/protocol.py +++ b/apps/assets/const/protocol.py @@ -81,6 +81,26 @@ class Protocol(ChoicesMixin, models.TextChoices): cls.telnet: { 'port': 23, 'secret_types': ['password'], + 'setting': { + 'username_prompt': { + 'type': 'str', + 'default': 'username:|login:', + 'label': _('Username prompt'), + 'help_text': _('We will send username when we see this prompt') + }, + 'password_prompt': { + 'type': 'str', + 'default': 'password:', + 'label': _('Password prompt'), + 'help_text': _('We will send password when we see this prompt') + }, + 'success_prompt': { + 'type': 'str', + 'default': 'success|成功|#|>|\$', + 'label': _('Success prompt'), + 'help_text': _('We will consider login success when we see this prompt') + } + } }, cls.winrm: { 'port': 5985, diff --git a/apps/locale/ja/LC_MESSAGES/django.po b/apps/locale/ja/LC_MESSAGES/django.po index a51437386..b4b3b2634 100644 --- a/apps/locale/ja/LC_MESSAGES/django.po +++ b/apps/locale/ja/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-07-31 16:39+0800\n" +"POT-Creation-Date: 2023-08-02 16:52+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -45,7 +45,7 @@ msgid "Access key" msgstr "アクセスキー" #: accounts/const/account.py:9 assets/models/_user.py:48 -#: authentication/models/sso_token.py:14 +#: authentication/models/sso_token.py:14 settings/serializers/vault.py:19 msgid "Token" msgstr "トークン" @@ -53,7 +53,7 @@ msgstr "トークン" msgid "API key" msgstr "" -#: accounts/const/account.py:14 common/db/fields.py:244 +#: accounts/const/account.py:14 common/db/fields.py:235 #: settings/serializers/terminal.py:14 msgid "All" msgstr "すべて" @@ -187,10 +187,20 @@ msgstr "作成してプッシュ" msgid "Only create" msgstr "作成のみ" -#: accounts/models/account.py:49 +#: accounts/const/vault.py:8 +#, fuzzy +#| msgid "Local" +msgid "Local Vault" +msgstr "ローカル" + +#: accounts/const/vault.py:9 +msgid "HCP Vault" +msgstr "" + +#: accounts/models/account.py:50 #: accounts/models/automations/gather_account.py:16 #: accounts/serializers/account/account.py:200 -#: accounts/serializers/account/account.py:237 +#: accounts/serializers/account/account.py:245 #: accounts/serializers/account/gathered_account.py:10 #: accounts/serializers/automations/change_secret.py:112 #: accounts/serializers/automations/change_secret.py:132 @@ -207,29 +217,29 @@ msgstr "作成のみ" msgid "Asset" msgstr "資産" -#: accounts/models/account.py:53 accounts/models/account.py:126 -#: accounts/serializers/account/account.py:208 -#: accounts/serializers/account/account.py:247 +#: accounts/models/account.py:54 accounts/models/account.py:127 +#: accounts/serializers/account/account.py:207 +#: accounts/serializers/account/account.py:255 #: accounts/serializers/account/template.py:16 #: authentication/serializers/connect_token_secret.py:49 msgid "Su from" msgstr "から切り替え" -#: accounts/models/account.py:55 settings/serializers/auth/cas.py:20 +#: accounts/models/account.py:56 settings/serializers/auth/cas.py:20 #: settings/serializers/auth/feishu.py:20 terminal/models/applet/applet.py:34 msgid "Version" msgstr "バージョン" -#: accounts/models/account.py:57 accounts/serializers/account/account.py:203 +#: accounts/models/account.py:58 accounts/serializers/account/account.py:202 #: users/models/user.py:804 msgid "Source" msgstr "ソース" -#: accounts/models/account.py:58 +#: accounts/models/account.py:59 msgid "Source ID" msgstr "ソース ID" -#: accounts/models/account.py:61 +#: accounts/models/account.py:62 #: accounts/serializers/automations/change_secret.py:113 #: accounts/serializers/automations/change_secret.py:133 #: acls/serializers/base.py:124 assets/serializers/asset/common.py:125 @@ -242,35 +252,35 @@ msgstr "ソース ID" msgid "Account" msgstr "アカウント" -#: accounts/models/account.py:67 +#: accounts/models/account.py:68 msgid "Can view asset account secret" msgstr "資産アカウントの秘密を表示できます" -#: accounts/models/account.py:68 +#: accounts/models/account.py:69 msgid "Can view asset history account" msgstr "資産履歴アカウントを表示できます" -#: accounts/models/account.py:69 +#: accounts/models/account.py:70 msgid "Can view asset history account secret" msgstr "資産履歴アカウントパスワードを表示できます" -#: accounts/models/account.py:70 +#: accounts/models/account.py:71 msgid "Can verify account" msgstr "アカウントを確認できます" -#: accounts/models/account.py:71 +#: accounts/models/account.py:72 msgid "Can push account" msgstr "アカウントをプッシュできます" -#: accounts/models/account.py:130 +#: accounts/models/account.py:131 msgid "Account template" msgstr "アカウント テンプレート" -#: accounts/models/account.py:135 +#: accounts/models/account.py:136 msgid "Can view asset account template secret" msgstr "アセット アカウント テンプレートのパスワードを表示できます" -#: accounts/models/account.py:136 +#: accounts/models/account.py:137 msgid "Can change asset account template secret" msgstr "アセット アカウント テンプレートのパスワードを変更できます" @@ -323,7 +333,7 @@ msgstr "理由" #: accounts/models/automations/backup_account.py:99 #: accounts/serializers/automations/change_secret.py:111 #: accounts/serializers/automations/change_secret.py:134 -#: ops/serializers/job.py:56 terminal/serializers/session.py:43 +#: ops/serializers/job.py:56 terminal/serializers/session.py:44 msgid "Is success" msgstr "成功は" @@ -368,7 +378,7 @@ msgid "Can add push account execution" msgstr "プッシュ アカウントの作成の実行" #: accounts/models/automations/change_secret.py:18 accounts/models/base.py:36 -#: accounts/serializers/account/account.py:419 +#: accounts/serializers/account/account.py:427 #: accounts/serializers/account/base.py:16 #: accounts/serializers/automations/change_secret.py:46 #: authentication/serializers/connect_token_secret.py:41 @@ -377,8 +387,8 @@ msgid "Secret type" msgstr "鍵の種類" #: accounts/models/automations/change_secret.py:20 -#: accounts/models/automations/change_secret.py:89 accounts/models/base.py:38 -#: accounts/serializers/account/base.py:19 +#: accounts/models/automations/change_secret.py:89 +#: accounts/models/mixins/vault.py:48 accounts/serializers/account/base.py:19 #: authentication/models/temp_token.py:10 #: authentication/templates/authentication/_access_key_modal.html:31 #: settings/serializers/auth/radius.py:19 @@ -418,7 +428,7 @@ msgid "Date finished" msgstr "終了日" #: accounts/models/automations/change_secret.py:93 -#: accounts/serializers/account/account.py:239 assets/const/automation.py:8 +#: accounts/serializers/account/account.py:247 assets/const/automation.py:8 #: authentication/views/base.py:26 authentication/views/base.py:27 #: authentication/views/base.py:28 common/const/choices.py:20 msgid "Error" @@ -497,7 +507,7 @@ msgstr "アカウントの確認" #: assets/serializers/platform.py:223 #: authentication/serializers/connect_token_secret.py:110 ops/mixin.py:21 #: ops/models/adhoc.py:20 ops/models/celery.py:15 ops/models/celery.py:57 -#: ops/models/job.py:94 ops/models/playbook.py:23 ops/serializers/job.py:20 +#: ops/models/job.py:94 ops/models/playbook.py:28 ops/serializers/job.py:20 #: orgs/models.py:80 perms/models/asset_permission.py:56 rbac/models/role.py:29 #: settings/models.py:32 settings/serializers/sms.py:6 #: terminal/models/applet/applet.py:32 terminal/models/component/endpoint.py:12 @@ -509,11 +519,11 @@ msgstr "アカウントの確認" msgid "Name" msgstr "名前" -#: accounts/models/base.py:39 +#: accounts/models/base.py:38 msgid "Privileged" msgstr "特権アカウント" -#: accounts/models/base.py:40 assets/models/asset/common.py:156 +#: accounts/models/base.py:39 assets/models/asset/common.py:156 #: assets/models/automations/base.py:21 assets/models/cmd_filter.py:39 #: assets/models/label.py:22 #: authentication/serializers/connect_token_secret.py:114 @@ -588,8 +598,8 @@ msgstr "カテゴリ" #: assets/serializers/asset/common.py:122 assets/serializers/platform.py:112 #: assets/serializers/platform.py:127 audits/serializers.py:49 #: authentication/serializers/connect_token_secret.py:123 ops/models/job.py:105 -#: perms/serializers/user_permission.py:27 terminal/models/applet/applet.py:38 -#: terminal/models/component/storage.py:57 +#: perms/serializers/user_permission.py:27 settings/serializers/vault.py:13 +#: terminal/models/applet/applet.py:38 terminal/models/component/storage.py:57 #: terminal/models/component/storage.py:146 terminal/serializers/applet.py:29 #: terminal/serializers/session.py:20 terminal/serializers/storage.py:226 #: terminal/serializers/storage.py:238 tickets/models/comment.py:26 @@ -603,23 +613,22 @@ msgstr "タイプ" msgid "Asset not found" msgstr "資産が存在しません" -#: accounts/serializers/account/account.py:201 -#: accounts/serializers/account/base.py:64 +#: accounts/serializers/account/account.py:236 msgid "Has secret" msgstr "エスクローされたパスワード" -#: accounts/serializers/account/account.py:238 ops/models/celery.py:60 +#: accounts/serializers/account/account.py:246 ops/models/celery.py:60 #: tickets/models/comment.py:13 tickets/models/ticket/general.py:45 #: tickets/models/ticket/general.py:279 tickets/serializers/super_ticket.py:14 #: tickets/serializers/ticket/ticket.py:21 msgid "State" msgstr "状態" -#: accounts/serializers/account/account.py:240 +#: accounts/serializers/account/account.py:248 msgid "Changed" msgstr "編集済み" -#: accounts/serializers/account/account.py:250 +#: accounts/serializers/account/account.py:258 #: accounts/serializers/automations/base.py:22 acls/models/base.py:97 #: assets/models/automations/base.py:19 #: assets/serializers/automations/base.py:20 ops/models/base.py:17 @@ -628,27 +637,27 @@ msgstr "編集済み" msgid "Assets" msgstr "資産" -#: accounts/serializers/account/account.py:305 +#: accounts/serializers/account/account.py:313 msgid "Account already exists" msgstr "アカウントはすでに存在しています" -#: accounts/serializers/account/account.py:355 +#: accounts/serializers/account/account.py:363 #, python-format msgid "Asset does not support this secret type: %s" msgstr "アセットはアカウント タイプをサポートしていません: %s" -#: accounts/serializers/account/account.py:387 +#: accounts/serializers/account/account.py:395 msgid "Account has exist" msgstr "アカウントはすでに存在しています" -#: accounts/serializers/account/account.py:420 +#: accounts/serializers/account/account.py:428 #: authentication/serializers/connect_token_secret.py:156 #: authentication/templates/authentication/_access_key_modal.html:30 #: perms/models/perm_node.py:21 users/serializers/group.py:31 msgid "ID" msgstr "ID" -#: accounts/serializers/account/account.py:427 acls/serializers/base.py:116 +#: accounts/serializers/account/account.py:435 acls/serializers/base.py:116 #: assets/models/cmd_filter.py:24 assets/models/label.py:16 audits/models.py:49 #: audits/models.py:85 audits/models.py:163 #: authentication/models/connection_token.py:32 @@ -656,10 +665,10 @@ msgstr "ID" #: notifications/models/notification.py:12 #: perms/api/user_permission/mixin.py:55 perms/models/asset_permission.py:58 #: perms/serializers/permission.py:30 rbac/builtin.py:123 -#: rbac/models/rolebinding.py:49 terminal/backends/command/models.py:16 -#: terminal/models/session/session.py:29 terminal/models/session/sharing.py:33 -#: terminal/notifications.py:156 terminal/notifications.py:205 -#: terminal/serializers/command.py:16 +#: rbac/models/rolebinding.py:49 rbac/serializers/rolebinding.py:17 +#: terminal/backends/command/models.py:16 terminal/models/session/session.py:29 +#: terminal/models/session/sharing.py:33 terminal/notifications.py:156 +#: terminal/notifications.py:205 terminal/serializers/command.py:16 #: terminal/templates/terminal/_msg_command_warning.html:6 #: terminal/templates/terminal/_msg_session_sharing.html:6 #: tickets/models/comment.py:21 users/const.py:14 users/models/user.py:947 @@ -667,7 +676,7 @@ msgstr "ID" msgid "User" msgstr "ユーザー" -#: accounts/serializers/account/account.py:428 +#: accounts/serializers/account/account.py:436 #: authentication/templates/authentication/_access_key_modal.html:33 #: terminal/notifications.py:158 terminal/notifications.py:207 msgid "Date" @@ -698,12 +707,12 @@ msgstr "資産タイプ" msgid "Key password" msgstr "キーパスワード" -#: accounts/serializers/account/base.py:80 +#: accounts/serializers/account/base.py:78 #: assets/serializers/asset/common.py:311 msgid "Spec info" msgstr "特別情報" -#: accounts/serializers/account/base.py:82 +#: accounts/serializers/account/base.py:80 msgid "" "Tip: If no username is required for authentication, fill in `null`, If AD " "account, like `username@domain`" @@ -769,6 +778,12 @@ msgstr "資産の口座番号を収集する" msgid "Push accounts to assets" msgstr "アカウントをアセットにプッシュ:" +#: accounts/tasks/vault.py:15 +#, fuzzy +#| msgid "Sync instance detail" +msgid "Sync secret to vault" +msgstr "同期インスタンスの詳細" + #: accounts/tasks/verify_account.py:49 msgid "Verify asset account availability" msgstr "アセット アカウントの可用性を確認する" @@ -777,19 +792,19 @@ msgstr "アセット アカウントの可用性を確認する" msgid "Verify accounts connectivity" msgstr "アカウント接続のテスト" -#: accounts/utils.py:43 +#: accounts/utils.py:41 msgid "Password can not contains `{{` " msgstr "パスワードには '{{' を含まない" -#: accounts/utils.py:46 +#: accounts/utils.py:44 msgid "Password can not contains `'` " msgstr "パスワードには `'` を含まない" -#: accounts/utils.py:48 +#: accounts/utils.py:46 msgid "Password can not contains `\"` " msgstr "パスワードには `\"` を含まない" -#: accounts/utils.py:54 +#: accounts/utils.py:52 msgid "private key invalid or passphrase error" msgstr "秘密鍵が無効またはpassphraseエラー" @@ -1083,14 +1098,15 @@ msgstr "無効" msgid "Basic" msgstr "基本" -#: assets/const/base.py:35 assets/const/protocol.py:201 +#: assets/const/base.py:35 assets/const/protocol.py:221 #: assets/models/asset/web.py:13 msgid "Script" msgstr "脚本" #: assets/const/category.py:10 assets/models/asset/host.py:8 #: settings/serializers/auth/radius.py:16 settings/serializers/auth/sms.py:67 -#: terminal/models/component/endpoint.py:13 terminal/serializers/applet.py:17 +#: settings/serializers/vault.py:16 terminal/models/component/endpoint.py:13 +#: terminal/serializers/applet.py:17 #: xpack/plugins/cloud/serializers/account_attrs.py:72 msgid "Host" msgstr "ホスト" @@ -1183,41 +1199,71 @@ msgstr "接続に使用するセキュリティ レイヤー" msgid "AD domain" msgstr "AD ドメイン" -#: assets/const/protocol.py:92 assets/models/asset/database.py:10 +#: assets/const/protocol.py:88 +#, fuzzy +#| msgid "Username attr" +msgid "Username prompt" +msgstr "ユーザー名のプロパティ" + +#: assets/const/protocol.py:89 +msgid "We will send username when we see this prompt" +msgstr "" + +#: assets/const/protocol.py:94 +#, fuzzy +#| msgid "Password auth" +msgid "Password prompt" +msgstr "パスワード認証" + +#: assets/const/protocol.py:95 +msgid "We will send password when we see this prompt" +msgstr "" + +#: assets/const/protocol.py:100 +#, fuzzy +#| msgid "Success" +msgid "Success prompt" +msgstr "成功" + +#: assets/const/protocol.py:101 +msgid "We will consider login success when we see this prompt" +msgstr "" + +#: assets/const/protocol.py:112 assets/models/asset/database.py:10 #: settings/serializers/email.py:37 msgid "Use SSL" msgstr "SSLの使用" -#: assets/const/protocol.py:127 +#: assets/const/protocol.py:147 msgid "SYSDBA" msgstr "SYSDBA" -#: assets/const/protocol.py:128 +#: assets/const/protocol.py:148 msgid "Connect as SYSDBA" msgstr "SYSDBA として接続" -#: assets/const/protocol.py:157 +#: assets/const/protocol.py:177 msgid "Auth username" msgstr "ユーザー名で認証する" -#: assets/const/protocol.py:178 assets/models/asset/web.py:9 +#: assets/const/protocol.py:198 assets/models/asset/web.py:9 #: assets/serializers/asset/info/spec.py:16 msgid "Autofill" msgstr "自動充填" -#: assets/const/protocol.py:186 assets/models/asset/web.py:10 +#: assets/const/protocol.py:206 assets/models/asset/web.py:10 msgid "Username selector" msgstr "ユーザー名ピッカー" -#: assets/const/protocol.py:191 assets/models/asset/web.py:11 +#: assets/const/protocol.py:211 assets/models/asset/web.py:11 msgid "Password selector" msgstr "パスワードセレクター" -#: assets/const/protocol.py:196 assets/models/asset/web.py:12 +#: assets/const/protocol.py:216 assets/models/asset/web.py:12 msgid "Submit selector" msgstr "ボタンセレクターを確認する" -#: assets/const/protocol.py:219 +#: assets/const/protocol.py:239 msgid "API mode" msgstr "APIモード" @@ -1244,7 +1290,7 @@ msgstr "SSHパブリックキー" #: assets/models/_user.py:27 assets/models/cmd_filter.py:40 #: assets/models/cmd_filter.py:88 assets/models/group.py:20 #: common/db/models.py:36 ops/models/adhoc.py:26 ops/models/job.py:113 -#: ops/models/playbook.py:26 rbac/models/role.py:37 settings/models.py:37 +#: ops/models/playbook.py:31 rbac/models/role.py:37 settings/models.py:37 #: terminal/models/applet/applet.py:44 terminal/models/applet/applet.py:250 #: terminal/models/applet/host.py:141 terminal/models/component/endpoint.py:24 #: terminal/models/component/endpoint.py:102 @@ -1296,7 +1342,7 @@ msgstr "ユーザーと同じユーザー名" #: assets/models/_user.py:52 authentication/models/connection_token.py:41 #: authentication/serializers/connect_token_secret.py:111 #: terminal/models/applet/applet.py:41 terminal/serializers/session.py:18 -#: terminal/serializers/session.py:39 terminal/serializers/storage.py:70 +#: terminal/serializers/session.py:40 terminal/serializers/storage.py:70 msgid "Protocol" msgstr "プロトコル" @@ -1729,8 +1775,8 @@ msgstr "プロトコルが必要です: {}" msgid "Default database" msgstr "デフォルト・データベース" -#: assets/serializers/asset/database.py:28 common/db/fields.py:579 -#: common/db/fields.py:584 common/serializers/fields.py:104 +#: assets/serializers/asset/database.py:28 common/db/fields.py:570 +#: common/db/fields.py:575 common/serializers/fields.py:104 #: tickets/serializers/ticket/common.py:58 #: xpack/plugins/cloud/serializers/account_attrs.py:56 #: xpack/plugins/cloud/serializers/account_attrs.py:79 @@ -2031,7 +2077,7 @@ msgstr "パスワードを変更する" #: audits/const.py:35 settings/serializers/terminal.py:6 #: terminal/models/applet/host.py:26 terminal/models/component/terminal.py:163 -#: terminal/serializers/session.py:46 terminal/serializers/session.py:55 +#: terminal/serializers/session.py:47 terminal/serializers/session.py:56 msgid "Terminal" msgstr "ターミナル" @@ -2674,7 +2720,6 @@ msgid "Connect options" msgstr "接続アイテム" #: authentication/models/connection_token.py:44 -#: rbac/serializers/rolebinding.py:21 msgid "User display" msgstr "ユーザー表示" @@ -2890,7 +2935,7 @@ msgstr "コードエラー" #: authentication/templates/authentication/_msg_reset_password_code.html:9 #: authentication/templates/authentication/_msg_rest_password_success.html:2 #: authentication/templates/authentication/_msg_rest_public_key_success.html:2 -#: jumpserver/conf.py:431 +#: jumpserver/conf.py:437 #: perms/templates/perms/_msg_item_permissions_expire.html:3 #: perms/templates/perms/_msg_permed_items_expire.html:3 #: tickets/templates/tickets/approve_check_password.html:33 @@ -3245,11 +3290,11 @@ msgstr "チャーフィールドへのマーシャルデータ" msgid "Marshal data to text field" msgstr "テキストフィールドへのマーシャルデータ" -#: common/db/fields.py:176 +#: common/db/fields.py:167 msgid "Encrypt field using Secret Key" msgstr "Secret Keyを使用したフィールドの暗号化" -#: common/db/fields.py:567 +#: common/db/fields.py:558 msgid "" "Invalid JSON data for JSONManyToManyField, should be like {'type': 'all'} or " "{'type': 'ids', 'ids': []} or {'type': 'attrs', 'attrs': [{'name': 'ip', " @@ -3259,19 +3304,19 @@ msgstr "" "{'type':'ids','ids':[]}或 #タイプ:属性、属性:[#名前:ip、照合:正確、" "値:1.1.1.1}" -#: common/db/fields.py:574 +#: common/db/fields.py:565 msgid "Invalid type, should be \"all\", \"ids\" or \"attrs\"" msgstr "無効なタイプです。all、ids、またはattrsでなければなりません" -#: common/db/fields.py:577 +#: common/db/fields.py:568 msgid "Invalid ids for ids, should be a list" msgstr "無効なID、リストでなければなりません" -#: common/db/fields.py:582 common/db/fields.py:587 +#: common/db/fields.py:573 common/db/fields.py:578 msgid "Invalid attrs, should be a list of dict" msgstr "無効な属性、dictリストでなければなりません" -#: common/db/fields.py:589 +#: common/db/fields.py:580 msgid "Invalid attrs, should be has name and value" msgstr "名前と値が必要な無効な属性" @@ -3485,11 +3530,11 @@ msgstr "検索のエクスポート: %s" msgid "User %s view/export secret" msgstr "ユーザー %s がパスワードを閲覧/導き出しました" -#: jumpserver/conf.py:430 +#: jumpserver/conf.py:436 msgid "Create account successfully" msgstr "アカウントを正常に作成" -#: jumpserver/conf.py:432 +#: jumpserver/conf.py:438 msgid "Your account has been created successfully" msgstr "アカウントが正常に作成されました" @@ -3696,7 +3741,7 @@ msgid "Args" msgstr "アルグ" #: ops/models/adhoc.py:25 ops/models/base.py:16 ops/models/base.py:53 -#: ops/models/job.py:106 ops/models/job.py:192 ops/models/playbook.py:25 +#: ops/models/job.py:106 ops/models/job.py:192 ops/models/playbook.py:30 #: terminal/models/session/sharing.py:24 msgid "Creator" msgstr "作成者" @@ -3791,11 +3836,11 @@ msgstr "Material を選択してオプションを設定します。" msgid "Job Execution" msgstr "ジョブ実行" -#: ops/models/playbook.py:28 +#: ops/models/playbook.py:33 msgid "CreateMethod" msgstr "创建方式" -#: ops/models/playbook.py:29 +#: ops/models/playbook.py:34 msgid "VCS URL" msgstr "VCS URL" @@ -3835,7 +3880,7 @@ msgstr "保存後に実行" msgid "Job type" msgstr "タスクの種類" -#: ops/serializers/job.py:57 terminal/serializers/session.py:47 +#: ops/serializers/job.py:57 terminal/serializers/session.py:48 msgid "Is finished" msgstr "終了しました" @@ -3932,14 +3977,14 @@ msgstr "アプリ組織" #: orgs/mixins/models.py:57 orgs/mixins/serializers.py:25 orgs/models.py:89 #: rbac/const.py:7 rbac/models/rolebinding.py:56 -#: rbac/serializers/rolebinding.py:40 settings/serializers/auth/ldap.py:63 +#: rbac/serializers/rolebinding.py:44 settings/serializers/auth/ldap.py:63 #: terminal/templates/terminal/_msg_command_warning.html:21 #: terminal/templates/terminal/_msg_session_sharing.html:14 #: tickets/models/ticket/general.py:302 tickets/serializers/ticket/ticket.py:60 msgid "Organization" msgstr "組織" -#: orgs/mixins/serializers.py:26 rbac/serializers/rolebinding.py:23 +#: orgs/mixins/serializers.py:26 rbac/serializers/rolebinding.py:27 msgid "Org name" msgstr "組織名" @@ -4079,7 +4124,7 @@ msgstr "ロールはユーザーにバインドされており、破壊するこ msgid "Internal role, can't be update" msgstr "内部ロール、更新できません" -#: rbac/api/rolebinding.py:52 +#: rbac/api/rolebinding.py:45 msgid "{} at least one system role" msgstr "{} 少なくとも1つのシステムロール" @@ -4192,11 +4237,7 @@ msgstr "ユーザー数" msgid "Display name" msgstr "表示名" -#: rbac/serializers/rolebinding.py:22 -msgid "Role display" -msgstr "ロール表示" - -#: rbac/serializers/rolebinding.py:56 +#: rbac/serializers/rolebinding.py:60 msgid "Has bound this role" msgstr "この役割をバインドしました" @@ -4275,7 +4316,7 @@ msgid "View permission tree" msgstr "権限ツリーの表示" #: settings/api/dingtalk.py:31 settings/api/feishu.py:36 -#: settings/api/sms.py:155 settings/api/wecom.py:37 +#: settings/api/sms.py:155 settings/api/vault.py:39 settings/api/wecom.py:37 msgid "Test success" msgstr "テストの成功" @@ -4328,34 +4369,40 @@ msgid "Can change auth setting" msgstr "資格認定の設定" #: settings/models.py:162 +#, fuzzy +#| msgid "Can change auth setting" +msgid "Can change vault setting" +msgstr "資格認定の設定" + +#: settings/models.py:163 msgid "Can change system msg sub setting" msgstr "システムmsgサブ设定を変更できます" -#: settings/models.py:163 +#: settings/models.py:164 msgid "Can change sms setting" msgstr "Smsの設定を変えることができます" -#: settings/models.py:164 +#: settings/models.py:165 msgid "Can change security setting" msgstr "セキュリティ設定を変更できます" -#: settings/models.py:165 +#: settings/models.py:166 msgid "Can change clean setting" msgstr "きれいな設定を変えることができます" -#: settings/models.py:166 +#: settings/models.py:167 msgid "Can change interface setting" msgstr "インターフェイスの設定を変えることができます" -#: settings/models.py:167 +#: settings/models.py:168 msgid "Can change license setting" msgstr "ライセンス設定を変更できます" -#: settings/models.py:168 +#: settings/models.py:169 msgid "Can change terminal setting" msgstr "ターミナルの設定を変えることができます" -#: settings/models.py:169 +#: settings/models.py:170 msgid "Can change other setting" msgstr "他の設定を変えることができます" @@ -5368,6 +5415,10 @@ msgstr "" "ヒント: Luna ページでグラフィック アセットを接続するときに使用するデフォルト" "の解像度" +#: settings/serializers/vault.py:22 +msgid "Mount Point" +msgstr "" + #: settings/tasks/ldap.py:24 msgid "Periodic import ldap user" msgstr "LDAP ユーザーを定期的にインポートする" @@ -5563,8 +5614,8 @@ msgstr "期限切れです。" #, python-format msgid "" "\n" -" Your password has expired, please click this link update password.\n" +" Your password has expired, please click this link update password.\n" " " msgstr "" "\n" @@ -5585,34 +5636,34 @@ msgid "" " " msgstr "" "\n" -" クリックしてください リンク パスワードの更新\n" +" クリックしてください リンク パスワードの更新\n" " " #: templates/_message.html:43 #, python-format msgid "" "\n" -" Your information was incomplete. Please click this link to complete your information.\n" +" Your information was incomplete. Please click this link to complete your information.\n" " " msgstr "" "\n" -" あなたの情報が不完全なので、クリックしてください。 リンク 補完\n" +" あなたの情報が不完全なので、クリックしてください。 リンク 補完\n" " " #: templates/_message.html:56 #, python-format msgid "" "\n" -" Your ssh public key not set or expired. Please click this link to update\n" +" Your ssh public key not set or expired. Please click this link to update\n" " " msgstr "" "\n" -" SSHキーが設定されていないか無効になっている場合は、 リンク 更新\n" +" SSHキーが設定されていないか無効になっている場合は、 リンク 更新\n" " " #: templates/_mfa_login_field.html:28 @@ -5702,7 +5753,7 @@ msgstr "コマンドストア" msgid "Invalid" msgstr "無効" -#: terminal/api/component/storage.py:119 terminal/tasks.py:140 +#: terminal/api/component/storage.py:119 terminal/tasks.py:141 msgid "Test failure: {}" msgstr "テスト失敗: {}" @@ -5711,7 +5762,7 @@ msgid "Test successful" msgstr "テスト成功" #: terminal/api/component/storage.py:124 terminal/notifications.py:240 -#: terminal/tasks.py:144 +#: terminal/tasks.py:145 msgid "Test failure: Account invalid" msgstr "テスト失敗: アカウントが無効" @@ -6040,23 +6091,27 @@ msgstr "リプレイ" msgid "Date end" msgstr "終了日" -#: terminal/models/session/session.py:261 +#: terminal/models/session/session.py:47 terminal/serializers/session.py:55 +msgid "Command amount" +msgstr "コマンド量" + +#: terminal/models/session/session.py:281 msgid "Session record" msgstr "セッション記録" -#: terminal/models/session/session.py:263 +#: terminal/models/session/session.py:283 msgid "Can monitor session" msgstr "セッションを監視できます" -#: terminal/models/session/session.py:264 +#: terminal/models/session/session.py:284 msgid "Can share session" msgstr "セッションを共有できます" -#: terminal/models/session/session.py:265 +#: terminal/models/session/session.py:285 msgid "Can terminate session" msgstr "セッションを終了できます" -#: terminal/models/session/session.py:266 +#: terminal/models/session/session.py:286 msgid "Can validate session action perm" msgstr "セッションアクションのパーマを検証できます" @@ -6311,38 +6366,34 @@ msgstr "" msgid "Asset IP" msgstr "資産 IP" -#: terminal/serializers/session.py:22 terminal/serializers/session.py:44 +#: terminal/serializers/session.py:22 terminal/serializers/session.py:45 msgid "Can replay" msgstr "再生できます" -#: terminal/serializers/session.py:23 terminal/serializers/session.py:45 +#: terminal/serializers/session.py:23 terminal/serializers/session.py:46 msgid "Can join" msgstr "参加できます" -#: terminal/serializers/session.py:24 terminal/serializers/session.py:48 +#: terminal/serializers/session.py:24 terminal/serializers/session.py:49 msgid "Can terminate" msgstr "終了できます" -#: terminal/serializers/session.py:40 +#: terminal/serializers/session.py:41 msgid "User ID" msgstr "ユーザーID" -#: terminal/serializers/session.py:41 +#: terminal/serializers/session.py:42 msgid "Asset ID" msgstr "資産ID" -#: terminal/serializers/session.py:42 +#: terminal/serializers/session.py:43 msgid "Login from display" msgstr "表示からのログイン" -#: terminal/serializers/session.py:49 +#: terminal/serializers/session.py:50 msgid "Terminal display" msgstr "ターミナルディスプレイ" -#: terminal/serializers/session.py:54 -msgid "Command amount" -msgstr "コマンド量" - #: terminal/serializers/storage.py:22 msgid "Endpoint invalid: remove path `{}`" msgstr "エンドポイントが無効: パス '{}' を削除" @@ -6433,11 +6484,11 @@ msgstr "アプリケーション マシンの展開を実行する" msgid "Install applet" msgstr "アプリをインストールする" -#: terminal/tasks.py:110 +#: terminal/tasks.py:111 msgid "Generate applet host accounts" msgstr "リモートアプリケーション上のアカウントを収集する" -#: terminal/tasks.py:122 +#: terminal/tasks.py:123 msgid "Check command replay storage connectivity" msgstr "チェックコマンドと録画ストレージの接続性" @@ -7953,6 +8004,9 @@ msgstr "究極のエディション" msgid "Community edition" msgstr "コミュニティ版" +#~ msgid "Role display" +#~ msgstr "ロール表示" + #~ msgid "SFTP enabled" #~ msgstr "SFTP が有効" diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po index 6a599c0a0..9c21b13d7 100644 --- a/apps/locale/zh/LC_MESSAGES/django.po +++ b/apps/locale/zh/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: JumpServer 0.3.3\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-07-31 16:39+0800\n" +"POT-Creation-Date: 2023-08-02 16:52+0800\n" "PO-Revision-Date: 2021-05-20 10:54+0800\n" "Last-Translator: ibuler \n" "Language-Team: JumpServer team\n" @@ -44,7 +44,7 @@ msgid "Access key" msgstr "Access key" #: accounts/const/account.py:9 assets/models/_user.py:48 -#: authentication/models/sso_token.py:14 +#: authentication/models/sso_token.py:14 settings/serializers/vault.py:19 msgid "Token" msgstr "Token" @@ -52,7 +52,7 @@ msgstr "Token" msgid "API key" msgstr "" -#: accounts/const/account.py:14 common/db/fields.py:244 +#: accounts/const/account.py:14 common/db/fields.py:235 #: settings/serializers/terminal.py:14 msgid "All" msgstr "全部" @@ -186,10 +186,20 @@ msgstr "创建并推送" msgid "Only create" msgstr "仅创建" -#: accounts/models/account.py:49 +#: accounts/const/vault.py:8 +#, fuzzy +#| msgid "Local" +msgid "Local Vault" +msgstr "数据库" + +#: accounts/const/vault.py:9 +msgid "HCP Vault" +msgstr "" + +#: accounts/models/account.py:50 #: accounts/models/automations/gather_account.py:16 #: accounts/serializers/account/account.py:200 -#: accounts/serializers/account/account.py:237 +#: accounts/serializers/account/account.py:245 #: accounts/serializers/account/gathered_account.py:10 #: accounts/serializers/automations/change_secret.py:112 #: accounts/serializers/automations/change_secret.py:132 @@ -206,29 +216,29 @@ msgstr "仅创建" msgid "Asset" msgstr "资产" -#: accounts/models/account.py:53 accounts/models/account.py:126 -#: accounts/serializers/account/account.py:208 -#: accounts/serializers/account/account.py:247 +#: accounts/models/account.py:54 accounts/models/account.py:127 +#: accounts/serializers/account/account.py:207 +#: accounts/serializers/account/account.py:255 #: accounts/serializers/account/template.py:16 #: authentication/serializers/connect_token_secret.py:49 msgid "Su from" msgstr "切换自" -#: accounts/models/account.py:55 settings/serializers/auth/cas.py:20 +#: accounts/models/account.py:56 settings/serializers/auth/cas.py:20 #: settings/serializers/auth/feishu.py:20 terminal/models/applet/applet.py:34 msgid "Version" msgstr "版本" -#: accounts/models/account.py:57 accounts/serializers/account/account.py:203 +#: accounts/models/account.py:58 accounts/serializers/account/account.py:202 #: users/models/user.py:804 msgid "Source" msgstr "来源" -#: accounts/models/account.py:58 +#: accounts/models/account.py:59 msgid "Source ID" msgstr "来源 ID" -#: accounts/models/account.py:61 +#: accounts/models/account.py:62 #: accounts/serializers/automations/change_secret.py:113 #: accounts/serializers/automations/change_secret.py:133 #: acls/serializers/base.py:124 assets/serializers/asset/common.py:125 @@ -241,35 +251,35 @@ msgstr "来源 ID" msgid "Account" msgstr "账号" -#: accounts/models/account.py:67 +#: accounts/models/account.py:68 msgid "Can view asset account secret" msgstr "可以查看资产账号密码" -#: accounts/models/account.py:68 +#: accounts/models/account.py:69 msgid "Can view asset history account" msgstr "可以查看资产历史账号" -#: accounts/models/account.py:69 +#: accounts/models/account.py:70 msgid "Can view asset history account secret" msgstr "可以查看资产历史账号密码" -#: accounts/models/account.py:70 +#: accounts/models/account.py:71 msgid "Can verify account" msgstr "可以验证账号" -#: accounts/models/account.py:71 +#: accounts/models/account.py:72 msgid "Can push account" msgstr "可以推送账号" -#: accounts/models/account.py:130 +#: accounts/models/account.py:131 msgid "Account template" msgstr "账号模版" -#: accounts/models/account.py:135 +#: accounts/models/account.py:136 msgid "Can view asset account template secret" msgstr "可以查看资产账号模版密码" -#: accounts/models/account.py:136 +#: accounts/models/account.py:137 msgid "Can change asset account template secret" msgstr "可以更改资产账号模版密码" @@ -322,7 +332,7 @@ msgstr "原因" #: accounts/models/automations/backup_account.py:99 #: accounts/serializers/automations/change_secret.py:111 #: accounts/serializers/automations/change_secret.py:134 -#: ops/serializers/job.py:56 terminal/serializers/session.py:43 +#: ops/serializers/job.py:56 terminal/serializers/session.py:44 msgid "Is success" msgstr "是否成功" @@ -367,7 +377,7 @@ msgid "Can add push account execution" msgstr "创建推送账号执行" #: accounts/models/automations/change_secret.py:18 accounts/models/base.py:36 -#: accounts/serializers/account/account.py:419 +#: accounts/serializers/account/account.py:427 #: accounts/serializers/account/base.py:16 #: accounts/serializers/automations/change_secret.py:46 #: authentication/serializers/connect_token_secret.py:41 @@ -376,8 +386,8 @@ msgid "Secret type" msgstr "密文类型" #: accounts/models/automations/change_secret.py:20 -#: accounts/models/automations/change_secret.py:89 accounts/models/base.py:38 -#: accounts/serializers/account/base.py:19 +#: accounts/models/automations/change_secret.py:89 +#: accounts/models/mixins/vault.py:48 accounts/serializers/account/base.py:19 #: authentication/models/temp_token.py:10 #: authentication/templates/authentication/_access_key_modal.html:31 #: settings/serializers/auth/radius.py:19 @@ -417,7 +427,7 @@ msgid "Date finished" msgstr "结束日期" #: accounts/models/automations/change_secret.py:93 -#: accounts/serializers/account/account.py:239 assets/const/automation.py:8 +#: accounts/serializers/account/account.py:247 assets/const/automation.py:8 #: authentication/views/base.py:26 authentication/views/base.py:27 #: authentication/views/base.py:28 common/const/choices.py:20 msgid "Error" @@ -496,7 +506,7 @@ msgstr "账号验证" #: assets/serializers/platform.py:223 #: authentication/serializers/connect_token_secret.py:110 ops/mixin.py:21 #: ops/models/adhoc.py:20 ops/models/celery.py:15 ops/models/celery.py:57 -#: ops/models/job.py:94 ops/models/playbook.py:23 ops/serializers/job.py:20 +#: ops/models/job.py:94 ops/models/playbook.py:28 ops/serializers/job.py:20 #: orgs/models.py:80 perms/models/asset_permission.py:56 rbac/models/role.py:29 #: settings/models.py:32 settings/serializers/sms.py:6 #: terminal/models/applet/applet.py:32 terminal/models/component/endpoint.py:12 @@ -508,11 +518,11 @@ msgstr "账号验证" msgid "Name" msgstr "名称" -#: accounts/models/base.py:39 +#: accounts/models/base.py:38 msgid "Privileged" msgstr "特权账号" -#: accounts/models/base.py:40 assets/models/asset/common.py:156 +#: accounts/models/base.py:39 assets/models/asset/common.py:156 #: assets/models/automations/base.py:21 assets/models/cmd_filter.py:39 #: assets/models/label.py:22 #: authentication/serializers/connect_token_secret.py:114 @@ -584,8 +594,8 @@ msgstr "类别" #: assets/serializers/asset/common.py:122 assets/serializers/platform.py:112 #: assets/serializers/platform.py:127 audits/serializers.py:49 #: authentication/serializers/connect_token_secret.py:123 ops/models/job.py:105 -#: perms/serializers/user_permission.py:27 terminal/models/applet/applet.py:38 -#: terminal/models/component/storage.py:57 +#: perms/serializers/user_permission.py:27 settings/serializers/vault.py:13 +#: terminal/models/applet/applet.py:38 terminal/models/component/storage.py:57 #: terminal/models/component/storage.py:146 terminal/serializers/applet.py:29 #: terminal/serializers/session.py:20 terminal/serializers/storage.py:226 #: terminal/serializers/storage.py:238 tickets/models/comment.py:26 @@ -599,23 +609,22 @@ msgstr "类型" msgid "Asset not found" msgstr "资产不存在" -#: accounts/serializers/account/account.py:201 -#: accounts/serializers/account/base.py:64 +#: accounts/serializers/account/account.py:236 msgid "Has secret" msgstr "已托管密码" -#: accounts/serializers/account/account.py:238 ops/models/celery.py:60 +#: accounts/serializers/account/account.py:246 ops/models/celery.py:60 #: tickets/models/comment.py:13 tickets/models/ticket/general.py:45 #: tickets/models/ticket/general.py:279 tickets/serializers/super_ticket.py:14 #: tickets/serializers/ticket/ticket.py:21 msgid "State" msgstr "状态" -#: accounts/serializers/account/account.py:240 +#: accounts/serializers/account/account.py:248 msgid "Changed" msgstr "已修改" -#: accounts/serializers/account/account.py:250 +#: accounts/serializers/account/account.py:258 #: accounts/serializers/automations/base.py:22 acls/models/base.py:97 #: assets/models/automations/base.py:19 #: assets/serializers/automations/base.py:20 ops/models/base.py:17 @@ -624,27 +633,27 @@ msgstr "已修改" msgid "Assets" msgstr "资产" -#: accounts/serializers/account/account.py:305 +#: accounts/serializers/account/account.py:313 msgid "Account already exists" msgstr "账号已存在" -#: accounts/serializers/account/account.py:355 +#: accounts/serializers/account/account.py:363 #, python-format msgid "Asset does not support this secret type: %s" msgstr "资产不支持账号类型: %s" -#: accounts/serializers/account/account.py:387 +#: accounts/serializers/account/account.py:395 msgid "Account has exist" msgstr "账号已存在" -#: accounts/serializers/account/account.py:420 +#: accounts/serializers/account/account.py:428 #: authentication/serializers/connect_token_secret.py:156 #: authentication/templates/authentication/_access_key_modal.html:30 #: perms/models/perm_node.py:21 users/serializers/group.py:31 msgid "ID" msgstr "ID" -#: accounts/serializers/account/account.py:427 acls/serializers/base.py:116 +#: accounts/serializers/account/account.py:435 acls/serializers/base.py:116 #: assets/models/cmd_filter.py:24 assets/models/label.py:16 audits/models.py:49 #: audits/models.py:85 audits/models.py:163 #: authentication/models/connection_token.py:32 @@ -652,10 +661,10 @@ msgstr "ID" #: notifications/models/notification.py:12 #: perms/api/user_permission/mixin.py:55 perms/models/asset_permission.py:58 #: perms/serializers/permission.py:30 rbac/builtin.py:123 -#: rbac/models/rolebinding.py:49 terminal/backends/command/models.py:16 -#: terminal/models/session/session.py:29 terminal/models/session/sharing.py:33 -#: terminal/notifications.py:156 terminal/notifications.py:205 -#: terminal/serializers/command.py:16 +#: rbac/models/rolebinding.py:49 rbac/serializers/rolebinding.py:17 +#: terminal/backends/command/models.py:16 terminal/models/session/session.py:29 +#: terminal/models/session/sharing.py:33 terminal/notifications.py:156 +#: terminal/notifications.py:205 terminal/serializers/command.py:16 #: terminal/templates/terminal/_msg_command_warning.html:6 #: terminal/templates/terminal/_msg_session_sharing.html:6 #: tickets/models/comment.py:21 users/const.py:14 users/models/user.py:947 @@ -663,7 +672,7 @@ msgstr "ID" msgid "User" msgstr "用户" -#: accounts/serializers/account/account.py:428 +#: accounts/serializers/account/account.py:436 #: authentication/templates/authentication/_access_key_modal.html:33 #: terminal/notifications.py:158 terminal/notifications.py:207 msgid "Date" @@ -694,12 +703,12 @@ msgstr "资产类型" msgid "Key password" msgstr "密钥密码" -#: accounts/serializers/account/base.py:80 +#: accounts/serializers/account/base.py:78 #: assets/serializers/asset/common.py:311 msgid "Spec info" msgstr "特殊信息" -#: accounts/serializers/account/base.py:82 +#: accounts/serializers/account/base.py:80 msgid "" "Tip: If no username is required for authentication, fill in `null`, If AD " "account, like `username@domain`" @@ -765,6 +774,12 @@ msgstr "收集资产上的账号" msgid "Push accounts to assets" msgstr "推送账号到资产" +#: accounts/tasks/vault.py:15 +#, fuzzy +#| msgid "Sync instance detail" +msgid "Sync secret to vault" +msgstr "同步实例详情" + #: accounts/tasks/verify_account.py:49 msgid "Verify asset account availability" msgstr "验证资产账号可用性" @@ -773,19 +788,19 @@ msgstr "验证资产账号可用性" msgid "Verify accounts connectivity" msgstr "测试账号可连接性" -#: accounts/utils.py:43 +#: accounts/utils.py:41 msgid "Password can not contains `{{` " msgstr "密码不能包含 `{{` 字符" -#: accounts/utils.py:46 +#: accounts/utils.py:44 msgid "Password can not contains `'` " msgstr "密码不能包含 `'` 字符" -#: accounts/utils.py:48 +#: accounts/utils.py:46 msgid "Password can not contains `\"` " msgstr "密码不能包含 `\"` 字符" -#: accounts/utils.py:54 +#: accounts/utils.py:52 msgid "private key invalid or passphrase error" msgstr "密钥不合法或密钥密码错误" @@ -1076,14 +1091,15 @@ msgstr "禁用" msgid "Basic" msgstr "基本" -#: assets/const/base.py:35 assets/const/protocol.py:201 +#: assets/const/base.py:35 assets/const/protocol.py:221 #: assets/models/asset/web.py:13 msgid "Script" msgstr "脚本" #: assets/const/category.py:10 assets/models/asset/host.py:8 #: settings/serializers/auth/radius.py:16 settings/serializers/auth/sms.py:67 -#: terminal/models/component/endpoint.py:13 terminal/serializers/applet.py:17 +#: settings/serializers/vault.py:16 terminal/models/component/endpoint.py:13 +#: terminal/serializers/applet.py:17 #: xpack/plugins/cloud/serializers/account_attrs.py:72 msgid "Host" msgstr "主机" @@ -1176,41 +1192,71 @@ msgstr "连接 RDP 使用的安全层" msgid "AD domain" msgstr "AD 网域" -#: assets/const/protocol.py:92 assets/models/asset/database.py:10 +#: assets/const/protocol.py:88 +#, fuzzy +#| msgid "Username attr" +msgid "Username prompt" +msgstr "用户名属性" + +#: assets/const/protocol.py:89 +msgid "We will send username when we see this prompt" +msgstr "" + +#: assets/const/protocol.py:94 +#, fuzzy +#| msgid "Password auth" +msgid "Password prompt" +msgstr "密码认证" + +#: assets/const/protocol.py:95 +msgid "We will send password when we see this prompt" +msgstr "" + +#: assets/const/protocol.py:100 +#, fuzzy +#| msgid "Success" +msgid "Success prompt" +msgstr "成功" + +#: assets/const/protocol.py:101 +msgid "We will consider login success when we see this prompt" +msgstr "" + +#: assets/const/protocol.py:112 assets/models/asset/database.py:10 #: settings/serializers/email.py:37 msgid "Use SSL" msgstr "使用 SSL" -#: assets/const/protocol.py:127 +#: assets/const/protocol.py:147 msgid "SYSDBA" msgstr "SYSDBA" -#: assets/const/protocol.py:128 +#: assets/const/protocol.py:148 msgid "Connect as SYSDBA" msgstr "以 SYSDBA 角色连接" -#: assets/const/protocol.py:157 +#: assets/const/protocol.py:177 msgid "Auth username" msgstr "使用用户名认证" -#: assets/const/protocol.py:178 assets/models/asset/web.py:9 +#: assets/const/protocol.py:198 assets/models/asset/web.py:9 #: assets/serializers/asset/info/spec.py:16 msgid "Autofill" msgstr "自动代填" -#: assets/const/protocol.py:186 assets/models/asset/web.py:10 +#: assets/const/protocol.py:206 assets/models/asset/web.py:10 msgid "Username selector" msgstr "用户名选择器" -#: assets/const/protocol.py:191 assets/models/asset/web.py:11 +#: assets/const/protocol.py:211 assets/models/asset/web.py:11 msgid "Password selector" msgstr "密码选择器" -#: assets/const/protocol.py:196 assets/models/asset/web.py:12 +#: assets/const/protocol.py:216 assets/models/asset/web.py:12 msgid "Submit selector" msgstr "确认按钮选择器" -#: assets/const/protocol.py:219 +#: assets/const/protocol.py:239 msgid "API mode" msgstr "API 模式" @@ -1237,7 +1283,7 @@ msgstr "SSH公钥" #: assets/models/_user.py:27 assets/models/cmd_filter.py:40 #: assets/models/cmd_filter.py:88 assets/models/group.py:20 #: common/db/models.py:36 ops/models/adhoc.py:26 ops/models/job.py:113 -#: ops/models/playbook.py:26 rbac/models/role.py:37 settings/models.py:37 +#: ops/models/playbook.py:31 rbac/models/role.py:37 settings/models.py:37 #: terminal/models/applet/applet.py:44 terminal/models/applet/applet.py:250 #: terminal/models/applet/host.py:141 terminal/models/component/endpoint.py:24 #: terminal/models/component/endpoint.py:102 @@ -1289,7 +1335,7 @@ msgstr "用户名与用户相同" #: assets/models/_user.py:52 authentication/models/connection_token.py:41 #: authentication/serializers/connect_token_secret.py:111 #: terminal/models/applet/applet.py:41 terminal/serializers/session.py:18 -#: terminal/serializers/session.py:39 terminal/serializers/storage.py:70 +#: terminal/serializers/session.py:40 terminal/serializers/storage.py:70 msgid "Protocol" msgstr "协议" @@ -1720,8 +1766,8 @@ msgstr "协议是必填的: {}" msgid "Default database" msgstr "默认数据库" -#: assets/serializers/asset/database.py:28 common/db/fields.py:579 -#: common/db/fields.py:584 common/serializers/fields.py:104 +#: assets/serializers/asset/database.py:28 common/db/fields.py:570 +#: common/db/fields.py:575 common/serializers/fields.py:104 #: tickets/serializers/ticket/common.py:58 #: xpack/plugins/cloud/serializers/account_attrs.py:56 #: xpack/plugins/cloud/serializers/account_attrs.py:79 @@ -2015,7 +2061,7 @@ msgstr "改密" #: audits/const.py:35 settings/serializers/terminal.py:6 #: terminal/models/applet/host.py:26 terminal/models/component/terminal.py:163 -#: terminal/serializers/session.py:46 terminal/serializers/session.py:55 +#: terminal/serializers/session.py:47 terminal/serializers/session.py:56 msgid "Terminal" msgstr "终端" @@ -2642,7 +2688,6 @@ msgid "Connect options" msgstr "连接项" #: authentication/models/connection_token.py:44 -#: rbac/serializers/rolebinding.py:21 msgid "User display" msgstr "用户名称" @@ -2858,7 +2903,7 @@ msgstr "代码错误" #: authentication/templates/authentication/_msg_reset_password_code.html:9 #: authentication/templates/authentication/_msg_rest_password_success.html:2 #: authentication/templates/authentication/_msg_rest_public_key_success.html:2 -#: jumpserver/conf.py:431 +#: jumpserver/conf.py:437 #: perms/templates/perms/_msg_item_permissions_expire.html:3 #: perms/templates/perms/_msg_permed_items_expire.html:3 #: tickets/templates/tickets/approve_check_password.html:33 @@ -3205,11 +3250,11 @@ msgstr "编码数据为 char" msgid "Marshal data to text field" msgstr "编码数据为 text" -#: common/db/fields.py:176 +#: common/db/fields.py:167 msgid "Encrypt field using Secret Key" msgstr "加密的字段" -#: common/db/fields.py:567 +#: common/db/fields.py:558 msgid "" "Invalid JSON data for JSONManyToManyField, should be like {'type': 'all'} or " "{'type': 'ids', 'ids': []} or {'type': 'attrs', 'attrs': [{'name': 'ip', " @@ -3219,19 +3264,19 @@ msgstr "" "{'type': 'attrs', 'attrs': [{'name': 'ip', 'match': 'exact', 'value': " "'1.1.1.1'}}" -#: common/db/fields.py:574 +#: common/db/fields.py:565 msgid "Invalid type, should be \"all\", \"ids\" or \"attrs\"" msgstr "无效类型,应为 all、ids 或 attrs" -#: common/db/fields.py:577 +#: common/db/fields.py:568 msgid "Invalid ids for ids, should be a list" msgstr "无效的ID,应为列表" -#: common/db/fields.py:582 common/db/fields.py:587 +#: common/db/fields.py:573 common/db/fields.py:578 msgid "Invalid attrs, should be a list of dict" msgstr "无效的属性,应为dict列表" -#: common/db/fields.py:589 +#: common/db/fields.py:580 msgid "Invalid attrs, should be has name and value" msgstr "无效属性,应具有名称和值" @@ -3443,11 +3488,11 @@ msgstr "导出搜素: %s" msgid "User %s view/export secret" msgstr "用户 %s 查看/导出 了密码" -#: jumpserver/conf.py:430 +#: jumpserver/conf.py:436 msgid "Create account successfully" msgstr "创建账号成功" -#: jumpserver/conf.py:432 +#: jumpserver/conf.py:438 msgid "Your account has been created successfully" msgstr "你的账号已创建成功" @@ -3649,7 +3694,7 @@ msgid "Args" msgstr "参数" #: ops/models/adhoc.py:25 ops/models/base.py:16 ops/models/base.py:53 -#: ops/models/job.py:106 ops/models/job.py:192 ops/models/playbook.py:25 +#: ops/models/job.py:106 ops/models/job.py:192 ops/models/playbook.py:30 #: terminal/models/session/sharing.py:24 msgid "Creator" msgstr "创建者" @@ -3744,11 +3789,11 @@ msgstr "Material 类型" msgid "Job Execution" msgstr "作业执行" -#: ops/models/playbook.py:28 +#: ops/models/playbook.py:33 msgid "CreateMethod" msgstr "创建方式" -#: ops/models/playbook.py:29 +#: ops/models/playbook.py:34 msgid "VCS URL" msgstr "VCS URL" @@ -3788,7 +3833,7 @@ msgstr "保存后执行" msgid "Job type" msgstr "任务类型" -#: ops/serializers/job.py:57 terminal/serializers/session.py:47 +#: ops/serializers/job.py:57 terminal/serializers/session.py:48 msgid "Is finished" msgstr "是否完成" @@ -3884,14 +3929,14 @@ msgstr "组织管理" #: orgs/mixins/models.py:57 orgs/mixins/serializers.py:25 orgs/models.py:89 #: rbac/const.py:7 rbac/models/rolebinding.py:56 -#: rbac/serializers/rolebinding.py:40 settings/serializers/auth/ldap.py:63 +#: rbac/serializers/rolebinding.py:44 settings/serializers/auth/ldap.py:63 #: terminal/templates/terminal/_msg_command_warning.html:21 #: terminal/templates/terminal/_msg_session_sharing.html:14 #: tickets/models/ticket/general.py:302 tickets/serializers/ticket/ticket.py:60 msgid "Organization" msgstr "组织" -#: orgs/mixins/serializers.py:26 rbac/serializers/rolebinding.py:23 +#: orgs/mixins/serializers.py:26 rbac/serializers/rolebinding.py:27 msgid "Org name" msgstr "组织名称" @@ -4031,7 +4076,7 @@ msgstr "角色已绑定用户,不能删除" msgid "Internal role, can't be update" msgstr "内部角色,不能更新" -#: rbac/api/rolebinding.py:52 +#: rbac/api/rolebinding.py:45 msgid "{} at least one system role" msgstr "{} 至少有一个系统角色" @@ -4143,11 +4188,7 @@ msgstr "用户数量" msgid "Display name" msgstr "显示名称" -#: rbac/serializers/rolebinding.py:22 -msgid "Role display" -msgstr "角色显示" - -#: rbac/serializers/rolebinding.py:56 +#: rbac/serializers/rolebinding.py:60 msgid "Has bound this role" msgstr "已经绑定" @@ -4226,7 +4267,7 @@ msgid "View permission tree" msgstr "查看授权树" #: settings/api/dingtalk.py:31 settings/api/feishu.py:36 -#: settings/api/sms.py:155 settings/api/wecom.py:37 +#: settings/api/sms.py:155 settings/api/vault.py:39 settings/api/wecom.py:37 msgid "Test success" msgstr "测试成功" @@ -4279,34 +4320,40 @@ msgid "Can change auth setting" msgstr "认证设置" #: settings/models.py:162 +#, fuzzy +#| msgid "Can change auth setting" +msgid "Can change vault setting" +msgstr "认证设置" + +#: settings/models.py:163 msgid "Can change system msg sub setting" msgstr "消息订阅设置" -#: settings/models.py:163 +#: settings/models.py:164 msgid "Can change sms setting" msgstr "短信设置" -#: settings/models.py:164 +#: settings/models.py:165 msgid "Can change security setting" msgstr "安全设置" -#: settings/models.py:165 +#: settings/models.py:166 msgid "Can change clean setting" msgstr "定期清理" -#: settings/models.py:166 +#: settings/models.py:167 msgid "Can change interface setting" msgstr "界面设置" -#: settings/models.py:167 +#: settings/models.py:168 msgid "Can change license setting" msgstr "许可证设置" -#: settings/models.py:168 +#: settings/models.py:169 msgid "Can change terminal setting" msgstr "终端设置" -#: settings/models.py:169 +#: settings/models.py:170 msgid "Can change other setting" msgstr "其它设置" @@ -5291,6 +5338,10 @@ msgid "" "Tip: Default resolution to use when connecting graphical assets in Luna pages" msgstr "提示:在Luna 页面中连接图形化资产时默认使用的分辨率" +#: settings/serializers/vault.py:22 +msgid "Mount Point" +msgstr "" + #: settings/tasks/ldap.py:24 msgid "Periodic import ldap user" msgstr "周期导入 LDAP 用户" @@ -5481,13 +5532,13 @@ msgstr "过期。" #, python-format msgid "" "\n" -" Your password has expired, please click this link update password.\n" +" Your password has expired, please click this link update password.\n" " " msgstr "" "\n" -" 您的密码已经过期,请点击 链接 更新密码\n" +" 您的密码已经过期,请点击 链接 更新密码\n" " " #: templates/_message.html:30 @@ -5511,8 +5562,8 @@ msgstr "" #, python-format msgid "" "\n" -" Your information was incomplete. Please click this link to complete your information.\n" +" Your information was incomplete. Please click this link to complete your information.\n" " " msgstr "" "\n" @@ -5524,13 +5575,13 @@ msgstr "" #, python-format msgid "" "\n" -" Your ssh public key not set or expired. Please click this link to update\n" +" Your ssh public key not set or expired. Please click this link to update\n" " " msgstr "" "\n" -" 您的SSH密钥没有设置或已失效,请点击 链接 更新\n" +" 您的SSH密钥没有设置或已失效,请点击 链接 更新\n" " " #: templates/_mfa_login_field.html:28 @@ -5615,7 +5666,7 @@ msgstr "命令存储" msgid "Invalid" msgstr "无效" -#: terminal/api/component/storage.py:119 terminal/tasks.py:140 +#: terminal/api/component/storage.py:119 terminal/tasks.py:141 msgid "Test failure: {}" msgstr "测试失败: {}" @@ -5624,7 +5675,7 @@ msgid "Test successful" msgstr "测试成功" #: terminal/api/component/storage.py:124 terminal/notifications.py:240 -#: terminal/tasks.py:144 +#: terminal/tasks.py:145 msgid "Test failure: Account invalid" msgstr "测试失败: 账号无效" @@ -5953,23 +6004,27 @@ msgstr "回放" msgid "Date end" msgstr "结束日期" -#: terminal/models/session/session.py:261 +#: terminal/models/session/session.py:47 terminal/serializers/session.py:55 +msgid "Command amount" +msgstr "命令数量" + +#: terminal/models/session/session.py:281 msgid "Session record" msgstr "会话记录" -#: terminal/models/session/session.py:263 +#: terminal/models/session/session.py:283 msgid "Can monitor session" msgstr "可以监控会话" -#: terminal/models/session/session.py:264 +#: terminal/models/session/session.py:284 msgid "Can share session" msgstr "可以分享会话" -#: terminal/models/session/session.py:265 +#: terminal/models/session/session.py:285 msgid "Can terminate session" msgstr "可以终断会话" -#: terminal/models/session/session.py:266 +#: terminal/models/session/session.py:286 msgid "Can validate session action perm" msgstr "可以验证会话动作权限" @@ -6217,38 +6272,34 @@ msgstr "如果不同端点下的资产 IP 有冲突,使用资产标签实现" msgid "Asset IP" msgstr "资产 IP" -#: terminal/serializers/session.py:22 terminal/serializers/session.py:44 +#: terminal/serializers/session.py:22 terminal/serializers/session.py:45 msgid "Can replay" msgstr "是否可重放" -#: terminal/serializers/session.py:23 terminal/serializers/session.py:45 +#: terminal/serializers/session.py:23 terminal/serializers/session.py:46 msgid "Can join" msgstr "是否可加入" -#: terminal/serializers/session.py:24 terminal/serializers/session.py:48 +#: terminal/serializers/session.py:24 terminal/serializers/session.py:49 msgid "Can terminate" msgstr "是否可中断" -#: terminal/serializers/session.py:40 +#: terminal/serializers/session.py:41 msgid "User ID" msgstr "用户 ID" -#: terminal/serializers/session.py:41 +#: terminal/serializers/session.py:42 msgid "Asset ID" msgstr "资产 ID" -#: terminal/serializers/session.py:42 +#: terminal/serializers/session.py:43 msgid "Login from display" msgstr "登录来源名称" -#: terminal/serializers/session.py:49 +#: terminal/serializers/session.py:50 msgid "Terminal display" msgstr "终端显示" -#: terminal/serializers/session.py:54 -msgid "Command amount" -msgstr "命令数量" - #: terminal/serializers/storage.py:22 msgid "Endpoint invalid: remove path `{}`" msgstr "端点无效: 移除路径 `{}`" @@ -6339,11 +6390,11 @@ msgstr "运行应用机部署" msgid "Install applet" msgstr "安装应用" -#: terminal/tasks.py:110 +#: terminal/tasks.py:111 msgid "Generate applet host accounts" msgstr "收集远程应用上的账号" -#: terminal/tasks.py:122 +#: terminal/tasks.py:123 msgid "Check command replay storage connectivity" msgstr "检查命令及录像存储可连接性 " @@ -7837,6 +7888,9 @@ msgstr "旗舰版" msgid "Community edition" msgstr "社区版" +#~ msgid "Role display" +#~ msgstr "角色显示" + #~ msgid "SFTP enabled" #~ msgstr "SFTP 已启用" From 6d2e7cf7f4c2c4334be68f60a8ce17def7bd0c56 Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Wed, 2 Aug 2023 17:51:58 +0800 Subject: [PATCH 087/177] =?UTF-8?q?perf:=20=E4=BB=BB=E5=8A=A1=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E8=BF=87=E6=BB=A4=E9=A1=B9=20(#11181)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: feng <1304903146@qq.com> --- apps/accounts/api/automations/backup.py | 4 ++-- apps/accounts/api/automations/base.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/accounts/api/automations/backup.py b/apps/accounts/api/automations/backup.py index 134f9548c..b2d6d7352 100644 --- a/apps/accounts/api/automations/backup.py +++ b/apps/accounts/api/automations/backup.py @@ -26,8 +26,8 @@ class AccountBackupPlanViewSet(OrgBulkModelViewSet): class AccountBackupPlanExecutionViewSet(viewsets.ModelViewSet): serializer_class = serializers.AccountBackupPlanExecutionSerializer - search_fields = ('trigger',) - filterset_fields = ('trigger', 'plan_id') + search_fields = ('trigger', 'plan__name') + filterset_fields = ('trigger', 'plan_id', 'plan__name') http_method_names = ['get', 'post', 'options'] def get_queryset(self): diff --git a/apps/accounts/api/automations/base.py b/apps/accounts/api/automations/base.py index d5e588c04..70ebfd709 100644 --- a/apps/accounts/api/automations/base.py +++ b/apps/accounts/api/automations/base.py @@ -95,8 +95,8 @@ class AutomationExecutionViewSet( mixins.CreateModelMixin, mixins.ListModelMixin, mixins.RetrieveModelMixin, viewsets.GenericViewSet ): - search_fields = ('trigger',) - filterset_fields = ('trigger', 'automation_id') + search_fields = ('trigger', 'automation__name') + filterset_fields = ('trigger', 'automation_id', 'automation__name') serializer_class = serializers.AutomationExecutionSerializer tp: str From 41fa1d65ff2817937caddd7d417c2200ecce5d4d Mon Sep 17 00:00:00 2001 From: ibuler Date: Wed, 2 Aug 2023 17:54:11 +0800 Subject: [PATCH 088/177] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=20telnet=20?= =?UTF-8?q?=E5=B9=B3=E5=8F=B0=20setting?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../migrations/0123_auto_20230802_1740.py | 33 +++++++++++++++++++ apps/jumpserver/conf.py | 2 +- apps/jumpserver/settings/custom.py | 2 +- apps/locale/ja/LC_MESSAGES/django.mo | 4 +-- apps/locale/ja/LC_MESSAGES/django.po | 18 ++++------ apps/locale/zh/LC_MESSAGES/django.mo | 4 +-- apps/locale/zh/LC_MESSAGES/django.po | 18 ++++------ apps/settings/serializers/terminal.py | 5 --- 8 files changed, 51 insertions(+), 35 deletions(-) create mode 100644 apps/assets/migrations/0123_auto_20230802_1740.py diff --git a/apps/assets/migrations/0123_auto_20230802_1740.py b/apps/assets/migrations/0123_auto_20230802_1740.py new file mode 100644 index 000000000..904b9f379 --- /dev/null +++ b/apps/assets/migrations/0123_auto_20230802_1740.py @@ -0,0 +1,33 @@ +# Generated by Django 4.1.10 on 2023-08-02 09:40 + +from django.db import migrations +import json + + +def migrate_telnet_regex(apps, schema_editor): + setting_cls = apps.get_model('settings', 'Setting') + setting = setting_cls.objects.filter(name='TERMINAL_TELNET_REGEX').first() + if not setting: + print("Not found telnet regex setting, skip") + return + try: + value = json.loads(setting.value) + except Exception: + print("Invalid telnet regex setting, skip") + return + platform_protocol_cls = apps.get_model('assets', 'PlatformProtocol') + telnets = platform_protocol_cls.objects.filter(name='telnet') + if telnets.count() > 0: + telnets.update(setting={'success_prompt': value}) + print("Migrate telnet regex setting success: ", telnets.count()) + + +class Migration(migrations.Migration): + + dependencies = [ + ('assets', '0122_auto_20230801_1940'), + ] + + operations = [ + migrations.RunPython(migrate_telnet_regex) + ] diff --git a/apps/jumpserver/conf.py b/apps/jumpserver/conf.py index 98a6477d4..eb339f8a1 100644 --- a/apps/jumpserver/conf.py +++ b/apps/jumpserver/conf.py @@ -449,7 +449,6 @@ class Config(dict): 'TERMINAL_ASSET_LIST_PAGE_SIZE': 'auto', 'TERMINAL_SESSION_KEEP_DURATION': 200, 'TERMINAL_HOST_KEY': '', - 'TERMINAL_TELNET_REGEX': '', 'TERMINAL_COMMAND_STORAGE': {}, # Luna 页面 # 默认图形化分辨率 @@ -554,6 +553,7 @@ class Config(dict): 'TICKET_AUTHORIZE_DEFAULT_TIME': 7, 'TICKET_AUTHORIZE_DEFAULT_TIME_UNIT': 'day', 'PERIOD_TASK_ENABLED': True, + 'TERMINAL_TELNET_REGEX': '', # 导航栏 帮助 'HELP_DOCUMENT_URL': 'https://docs.jumpserver.org/zh/v3/', diff --git a/apps/jumpserver/settings/custom.py b/apps/jumpserver/settings/custom.py index 16d503f1c..71c90cef3 100644 --- a/apps/jumpserver/settings/custom.py +++ b/apps/jumpserver/settings/custom.py @@ -82,7 +82,7 @@ TERMINAL_ASSET_LIST_PAGE_SIZE = CONFIG.TERMINAL_ASSET_LIST_PAGE_SIZE TERMINAL_SESSION_KEEP_DURATION = CONFIG.TERMINAL_SESSION_KEEP_DURATION TERMINAL_HOST_KEY = CONFIG.TERMINAL_HOST_KEY TERMINAL_HEADER_TITLE = CONFIG.TERMINAL_HEADER_TITLE -TERMINAL_TELNET_REGEX = CONFIG.TERMINAL_TELNET_REGEX +# TERMINAL_TELNET_REGEX = CONFIG.TERMINAL_TELNET_REGEX # 默认图形化分辨率 TERMINAL_GRAPHICAL_RESOLUTION = CONFIG.TERMINAL_GRAPHICAL_RESOLUTION diff --git a/apps/locale/ja/LC_MESSAGES/django.mo b/apps/locale/ja/LC_MESSAGES/django.mo index e2cc899ec..4b1734de2 100644 --- a/apps/locale/ja/LC_MESSAGES/django.mo +++ b/apps/locale/ja/LC_MESSAGES/django.mo @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:538beabe7c224b203bbc0ebaf191509a8f407f6b3e8194038fc203bde10d6d5a -size 150250 +oid sha256:d9e79f70d055fa4d3fda971820bcd0eb186a8806d91346c7038add4ee89d647a +size 151115 diff --git a/apps/locale/ja/LC_MESSAGES/django.po b/apps/locale/ja/LC_MESSAGES/django.po index b4b3b2634..3c45e852b 100644 --- a/apps/locale/ja/LC_MESSAGES/django.po +++ b/apps/locale/ja/LC_MESSAGES/django.po @@ -1200,34 +1200,28 @@ msgid "AD domain" msgstr "AD ドメイン" #: assets/const/protocol.py:88 -#, fuzzy -#| msgid "Username attr" msgid "Username prompt" -msgstr "ユーザー名のプロパティ" +msgstr "ユーザー名プロンプト" #: assets/const/protocol.py:89 msgid "We will send username when we see this prompt" -msgstr "" +msgstr "このプロンプトが表示されたらユーザー名を送信します" #: assets/const/protocol.py:94 -#, fuzzy -#| msgid "Password auth" msgid "Password prompt" -msgstr "パスワード認証" +msgstr "パスワードプロンプト" #: assets/const/protocol.py:95 msgid "We will send password when we see this prompt" -msgstr "" +msgstr "このプロンプトが表示されたらパスワードを送信します" #: assets/const/protocol.py:100 -#, fuzzy -#| msgid "Success" msgid "Success prompt" -msgstr "成功" +msgstr "成功プロンプト" #: assets/const/protocol.py:101 msgid "We will consider login success when we see this prompt" -msgstr "" +msgstr "このプロンプトが表示されたらログイン成功とみなします" #: assets/const/protocol.py:112 assets/models/asset/database.py:10 #: settings/serializers/email.py:37 diff --git a/apps/locale/zh/LC_MESSAGES/django.mo b/apps/locale/zh/LC_MESSAGES/django.mo index 00fe60499..da572bc13 100644 --- a/apps/locale/zh/LC_MESSAGES/django.mo +++ b/apps/locale/zh/LC_MESSAGES/django.mo @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2cf5749656bd07818b67191c2f665246e903d74e76c49ebcdec6004322f75314 -size 122767 +oid sha256:f70c68e6f9f5cd621ae5ff04e73bb882d4849d3750a8c34f586dc3cc74adfca4 +size 123431 diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po index 9c21b13d7..2136158ea 100644 --- a/apps/locale/zh/LC_MESSAGES/django.po +++ b/apps/locale/zh/LC_MESSAGES/django.po @@ -1193,34 +1193,28 @@ msgid "AD domain" msgstr "AD 网域" #: assets/const/protocol.py:88 -#, fuzzy -#| msgid "Username attr" msgid "Username prompt" -msgstr "用户名属性" +msgstr "用户名提示" #: assets/const/protocol.py:89 msgid "We will send username when we see this prompt" -msgstr "" +msgstr "当我们看到这个提示时,我们将发送用户名" #: assets/const/protocol.py:94 -#, fuzzy -#| msgid "Password auth" msgid "Password prompt" -msgstr "密码认证" +msgstr "密码提示" #: assets/const/protocol.py:95 msgid "We will send password when we see this prompt" -msgstr "" +msgstr "当我们看到这个提示时,我们将发送密码" #: assets/const/protocol.py:100 -#, fuzzy -#| msgid "Success" msgid "Success prompt" -msgstr "成功" +msgstr "成功提示" #: assets/const/protocol.py:101 msgid "We will consider login success when we see this prompt" -msgstr "" +msgstr "当我们看到这个提示时,我们将认为登录成功" #: assets/const/protocol.py:112 assets/models/asset/database.py:10 #: settings/serializers/email.py:37 diff --git a/apps/settings/serializers/terminal.py b/apps/settings/serializers/terminal.py index 86465009e..ea1412cd1 100644 --- a/apps/settings/serializers/terminal.py +++ b/apps/settings/serializers/terminal.py @@ -30,11 +30,6 @@ class TerminalSettingSerializer(serializers.Serializer): TERMINAL_ASSET_LIST_PAGE_SIZE = serializers.ChoiceField( PAGE_SIZE_CHOICES, required=False, label=_('List page size') ) - TERMINAL_TELNET_REGEX = serializers.CharField( - allow_blank=True, max_length=1024, required=False, label=_('Telnet login regex'), - help_text=_("Tips: The login success message varies with devices. " - "if you cannot log in to the device through Telnet, set this parameter") - ) TERMINAL_MAGNUS_ENABLED = serializers.BooleanField(label=_("Enable database proxy")) TERMINAL_RAZOR_ENABLED = serializers.BooleanField(label=_("Enable Razor")) TERMINAL_KOKO_SSH_ENABLED = serializers.BooleanField(label=_("Enable SSH Client")) From ee874f3ddc0220c8248a373291da00680f8231e2 Mon Sep 17 00:00:00 2001 From: ibuler Date: Thu, 3 Aug 2023 10:52:13 +0800 Subject: [PATCH 089/177] =?UTF-8?q?perf:=20=E5=90=88=E5=B9=B6=20migrations?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../migrations/0121_auto_20230725_1458.py | 20 +++++++++++ .../migrations/0122_auto_20230801_1940.py | 24 -------------- .../migrations/0123_auto_20230802_1740.py | 33 ------------------- 3 files changed, 20 insertions(+), 57 deletions(-) delete mode 100644 apps/assets/migrations/0122_auto_20230801_1940.py delete mode 100644 apps/assets/migrations/0123_auto_20230802_1740.py diff --git a/apps/assets/migrations/0121_auto_20230725_1458.py b/apps/assets/migrations/0121_auto_20230725_1458.py index 011e9b40a..9e50e4337 100644 --- a/apps/assets/migrations/0121_auto_20230725_1458.py +++ b/apps/assets/migrations/0121_auto_20230725_1458.py @@ -1,6 +1,7 @@ # Generated by Django 4.1.10 on 2023-07-25 06:58 from django.db import migrations +import json def migrate_platforms_sftp_protocol(apps, schema_editor): @@ -68,6 +69,24 @@ def migrate_assets_sftp_protocol(apps, schema_editor): print(" - Add {}".format(len(new_protocols))) +def migrate_telnet_regex(apps, schema_editor): + setting_cls = apps.get_model('settings', 'Setting') + setting = setting_cls.objects.filter(name='TERMINAL_TELNET_REGEX').first() + if not setting: + print("Not found telnet regex setting, skip") + return + try: + value = json.loads(setting.value) + except Exception: + print("Invalid telnet regex setting, skip") + return + platform_protocol_cls = apps.get_model('assets', 'PlatformProtocol') + telnets = platform_protocol_cls.objects.filter(name='telnet') + if telnets.count() > 0: + telnets.update(setting={'success_prompt': value}) + print("Migrate telnet regex setting success: ", telnets.count()) + + class Migration(migrations.Migration): dependencies = [ @@ -77,4 +96,5 @@ class Migration(migrations.Migration): operations = [ migrations.RunPython(migrate_platforms_sftp_protocol), migrations.RunPython(migrate_assets_sftp_protocol), + migrations.RunPython(migrate_telnet_regex), ] diff --git a/apps/assets/migrations/0122_auto_20230801_1940.py b/apps/assets/migrations/0122_auto_20230801_1940.py deleted file mode 100644 index 3197ffec3..000000000 --- a/apps/assets/migrations/0122_auto_20230801_1940.py +++ /dev/null @@ -1,24 +0,0 @@ -# Generated by Django 4.1.10 on 2023-08-01 11:40 - -from django.db import migrations - - -def windows_platform_protocols_ssh_default(apps, schema_editor): - platform_cls = apps.get_model('assets', 'Platform') - windows_platform = platform_cls.objects.filter( - name='Windows', internal=True, type='windows' - ).first() - if not windows_platform: - return - - windows_platform.protocols.filter(name='ssh').update(default=True) - - -class Migration(migrations.Migration): - dependencies = [ - ('assets', '0121_auto_20230725_1458'), - ] - - operations = [ - migrations.RunPython(windows_platform_protocols_ssh_default) - ] diff --git a/apps/assets/migrations/0123_auto_20230802_1740.py b/apps/assets/migrations/0123_auto_20230802_1740.py deleted file mode 100644 index 904b9f379..000000000 --- a/apps/assets/migrations/0123_auto_20230802_1740.py +++ /dev/null @@ -1,33 +0,0 @@ -# Generated by Django 4.1.10 on 2023-08-02 09:40 - -from django.db import migrations -import json - - -def migrate_telnet_regex(apps, schema_editor): - setting_cls = apps.get_model('settings', 'Setting') - setting = setting_cls.objects.filter(name='TERMINAL_TELNET_REGEX').first() - if not setting: - print("Not found telnet regex setting, skip") - return - try: - value = json.loads(setting.value) - except Exception: - print("Invalid telnet regex setting, skip") - return - platform_protocol_cls = apps.get_model('assets', 'PlatformProtocol') - telnets = platform_protocol_cls.objects.filter(name='telnet') - if telnets.count() > 0: - telnets.update(setting={'success_prompt': value}) - print("Migrate telnet regex setting success: ", telnets.count()) - - -class Migration(migrations.Migration): - - dependencies = [ - ('assets', '0122_auto_20230801_1940'), - ] - - operations = [ - migrations.RunPython(migrate_telnet_regex) - ] From 8cfec07faa4a952f646278afe07e16392f4bdc0c Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Thu, 3 Aug 2023 11:21:30 +0800 Subject: [PATCH 090/177] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=20=E5=9C=A8AW?= =?UTF-8?q?S=E5=85=AC=E6=9C=89=E4=BA=91=E7=8E=AF=E5=A2=83=E4=B8=AD?= =?UTF-8?q?=EF=BC=8Crds=E7=AD=89=E8=B5=84=E4=BA=A7=E7=9A=84=E5=9F=9F?= =?UTF-8?q?=E5=90=8D=E8=A7=A3=E6=9E=90=E9=95=BF=E5=BA=A6=E8=B6=85=E8=BF=87?= =?UTF-8?q?JumpServer=E8=B5=84=E4=BA=A7=E9=99=90=E5=88=B6=E7=9A=84128?= =?UTF-8?q?=E5=AD=97=E8=8A=82=E5=AF=BC=E8=87=B4=E8=BF=9E=E6=8E=A5=E5=A4=B1?= =?UTF-8?q?=E8=B4=A5=E9=97=AE=E9=A2=98=20(#11188)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: feng <1304903146@qq.com> --- apps/terminal/serializers/session.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/apps/terminal/serializers/session.py b/apps/terminal/serializers/session.py index 16c224950..6e5476c3e 100644 --- a/apps/terminal/serializers/session.py +++ b/apps/terminal/serializers/session.py @@ -2,6 +2,7 @@ from django.utils.translation import gettext_lazy as _ from rest_framework import serializers from common.serializers.fields import LabeledChoiceField +from common.utils import pretty_string from orgs.mixins.serializers import BulkOrgResourceModelSerializer from .terminal import TerminalSmallSerializer from ..const import SessionType @@ -22,6 +23,7 @@ class SessionSerializer(BulkOrgResourceModelSerializer): can_replay = serializers.BooleanField(read_only=True, label=_("Can replay")) can_join = serializers.BooleanField(read_only=True, label=_("Can join")) can_terminate = serializers.BooleanField(read_only=True, label=_("Can terminate")) + asset = serializers.CharField(label=_("Asset"), style={'base_template': 'textarea.html'}) class Meta: model = Session @@ -50,6 +52,11 @@ class SessionSerializer(BulkOrgResourceModelSerializer): 'terminal_display': {'label': _('Terminal display')}, } + def validate_asset(self, value): + max_length = self.Meta.model.asset.field.max_length + value = pretty_string(value, max_length=max_length) + return value + class SessionDisplaySerializer(SessionSerializer): command_amount = serializers.IntegerField(read_only=True, label=_('Command amount')) From ff2aace569efb0f6a4334fc6830907254cb8aba9 Mon Sep 17 00:00:00 2001 From: jiangweidong Date: Thu, 3 Aug 2023 14:09:13 +0800 Subject: [PATCH 091/177] =?UTF-8?q?feat:=20ssh=5Fping=E5=8F=8Acustom=5Fcom?= =?UTF-8?q?mand=E6=94=AF=E6=8C=81sudo=E5=8F=8Asu=E5=88=87=E6=8D=A2?= =?UTF-8?q?=E7=94=A8=E6=88=B7=20(#11180)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../change_secret/custom/ssh/main.yml | 18 +++- .../verify_account/custom/ssh/main.yml | 6 ++ .../automations/ping/custom/ssh/main.yml | 6 ++ apps/ops/ansible/inventory.py | 11 +++ apps/ops/ansible/modules/custom_command.py | 9 +- .../ansible/modules_utils/custom_common.py | 99 +++++++++++++++---- 6 files changed, 119 insertions(+), 30 deletions(-) diff --git a/apps/accounts/automations/change_secret/custom/ssh/main.yml b/apps/accounts/automations/change_secret/custom/ssh/main.yml index 853a666d4..b35d2175a 100644 --- a/apps/accounts/automations/change_secret/custom/ssh/main.yml +++ b/apps/accounts/automations/change_secret/custom/ssh/main.yml @@ -2,9 +2,10 @@ gather_facts: no vars: ansible_connection: local + ansible_become: false tasks: - - name: Test privileged account + - name: Test privileged account (paramiko) ssh_ping: login_host: "{{ jms_asset.address }}" login_port: "{{ jms_asset.port }}" @@ -12,9 +13,14 @@ login_password: "{{ jms_account.secret }}" login_secret_type: "{{ jms_account.secret_type }}" login_private_key_path: "{{ jms_account.private_key_path }}" + become: "{{ custom_become | default(False) }}" + become_method: "{{ custom_become_method | default('su') }}" + become_user: "{{ custom_become_user | default('') }}" + become_password: "{{ custom_become_password | default('') }}" + become_private_key_path: "{{ custom_become_private_key_path | default(None) }}" register: ping_info - - name: Change asset password + - name: Change asset password (paramiko) custom_command: login_user: "{{ jms_account.username }}" login_password: "{{ jms_account.secret }}" @@ -22,6 +28,11 @@ login_port: "{{ jms_asset.port }}" login_secret_type: "{{ jms_account.secret_type }}" login_private_key_path: "{{ jms_account.private_key_path }}" + become: "{{ custom_become | default(False) }}" + become_method: "{{ custom_become_method | default('su') }}" + become_user: "{{ custom_become_user | default('') }}" + become_password: "{{ custom_become_password | default('') }}" + become_private_key_path: "{{ custom_become_private_key_path | default(None) }}" name: "{{ account.username }}" password: "{{ account.secret }}" commands: "{{ params.commands }}" @@ -30,9 +41,10 @@ when: ping_info is succeeded register: change_info - - name: Verify password + - name: Verify password (paramiko) ssh_ping: login_user: "{{ account.username }}" login_password: "{{ account.secret }}" login_host: "{{ jms_asset.address }}" login_port: "{{ jms_asset.port }}" + become: false diff --git a/apps/accounts/automations/verify_account/custom/ssh/main.yml b/apps/accounts/automations/verify_account/custom/ssh/main.yml index 29b1dc22b..4e35b9587 100644 --- a/apps/accounts/automations/verify_account/custom/ssh/main.yml +++ b/apps/accounts/automations/verify_account/custom/ssh/main.yml @@ -2,6 +2,7 @@ gather_facts: no vars: ansible_connection: local + ansible_become: false tasks: - name: Verify account (paramiko) @@ -12,3 +13,8 @@ login_password: "{{ account.secret }}" login_secret_type: "{{ account.secret_type }}" login_private_key_path: "{{ account.private_key_path }}" + become: "{{ custom_become | default(False) }}" + become_method: "{{ custom_become_method | default('su') }}" + become_user: "{{ custom_become_user | default('') }}" + become_password: "{{ custom_become_password | default('') }}" + become_private_key_path: "{{ custom_become_private_key_path | default(None) }}" diff --git a/apps/assets/automations/ping/custom/ssh/main.yml b/apps/assets/automations/ping/custom/ssh/main.yml index 9725f63d7..7820df8e7 100644 --- a/apps/assets/automations/ping/custom/ssh/main.yml +++ b/apps/assets/automations/ping/custom/ssh/main.yml @@ -2,6 +2,7 @@ gather_facts: no vars: ansible_connection: local + ansible_become: false tasks: - name: Test asset connection (paramiko) @@ -12,3 +13,8 @@ login_port: "{{ jms_asset.port }}" login_secret_type: "{{ jms_account.secret_type }}" login_private_key_path: "{{ jms_account.private_key_path }}" + become: "{{ custom_become | default(False) }}" + become_method: "{{ custom_become_method | default('su') }}" + become_user: "{{ custom_become_user | default('') }}" + become_password: "{{ custom_become_password | default('') }}" + become_private_key_path: "{{ custom_become_private_key_path | default(None) }}" diff --git a/apps/ops/ansible/inventory.py b/apps/ops/ansible/inventory.py index 653c5f40d..3f3dc19b0 100644 --- a/apps/ops/ansible/inventory.py +++ b/apps/ops/ansible/inventory.py @@ -76,6 +76,16 @@ class JMSInventory: var['ansible_ssh_private_key_file'] = account.private_key_path return var + @staticmethod + def make_custom_become_ansible_vars(account, platform): + var = { + 'custom_become': True, 'custom_become_method': platform.su_method, + 'custom_become_user': account.su_from.username, + 'custom_become_password': account.su_from.secret, + 'custom_become_private_key_path': account.su_from.private_key_path + } + return var + def make_account_vars(self, host, asset, account, automation, protocol, platform, gateway): from accounts.const import AutomationTypes if not account: @@ -89,6 +99,7 @@ class JMSInventory: su_from = account.su_from if platform.su_enabled and su_from: host.update(self.make_account_ansible_vars(su_from)) + host.update(self.make_custom_become_ansible_vars(account, platform)) become_method = 'sudo' if platform.su_method != 'su' else 'su' host['ansible_become'] = True host['ansible_become_method'] = 'sudo' diff --git a/apps/ops/ansible/modules/custom_command.py b/apps/ops/ansible/modules/custom_command.py index e4f7cf11d..947da2d31 100644 --- a/apps/ops/ansible/modules/custom_command.py +++ b/apps/ops/ansible/modules/custom_command.py @@ -90,9 +90,6 @@ def main(): name=dict(required=True, aliases=['user']), password=dict(aliases=['pass'], no_log=True), commands=dict(type='list', required=False), - first_conn_delay_time=dict( - type='float', required=False, default=0.5 - ), ) module = AnsibleModule(argument_spec=argument_spec) @@ -102,10 +99,10 @@ def main(): module.fail_json( msg='No command found, please go to the platform details to add' ) - err = ssh_client.execute(commands) - if err: + output, err_msg = ssh_client.execute(commands) + if err_msg: module.fail_json( - msg='There was a problem executing the command: %s' % err + msg='There was a problem executing the command: %s' % err_msg ) user = module.params['name'] diff --git a/apps/ops/ansible/modules_utils/custom_common.py b/apps/ops/ansible/modules_utils/custom_common.py index 5da1a725e..01546ff33 100644 --- a/apps/ops/ansible/modules_utils/custom_common.py +++ b/apps/ops/ansible/modules_utils/custom_common.py @@ -1,7 +1,6 @@ import time import paramiko -from paramiko.ssh_exception import SSHException, NoValidConnectionsError def common_argument_spec(): @@ -12,6 +11,13 @@ def common_argument_spec(): login_password=dict(type='str', required=False, no_log=True), login_secret_type=dict(type='str', required=False, default='password'), login_private_key_path=dict(type='str', required=False, no_log=True), + first_conn_delay_time=dict(type='float', required=False, default=0.5), + + become=dict(type='bool', default=False, required=False), + become_method=dict(type='str', required=False), + become_user=dict(type='str', required=False), + become_password=dict(type='str', required=False, no_log=True), + become_private_key_path=dict(type='str', required=False, no_log=True), ) return options @@ -19,6 +25,7 @@ def common_argument_spec(): class SSHClient: def __init__(self, module): self.module = module + self.channel = None self.is_connect = False self.client = paramiko.SSHClient() self.client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) @@ -28,40 +35,90 @@ class SSHClient: 'allow_agent': False, 'look_for_keys': False, 'hostname': self.module.params['login_host'], 'port': self.module.params['login_port'], - 'username': self.module.params['login_user'], + 'key_filename': self.module.params['login_private_key_path'] or None } - secret_type = self.module.params['login_secret_type'] - if secret_type == 'ssh_key': - params['key_filename'] = self.module.params['login_private_key_path'] + if self.module.params['become']: + params['username'] = self.module.params['become_user'] + params['password'] = self.module.params['become_password'] + params['key_filename'] = self.module.params['become_private_key_path'] or None else: + params['username'] = self.module.params['login_user'] params['password'] = self.module.params['login_password'] + params['key_filename'] = self.module.params['login_private_key_path'] or None return params + def _get_channel(self): + self.channel = self.client.invoke_shell() + # 读取首次登陆终端返回的消息 + self.channel.recv(2048) + # 网络设备一般登录有延迟,等终端有返回后再执行命令 + delay_time = self.module.params['first_conn_delay_time'] + time.sleep(delay_time) + + @staticmethod + def _is_match_user(user, content): + # 正常命令切割后是[命令,用户名,交互前缀] + remote_user = content.split()[1] if len(content.split()) >= 3 else None + return remote_user and remote_user == user + + def switch_user(self): + self._get_channel() + if not self.module.params['become']: + return None + method = self.module.params['become_method'] + username = self.module.params['login_user'] + if method == 'sudo': + switch_method = 'sudo su -' + password = self.module.params['become_password'] + elif method == 'su': + switch_method = 'su -' + password = self.module.params['login_password'] + else: + self.module.fail_json(msg='Become method %s not support' % method) + return + commands = [f'{switch_method} {username}', password] + su_output, err_msg = self.execute(commands) + if err_msg: + return err_msg + i_output, err_msg = self.execute(['whoami']) + if err_msg: + return err_msg + + if self._is_match_user(username, i_output): + err_msg = '' + else: + err_msg = su_output + return err_msg + def connect(self): try: self.client.connect(**self.get_connect_params()) - except (SSHException, NoValidConnectionsError) as err: - err_msg = str(err) - else: self.is_connect = True - err_msg = '' + err_msg = self.switch_user() + except Exception as err: + err_msg = str(err) return err_msg + def _get_recv(self, size=1024, encoding='utf-8'): + output = self.channel.recv(size).decode(encoding) + return output + def execute(self, commands): if not self.is_connect: self.connect() - - channel = self.client.invoke_shell() - # 读取首次登陆终端返回的消息 - channel.recv(2048) - # 网络设备一般登录有延迟,等终端有返回后再执行命令 - delay_time = self.module.params['first_conn_delay_time'] - time.sleep(delay_time) - err_msg = '' + output, error_msg = '', '' try: for command in commands: - channel.send(command + '\n') + self.channel.send(command + '\n') time.sleep(0.3) - except SSHException as e: - err_msg = str(e) - return err_msg + output = self._get_recv() + except Exception as e: + error_msg = str(e) + return output, error_msg + + def __del__(self): + try: + self.channel.close() + self.client.close() + except: + pass From 65916a469c1184d238955811c917de99595854ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=90=B4=E5=B0=8F=E7=99=BD?= <296015668@qq.com> Date: Thu, 3 Aug 2023 14:33:22 +0800 Subject: [PATCH 092/177] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=E6=9E=84?= =?UTF-8?q?=E5=BB=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 108 +++++--- Dockerfile-ee | 4 +- poetry.lock | 388 ++++++---------------------- pyproject.toml | 24 +- requirements/requirements.txt | 1 - requirements/requirements_xpack.txt | 4 +- 6 files changed, 176 insertions(+), 353 deletions(-) diff --git a/Dockerfile b/Dockerfile index 4df68fa31..bc233dfd0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,17 +1,6 @@ -FROM python:3.11.4-slim-bullseye as stage-build +FROM jumpserver/python:3.11-slim-buster as stage-build ARG TARGETARCH -ARG VERSION -ENV VERSION=$VERSION - -WORKDIR /opt/jumpserver -ADD . . -RUN cd utils && bash -ixeu build.sh - -FROM python:3.11.4-slim-bullseye -ARG TARGETARCH -MAINTAINER JumpServer Team - ARG BUILD_DEPENDENCIES=" \ g++ \ make \ @@ -22,6 +11,7 @@ ARG DEPENDENCIES=" \ libpq-dev \ libffi-dev \ libjpeg-dev \ + libkrb5-dev \ libldap2-dev \ libsasl2-dev \ libssl-dev \ @@ -36,15 +26,10 @@ ARG TOOLS=" \ curl \ default-libmysqlclient-dev \ default-mysql-client \ - locales \ - openssh-client \ - procps \ - sshpass \ - telnet \ - unzip \ - vim \ git \ - nmap \ + git-lfs \ + unzip \ + xz-utils \ wget" ARG APT_MIRROR=http://mirrors.ustc.edu.cn @@ -57,6 +42,73 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked,id=core \ && apt-get -y install --no-install-recommends ${BUILD_DEPENDENCIES} \ && apt-get -y install --no-install-recommends ${DEPENDENCIES} \ && apt-get -y install --no-install-recommends ${TOOLS} \ + && echo "no" | dpkg-reconfigure dash \ + && rm -rf /var/lib/apt/lists/* + +RUN set -ex \ + && cd /opt \ + && \ + if [ "${TARGETARCH}" == "loong64" ]; then \ + mkdir -p /opt/rust-install; \ + wget -O /opt/rust.tar.gz https://rust-lang.loongnix.cn/dist/2022-11-03/rust-1.65.0-loongarch64-unknown-linux-gnu.tar.xz; \ + tar -xf /opt/rust.tar.gz -C /opt/rust-install --strip-components=1; \ + cd /opt/rust-install && ./install.sh; \ + rm -rf /opt/rust.tar.gz /opt/rust-install; \ + fi + +ARG VERSION +ENV VERSION=$VERSION + +WORKDIR /opt/jumpserver +ADD . . +RUN cd utils && bash -ixeu build.sh + +ARG PIP_MIRROR=https://pypi.tuna.tsinghua.edu.cn/simple +RUN --mount=type=cache,target=/root/.cache \ + set -ex \ + && \ + if [ "${TARGETARCH}" == "loong64" ]; then \ + pip install https://download.jumpserver.org/pypi/simple/rpds_py/rpds_py-0.9.2-cp311-cp311-linux_loongarch64.whl; \ + pip install https://download.jumpserver.org/pypi/simple/cryptography/cryptography-41.0.2-cp311-cp311-linux_loongarch64.whl; \ + fi \ + && pip install poetry -i ${PIP_MIRROR} + +RUN --mount=type=cache,target=/root/.cache \ + --mount=type=cache,target=/root/.cargo \ + set -ex \ + && poetry config virtualenvs.create false \ + && poetry install + +FROM jumpserver/python:3.11-slim-buster +ARG TARGETARCH + +ARG DEPENDENCIES=" \ + libxmlsec1-openssl" + +ARG TOOLS=" \ + ca-certificates \ + curl \ + default-libmysqlclient-dev \ + default-mysql-client \ + inetutils-ping \ + locales \ + openssh-client \ + procps \ + sshpass \ + telnet \ + unzip \ + vim \ + wget" + +ARG APT_MIRROR=http://mirrors.ustc.edu.cn + +RUN --mount=type=cache,target=/var/cache/apt,sharing=locked,id=core \ + sed -i "s@http://.*.debian.org@${APT_MIRROR}@g" /etc/apt/sources.list \ + && rm -f /etc/apt/apt.conf.d/docker-clean \ + && ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \ + && apt-get update \ + && apt-get -y install --no-install-recommends ${DEPENDENCIES} \ + && apt-get -y install --no-install-recommends ${TOOLS} \ && mkdir -p /root/.ssh/ \ && echo "Host *\n\tStrictHostKeyChecking no\n\tUserKnownHostsFile /dev/null\n\tCiphers +aes128-cbc\n\tKexAlgorithms +diffie-hellman-group1-sha1\n\tHostKeyAlgorithms +ssh-rsa" > /root/.ssh/config \ && echo "set mouse-=a" > ~/.vimrc \ @@ -80,23 +132,17 @@ RUN set -ex \ rm -f instantclient-basiclite-linux.${TARGETARCH}-19.10.0.0.0.zip; \ fi -WORKDIR /tmp/build -COPY ./pyproject.toml ./pyproject.toml -COPY ./poetry.lock ./poetry.lock +COPY --from=stage-build /opt/jumpserver/release/jumpserver /opt/jumpserver +WORKDIR /opt/jumpserver ARG PIP_MIRROR=https://pypi.douban.com/simple - -RUN --mount=type=cache,target=/root/.cache/poetry \ +RUN --mount=type=cache,target=/root/.cache \ set -ex \ - && pip install poetry==1.5.1 -i ${PIP_MIRROR} \ + && echo > /opt/jumpserver/config.yml \ + && pip install poetry -i ${PIP_MIRROR} \ && poetry config virtualenvs.create false \ && poetry install --only=main -COPY --from=stage-build /opt/jumpserver/release/jumpserver /opt/jumpserver -RUN echo > /opt/jumpserver/config.yml \ - && rm -rf /tmp/build - -WORKDIR /opt/jumpserver VOLUME /opt/jumpserver/data VOLUME /opt/jumpserver/logs diff --git a/Dockerfile-ee b/Dockerfile-ee index 946615d34..9594e1579 100644 --- a/Dockerfile-ee +++ b/Dockerfile-ee @@ -1,10 +1,12 @@ ARG VERSION FROM registry.fit2cloud.com/jumpserver/xpack:${VERSION} as build-xpack FROM jumpserver/core:${VERSION} +ARG TARGETARCH + COPY --from=build-xpack /opt/xpack /opt/jumpserver/apps/xpack WORKDIR /opt/jumpserver -RUN --mount=type=cache,target=/root/.cache/pip \ +RUN --mount=type=cache,target=/root/.cache \ set -ex \ && poetry install --only=xpack diff --git a/poetry.lock b/poetry.lock index 30075ac44..db5ea8851 100644 --- a/poetry.lock +++ b/poetry.lock @@ -463,9 +463,7 @@ version = "2.14.1" description = "Radically simple IT automation" optional = false python-versions = ">=3.9" -files = [ - {file = "ansible-2.14.1.2.zip", hash = "sha256:813b39d8e03d5ea23b47703b3ba4d0372f68141b33e2b1be28deb6ad28b31c73"}, -] +files = [] [package.dependencies] cryptography = "*" @@ -501,31 +499,6 @@ type = "legacy" url = "https://pypi.tuna.tsinghua.edu.cn/simple" reference = "tsinghua" -[[package]] -name = "anyio" -version = "3.7.1" -description = "High level compatibility layer for multiple asynchronous event loop implementations" -optional = false -python-versions = ">=3.7" -files = [ - {file = "anyio-3.7.1-py3-none-any.whl", hash = "sha256:91dee416e570e92c64041bd18b900d1d6fa78dff7048769ce5ac5ddad004fbb5"}, - {file = "anyio-3.7.1.tar.gz", hash = "sha256:44a3c9aba0f5defa43261a8b3efb97891f2bd7d804e0e1f56419befa1adfc780"}, -] - -[package.dependencies] -idna = ">=2.8" -sniffio = ">=1.1" - -[package.extras] -doc = ["Sphinx", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme (>=1.2.2)", "sphinxcontrib-jquery"] -test = ["anyio[trio]", "coverage[toml] (>=4.5)", "hypothesis (>=4.0)", "mock (>=4)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"] -trio = ["trio (<0.22)"] - -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" - [[package]] name = "appnope" version = "0.1.3" @@ -1848,9 +1821,7 @@ version = "4.3.0" description = "" optional = false python-versions = ">=3.7" -files = [ - {file = "django-cas-ng-4.3.1.zip", hash = "sha256:aeea96ad7958e3cb40d9bb5ef6a1add66f720835dfe87cc1dfe163f92d084690"}, -] +files = [] [package.dependencies] Django = ">=2.2" @@ -1982,9 +1953,7 @@ version = "1.4.0" description = "Django authentication backend for RADIUS" optional = false python-versions = "*" -files = [ - {file = "1.5.0.zip", hash = "sha256:b50680dd1c577a099f90d510856b3e55aa496d8c876beabb5b0a79fc94fcfae9"}, -] +files = [] [package.dependencies] pyrad = ">=1.2,<2.2 || >2.2" @@ -2850,6 +2819,24 @@ type = "legacy" url = "https://pypi.tuna.tsinghua.edu.cn/simple" reference = "tsinghua" +[[package]] +name = "greenlet" +version = "2.0.2" +description = "Lightweight in-process concurrent programming" +optional = false +python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*" +files = [ + {file = "greenlet-2.0.2-cp311-cp311-linux_loongarch64.whl", hash = "sha256:65f6e0520d2cad7b0d5c7486e050ffe4d1e3a83b6a9f214e9bb51b56fb3ba163"}, +] + +[package.extras] +docs = ["Sphinx", "docutils (<0.18)"] +test = ["objgraph", "psutil"] + +[package.source] +type = "url" +url = "https://download.jumpserver.org/pypi/simple/greenlet/greenlet-2.0.2-cp311-cp311-linux_loongarch64.whl" + [[package]] name = "grpcio" version = "1.56.2" @@ -2912,6 +2899,23 @@ type = "legacy" url = "https://pypi.tuna.tsinghua.edu.cn/simple" reference = "tsinghua" +[[package]] +name = "grpcio" +version = "1.56.2" +description = "HTTP/2-based RPC framework" +optional = false +python-versions = ">=3.7" +files = [ + {file = "grpcio-1.56.2-cp311-cp311-linux_loongarch64.whl", hash = "sha256:c1625d6e03b33927cedbd79d13d6caa07173b67245f04373b814b3ae7dc050a7"}, +] + +[package.extras] +protobuf = ["grpcio-tools (>=1.56.2)"] + +[package.source] +type = "url" +url = "https://download.jumpserver.org/pypi/simple/grpcio/grpcio-1.56.2-cp311-cp311-linux_loongarch64.whl" + [[package]] name = "grpcio-status" version = "1.56.2" @@ -3010,58 +3014,6 @@ type = "legacy" url = "https://pypi.tuna.tsinghua.edu.cn/simple" reference = "tsinghua" -[[package]] -name = "httptools" -version = "0.6.0" -description = "A collection of framework independent HTTP protocol utils." -optional = false -python-versions = ">=3.5.0" -files = [ - {file = "httptools-0.6.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:818325afee467d483bfab1647a72054246d29f9053fd17cc4b86cda09cc60339"}, - {file = "httptools-0.6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72205730bf1be875003692ca54a4a7c35fac77b4746008966061d9d41a61b0f5"}, - {file = "httptools-0.6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:33eb1d4e609c835966e969a31b1dedf5ba16b38cab356c2ce4f3e33ffa94cad3"}, - {file = "httptools-0.6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6bdc6675ec6cb79d27e0575750ac6e2b47032742e24eed011b8db73f2da9ed40"}, - {file = "httptools-0.6.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:463c3bc5ef64b9cf091be9ac0e0556199503f6e80456b790a917774a616aff6e"}, - {file = "httptools-0.6.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:82f228b88b0e8c6099a9c4757ce9fdbb8b45548074f8d0b1f0fc071e35655d1c"}, - {file = "httptools-0.6.0-cp310-cp310-win_amd64.whl", hash = "sha256:0781fedc610293a2716bc7fa142d4c85e6776bc59d617a807ff91246a95dea35"}, - {file = "httptools-0.6.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:721e503245d591527cddd0f6fd771d156c509e831caa7a57929b55ac91ee2b51"}, - {file = "httptools-0.6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:274bf20eeb41b0956e34f6a81f84d26ed57c84dd9253f13dcb7174b27ccd8aaf"}, - {file = "httptools-0.6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:259920bbae18740a40236807915def554132ad70af5067e562f4660b62c59b90"}, - {file = "httptools-0.6.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03bfd2ae8a2d532952ac54445a2fb2504c804135ed28b53fefaf03d3a93eb1fd"}, - {file = "httptools-0.6.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:f959e4770b3fc8ee4dbc3578fd910fab9003e093f20ac8c621452c4d62e517cb"}, - {file = "httptools-0.6.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:6e22896b42b95b3237eccc42278cd72c0df6f23247d886b7ded3163452481e38"}, - {file = "httptools-0.6.0-cp311-cp311-win_amd64.whl", hash = "sha256:38f3cafedd6aa20ae05f81f2e616ea6f92116c8a0f8dcb79dc798df3356836e2"}, - {file = "httptools-0.6.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:47043a6e0ea753f006a9d0dd076a8f8c99bc0ecae86a0888448eb3076c43d717"}, - {file = "httptools-0.6.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:35a541579bed0270d1ac10245a3e71e5beeb1903b5fbbc8d8b4d4e728d48ff1d"}, - {file = "httptools-0.6.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65d802e7b2538a9756df5acc062300c160907b02e15ed15ba035b02bce43e89c"}, - {file = "httptools-0.6.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:26326e0a8fe56829f3af483200d914a7cd16d8d398d14e36888b56de30bec81a"}, - {file = "httptools-0.6.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:e41ccac9e77cd045f3e4ee0fc62cbf3d54d7d4b375431eb855561f26ee7a9ec4"}, - {file = "httptools-0.6.0-cp37-cp37m-win_amd64.whl", hash = "sha256:4e748fc0d5c4a629988ef50ac1aef99dfb5e8996583a73a717fc2cac4ab89932"}, - {file = "httptools-0.6.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:cf8169e839a0d740f3d3c9c4fa630ac1a5aaf81641a34575ca6773ed7ce041a1"}, - {file = "httptools-0.6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:5dcc14c090ab57b35908d4a4585ec5c0715439df07be2913405991dbb37e049d"}, - {file = "httptools-0.6.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d0b0571806a5168013b8c3d180d9f9d6997365a4212cb18ea20df18b938aa0b"}, - {file = "httptools-0.6.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0fb4a608c631f7dcbdf986f40af7a030521a10ba6bc3d36b28c1dc9e9035a3c0"}, - {file = "httptools-0.6.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:93f89975465133619aea8b1952bc6fa0e6bad22a447c6d982fc338fbb4c89649"}, - {file = "httptools-0.6.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:73e9d66a5a28b2d5d9fbd9e197a31edd02be310186db423b28e6052472dc8201"}, - {file = "httptools-0.6.0-cp38-cp38-win_amd64.whl", hash = "sha256:22c01fcd53648162730a71c42842f73b50f989daae36534c818b3f5050b54589"}, - {file = "httptools-0.6.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:3f96d2a351b5625a9fd9133c95744e8ca06f7a4f8f0b8231e4bbaae2c485046a"}, - {file = "httptools-0.6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:72ec7c70bd9f95ef1083d14a755f321d181f046ca685b6358676737a5fecd26a"}, - {file = "httptools-0.6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b703d15dbe082cc23266bf5d9448e764c7cb3fcfe7cb358d79d3fd8248673ef9"}, - {file = "httptools-0.6.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:82c723ed5982f8ead00f8e7605c53e55ffe47c47465d878305ebe0082b6a1755"}, - {file = "httptools-0.6.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b0a816bb425c116a160fbc6f34cece097fd22ece15059d68932af686520966bd"}, - {file = "httptools-0.6.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:dea66d94e5a3f68c5e9d86e0894653b87d952e624845e0b0e3ad1c733c6cc75d"}, - {file = "httptools-0.6.0-cp39-cp39-win_amd64.whl", hash = "sha256:23b09537086a5a611fad5696fc8963d67c7e7f98cb329d38ee114d588b0b74cd"}, - {file = "httptools-0.6.0.tar.gz", hash = "sha256:9fc6e409ad38cbd68b177cd5158fc4042c796b82ca88d99ec78f07bed6c6b796"}, -] - -[package.extras] -test = ["Cython (>=0.29.24,<0.30.0)"] - -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" - [[package]] name = "humanize" version = "4.7.0" @@ -4201,48 +4153,21 @@ reference = "tsinghua" [[package]] name = "oracledb" -version = "1.3.2" +version = "1.4.0b1" description = "Python interface to Oracle Database" optional = false python-versions = ">=3.6" -files = [ - {file = "oracledb-1.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:bee717f90118a95f0c661d27e7a65255eb5e400b95cbe4019b75014b3691ef90"}, - {file = "oracledb-1.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:000c5a31ecc5569e6dec4dcaf4552509d88a19051e57deb0af96296f9937dc6a"}, - {file = "oracledb-1.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c37c249c4323b61c3e333c2cf724e19e6416d35130acf0f684eefad17a73b040"}, - {file = "oracledb-1.3.2-cp310-cp310-win32.whl", hash = "sha256:2680f460708904a2d2e4f853990bce10a963905205acf0e709c32cad353a5d2f"}, - {file = "oracledb-1.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:0fdfa5e119270332eab1ee5900a503423e87d1b8ae6da17c426dd34822217213"}, - {file = "oracledb-1.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:de0ada0cbea8b1524f0798cedc38dabc9a8bfcb67f738b914e7a8eb873cc854a"}, - {file = "oracledb-1.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:138904100c5218c33005ec5b07688ce68f40ea20c28b3b840738401ae2a862a1"}, - {file = "oracledb-1.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:839f7a4d8d34130dd99a44c064bc9eea130a0d2406f723398ebb0b29b6d3a8cf"}, - {file = "oracledb-1.3.2-cp311-cp311-win32.whl", hash = "sha256:8e37e2b41900a113894049f3c9d7b64e93f613ed52104f2f05ef3284e2e1bb8f"}, - {file = "oracledb-1.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:cedd48e7d107884d4a19c9ad449b3c3cb3b3e4d67a6eddacb966b1370cc1f35e"}, - {file = "oracledb-1.3.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3a285f35edf435a7f60f54074d9925deb63146b4cc0f6998eba75a282c8ce497"}, - {file = "oracledb-1.3.2-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e86e5203767e1216ceeda6b7c087b804fa2f44041680d5099900c3cf5724915"}, - {file = "oracledb-1.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:043d7d5fdda0ea43734cd4cf67771efddc9307eef10cc83afc19599d39a23d72"}, - {file = "oracledb-1.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:08cff689d8117c817458a633859a35c21fc44f39bf56c9c8f62ec02789d0e1e0"}, - {file = "oracledb-1.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2279f8550d80ed30315ef84e88b8ec5b533064e8a81ef96265647019ccee8e85"}, - {file = "oracledb-1.3.2-cp37-cp37m-win32.whl", hash = "sha256:af8d8635453961556b84e37a1dd40c94e18d1b5d3b54020fafce0f3e67472b90"}, - {file = "oracledb-1.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:6e8710cdb14c4510f65c11c02f1d97c079d20e0692a431a1af0e964064b7e32c"}, - {file = "oracledb-1.3.2-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:9808e4169e3f330f2ea6dd15376432886d7ed84344f447048d9305a520f31a7a"}, - {file = "oracledb-1.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e0b760c58f73a262af01e093fc9b183de59516b618319fb53b281eedde1dccbc"}, - {file = "oracledb-1.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ea5a26481c798978210505a1252eec6814cf28005e18a80f935cbcf5b74dabb"}, - {file = "oracledb-1.3.2-cp38-cp38-win32.whl", hash = "sha256:790798eb1e9b96639c02e91f3b3f00934d722d9de0ac375adcda37b83bba61a6"}, - {file = "oracledb-1.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:796b900fe85af572ff3d7227372ca3a2edd5f756e538e95ffbfc689df3881696"}, - {file = "oracledb-1.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5f669d7fa78a865d10ad9840a2cb6958b395c572c119ff51489a4a738302727e"}, - {file = "oracledb-1.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d5e20ed24335c59f42003750be3063f3d75f371af35eff47cc9177e9a4193af2"}, - {file = "oracledb-1.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eb49ebd84d65080703ea8a2b2edde3ac27a6fdc9c491db2dbde0b960f40e3c10"}, - {file = "oracledb-1.3.2-cp39-cp39-win32.whl", hash = "sha256:022a6631ac779f0d600870fea1f7600a03eabcb4609138e91ac77b8126a9373b"}, - {file = "oracledb-1.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:4fdeb8b2158d5fb93451d57152f9cfb25f0d876dcbb90305133267196c9efd84"}, - {file = "oracledb-1.3.2.tar.gz", hash = "sha256:bb3c391c167b5778ddb15a7538a2b36db5c9b88a50c86c61781ca9ff302bb643"}, -] +files = [] +develop = false [package.dependencies] cryptography = ">=3.2.1" [package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" +type = "git" +url = "https://github.com/oracle/python-oracledb.git" +reference = "main" +resolved_reference = "9f1019a10813d98fe667283e04d6b64d05438867" [[package]] name = "os-service-types" @@ -5367,72 +5292,39 @@ reference = "tsinghua" [[package]] name = "pymssql" -version = "2.2.7" +version = "2.2.8" description = "DB-API interface to Microsoft SQL Server for Python. (new Cython-based version)" optional = false python-versions = "*" files = [ - {file = "pymssql-2.2.7-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:9a883def0ded86dc93cdb45dcbe924f79bd141e6bc39975d6077f88e156f3741"}, - {file = "pymssql-2.2.7-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:83ee4914bacecc715fcdb3cc22aedc8d9bf22f62e75802799fe9773b718fd41b"}, - {file = "pymssql-2.2.7-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2a8b1b903527f0f8c287582bfe01b28180f173583b8501914c1134659ead3c1d"}, - {file = "pymssql-2.2.7-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4aa12c836c307c80c1148eb190362bbbe178abc311e6715316b9950327af7a14"}, - {file = "pymssql-2.2.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70260e05717cd6d72a622ee29d06375fa44d58fe825d4964a63344ae34d80223"}, - {file = "pymssql-2.2.7-cp310-cp310-manylinux_2_24_i686.whl", hash = "sha256:c42a03cab7edd2bf6c4e075a9f1f7252151a4022216d7c85af4e4e4751f3bb14"}, - {file = "pymssql-2.2.7-cp310-cp310-manylinux_2_24_x86_64.whl", hash = "sha256:9bfb8f04b26d398f2fb7741733a33c7cfe418bbbf922703e5c4c409e86891785"}, - {file = "pymssql-2.2.7-cp310-cp310-win32.whl", hash = "sha256:0dbb905655f5976b94b6f899d4675ffdd460e7cb5516fba332cf0d77c15c2e9e"}, - {file = "pymssql-2.2.7-cp310-cp310-win_amd64.whl", hash = "sha256:2ce4f9fd604b9c7f9efad56afb3dcb2331c3c87bada172388f69d91297f20939"}, - {file = "pymssql-2.2.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8fe96bcbb26e7603ef63696f59fa19364c793aab25f2b606dc04d50917c7b35f"}, - {file = "pymssql-2.2.7-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:628611bc8cab379f8353ad29b93a07162254c9b75efb5fe5255ac855a8d3abe4"}, - {file = "pymssql-2.2.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:045029bed7cea6fcbc630e18f956f7ec6d1bde25c570019ff1f8f0e2b9abd5f0"}, - {file = "pymssql-2.2.7-cp311-cp311-manylinux_2_24_i686.whl", hash = "sha256:ad3c2e67fd04fb860ffb3affd068e109ef92488a74274347235df45664de4a27"}, - {file = "pymssql-2.2.7-cp311-cp311-manylinux_2_24_x86_64.whl", hash = "sha256:7099e45e91460ffec10e551830c722c27f207a41fd2267446a9b1a798e89d3bc"}, - {file = "pymssql-2.2.7-cp311-cp311-win32.whl", hash = "sha256:4dbe67d60472e18d01bcfba139f404f017ab9e9bd1b558d527befbb47dbd6486"}, - {file = "pymssql-2.2.7-cp311-cp311-win_amd64.whl", hash = "sha256:a9a40bf77792532fe643ee07ae0de930f6386c8593348baef07d76d1b2f48967"}, - {file = "pymssql-2.2.7-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:e6116a0389939bba789fb3fccdd976773cfce7d9cc48bf2eb933cdc2c8ce2b19"}, - {file = "pymssql-2.2.7-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:2b0415e6063b06234921d2d7d2b226cc68d197976f05b1547555ebfb3c446d01"}, - {file = "pymssql-2.2.7-cp36-cp36m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:d84a0fe84dda22dd50efd9ef9f68349a9df88edeb1c719e1545961e7bb74c27c"}, - {file = "pymssql-2.2.7-cp36-cp36m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9eeff70c3af730fee19406dda11a7cef0e70e397d53f7c2edb13bd11d8e3b1b5"}, - {file = "pymssql-2.2.7-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4dd8ae8b5bc7dd78af8b886721c9b586b5269fea4f0e425c64ee2444356cb292"}, - {file = "pymssql-2.2.7-cp36-cp36m-manylinux_2_24_i686.whl", hash = "sha256:a061af4df57863abee1a8a87cad357f660294e038ef9a3375e258c10f982164c"}, - {file = "pymssql-2.2.7-cp36-cp36m-manylinux_2_24_x86_64.whl", hash = "sha256:1b723fccf11caf57cb44051e83955f170d2cad8ad931cbb4ab97d263691c4bd5"}, - {file = "pymssql-2.2.7-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:016d1f903b0bd9a7f094712668bcf9fa86ef305fba4b933d182c152043706191"}, - {file = "pymssql-2.2.7-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:bf4640b04663e0296d8562ba835bd8636ca763495ece0fc023a2192adcfacdb2"}, - {file = "pymssql-2.2.7-cp36-cp36m-win32.whl", hash = "sha256:9a5a554af18e803a2532a8232817b0904cb7cb6d8c1a1cf716fe6a5f568a1111"}, - {file = "pymssql-2.2.7-cp36-cp36m-win_amd64.whl", hash = "sha256:1c0b7ed54b38ba2a59695dd9d0adba6a144ac37de459d514668b18e45f5a232d"}, - {file = "pymssql-2.2.7-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:f26de948303c2146089c1a5f8c4c5c46e6fd21b8b6b550c19c1f056d87ab112d"}, - {file = "pymssql-2.2.7-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:97760db6df17327ebedd58a93d7cd5c2c453faa517bc9bdfbe19ad1ff66b96a5"}, - {file = "pymssql-2.2.7-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:5ce2089b5b88a56eb599118b4f9a1b119e9056e85f8c6cb3002e44493181dd76"}, - {file = "pymssql-2.2.7-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:597563146e4ab088ee907c836075b9300541c16eef9791f4fbdfe6100894d512"}, - {file = "pymssql-2.2.7-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6cd3ee322daf8fcbb6e58deb21daa4adceea658e433eef3d3cae8c5be5049086"}, - {file = "pymssql-2.2.7-cp37-cp37m-manylinux_2_24_i686.whl", hash = "sha256:18b611ee72c5f4095cd8e942047982e92ab4d2d2ce5a457b85ef03bb8e385e7e"}, - {file = "pymssql-2.2.7-cp37-cp37m-manylinux_2_24_x86_64.whl", hash = "sha256:2d97127604bfde669cfc6e14f03536925e1a446d2bf4b7f3c7d671be07801361"}, - {file = "pymssql-2.2.7-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:16a281b556975d4c79cad6d41e902aba32017351aebfa4ede30581e00e89b1c1"}, - {file = "pymssql-2.2.7-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:7e9a277352a5a081a20107e112c7b820ecb76c2320779d1fc15b783110a2c1f5"}, - {file = "pymssql-2.2.7-cp37-cp37m-win32.whl", hash = "sha256:e06e6c189821fe259764dd8c61551ebcc2e5ec3752d06f850e79b520c2e92998"}, - {file = "pymssql-2.2.7-cp37-cp37m-win_amd64.whl", hash = "sha256:4306f74b4b19acc367b4bf6afb5ef961d35362f416622ae24a73035f75cfcdee"}, - {file = "pymssql-2.2.7-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:26eb3bb6f4b6a57e2f7e2639179914aa5c962522ccd68f5aecb0190e8d34893f"}, - {file = "pymssql-2.2.7-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:28151def07dc86e3b44dc0759ce130e56ebbab17b41c01458fc217678eccce31"}, - {file = "pymssql-2.2.7-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:51855d2f63e20f4d2ed6986d0f10cc03f341f959638e60d041a1ddb5a95d00fd"}, - {file = "pymssql-2.2.7-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bbf6717d85b62b95b9c96f3dd12166297dc9cef4f0887534d62c6a00c85bba4e"}, - {file = "pymssql-2.2.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:429491158fbee5309bd18b15d6fb29ad986b91afef4d05db5640fa7206d0d338"}, - {file = "pymssql-2.2.7-cp38-cp38-manylinux_2_24_i686.whl", hash = "sha256:3067423fb4cbf476c8d465fe5b7f081d3508524c1f4907b961a4c69af4280454"}, - {file = "pymssql-2.2.7-cp38-cp38-manylinux_2_24_x86_64.whl", hash = "sha256:1fc8a4b7d1a4146db70b5fbec3511bcfccb7b34d22a2aba89427bf55f8e44e23"}, - {file = "pymssql-2.2.7-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6f873e481f7175bed246f756e250778ca723e52ec14bd9cb2bb0cfaeea237868"}, - {file = "pymssql-2.2.7-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:0da65a89c95dc6336281c6a84f67abece9d50350dfd9b1c574b04aeb7148967d"}, - {file = "pymssql-2.2.7-cp38-cp38-win32.whl", hash = "sha256:4c9b337972377cabe4782e3cb4fae95b328305b0815392004a330314f3441fd8"}, - {file = "pymssql-2.2.7-cp38-cp38-win_amd64.whl", hash = "sha256:46271abb5a657004c220a4675f4365978e1b67e826de5b98a2c06855e9816e17"}, - {file = "pymssql-2.2.7-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:ec7889c696f2cc27d17af86e21062d032d795bf81e48802820a69cfeb740667c"}, - {file = "pymssql-2.2.7-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:25c330fab365174a29f7b5d77b03c05836ee3d39e135fad7d66380b5d5b99911"}, - {file = "pymssql-2.2.7-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c638398a023471ebde4774e2f8e5237bed07e7f934c4142c6d8e63ed42a86db1"}, - {file = "pymssql-2.2.7-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aa413e4fa34c53b6cfaaf294ca9070bbce1c52e5b284b35ce8e2bfbfaeae9d96"}, - {file = "pymssql-2.2.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:319e0dabd35ddb3e20798e4dc1ed6a8f8038101deafd7aabf531c0c6eaedeb5d"}, - {file = "pymssql-2.2.7-cp39-cp39-manylinux_2_24_i686.whl", hash = "sha256:8d8a13e89483891afabf67211453eab7c8d5f73379ed77c21160a672d3a818fb"}, - {file = "pymssql-2.2.7-cp39-cp39-manylinux_2_24_x86_64.whl", hash = "sha256:56916753f74ffa1e3b89483ce529ba13fd42944636558099b173b5343815fb0e"}, - {file = "pymssql-2.2.7-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:084a1573a5e4a10e7ad6e978f98ad3cc9704fc844beec4275aab1ff691533712"}, - {file = "pymssql-2.2.7-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6ed58a251e3aaffe4c731adad7d1468593dcd45f19375f1501f2bf8a54e1e355"}, - {file = "pymssql-2.2.7-cp39-cp39-win32.whl", hash = "sha256:78884588abfc44e99e3eaec46e19f5b08854af66eae9719a87a63b4645cf49b1"}, - {file = "pymssql-2.2.7-cp39-cp39-win_amd64.whl", hash = "sha256:cfa2bf7b8f7f462f72b2fa78b7753fc6c86a660dbea57d663993716afbb05072"}, - {file = "pymssql-2.2.7.tar.gz", hash = "sha256:ff95b910532ec7b02e4322231c117d3d6af0abab667e6fbf15442db873943045"}, + {file = "pymssql-2.2.8-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:30bfd7b8edef78097ccd3f52ac3f3a5c3cf0019f8a280f306cacbbb165caaf63"}, + {file = "pymssql-2.2.8-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:049f2e3de919e8e02504780a21ebbf235e21ca8ed5c7538c5b6e705aa6c43d8c"}, + {file = "pymssql-2.2.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0dd86d8e3e346e34f3f03d12e333747b53a1daa74374a727f4714d5b82ee0dd5"}, + {file = "pymssql-2.2.8-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:508226a0df7cb6faeda9f8e84e85743690ca427d7b27af9a73d75fcf0c1eef6e"}, + {file = "pymssql-2.2.8-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:d873e553374d5b1c57fe1c43bb75e3bcc2920678db1ef26f6bfed396c7d21b30"}, + {file = "pymssql-2.2.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf31b8b76634c826a91f9999e15b7bfb0c051a0f53b319fd56481a67e5b903bb"}, + {file = "pymssql-2.2.8-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:821945c2214fe666fd456c61e09a29a00e7719c9e136c801bffb3a254e9c579b"}, + {file = "pymssql-2.2.8-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:ebe7f64d5278d807f14bea08951e02512bfbc6219fd4d4f15bb45ded885cf3d4"}, + {file = "pymssql-2.2.8-cp36-cp36m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:253af3d39fc0235627966817262d5c4c94ad09dcbea59664748063470048c29c"}, + {file = "pymssql-2.2.8-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c9d109df536dc5f7dd851a88d285a4c9cb12a9314b621625f4f5ab1197eb312"}, + {file = "pymssql-2.2.8-cp36-cp36m-manylinux_2_28_x86_64.whl", hash = "sha256:358d5acf0298d6618edf7fedc4ce3dc8fb5ce8a9db85e7332d5196d29d841821"}, + {file = "pymssql-2.2.8-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:63e1be8936372c07aee2405203ee0161ce76b03893cafe3d46841be9886f5ffe"}, + {file = "pymssql-2.2.8-cp37-cp37m-macosx_11_0_x86_64.whl", hash = "sha256:381d8a47c4665d99f114849bed23bcba1922c9d005accc3ac19cee8a1d3522dc"}, + {file = "pymssql-2.2.8-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4f365033c9b4263b74b8a332bbdf2d7d8d7230f05805439b4f3fbf0a0164acfe"}, + {file = "pymssql-2.2.8-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03903bdf23a2aac26e9b772b3998efeba079fcb6fcfa6df7abc614e9afa14af0"}, + {file = "pymssql-2.2.8-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:5c83208138f87942c5f08aa50c5fb8d89b7f15340cde58a77b08f49df277e134"}, + {file = "pymssql-2.2.8-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:7e4538e85d7b5fb3867636391f91e9e18ac2e0aef660d25e97268e04339f2c36"}, + {file = "pymssql-2.2.8-cp38-cp38-macosx_11_0_x86_64.whl", hash = "sha256:e920d6f805a525f19e770e48326a5f96b83d7b8dfd093f5b7015b54ef84bcf4c"}, + {file = "pymssql-2.2.8-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2446645eb8684c0cb246a3294110455dd89a29608dfa7a58ea88aa42aa1cf005"}, + {file = "pymssql-2.2.8-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3906993300650844ec140aa58772c0f5f3e9e9d5709c061334fd1551acdcf066"}, + {file = "pymssql-2.2.8-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:7309c7352e4a87c9995c3183ebfe0ff4135e955bb759109637673c61c9f0ca8d"}, + {file = "pymssql-2.2.8-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:9b8d603cc1ec7ae585c5a409a1d45e8da067970c79dd550d45c238ae0aa0f79f"}, + {file = "pymssql-2.2.8-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:895041edd002a2e91d8a4faf0906b6fbfef29d9164bc6beb398421f5927fa40e"}, + {file = "pymssql-2.2.8-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6b2d9c6d38a416c6f2db36ff1cd8e69f9a5387a46f9f4f612623192e0c9404b1"}, + {file = "pymssql-2.2.8-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d63d6f25cf40fe6a03c49be2d4d337858362b8ab944d6684c268e4990807cf0c"}, + {file = "pymssql-2.2.8-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:c83ad3ad20951f3a94894b354fa5fa9666dcd5ebb4a635dad507c7d1dd545833"}, + {file = "pymssql-2.2.8-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:3933f7f082be74698eea835df51798dab9bc727d94d3d280bffc75ab9265f890"}, + {file = "pymssql-2.2.8.tar.gz", hash = "sha256:9baefbfbd07d0142756e2dfcaa804154361ac5806ab9381350aad4e780c3033e"}, ] [package.source] @@ -5690,25 +5582,6 @@ type = "legacy" url = "https://pypi.tuna.tsinghua.edu.cn/simple" reference = "tsinghua" -[[package]] -name = "python-dotenv" -version = "1.0.0" -description = "Read key-value pairs from a .env file and set them as environment variables" -optional = false -python-versions = ">=3.8" -files = [ - {file = "python-dotenv-1.0.0.tar.gz", hash = "sha256:a8df96034aae6d2d50a4ebe8216326c61c3eb64836776504fcca410e5937a3ba"}, - {file = "python_dotenv-1.0.0-py3-none-any.whl", hash = "sha256:f5971a9226b701070a4bf2c38c89e5a3f0d64de8debda981d1db98583009122a"}, -] - -[package.extras] -cli = ["click (>=5.0)"] - -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" - [[package]] name = "python-keystoneclient" version = "5.1.0" @@ -6387,22 +6260,6 @@ type = "legacy" url = "https://pypi.tuna.tsinghua.edu.cn/simple" reference = "tsinghua" -[[package]] -name = "sniffio" -version = "1.3.0" -description = "Sniff out which async library your code is running under" -optional = false -python-versions = ">=3.7" -files = [ - {file = "sniffio-1.3.0-py3-none-any.whl", hash = "sha256:eecefdce1e5bbfb7ad2eeaabf7c1eeb404d7757c379bd1f7e5cce9d8bf425384"}, - {file = "sniffio-1.3.0.tar.gz", hash = "sha256:e60305c5e5d314f5389259b7f22aaa33d8f7dee49763119234af3755c55b9101"}, -] - -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" - [[package]] name = "soupsieve" version = "2.4.1" @@ -6867,14 +6724,7 @@ files = [ [package.dependencies] click = ">=7.0" -colorama = {version = ">=0.4", optional = true, markers = "sys_platform == \"win32\" and extra == \"standard\""} h11 = ">=0.8" -httptools = {version = ">=0.5.0", optional = true, markers = "extra == \"standard\""} -python-dotenv = {version = ">=0.13", optional = true, markers = "extra == \"standard\""} -pyyaml = {version = ">=5.1", optional = true, markers = "extra == \"standard\""} -uvloop = {version = ">=0.14.0,<0.15.0 || >0.15.0,<0.15.1 || >0.15.1", optional = true, markers = "(sys_platform != \"win32\" and sys_platform != \"cygwin\") and platform_python_implementation != \"PyPy\" and extra == \"standard\""} -watchfiles = {version = ">=0.13", optional = true, markers = "extra == \"standard\""} -websockets = {version = ">=10.4", optional = true, markers = "extra == \"standard\""} [package.extras] standard = ["colorama (>=0.4)", "httptools (>=0.5.0)", "python-dotenv (>=0.13)", "pyyaml (>=5.1)", "uvloop (>=0.14.0,!=0.15.0,!=0.15.1)", "watchfiles (>=0.13)", "websockets (>=10.4)"] @@ -6884,55 +6734,6 @@ type = "legacy" url = "https://pypi.tuna.tsinghua.edu.cn/simple" reference = "tsinghua" -[[package]] -name = "uvloop" -version = "0.17.0" -description = "Fast implementation of asyncio event loop on top of libuv" -optional = false -python-versions = ">=3.7" -files = [ - {file = "uvloop-0.17.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ce9f61938d7155f79d3cb2ffa663147d4a76d16e08f65e2c66b77bd41b356718"}, - {file = "uvloop-0.17.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:68532f4349fd3900b839f588972b3392ee56042e440dd5873dfbbcd2cc67617c"}, - {file = "uvloop-0.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0949caf774b9fcefc7c5756bacbbbd3fc4c05a6b7eebc7c7ad6f825b23998d6d"}, - {file = "uvloop-0.17.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ff3d00b70ce95adce264462c930fbaecb29718ba6563db354608f37e49e09024"}, - {file = "uvloop-0.17.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:a5abddb3558d3f0a78949c750644a67be31e47936042d4f6c888dd6f3c95f4aa"}, - {file = "uvloop-0.17.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8efcadc5a0003d3a6e887ccc1fb44dec25594f117a94e3127954c05cf144d811"}, - {file = "uvloop-0.17.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:3378eb62c63bf336ae2070599e49089005771cc651c8769aaad72d1bd9385a7c"}, - {file = "uvloop-0.17.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6aafa5a78b9e62493539456f8b646f85abc7093dd997f4976bb105537cf2635e"}, - {file = "uvloop-0.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c686a47d57ca910a2572fddfe9912819880b8765e2f01dc0dd12a9bf8573e539"}, - {file = "uvloop-0.17.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:864e1197139d651a76c81757db5eb199db8866e13acb0dfe96e6fc5d1cf45fc4"}, - {file = "uvloop-0.17.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:2a6149e1defac0faf505406259561bc14b034cdf1d4711a3ddcdfbaa8d825a05"}, - {file = "uvloop-0.17.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:6708f30db9117f115eadc4f125c2a10c1a50d711461699a0cbfaa45b9a78e376"}, - {file = "uvloop-0.17.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:23609ca361a7fc587031429fa25ad2ed7242941adec948f9d10c045bfecab06b"}, - {file = "uvloop-0.17.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2deae0b0fb00a6af41fe60a675cec079615b01d68beb4cc7b722424406b126a8"}, - {file = "uvloop-0.17.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45cea33b208971e87a31c17622e4b440cac231766ec11e5d22c76fab3bf9df62"}, - {file = "uvloop-0.17.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:9b09e0f0ac29eee0451d71798878eae5a4e6a91aa275e114037b27f7db72702d"}, - {file = "uvloop-0.17.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:dbbaf9da2ee98ee2531e0c780455f2841e4675ff580ecf93fe5c48fe733b5667"}, - {file = "uvloop-0.17.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:a4aee22ece20958888eedbad20e4dbb03c37533e010fb824161b4f05e641f738"}, - {file = "uvloop-0.17.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:307958f9fc5c8bb01fad752d1345168c0abc5d62c1b72a4a8c6c06f042b45b20"}, - {file = "uvloop-0.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ebeeec6a6641d0adb2ea71dcfb76017602ee2bfd8213e3fcc18d8f699c5104f"}, - {file = "uvloop-0.17.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1436c8673c1563422213ac6907789ecb2b070f5939b9cbff9ef7113f2b531595"}, - {file = "uvloop-0.17.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:8887d675a64cfc59f4ecd34382e5b4f0ef4ae1da37ed665adba0c2badf0d6578"}, - {file = "uvloop-0.17.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:3db8de10ed684995a7f34a001f15b374c230f7655ae840964d51496e2f8a8474"}, - {file = "uvloop-0.17.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7d37dccc7ae63e61f7b96ee2e19c40f153ba6ce730d8ba4d3b4e9738c1dccc1b"}, - {file = "uvloop-0.17.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:cbbe908fda687e39afd6ea2a2f14c2c3e43f2ca88e3a11964b297822358d0e6c"}, - {file = "uvloop-0.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3d97672dc709fa4447ab83276f344a165075fd9f366a97b712bdd3fee05efae8"}, - {file = "uvloop-0.17.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f1e507c9ee39c61bfddd79714e4f85900656db1aec4d40c6de55648e85c2799c"}, - {file = "uvloop-0.17.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:c092a2c1e736086d59ac8e41f9c98f26bbf9b9222a76f21af9dfe949b99b2eb9"}, - {file = "uvloop-0.17.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:30babd84706115626ea78ea5dbc7dd8d0d01a2e9f9b306d24ca4ed5796c66ded"}, - {file = "uvloop-0.17.0.tar.gz", hash = "sha256:0ddf6baf9cf11a1a22c71487f39f15b2cf78eb5bde7e5b45fbb99e8a9d91b9e1"}, -] - -[package.extras] -dev = ["Cython (>=0.29.32,<0.30.0)", "Sphinx (>=4.1.2,<4.2.0)", "aiohttp", "flake8 (>=3.9.2,<3.10.0)", "mypy (>=0.800)", "psutil", "pyOpenSSL (>=22.0.0,<22.1.0)", "pycodestyle (>=2.7.0,<2.8.0)", "pytest (>=3.6.0)", "sphinx-rtd-theme (>=0.5.2,<0.6.0)", "sphinxcontrib-asyncio (>=0.3.0,<0.4.0)"] -docs = ["Sphinx (>=4.1.2,<4.2.0)", "sphinx-rtd-theme (>=0.5.2,<0.6.0)", "sphinxcontrib-asyncio (>=0.3.0,<0.4.0)"] -test = ["Cython (>=0.29.32,<0.30.0)", "aiohttp", "flake8 (>=3.9.2,<3.10.0)", "mypy (>=0.800)", "psutil", "pyOpenSSL (>=22.0.0,<22.1.0)", "pycodestyle (>=2.7.0,<2.8.0)"] - -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" - [[package]] name = "vine" version = "5.0.0" @@ -6949,45 +6750,6 @@ type = "legacy" url = "https://pypi.tuna.tsinghua.edu.cn/simple" reference = "tsinghua" -[[package]] -name = "watchfiles" -version = "0.19.0" -description = "Simple, modern and high performance file watching and code reload in python." -optional = false -python-versions = ">=3.7" -files = [ - {file = "watchfiles-0.19.0-cp37-abi3-macosx_10_7_x86_64.whl", hash = "sha256:91633e64712df3051ca454ca7d1b976baf842d7a3640b87622b323c55f3345e7"}, - {file = "watchfiles-0.19.0-cp37-abi3-macosx_11_0_arm64.whl", hash = "sha256:b6577b8c6c8701ba8642ea9335a129836347894b666dd1ec2226830e263909d3"}, - {file = "watchfiles-0.19.0-cp37-abi3-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:18b28f6ad871b82df9542ff958d0c86bb0d8310bb09eb8e87d97318a3b5273af"}, - {file = "watchfiles-0.19.0-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fac19dc9cbc34052394dbe81e149411a62e71999c0a19e1e09ce537867f95ae0"}, - {file = "watchfiles-0.19.0-cp37-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:09ea3397aecbc81c19ed7f025e051a7387feefdb789cf768ff994c1228182fda"}, - {file = "watchfiles-0.19.0-cp37-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c0376deac92377817e4fb8f347bf559b7d44ff556d9bc6f6208dd3f79f104aaf"}, - {file = "watchfiles-0.19.0-cp37-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c75eff897786ee262c9f17a48886f4e98e6cfd335e011c591c305e5d083c056"}, - {file = "watchfiles-0.19.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cb5d45c4143c1dd60f98a16187fd123eda7248f84ef22244818c18d531a249d1"}, - {file = "watchfiles-0.19.0-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:79c533ff593db861ae23436541f481ec896ee3da4e5db8962429b441bbaae16e"}, - {file = "watchfiles-0.19.0-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:3d7d267d27aceeeaa3de0dd161a0d64f0a282264d592e335fff7958cc0cbae7c"}, - {file = "watchfiles-0.19.0-cp37-abi3-win32.whl", hash = "sha256:176a9a7641ec2c97b24455135d58012a5be5c6217fc4d5fef0b2b9f75dbf5154"}, - {file = "watchfiles-0.19.0-cp37-abi3-win_amd64.whl", hash = "sha256:945be0baa3e2440151eb3718fd8846751e8b51d8de7b884c90b17d271d34cae8"}, - {file = "watchfiles-0.19.0-cp37-abi3-win_arm64.whl", hash = "sha256:0089c6dc24d436b373c3c57657bf4f9a453b13767150d17284fc6162b2791911"}, - {file = "watchfiles-0.19.0-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:cae3dde0b4b2078f31527acff6f486e23abed307ba4d3932466ba7cdd5ecec79"}, - {file = "watchfiles-0.19.0-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:7f3920b1285a7d3ce898e303d84791b7bf40d57b7695ad549dc04e6a44c9f120"}, - {file = "watchfiles-0.19.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9afd0d69429172c796164fd7fe8e821ade9be983f51c659a38da3faaaaac44dc"}, - {file = "watchfiles-0.19.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:68dce92b29575dda0f8d30c11742a8e2b9b8ec768ae414b54f7453f27bdf9545"}, - {file = "watchfiles-0.19.0-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:5569fc7f967429d4bc87e355cdfdcee6aabe4b620801e2cf5805ea245c06097c"}, - {file = "watchfiles-0.19.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:5471582658ea56fca122c0f0d0116a36807c63fefd6fdc92c71ca9a4491b6b48"}, - {file = "watchfiles-0.19.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b538014a87f94d92f98f34d3e6d2635478e6be6423a9ea53e4dd96210065e193"}, - {file = "watchfiles-0.19.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:20b44221764955b1e703f012c74015306fb7e79a00c15370785f309b1ed9aa8d"}, - {file = "watchfiles-0.19.0.tar.gz", hash = "sha256:d9b073073e048081e502b6c6b0b88714c026a1a4c890569238d04aca5f9ca74b"}, -] - -[package.dependencies] -anyio = ">=3.0.0" - -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" - [[package]] name = "wcwidth" version = "0.2.6" @@ -7413,4 +7175,4 @@ reference = "tsinghua" [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "3dc9498476fdd72f17898b76a31f029099e2224c78028d919dfeb964e14df5e8" +content-hash = "0b6107439bac42ee20efd101c5b033857124c63c534eacaa5f03e93c581e2422" diff --git a/pyproject.toml b/pyproject.toml index a09355113..3df29cc7d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -103,13 +103,17 @@ django-proxy = "1.2.2" channels-redis = "4.1.0" python-daemon = "3.0.1" eventlet = "0.33.3" -greenlet = "2.0.2" +# greenlet = "2.0.2" +greenlet = [ + { url = "https://download.jumpserver.org/pypi/simple/greenlet/greenlet-2.0.2-cp311-cp311-linux_loongarch64.whl", markers = "sys_platform == 'linux' and platform_machine == 'loongarch64'" }, + { version = "2.0.2", source = "tsinghua", markers = "platform_machine != 'loongarch64'" } +] gunicorn = "21.2.0" celery = "5.3.1" flower = "2.0.0" django-celery-beat = "2.5.0" kombu = "5.3.1" -uvicorn = { version = "0.22.0", extras = ["standard"] } +uvicorn = "0.22.0" websockets = "11.0.3" python-ldap = "3.4.3" ldap3 = "2.9.1" @@ -151,7 +155,11 @@ azure-identity = "1.13.0" azure-mgmt-compute = "30.0.0" azure-mgmt-network = "23.1.0" google-cloud-compute = "1.13.0" -grpcio = "1.56.2" +# grpcio = "1.56.2" +grpcio = [ + { url = "https://download.jumpserver.org/pypi/simple/grpcio/grpcio-1.56.2-cp311-cp311-linux_loongarch64.whl", markers = "sys_platform == 'linux' and platform_machine == 'loongarch64'" }, + { version = "1.56.2", source = "tsinghua", markers = "platform_machine != 'loongarch64'" } +] alibabacloud-dysmsapi20170525 = "2.0.24" python-novaclient = "18.3.0" python-keystoneclient = "5.1.0" @@ -160,9 +168,10 @@ tencentcloud-sdk-python = "3.0.941" aliyun-python-sdk-core-v3 = "2.13.33" aliyun-python-sdk-ecs = "4.24.64" keystoneauth1 = "5.2.1" -oracledb = "1.3.2" +# oracledb = "1.4.0" +oracledb = { git = "https://github.com/oracle/python-oracledb.git", branch = "main" } psycopg2-binary = "2.9.6" -pymssql = "2.2.7" +pymssql = "2.2.8" psycopg2 = "2.9.6" ucloud-sdk-python3 = "0.11.50" @@ -171,6 +180,11 @@ name = "tsinghua" url = "https://pypi.tuna.tsinghua.edu.cn/simple/" priority = "primary" + +[[tool.poetry.source]] +name = "PyPI" +priority = "primary" + [build-system] requires = ["poetry-core"] build-backend = "poetry.core.masonry.api" diff --git a/requirements/requirements.txt b/requirements/requirements.txt index 3bb7cbee4..221421582 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -105,7 +105,6 @@ flower==2.0.0 django-celery-beat==2.5.0 kombu==5.3.1 uvicorn==0.22.0 -uvicorn[standard]==0.22.0 websockets==11.0.3 # Auth python-ldap==3.4.3 diff --git a/requirements/requirements_xpack.txt b/requirements/requirements_xpack.txt index 253ea793b..e77e836a3 100644 --- a/requirements/requirements_xpack.txt +++ b/requirements/requirements_xpack.txt @@ -16,8 +16,8 @@ aliyun-python-sdk-ecs==4.24.64 #huaweicloud-sdk-python==1.0.28 keystoneauth1==5.2.1 # DB requirements -oracledb==1.3.2 +# oracledb==1.4.0 psycopg2-binary==2.9.6 -pymssql==2.2.7 +pymssql==2.2.8 psycopg2==2.9.6 ucloud-sdk-python3==0.11.50 From 27c4e1d895b4f8d4d66fcf4ce34dc11669308407 Mon Sep 17 00:00:00 2001 From: ibuler Date: Thu, 3 Aug 2023 16:09:54 +0800 Subject: [PATCH 093/177] =?UTF-8?q?perf:=20web=20=E5=B9=B3=E5=8F=B0?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E9=AB=98=E7=BA=A7=E9=80=89=E9=A1=B9=EF=BC=8C?= =?UTF-8?q?=E5=8F=AF=E4=BB=A5=E6=8E=A7=E5=88=B6=E6=98=AF=E5=90=A6=E5=AE=89?= =?UTF-8?q?=E5=85=A8=E6=A8=A1=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/assets/const/protocol.py | 9 ++ .../migrations/0122_auto_20230803_1553.py | 24 +++++ apps/locale/ja/LC_MESSAGES/django.mo | 4 +- apps/locale/ja/LC_MESSAGES/django.po | 91 ++++++++++--------- apps/locale/zh/LC_MESSAGES/django.mo | 4 +- apps/locale/zh/LC_MESSAGES/django.po | 90 ++++++++++-------- 6 files changed, 137 insertions(+), 85 deletions(-) create mode 100644 apps/assets/migrations/0122_auto_20230803_1553.py diff --git a/apps/assets/const/protocol.py b/apps/assets/const/protocol.py index 6886cbc4d..e2a601618 100644 --- a/apps/assets/const/protocol.py +++ b/apps/assets/const/protocol.py @@ -194,6 +194,15 @@ class Protocol(ChoicesMixin, models.TextChoices): 'port_from_addr': True, 'secret_types': ['password'], 'setting': { + 'safe_mode': { + 'type': 'bool', + 'default': True, + 'label': _('Safe mode'), + 'help_text': _( + 'When safe mode is enabled, some operations will be disabled, such as: ' + 'New tab, right click, visit other website, etc.' + ) + }, 'autofill': { 'label': _('Autofill'), 'type': 'choice', diff --git a/apps/assets/migrations/0122_auto_20230803_1553.py b/apps/assets/migrations/0122_auto_20230803_1553.py new file mode 100644 index 000000000..4f3071153 --- /dev/null +++ b/apps/assets/migrations/0122_auto_20230803_1553.py @@ -0,0 +1,24 @@ +# Generated by Django 4.1.10 on 2023-08-03 07:53 + +from django.db import migrations + + +def migrate_web_setting_safe_mode(apps, schema_editor): + platform_protocol_cls = apps.get_model('assets', 'PlatformProtocol') + protocols = platform_protocol_cls.objects.filter(name='http') + for protocol in protocols: + setting = protocol.setting or {} + setting['safe_mode'] = False + protocol.setting = setting + protocol.save(update_fields=['setting']) + + +class Migration(migrations.Migration): + + dependencies = [ + ('assets', '0121_auto_20230725_1458'), + ] + + operations = [ + migrations.RunPython(migrate_web_setting_safe_mode), + ] diff --git a/apps/locale/ja/LC_MESSAGES/django.mo b/apps/locale/ja/LC_MESSAGES/django.mo index 4b1734de2..0d745e972 100644 --- a/apps/locale/ja/LC_MESSAGES/django.mo +++ b/apps/locale/ja/LC_MESSAGES/django.mo @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d9e79f70d055fa4d3fda971820bcd0eb186a8806d91346c7038add4ee89d647a -size 151115 +oid sha256:cebc816d765d1b53b4984dabe689b73e25ebea0bbd053625d5f7d94e0bf66852 +size 151070 diff --git a/apps/locale/ja/LC_MESSAGES/django.po b/apps/locale/ja/LC_MESSAGES/django.po index 3c45e852b..1f95b728e 100644 --- a/apps/locale/ja/LC_MESSAGES/django.po +++ b/apps/locale/ja/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-08-02 16:52+0800\n" +"POT-Creation-Date: 2023-08-03 15:51+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -211,6 +211,7 @@ msgstr "" #: perms/models/asset_permission.py:64 perms/serializers/permission.py:34 #: terminal/backends/command/models.py:17 terminal/models/session/session.py:31 #: terminal/notifications.py:155 terminal/serializers/command.py:17 +#: terminal/serializers/session.py:26 #: terminal/templates/terminal/_msg_command_warning.html:4 #: terminal/templates/terminal/_msg_session_sharing.html:4 #: tickets/models/ticket/apply_asset.py:16 xpack/plugins/cloud/models.py:212 @@ -333,7 +334,7 @@ msgstr "理由" #: accounts/models/automations/backup_account.py:99 #: accounts/serializers/automations/change_secret.py:111 #: accounts/serializers/automations/change_secret.py:134 -#: ops/serializers/job.py:56 terminal/serializers/session.py:44 +#: ops/serializers/job.py:56 terminal/serializers/session.py:46 msgid "Is success" msgstr "成功は" @@ -601,7 +602,7 @@ msgstr "カテゴリ" #: perms/serializers/user_permission.py:27 settings/serializers/vault.py:13 #: terminal/models/applet/applet.py:38 terminal/models/component/storage.py:57 #: terminal/models/component/storage.py:146 terminal/serializers/applet.py:29 -#: terminal/serializers/session.py:20 terminal/serializers/storage.py:226 +#: terminal/serializers/session.py:21 terminal/serializers/storage.py:226 #: terminal/serializers/storage.py:238 tickets/models/comment.py:26 #: tickets/models/flow.py:56 tickets/models/ticket/apply_application.py:16 #: tickets/models/ticket/general.py:275 tickets/serializers/flow.py:53 @@ -1098,7 +1099,7 @@ msgstr "無効" msgid "Basic" msgstr "基本" -#: assets/const/base.py:35 assets/const/protocol.py:221 +#: assets/const/base.py:35 assets/const/protocol.py:230 #: assets/models/asset/web.py:13 msgid "Script" msgstr "脚本" @@ -1240,24 +1241,34 @@ msgstr "SYSDBA として接続" msgid "Auth username" msgstr "ユーザー名で認証する" -#: assets/const/protocol.py:198 assets/models/asset/web.py:9 +#: assets/const/protocol.py:200 +msgid "Safe mode" +msgstr "安全モード" + +#: assets/const/protocol.py:202 +msgid "" +"When safe mode is enabled, some operations will be disabled, such as: New " +"tab, right click, visit other website, etc." +msgstr "安全モードが有効になっている場合、新しいタブ、右クリック、他のウェブサイトへのアクセスなど、一部の操作が無効になります" + +#: assets/const/protocol.py:207 assets/models/asset/web.py:9 #: assets/serializers/asset/info/spec.py:16 msgid "Autofill" msgstr "自動充填" -#: assets/const/protocol.py:206 assets/models/asset/web.py:10 +#: assets/const/protocol.py:215 assets/models/asset/web.py:10 msgid "Username selector" msgstr "ユーザー名ピッカー" -#: assets/const/protocol.py:211 assets/models/asset/web.py:11 +#: assets/const/protocol.py:220 assets/models/asset/web.py:11 msgid "Password selector" msgstr "パスワードセレクター" -#: assets/const/protocol.py:216 assets/models/asset/web.py:12 +#: assets/const/protocol.py:225 assets/models/asset/web.py:12 msgid "Submit selector" msgstr "ボタンセレクターを確認する" -#: assets/const/protocol.py:239 +#: assets/const/protocol.py:248 msgid "API mode" msgstr "APIモード" @@ -1335,8 +1346,8 @@ msgstr "ユーザーと同じユーザー名" #: assets/models/_user.py:52 authentication/models/connection_token.py:41 #: authentication/serializers/connect_token_secret.py:111 -#: terminal/models/applet/applet.py:41 terminal/serializers/session.py:18 -#: terminal/serializers/session.py:40 terminal/serializers/storage.py:70 +#: terminal/models/applet/applet.py:41 terminal/serializers/session.py:19 +#: terminal/serializers/session.py:42 terminal/serializers/storage.py:70 msgid "Protocol" msgstr "プロトコル" @@ -2071,7 +2082,7 @@ msgstr "パスワードを変更する" #: audits/const.py:35 settings/serializers/terminal.py:6 #: terminal/models/applet/host.py:26 terminal/models/component/terminal.py:163 -#: terminal/serializers/session.py:47 terminal/serializers/session.py:56 +#: terminal/serializers/session.py:49 terminal/serializers/session.py:63 msgid "Terminal" msgstr "ターミナル" @@ -3596,15 +3607,15 @@ msgstr "システムメッセージ" msgid "Publish the station message" msgstr "投稿サイトニュース" -#: ops/ansible/inventory.py:82 +#: ops/ansible/inventory.py:92 msgid "No account available" msgstr "利用可能なアカウントがありません" -#: ops/ansible/inventory.py:247 +#: ops/ansible/inventory.py:258 msgid "Ansible disabled" msgstr "Ansible 無効" -#: ops/ansible/inventory.py:263 +#: ops/ansible/inventory.py:274 msgid "Skip hosts below:" msgstr "次のホストをスキップします: " @@ -3874,7 +3885,7 @@ msgstr "保存後に実行" msgid "Job type" msgstr "タスクの種類" -#: ops/serializers/job.py:57 terminal/serializers/session.py:48 +#: ops/serializers/job.py:57 terminal/serializers/session.py:50 msgid "Is finished" msgstr "終了しました" @@ -5374,35 +5385,23 @@ msgstr "リストの並べ替え" msgid "List page size" msgstr "ページサイズを一覧表示" -#: settings/serializers/terminal.py:34 -msgid "Telnet login regex" -msgstr "Telnetログインregex" - -#: settings/serializers/terminal.py:35 -msgid "" -"Tips: The login success message varies with devices. if you cannot log in to " -"the device through Telnet, set this parameter" -msgstr "" -"ヒント: ログイン成功メッセージはデバイスによって異なります。Telnet経由でデバ" -"イスにログインできない場合は、このパラメーターを設定します。" - -#: settings/serializers/terminal.py:38 +#: settings/serializers/terminal.py:33 msgid "Enable database proxy" msgstr "属性マップの有効化" -#: settings/serializers/terminal.py:39 +#: settings/serializers/terminal.py:34 msgid "Enable Razor" msgstr "Razor の有効化" -#: settings/serializers/terminal.py:40 +#: settings/serializers/terminal.py:35 msgid "Enable SSH Client" msgstr "SSH Clientの有効化" -#: settings/serializers/terminal.py:51 +#: settings/serializers/terminal.py:46 msgid "Default graphics resolution" msgstr "デフォルトのグラフィック解像度" -#: settings/serializers/terminal.py:52 +#: settings/serializers/terminal.py:47 msgid "" "Tip: Default resolution to use when connecting graphical assets in Luna pages" msgstr "" @@ -6085,7 +6084,7 @@ msgstr "リプレイ" msgid "Date end" msgstr "終了日" -#: terminal/models/session/session.py:47 terminal/serializers/session.py:55 +#: terminal/models/session/session.py:47 terminal/serializers/session.py:62 msgid "Command amount" msgstr "コマンド量" @@ -6360,31 +6359,31 @@ msgstr "" msgid "Asset IP" msgstr "資産 IP" -#: terminal/serializers/session.py:22 terminal/serializers/session.py:45 +#: terminal/serializers/session.py:23 terminal/serializers/session.py:47 msgid "Can replay" msgstr "再生できます" -#: terminal/serializers/session.py:23 terminal/serializers/session.py:46 +#: terminal/serializers/session.py:24 terminal/serializers/session.py:48 msgid "Can join" msgstr "参加できます" -#: terminal/serializers/session.py:24 terminal/serializers/session.py:49 +#: terminal/serializers/session.py:25 terminal/serializers/session.py:51 msgid "Can terminate" msgstr "終了できます" -#: terminal/serializers/session.py:41 +#: terminal/serializers/session.py:43 msgid "User ID" msgstr "ユーザーID" -#: terminal/serializers/session.py:42 +#: terminal/serializers/session.py:44 msgid "Asset ID" msgstr "資産ID" -#: terminal/serializers/session.py:43 +#: terminal/serializers/session.py:45 msgid "Login from display" msgstr "表示からのログイン" -#: terminal/serializers/session.py:50 +#: terminal/serializers/session.py:52 msgid "Terminal display" msgstr "ターミナルディスプレイ" @@ -7998,6 +7997,16 @@ msgstr "究極のエディション" msgid "Community edition" msgstr "コミュニティ版" +#~ msgid "Telnet login regex" +#~ msgstr "Telnetログインregex" + +#~ msgid "" +#~ "Tips: The login success message varies with devices. if you cannot log in " +#~ "to the device through Telnet, set this parameter" +#~ msgstr "" +#~ "ヒント: ログイン成功メッセージはデバイスによって異なります。Telnet経由でデ" +#~ "バイスにログインできない場合は、このパラメーターを設定します。" + #~ msgid "Role display" #~ msgstr "ロール表示" diff --git a/apps/locale/zh/LC_MESSAGES/django.mo b/apps/locale/zh/LC_MESSAGES/django.mo index da572bc13..9823d5f58 100644 --- a/apps/locale/zh/LC_MESSAGES/django.mo +++ b/apps/locale/zh/LC_MESSAGES/django.mo @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f70c68e6f9f5cd621ae5ff04e73bb882d4849d3750a8c34f586dc3cc74adfca4 -size 123431 +oid sha256:1b7a963a93db87dd16ca9d63423b2f277dd6bc0a95abfae1533e6bf65e624da4 +size 123404 diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po index 2136158ea..17a4c6e5e 100644 --- a/apps/locale/zh/LC_MESSAGES/django.po +++ b/apps/locale/zh/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: JumpServer 0.3.3\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-08-02 16:52+0800\n" +"POT-Creation-Date: 2023-08-03 15:51+0800\n" "PO-Revision-Date: 2021-05-20 10:54+0800\n" "Last-Translator: ibuler \n" "Language-Team: JumpServer team\n" @@ -210,6 +210,7 @@ msgstr "" #: perms/models/asset_permission.py:64 perms/serializers/permission.py:34 #: terminal/backends/command/models.py:17 terminal/models/session/session.py:31 #: terminal/notifications.py:155 terminal/serializers/command.py:17 +#: terminal/serializers/session.py:26 #: terminal/templates/terminal/_msg_command_warning.html:4 #: terminal/templates/terminal/_msg_session_sharing.html:4 #: tickets/models/ticket/apply_asset.py:16 xpack/plugins/cloud/models.py:212 @@ -332,7 +333,7 @@ msgstr "原因" #: accounts/models/automations/backup_account.py:99 #: accounts/serializers/automations/change_secret.py:111 #: accounts/serializers/automations/change_secret.py:134 -#: ops/serializers/job.py:56 terminal/serializers/session.py:44 +#: ops/serializers/job.py:56 terminal/serializers/session.py:46 msgid "Is success" msgstr "是否成功" @@ -597,7 +598,7 @@ msgstr "类别" #: perms/serializers/user_permission.py:27 settings/serializers/vault.py:13 #: terminal/models/applet/applet.py:38 terminal/models/component/storage.py:57 #: terminal/models/component/storage.py:146 terminal/serializers/applet.py:29 -#: terminal/serializers/session.py:20 terminal/serializers/storage.py:226 +#: terminal/serializers/session.py:21 terminal/serializers/storage.py:226 #: terminal/serializers/storage.py:238 tickets/models/comment.py:26 #: tickets/models/flow.py:56 tickets/models/ticket/apply_application.py:16 #: tickets/models/ticket/general.py:275 tickets/serializers/flow.py:53 @@ -1091,7 +1092,7 @@ msgstr "禁用" msgid "Basic" msgstr "基本" -#: assets/const/base.py:35 assets/const/protocol.py:221 +#: assets/const/base.py:35 assets/const/protocol.py:230 #: assets/models/asset/web.py:13 msgid "Script" msgstr "脚本" @@ -1233,24 +1234,34 @@ msgstr "以 SYSDBA 角色连接" msgid "Auth username" msgstr "使用用户名认证" -#: assets/const/protocol.py:198 assets/models/asset/web.py:9 +#: assets/const/protocol.py:200 +msgid "Safe mode" +msgstr "安全模式" + +#: assets/const/protocol.py:202 +msgid "" +"When safe mode is enabled, some operations will be disabled, such as: New " +"tab, right click, visit other website, etc." +msgstr "当安全模式启用时,一些操作将被禁用,例如:新建标签页、右键、访问其它网站 等" + +#: assets/const/protocol.py:207 assets/models/asset/web.py:9 #: assets/serializers/asset/info/spec.py:16 msgid "Autofill" msgstr "自动代填" -#: assets/const/protocol.py:206 assets/models/asset/web.py:10 +#: assets/const/protocol.py:215 assets/models/asset/web.py:10 msgid "Username selector" msgstr "用户名选择器" -#: assets/const/protocol.py:211 assets/models/asset/web.py:11 +#: assets/const/protocol.py:220 assets/models/asset/web.py:11 msgid "Password selector" msgstr "密码选择器" -#: assets/const/protocol.py:216 assets/models/asset/web.py:12 +#: assets/const/protocol.py:225 assets/models/asset/web.py:12 msgid "Submit selector" msgstr "确认按钮选择器" -#: assets/const/protocol.py:239 +#: assets/const/protocol.py:248 msgid "API mode" msgstr "API 模式" @@ -1328,8 +1339,8 @@ msgstr "用户名与用户相同" #: assets/models/_user.py:52 authentication/models/connection_token.py:41 #: authentication/serializers/connect_token_secret.py:111 -#: terminal/models/applet/applet.py:41 terminal/serializers/session.py:18 -#: terminal/serializers/session.py:40 terminal/serializers/storage.py:70 +#: terminal/models/applet/applet.py:41 terminal/serializers/session.py:19 +#: terminal/serializers/session.py:42 terminal/serializers/storage.py:70 msgid "Protocol" msgstr "协议" @@ -2055,7 +2066,7 @@ msgstr "改密" #: audits/const.py:35 settings/serializers/terminal.py:6 #: terminal/models/applet/host.py:26 terminal/models/component/terminal.py:163 -#: terminal/serializers/session.py:47 terminal/serializers/session.py:56 +#: terminal/serializers/session.py:49 terminal/serializers/session.py:63 msgid "Terminal" msgstr "终端" @@ -3549,15 +3560,15 @@ msgstr "系统信息" msgid "Publish the station message" msgstr "发布站内消息" -#: ops/ansible/inventory.py:82 +#: ops/ansible/inventory.py:92 msgid "No account available" msgstr "无可用账号" -#: ops/ansible/inventory.py:247 +#: ops/ansible/inventory.py:258 msgid "Ansible disabled" msgstr "Ansible 已禁用" -#: ops/ansible/inventory.py:263 +#: ops/ansible/inventory.py:274 msgid "Skip hosts below:" msgstr "跳过以下主机: " @@ -3827,7 +3838,7 @@ msgstr "保存后执行" msgid "Job type" msgstr "任务类型" -#: ops/serializers/job.py:57 terminal/serializers/session.py:48 +#: ops/serializers/job.py:57 terminal/serializers/session.py:50 msgid "Is finished" msgstr "是否完成" @@ -5300,34 +5311,23 @@ msgstr "资产列表排序" msgid "List page size" msgstr "资产列表每页数量" -#: settings/serializers/terminal.py:34 -msgid "Telnet login regex" -msgstr "Telnet 成功正则表达式" - -#: settings/serializers/terminal.py:35 -msgid "" -"Tips: The login success message varies with devices. if you cannot log in to " -"the device through Telnet, set this parameter" -msgstr "" -"提示: 不同设备登录成功提示不一样,所以如果 telnet 不能正常登录,可以这里设置" - -#: settings/serializers/terminal.py:38 +#: settings/serializers/terminal.py:33 msgid "Enable database proxy" msgstr "启用数据库组件" -#: settings/serializers/terminal.py:39 +#: settings/serializers/terminal.py:34 msgid "Enable Razor" msgstr "启用 Razor 服务" -#: settings/serializers/terminal.py:40 +#: settings/serializers/terminal.py:35 msgid "Enable SSH Client" msgstr "启用 SSH Client" -#: settings/serializers/terminal.py:51 +#: settings/serializers/terminal.py:46 msgid "Default graphics resolution" msgstr "默认图形化分辨率" -#: settings/serializers/terminal.py:52 +#: settings/serializers/terminal.py:47 msgid "" "Tip: Default resolution to use when connecting graphical assets in Luna pages" msgstr "提示:在Luna 页面中连接图形化资产时默认使用的分辨率" @@ -5998,7 +5998,7 @@ msgstr "回放" msgid "Date end" msgstr "结束日期" -#: terminal/models/session/session.py:47 terminal/serializers/session.py:55 +#: terminal/models/session/session.py:47 terminal/serializers/session.py:62 msgid "Command amount" msgstr "命令数量" @@ -6266,31 +6266,31 @@ msgstr "如果不同端点下的资产 IP 有冲突,使用资产标签实现" msgid "Asset IP" msgstr "资产 IP" -#: terminal/serializers/session.py:22 terminal/serializers/session.py:45 +#: terminal/serializers/session.py:23 terminal/serializers/session.py:47 msgid "Can replay" msgstr "是否可重放" -#: terminal/serializers/session.py:23 terminal/serializers/session.py:46 +#: terminal/serializers/session.py:24 terminal/serializers/session.py:48 msgid "Can join" msgstr "是否可加入" -#: terminal/serializers/session.py:24 terminal/serializers/session.py:49 +#: terminal/serializers/session.py:25 terminal/serializers/session.py:51 msgid "Can terminate" msgstr "是否可中断" -#: terminal/serializers/session.py:41 +#: terminal/serializers/session.py:43 msgid "User ID" msgstr "用户 ID" -#: terminal/serializers/session.py:42 +#: terminal/serializers/session.py:44 msgid "Asset ID" msgstr "资产 ID" -#: terminal/serializers/session.py:43 +#: terminal/serializers/session.py:45 msgid "Login from display" msgstr "登录来源名称" -#: terminal/serializers/session.py:50 +#: terminal/serializers/session.py:52 msgid "Terminal display" msgstr "终端显示" @@ -7882,6 +7882,16 @@ msgstr "旗舰版" msgid "Community edition" msgstr "社区版" +#~ msgid "Telnet login regex" +#~ msgstr "Telnet 成功正则表达式" + +#~ msgid "" +#~ "Tips: The login success message varies with devices. if you cannot log in " +#~ "to the device through Telnet, set this parameter" +#~ msgstr "" +#~ "提示: 不同设备登录成功提示不一样,所以如果 telnet 不能正常登录,可以这里设" +#~ "置" + #~ msgid "Role display" #~ msgstr "角色显示" From 6b9f40d5c19ecaac553fa3e554a1b18cfaa38e8c Mon Sep 17 00:00:00 2001 From: ibuler Date: Thu, 3 Aug 2023 16:52:15 +0800 Subject: [PATCH 094/177] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=20safe=20mod?= =?UTF-8?q?e?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/assets/const/protocol.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/assets/const/protocol.py b/apps/assets/const/protocol.py index e2a601618..553201237 100644 --- a/apps/assets/const/protocol.py +++ b/apps/assets/const/protocol.py @@ -196,7 +196,7 @@ class Protocol(ChoicesMixin, models.TextChoices): 'setting': { 'safe_mode': { 'type': 'bool', - 'default': True, + 'default': False, 'label': _('Safe mode'), 'help_text': _( 'When safe mode is enabled, some operations will be disabled, such as: ' From 2aacb07b15345a532ae9c48737258c8a05ad0efe Mon Sep 17 00:00:00 2001 From: Bai Date: Thu, 3 Aug 2023 18:23:42 +0800 Subject: [PATCH 095/177] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=20MAX=5FLIMIT?= =?UTF-8?q?=5FPER=5FPAGE,=20=E9=BB=98=E8=AE=A4=E5=80=BC=E4=BB=A5=E5=8F=8A?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E7=B1=BB=E5=9E=8B=E8=BD=AC=E6=8D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/jumpserver/conf.py | 3 +++ apps/jumpserver/rewriting/pagination.py | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/apps/jumpserver/conf.py b/apps/jumpserver/conf.py index eb339f8a1..2ba1a3124 100644 --- a/apps/jumpserver/conf.py +++ b/apps/jumpserver/conf.py @@ -567,6 +567,9 @@ class Config(dict): # FTP 文件上传下载备份阈值,单位(M),当值小于等于0时,不备份 'FTP_FILE_MAX_STORE': 100, + + # API 请求次数限制 + 'MAX_LIMIT_PER_PAGE': 100 } old_config_map = { diff --git a/apps/jumpserver/rewriting/pagination.py b/apps/jumpserver/rewriting/pagination.py index cd6ad2642..a924d854a 100644 --- a/apps/jumpserver/rewriting/pagination.py +++ b/apps/jumpserver/rewriting/pagination.py @@ -3,4 +3,4 @@ from rest_framework.pagination import LimitOffsetPagination class MaxLimitOffsetPagination(LimitOffsetPagination): - max_limit = settings.MAX_LIMIT_PER_PAGE or 100 + max_limit = settings.MAX_LIMIT_PER_PAGE From e424e3c31148835c609576696294e29016d8d853 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=90=B4=E5=B0=8F=E7=99=BD?= <296015668@qq.com> Date: Sat, 5 Aug 2023 14:18:27 +0800 Subject: [PATCH 096/177] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=20Dockerfile?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/Dockerfile b/Dockerfile index bc233dfd0..1badb89df 100644 --- a/Dockerfile +++ b/Dockerfile @@ -45,6 +45,7 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked,id=core \ && echo "no" | dpkg-reconfigure dash \ && rm -rf /var/lib/apt/lists/* +WORKDIR /opt RUN set -ex \ && cd /opt \ && \ @@ -53,6 +54,7 @@ RUN set -ex \ wget -O /opt/rust.tar.gz https://rust-lang.loongnix.cn/dist/2022-11-03/rust-1.65.0-loongarch64-unknown-linux-gnu.tar.xz; \ tar -xf /opt/rust.tar.gz -C /opt/rust-install --strip-components=1; \ cd /opt/rust-install && ./install.sh; \ + cd /opt; \ rm -rf /opt/rust.tar.gz /opt/rust-install; \ fi @@ -66,16 +68,7 @@ RUN cd utils && bash -ixeu build.sh ARG PIP_MIRROR=https://pypi.tuna.tsinghua.edu.cn/simple RUN --mount=type=cache,target=/root/.cache \ set -ex \ - && \ - if [ "${TARGETARCH}" == "loong64" ]; then \ - pip install https://download.jumpserver.org/pypi/simple/rpds_py/rpds_py-0.9.2-cp311-cp311-linux_loongarch64.whl; \ - pip install https://download.jumpserver.org/pypi/simple/cryptography/cryptography-41.0.2-cp311-cp311-linux_loongarch64.whl; \ - fi \ - && pip install poetry -i ${PIP_MIRROR} - -RUN --mount=type=cache,target=/root/.cache \ - --mount=type=cache,target=/root/.cargo \ - set -ex \ + && pip install poetry -i ${PIP_MIRROR} \ && poetry config virtualenvs.create false \ && poetry install From 7636255533eb973c1ad5e9b5c3ff2d8f491fb320 Mon Sep 17 00:00:00 2001 From: jiangweidong Date: Mon, 7 Aug 2023 09:37:24 +0800 Subject: [PATCH 097/177] =?UTF-8?q?feat:=20=E7=B3=BB=E7=BB=9F=E5=B7=A5?= =?UTF-8?q?=E5=85=B7=E6=94=B9=E4=B8=BA=E5=BC=82=E6=AD=A5=EF=BC=8C=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0tcpdump=E5=B7=A5=E5=85=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/common/utils/ip/utils.py | 5 +- apps/settings/tools/__init__.py | 6 ++ apps/settings/tools/nmap.py | 57 +++++++++++++++ apps/settings/{utils => tools}/ping.py | 50 +++++++------ apps/settings/tools/tcpdump.py | 98 ++++++++++++++++++++++++++ apps/settings/tools/telnet.py | 63 +++++++++++++++++ apps/settings/utils/__init__.py | 3 - apps/settings/utils/common.py | 54 ++++++++++++++ apps/settings/utils/nmap.py | 60 ---------------- apps/settings/utils/telnet.py | 47 ------------ apps/settings/ws.py | 78 ++++++++++++-------- pyproject.toml | 1 + requirements/requirements.txt | 1 + 13 files changed, 358 insertions(+), 165 deletions(-) create mode 100644 apps/settings/tools/__init__.py create mode 100644 apps/settings/tools/nmap.py rename apps/settings/{utils => tools}/ping.py (80%) create mode 100644 apps/settings/tools/tcpdump.py create mode 100644 apps/settings/tools/telnet.py delete mode 100644 apps/settings/utils/nmap.py delete mode 100644 apps/settings/utils/telnet.py diff --git a/apps/common/utils/ip/utils.py b/apps/common/utils/ip/utils.py index 14851ff27..4931bccbb 100644 --- a/apps/common/utils/ip/utils.py +++ b/apps/common/utils/ip/utils.py @@ -113,7 +113,6 @@ def get_ip_city(ip): def lookup_domain(domain): try: - return socket.gethostbyname(domain) + return socket.gethostbyname(domain), '' except Exception as e: - print("Cannot resolve %s: Unknown host, %s" % (domain, e)) - return None + return None, f'Cannot resolve {domain}: Unknown host, {e}' diff --git a/apps/settings/tools/__init__.py b/apps/settings/tools/__init__.py new file mode 100644 index 000000000..09154d4b2 --- /dev/null +++ b/apps/settings/tools/__init__.py @@ -0,0 +1,6 @@ +# coding: utf-8 +# +from .ping import * +from .telnet import * +from .nmap import * +from .tcpdump import * diff --git a/apps/settings/tools/nmap.py b/apps/settings/tools/nmap.py new file mode 100644 index 000000000..d58c46824 --- /dev/null +++ b/apps/settings/tools/nmap.py @@ -0,0 +1,57 @@ +import asyncio +import time +import nmap + +from common.utils.timezone import local_now_display +from settings.utils import generate_ips + + +def get_nmap_result(nm, ip, ports, timeout): + results = [] + nm.scan(ip, ports=ports, timeout=timeout) + tcp_port = nm[ip].get('tcp', {}) + udp_port = nm[ip].get('udp', {}) + results.append(f'PORT\tSTATE\tSERVICE') + for port, info in tcp_port.items(): + results.append(f"{port}\t{info.get('state', 'unknown')}\t{info.get('name', 'unknown')}") + for port, info in udp_port.items(): + results.append(f"{port}\t{info.get('state', 'unknown')}\t{info.get('name', 'unknown')}") + return results + + +async def once_nmap(nm, ip, ports, timeout, display): + await display(f'Starting Nmap at {local_now_display()} for {ip}') + try: + is_ok = True + loop = asyncio.get_running_loop() + results = await loop.run_in_executor(None, get_nmap_result, nm, ip, ports, timeout) + for result in results: + await display(result) + + except KeyError: + is_ok = False + await display(f'Host seems down.') + except Exception as err: + is_ok = False + await display(f"Error: %s" % err) + return is_ok + + +async def verbose_nmap(dest_ips, dest_ports=None, timeout=None, display=None): + if not display: + return + + ips = generate_ips(dest_ips) + dest_port = ','.join(list(dest_ports)) if dest_ports else None + + nm = nmap.PortScanner() + success_num, start_time = 0, time.time() + nmap_version = '.'.join(map(lambda x: str(x), nm.nmap_version())) + await display(f'[Summary] Nmap (v{nmap_version}): {len(ips)} addresses were scanned') + for ip in ips: + ok = await once_nmap(nm, str(ip), dest_port, timeout, display) + if ok: + success_num += 1 + await display() + await display(f'[Done] Nmap: {len(ips)} IP addresses ({success_num} hosts up) ' + f'scanned in {round(time.time() - start_time, 2)} seconds') diff --git a/apps/settings/utils/ping.py b/apps/settings/tools/ping.py similarity index 80% rename from apps/settings/utils/ping.py rename to apps/settings/tools/ping.py index cb9e5e544..556bb9e5b 100644 --- a/apps/settings/utils/ping.py +++ b/apps/settings/tools/ping.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # - +import asyncio import os import select import socket @@ -23,16 +23,16 @@ def checksum(source_string): for count in range(0, count_to, 2): this = source_string[count + 1] * 256 + source_string[count] sum = sum + this - sum = sum & 0xffffffff # Necessary? + sum &= 0xffffffff # Necessary? if count_to < len(source_string): - sum = sum + ord(source_string[len(source_string) - 1]) - sum = sum & 0xffffffff # Necessary? + sum += ord(source_string[len(source_string) - 1]) + sum &= 0xffffffff # Necessary? sum = (sum >> 16) + (sum & 0xffff) - sum = sum + (sum >> 16) + sum += sum >> 16 answer = ~sum - answer = answer & 0xffff + answer &= 0xffff # Swap bytes. Bugger me if I know why. answer = answer >> 8 | (answer << 8 & 0xff00) @@ -61,7 +61,7 @@ def receive_one_ping(my_socket, id, timeout): time_sent = struct.unpack("d", received_packet[28: 28 + bytes])[0] return time_received - time_sent - time_left = time_left - how_long_in_select + time_left -= how_long_in_select if time_left <= 0: return @@ -118,7 +118,7 @@ def ping(dest_addr, timeout, psize, flag=0): raise # raise the original error process_pre = os.getpid() & 0xFF00 - flag = flag & 0x00FF + flag &= 0x00FF my_id = process_pre | flag send_one_ping(my_socket, dest_addr, my_id, psize) @@ -128,38 +128,42 @@ def ping(dest_addr, timeout, psize, flag=0): return delay -def verbose_ping(dest_ip, timeout=2, count=5, psize=64, display=None): +async def verbose_ping(dest_ip, timeout=2, count=5, psize=64, display=None): """ Send `count' ping with `psize' size to `dest_addr' with the given `timeout' and display the result. """ - ip = lookup_domain(dest_ip) - if not ip: + if not display: return - if display is None: - display = print + + ip, err = lookup_domain(dest_ip) + if not ip: + await display(err) + return + + await display("PING %s (%s): 56 data bytes" % (dest_ip, ip)) + await asyncio.sleep(0.1) error_count = 0 - display("PING %s (%s): 56 data bytes" % (dest_ip, ip)) for i in range(count): try: delay = ping(dest_ip, timeout, psize) except socket.gaierror as e: - display("failed. (socket error: '%s')" % str(e)) + await display("Failed (socket error: '%s')" % str(e)) error_count += 1 break if delay is None: - display("Request timeout for icmp_seq %i" % i) + await display("Request timeout for icmp_seq %i" % i) error_count += 1 else: delay *= 1000 - display("64 bytes from %s: icmp_seq=0 ttl=115 time=%.3f ms" % (ip, delay)) - time.sleep(1) - display(f'--- {dest_ip} ping statistics ---') - display(f'{count} packets transmitted, ' - f'{count - error_count} packets received, ' - f'{(error_count / count) * 100}% packet loss') - print() + await display("64 bytes from %s: icmp_seq=0 ttl=115 time=%.3f ms" % (ip, delay)) + await asyncio.sleep(1) + + await display(f'--- {dest_ip} ping statistics ---') + await display(f'{count} packets transmitted, ' + f'{count - error_count} packets received, ' + f'{(error_count / count) * 100}% packet loss') if __name__ == "__main__": diff --git a/apps/settings/tools/tcpdump.py b/apps/settings/tools/tcpdump.py new file mode 100644 index 000000000..2b5412c15 --- /dev/null +++ b/apps/settings/tools/tcpdump.py @@ -0,0 +1,98 @@ +import asyncio +import netifaces +import socket +import struct + +from common.utils.timezone import local_now_display +from settings.utils import generate_ips, generate_ports + + +async def once_tcpdump( + interface, src_ips, src_ports, dest_ips, dest_ports, display, stop_event +): + loop = asyncio.get_event_loop() + s = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.ntohs(0x0003)) + s.bind((interface, 0)) + s.setblocking(False) + while not stop_event.is_set(): + try: + packet = await loop.sock_recv(s, 65535) + except BlockingIOError: + await asyncio.sleep(0.1) + # 解析IP数据包 + ip_header = packet[14:34] + ip_hdr = struct.unpack('!BBHHHBBH4s4s', ip_header) + # 判断是否为TCP数据包 + protocol = ip_hdr[6] + if protocol != 6: + continue + # 解析TCP数据包 + tcp_header = packet[34:54] + tcp_hdr = struct.unpack('!HHLLBBHHH', tcp_header) + # 获取源地址、源端口号、目标地址、目标端口等信息 + src_ip, dest_ip = map(lambda x: socket.inet_ntoa(x), ip_hdr[8:10]) + src_port, dest_port = tcp_hdr[0], tcp_hdr[1] + # 获取数据包类型和长度 + packet_type = socket.htons(ip_hdr[6]) + packet_len = len(packet) + # 获取TCP标志位、序号、确认号、部分数据等信息 + seq, ack, flags = tcp_hdr[2], tcp_hdr[3], tcp_hdr[5] + data = packet[54:] + # 如果过滤的参数[源地址、源端口等]为空,则不过滤 + # 各个过滤参数之间为 `且` 的关系 + green_light = True + if src_ips and src_ip not in src_ips: + green_light = False + if src_ports and src_port not in src_ports: + green_light = False + if dest_ips and dest_ip not in dest_ips: + green_light = False + if dest_ports and dest_port not in dest_ports: + green_light = False + if not green_light: + continue + + results = [ + f'[{interface}][{local_now_display()}] {src_ip}:{src_port} -> ' + f'{dest_ip}:{dest_port} ({packet_type}, {packet_len} bytes)', + f'\tFlags: {flags} Seq: {seq}, Ack: {ack}', f'\tData: {data}' + ] + for r in results: + await display(r) + + +def list_show(items, default='all'): + return ','.join(map(str, items)) or default + + +async def verbose_tcpdump(interfaces, src_ips, src_ports, dest_ips, dest_ports, display=None): + if not display: + return + + stop_event = asyncio.Event() + valid_interface = netifaces.interfaces() + if interfaces: + valid_interface = set(netifaces.interfaces()) & set(interfaces) + + src_ips = generate_ips(src_ips) + src_ports = generate_ports(src_ports) + dest_ips = generate_ips(dest_ips) + dest_ports = generate_ports(dest_ports) + + summary = [ + f"[Summary] Tcpdump filter info: ", + f"Interface: [{list_show(valid_interface)}]", + f"Source address: [{list_show(src_ips)}]", + f"source port: [{list_show(src_ports)}]", + f"Destination address: [{list_show(dest_ips)}]", + f"Destination port: [{list_show(dest_ports)}]", + ] + for s in summary: + await display(s) + + params = [src_ips, src_ports, dest_ips, dest_ports, display, stop_event] + tasks = [ + asyncio.create_task(once_tcpdump(i, *params)) for i in valid_interface + ] + await asyncio.gather(*tasks) + stop_event.set() diff --git a/apps/settings/tools/telnet.py b/apps/settings/tools/telnet.py new file mode 100644 index 000000000..b54a393d8 --- /dev/null +++ b/apps/settings/tools/telnet.py @@ -0,0 +1,63 @@ +# -*- coding: utf-8 -*- +# +import asyncio + +from common.utils import lookup_domain + +PROMPT_REGEX = r'[\<|\[](.*)[\>|\]]' + + +async def telnet(dest_addr, port_number=23, timeout=10): + try: + reader, writer = await asyncio.wait_for( + asyncio.open_connection(dest_addr, port_number), timeout + ) + except asyncio.TimeoutError: + return False, 'Timeout' + except (ConnectionRefusedError, OSError) as e: + return False, str(e) + try: + # 发送命令 + writer.write(b"command\r\n") + await writer.drain() + # 读取响应 + response = await reader.readuntil() + except asyncio.TimeoutError: + writer.close() + await writer.wait_closed() + return False, 'Timeout' + writer.close() + await writer.wait_closed() + return True, response.decode('utf-8', 'ignore') + + +async def verbose_telnet(dest_ip, dest_port=23, timeout=10, display=None): + if not display: + return + + ip, err = lookup_domain(dest_ip) + if not ip: + await display(err) + return + + await display(f'Trying {dest_ip} ({ip}:{dest_port})') + try: + is_connective, resp = await telnet(dest_ip, dest_port, timeout) + if is_connective: + msg = f'Connected to {dest_ip} {dest_port} {resp}.\r\n' \ + f'Connection closed by foreign host.' + else: + msg = f'Unable to connect to remote host\r\n' \ + f'Reason: {resp}' + except Exception as e: + msg = 'Error: %s' % e + await display(msg) + + +if __name__ == "__main__": + print(verbose_telnet(dest_addr='1.1.1.1', port_number=2222)) + print(verbose_telnet(dest_addr='baidu.com', port_number=80)) + print(verbose_telnet(dest_addr='baidu.com', port_number=8080)) + print(verbose_telnet(dest_addr='192.168.4.1', port_number=2222)) + print(verbose_telnet(dest_addr='192.168.4.1', port_number=2223)) + print(verbose_telnet(dest_addr='ssssss', port_number=-1)) diff --git a/apps/settings/utils/__init__.py b/apps/settings/utils/__init__.py index 8983df3ad..91d05860e 100644 --- a/apps/settings/utils/__init__.py +++ b/apps/settings/utils/__init__.py @@ -3,6 +3,3 @@ from .ldap import * from .common import * -from .ping import * -from .telnet import * -from .nmap import * diff --git a/apps/settings/utils/common.py b/apps/settings/utils/common.py index 3d73e8cdd..e549f9b8c 100644 --- a/apps/settings/utils/common.py +++ b/apps/settings/utils/common.py @@ -1,6 +1,7 @@ # coding: utf-8 from jumpserver.context_processor import default_interface from django.conf import settings +from IPy import IP def get_interface_setting_or_default(): @@ -12,3 +13,56 @@ def get_interface_setting_or_default(): def get_login_title(): return get_interface_setting_or_default()['login_title'] + + +def generate_ips(ip_string): + # 支持的格式 + # 192.168.1.1,192.168.1.2 + # 192.168.1.1-12 | 192.168.1.1-192.168.1.12 | 192.168.1.0/30 | 192.168.1.1 + ips = [] + ip_list = ip_string.split(',') + if len(ip_list) > 1: + for ip in ip_list: + try: + ips.append(str(IP(ip))) + except ValueError: + pass + return ips + + ip_list = ip_string.split('-') + try: + if len(ip_list) == 2: + start_ip, end_ip = ip_list + if ip_list[1].find('.') == -1: + end_ip = start_ip[:start_ip.rindex('.') + 1] + end_ip + for ip in range(IP(start_ip).int(), IP(end_ip).int() + 1): + ips.extend((str(ip) for ip in IP(ip))) + else: + ips.extend((str(ip) for ip in IP(ip_list[0]))) + except ValueError: + ips = [] + return ips + + +def is_valid_port(port): + valid = True + try: + port = int(port) + if port > 65535 or port < 1: + valid = False + except (TypeError, ValueError): + valid = False + return valid + +def generate_ports(ports): + port_list = [] + if isinstance(ports, int): + port_list.append(ports) + elif isinstance(ports, str): + port_list.extend( + [int(p) for p in ports.split(',') if p.isdigit()] + ) + elif isinstance(ports, list): + port_list = ports + port_list = list(map(int, filter(is_valid_port, port_list))) + return port_list diff --git a/apps/settings/utils/nmap.py b/apps/settings/utils/nmap.py deleted file mode 100644 index 6e4282678..000000000 --- a/apps/settings/utils/nmap.py +++ /dev/null @@ -1,60 +0,0 @@ -import time -import nmap - -from IPy import IP - -from common.utils.timezone import local_now_display - - -def generate_ips(ip_string): - # 支持的格式 - # 192.168.1.1-12 | 192.168.1.1-192.168.1.12 | 192.168.1.0/30 | 192.168.1.1 - ip_list = ip_string.split('-') - ips = [] - try: - if len(ip_list) == 2: - start_ip, end_ip = ip_list - if ip_list[1].find('.') == -1: - end_ip = start_ip[:start_ip.rindex('.') + 1] + end_ip - for ip in range(IP(start_ip).int(), IP(end_ip).int() + 1): - ips.extend(IP(ip)) - else: - ips.extend(IP(ip_list[0])) - except Exception: - ips = [] - return ips - - -def once_nmap(nm, ip, ports, timeout, display): - nmap_version = '.'.join(map(lambda x: str(x), nm.nmap_version())) - display(f'Starting Nmap {nmap_version} at {local_now_display()} for {ip}') - try: - is_ok = True - nm.scan(ip, arguments='-sS -sU -F', ports=ports, timeout=timeout) - tcp_port = nm[ip].get('tcp', {}) - udp_port = nm[ip].get('udp', {}) - display(f'PORT\tSTATE\tSERVICE') - for port, info in tcp_port.items(): - display(f"{port}\t{info.get('state', 'unknown')}\t{info.get('name', 'unknown')}") - for port, info in udp_port.items(): - display(f"{port}\t{info.get('state', 'unknown')}\t{info.get('name', 'unknown')}") - except Exception: - is_ok = False - display(f'Nmap scan report for {ip} error.') - return is_ok - - -def verbose_nmap(dest_ip, dest_port=None, timeout=None, display=print): - dest_port = ','.join(list(dest_port)) if dest_port else None - - ips = generate_ips(dest_ip) - nm = nmap.PortScanner() - success_num, start_time = 0, time.time() - display(f'[Summary] Nmap: {len(ips)} IP addresses were scanned') - for ip in ips: - ok = once_nmap(nm, str(ip), dest_port, timeout, display) - if ok: - success_num += 1 - display('') - display(f'[Done] Nmap: {len(ips)} IP addresses ({success_num} hosts up) ' - f'scanned in {round(time.time() - start_time, 2)} seconds') diff --git a/apps/settings/utils/telnet.py b/apps/settings/utils/telnet.py deleted file mode 100644 index 9cb0a2c0b..000000000 --- a/apps/settings/utils/telnet.py +++ /dev/null @@ -1,47 +0,0 @@ -# -*- coding: utf-8 -*- -# -import socket -import telnetlib - -from common.utils import lookup_domain - -PROMPT_REGEX = r'[\<|\[](.*)[\>|\]]' - - -def telnet(dest_addr, port_number=23, timeout=10): - try: - connection = telnetlib.Telnet(dest_addr, port_number, timeout) - except (ConnectionRefusedError, socket.timeout, socket.gaierror) as e: - return False, str(e) - expected_regexes = [bytes(PROMPT_REGEX, encoding='ascii')] - index, prompt_regex, output = connection.expect(expected_regexes, timeout=3) - return True, output.decode('utf-8', 'ignore') - - -def verbose_telnet(dest_ip, dest_port=23, timeout=10, display=None): - if display is None: - display = print - ip = lookup_domain(dest_ip) - if not ip: - return - msg = 'Trying %s (%s:%s)' % (dest_ip, ip, dest_port) - display(msg) - try: - is_connective, resp = telnet(dest_ip, dest_port, timeout) - if is_connective: - template = 'Connected to {0} {1}.\r\n{2}Connection closed by foreign host.' - else: - template = 'telnet: connect to {0} {1} {2}\r\ntelnet: Unable to connect to remote host' - msg = template.format(dest_ip, dest_port, resp) - except Exception as e: - msg = 'Error: %s' % e - display(msg) - - -if __name__ == "__main__": - print(verbose_telnet(dest_addr='1.1.1.1', port_number=2222)) - print(verbose_telnet(dest_addr='baidu.com', port_number=80)) - print(verbose_telnet(dest_addr='baidu.com', port_number=8080)) - print(verbose_telnet(dest_addr='192.168.4.1', port_number=2222)) - print(verbose_telnet(dest_addr='192.168.4.1', port_number=2223)) - print(verbose_telnet(dest_addr='ssssss', port_number=-1)) diff --git a/apps/settings/ws.py b/apps/settings/ws.py index f5752e2a1..b15d61ea7 100644 --- a/apps/settings/ws.py +++ b/apps/settings/ws.py @@ -1,53 +1,73 @@ # -*- coding: utf-8 -*- # - import json -from channels.generic.websocket import JsonWebsocketConsumer +from channels.generic.websocket import AsyncJsonWebsocketConsumer from common.db.utils import close_old_connections from common.utils import get_logger -from .utils import verbose_ping, verbose_telnet, verbose_nmap +from .tools import verbose_ping, verbose_telnet, verbose_nmap, verbose_tcpdump + logger = get_logger(__name__) -class ToolsWebsocket(JsonWebsocketConsumer): +class ToolsWebsocket(AsyncJsonWebsocketConsumer): - def connect(self): + async def connect(self): user = self.scope["user"] if user.is_authenticated: - self.accept() + await self.accept() else: - self.close() + await self.close() - def send_msg(self, msg): - self.send_json({'msg': msg + '\r\n'}) + async def send_msg(self, msg=''): + await self.send_json({'msg': msg + '\r\n'}) - def imitate_ping(self, dest_ip, timeout=3, count=5, psize=64): - """ - Send `count' ping with `psize' size to `dest_ip' with - the given `timeout' and display the result. - """ - logger.info('receive request ping {}'.format(dest_ip)) - verbose_ping(dest_ip, timeout, count, psize, display=self.send_msg) + async def imitate_ping(self, dest_ip, timeout=3, count=5, psize=64): + params = { + 'dest_ip': dest_ip, 'timeout': timeout, + 'count': count, 'psize': psize + } + logger.info(f'Receive request ping: {params}') + await verbose_ping(display=self.send_msg, **params) - def imitate_telnet(self, dest_ip, dest_port=23, timeout=10): - logger.info('receive request telnet {}'.format(dest_ip)) - verbose_telnet(dest_ip, dest_port, timeout, display=self.send_msg) + async def imitate_telnet(self, dest_ip, dest_port=23, timeout=10): + params = { + 'dest_ip': dest_ip, 'dest_port': dest_port, 'timeout': timeout, + } + logger.info(f'Receive request telnet: {params}') + await verbose_telnet(display=self.send_msg, **params) - def imitate_nmap(self, dest_ip, dest_port=None, timeout=None): - logger.info('receive request nmap {}'.format(dest_ip)) - verbose_nmap(dest_ip, dest_port, timeout, display=self.send_msg) + async def imitate_nmap(self, dest_ips, dest_ports=None, timeout=None): + params = { + 'dest_ips': dest_ips, 'dest_ports': dest_ports, 'timeout': timeout, + } + logger.info(f'Receive request nmap: {params}') + await verbose_nmap(display=self.send_msg, **params) - def receive(self, text_data=None, bytes_data=None, **kwargs): + async def imitate_tcpdump( + self, interfaces=None, src_ips='', + src_ports='', dest_ips='', dest_ports='' + ): + params = { + 'interfaces': interfaces, 'src_ips': src_ips, 'src_ports': src_ports, + 'dest_ips': dest_ips, 'dest_ports': dest_ports + } + logger.info(f'Receive request tcpdump: {params}') + await verbose_tcpdump(display=self.send_msg, **params) + + async def receive(self, text_data=None, bytes_data=None, **kwargs): data = json.loads(text_data) tool_type = data.pop('tool_type', 'Ping') + try: + tool_func = getattr(self, f'imitate_{tool_type.lower()}') + await tool_func(**data) + except Exception as error: + await self.send_msg('Exception: %s' % error) + await self.send_msg() + await self.close() - tool_func = getattr(self, f'imitate_{tool_type.lower()}') - tool_func(**data) - self.close() - - def disconnect(self, code): - self.close() + async def disconnect(self, code): + await self.close() close_old_connections() diff --git a/pyproject.toml b/pyproject.toml index 3df29cc7d..860e65003 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -140,6 +140,7 @@ pympler = "1.0.1" hvac = "1.1.1" pyhcl = "0.4.4" ipy = "1.1" +netifaces = "^0.11.0" [tool.poetry.group.dev.dependencies] diff --git a/requirements/requirements.txt b/requirements/requirements.txt index 221421582..50b2fea41 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -94,6 +94,7 @@ openapi-codec==1.3.2 Pillow==10.0.0 pytz==2023.3 # Runtime +netifaces==0.11.0 django-proxy==1.2.2 channels-redis==4.1.0 python-daemon==3.0.1 From 49662b308d11930f2b6a40a6e9954e17ea871c2d Mon Sep 17 00:00:00 2001 From: Eric Date: Fri, 4 Aug 2023 16:53:18 +0800 Subject: [PATCH 098/177] =?UTF-8?q?feat:=20Chrome=20=E5=BA=94=E7=94=A8?= =?UTF-8?q?=E9=80=9A=E8=BF=87=E5=B9=B3=E5=8F=B0=E7=9A=84=E5=AE=89=E5=85=A8?= =?UTF-8?q?=E6=A8=A1=E5=BC=8F=E5=8A=A8=E6=80=81=E5=8A=A0=E8=BD=BD=E6=89=A9?= =?UTF-8?q?=E5=B1=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/terminal/applets/chrome/app.py | 10 ++++++---- apps/terminal/applets/chrome/common.py | 1 + 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/apps/terminal/applets/chrome/app.py b/apps/terminal/applets/chrome/app.py index b19e219d1..14654386e 100644 --- a/apps/terminal/applets/chrome/app.py +++ b/apps/terminal/applets/chrome/app.py @@ -221,10 +221,6 @@ def default_chrome_driver_options(): options.add_argument('--ignore-certificate-errors-spki-list') options.add_argument('--allow-running-insecure-content') - # 加载 extensions - extension_paths = load_extensions() - for extension_path in extension_paths: - options.add_argument('--load-extension={}'.format(extension_path)) # 禁用开发者工具 options.add_argument("--disable-dev-tools") # 禁用 密码管理器弹窗 @@ -248,6 +244,12 @@ class AppletApplication(BaseApplication): self._chrome_options = default_chrome_driver_options() self._chrome_options.add_argument("--app={}".format(self.asset.address)) self._chrome_options.add_argument("--user-data-dir={}".format(self._tmp_user_dir.name)) + protocol_setting = self.platform.get_protocol_setting(self.protocol) + if protocol_setting and protocol_setting.safe_mode: + # 加载 extensions + extension_paths = load_extensions() + for extension_path in extension_paths: + self._chrome_options.add_argument('--load-extension={}'.format(extension_path)) @wrapper_progress_bar def run(self): diff --git a/apps/terminal/applets/chrome/common.py b/apps/terminal/applets/chrome/common.py index 06d23f9fd..161150a0d 100644 --- a/apps/terminal/applets/chrome/common.py +++ b/apps/terminal/applets/chrome/common.py @@ -160,6 +160,7 @@ class ProtocolSetting(DictObj): password_selector: str submit_selector: str script: list[Step] + safe_mode: bool class PlatformProtocolSetting(DictObj): From c2f1e4f4f6d310bc2f46e6257766cc61fb45b346 Mon Sep 17 00:00:00 2001 From: jiangweidong Date: Mon, 7 Aug 2023 11:07:28 +0800 Subject: [PATCH 099/177] =?UTF-8?q?fix:=20=E6=B7=BB=E5=8A=A0=E5=8D=8E?= =?UTF-8?q?=E4=B8=BA=E4=BA=91=E4=BE=9D=E8=B5=96=E5=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- poetry.lock | 65 +++++++++++++++++++++++++++++++++++++++++++++++++- pyproject.toml | 2 ++ 2 files changed, 66 insertions(+), 1 deletion(-) diff --git a/poetry.lock b/poetry.lock index db5ea8851..11440434f 100644 --- a/poetry.lock +++ b/poetry.lock @@ -3014,6 +3014,50 @@ type = "legacy" url = "https://pypi.tuna.tsinghua.edu.cn/simple" reference = "tsinghua" +[[package]] +name = "huaweicloudsdkcore" +version = "3.1.52" +description = "HuaweiCloud SDK Python Core" +optional = false +python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*" +files = [ + {file = "huaweicloudsdkcore-3.1.52-py2.py3-none-any.whl", hash = "sha256:1c8abc831e4f28460c41fcf46112e6fc7b38035b639d9899b04b8753d8bc835d"}, +] + +[package.dependencies] +PyYAML = ">=5.4.1" +requests = "*" +requests-toolbelt = ">=0.10.1" +simplejson = ">=3.18.0" +six = ">=1.16.0" +typing-extensions = "*" + +[package.extras] +python-version-2-7- = ["certifi (>=2022.12.7)", "configparser (>=4.0.2)", "futures (>=3.3.0)"] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "huaweicloudsdkecs" +version = "3.1.52" +description = "ECS" +optional = false +python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*" +files = [ + {file = "huaweicloudsdkecs-3.1.52-py2.py3-none-any.whl", hash = "sha256:39631ec15082b438c10dbc310619cea5cd71319ac95caf9989666193fd456de3"}, +] + +[package.dependencies] +huaweicloudsdkcore = ">=3.1.52" + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "humanize" version = "4.7.0" @@ -5994,6 +6038,25 @@ type = "legacy" url = "https://pypi.tuna.tsinghua.edu.cn/simple" reference = "tsinghua" +[[package]] +name = "requests-toolbelt" +version = "1.0.0" +description = "A utility belt for advanced users of python-requests" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "requests-toolbelt-1.0.0.tar.gz", hash = "sha256:7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6"}, + {file = "requests_toolbelt-1.0.0-py2.py3-none-any.whl", hash = "sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06"}, +] + +[package.dependencies] +requests = ">=2.0.1,<3.0.0" + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + [[package]] name = "resolvelib" version = "0.8.1" @@ -7175,4 +7238,4 @@ reference = "tsinghua" [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "0b6107439bac42ee20efd101c5b033857124c63c534eacaa5f03e93c581e2422" +content-hash = "acdb324e0081968235e843be40803734f3ab814de44c90c4367fa0ef0801759d" diff --git a/pyproject.toml b/pyproject.toml index 860e65003..069fd91a4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -175,6 +175,8 @@ psycopg2-binary = "2.9.6" pymssql = "2.2.8" psycopg2 = "2.9.6" ucloud-sdk-python3 = "0.11.50" +huaweicloudsdkecs = "3.1.52" +huaweicloudsdkcore = "3.1.52" [[tool.poetry.source]] name = "tsinghua" From 38803518fcbbe3c3e0f4063f9f9e52615508f4c0 Mon Sep 17 00:00:00 2001 From: jiangweidong Date: Mon, 7 Aug 2023 12:11:35 +0800 Subject: [PATCH 100/177] =?UTF-8?q?perf:=20=E7=B1=BB=E5=9E=8B=E6=A0=91?= =?UTF-8?q?=E5=8F=B3=E5=87=BB=E5=8F=AF=E4=BB=A5=E8=8E=B7=E5=8F=96=E8=8A=82?= =?UTF-8?q?=E7=82=B9=E4=B8=8B=E6=89=80=E6=9C=89=E7=9A=84=E8=B5=84=E4=BA=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/perms/api/user_permission/tree/node_with_asset.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/perms/api/user_permission/tree/node_with_asset.py b/apps/perms/api/user_permission/tree/node_with_asset.py index 5469c6ed3..72080247a 100644 --- a/apps/perms/api/user_permission/tree/node_with_asset.py +++ b/apps/perms/api/user_permission/tree/node_with_asset.py @@ -188,6 +188,8 @@ class UserPermedNodeChildrenWithAssetsAsCategoryTreeApi( _type = meta.get('_type') if _type: node['type'] = _type + meta.setdefault('data', {}) + node['meta'] = meta nodes.append(node) if not self.is_sync: From ecca64ef425ab7b961cc43d716139910582af8bf Mon Sep 17 00:00:00 2001 From: jiangweidong Date: Mon, 7 Aug 2023 13:43:09 +0800 Subject: [PATCH 101/177] =?UTF-8?q?perf:=20Dockerfile=E4=B8=AD=E5=AE=89?= =?UTF-8?q?=E8=A3=85nmap=E5=B7=A5=E5=85=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Dockerfile b/Dockerfile index 1badb89df..7d6b2b35a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -30,6 +30,7 @@ ARG TOOLS=" \ git-lfs \ unzip \ xz-utils \ + nmap \ wget" ARG APT_MIRROR=http://mirrors.ustc.edu.cn From f588a112fb395a77e87e03828427a4d077ec290e Mon Sep 17 00:00:00 2001 From: jiangweidong Date: Mon, 7 Aug 2023 13:46:45 +0800 Subject: [PATCH 102/177] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9nmap=E4=BD=8D?= =?UTF-8?q?=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 7d6b2b35a..42ef5566c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -30,7 +30,6 @@ ARG TOOLS=" \ git-lfs \ unzip \ xz-utils \ - nmap \ wget" ARG APT_MIRROR=http://mirrors.ustc.edu.cn @@ -92,6 +91,7 @@ ARG TOOLS=" \ telnet \ unzip \ vim \ + nmap \ wget" ARG APT_MIRROR=http://mirrors.ustc.edu.cn From c21fcacf70ef638e182de78fc00762e24e6c4c47 Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Mon, 7 Aug 2023 14:55:17 +0800 Subject: [PATCH 103/177] =?UTF-8?q?perf:=20=E6=A3=80=E6=B5=8B=E4=B8=8D?= =?UTF-8?q?=E5=B8=B8=E7=94=A8=E8=B4=A6=E5=8F=B7=20(#11205)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: feng <1304903146@qq.com> --- apps/jumpserver/conf.py | 1 + apps/jumpserver/settings/custom.py | 1 + apps/settings/serializers/security.py | 5 +++++ apps/users/tasks.py | 31 +++++++++++++++++++++++---- 4 files changed, 34 insertions(+), 4 deletions(-) diff --git a/apps/jumpserver/conf.py b/apps/jumpserver/conf.py index 2ba1a3124..a76d02075 100644 --- a/apps/jumpserver/conf.py +++ b/apps/jumpserver/conf.py @@ -487,6 +487,7 @@ class Config(dict): 'SECURITY_LUNA_REMEMBER_AUTH': True, 'SECURITY_WATERMARK_ENABLED': True, 'SECURITY_MFA_VERIFY_TTL': 3600, + 'SECURITY_UNCOMMON_USERS_TTL': 30, 'VERIFY_CODE_TTL': 60, 'SECURITY_SESSION_SHARE': True, 'SECURITY_CHECK_DIFFERENT_CITY_LOGIN': True, diff --git a/apps/jumpserver/settings/custom.py b/apps/jumpserver/settings/custom.py index 71c90cef3..78b888ced 100644 --- a/apps/jumpserver/settings/custom.py +++ b/apps/jumpserver/settings/custom.py @@ -54,6 +54,7 @@ SECURITY_PASSWORD_RULES = [ ] VERIFY_CODE_TTL = CONFIG.VERIFY_CODE_TTL SECURITY_MFA_VERIFY_TTL = CONFIG.SECURITY_MFA_VERIFY_TTL +SECURITY_UNCOMMON_USERS_TTL = CONFIG.SECURITY_UNCOMMON_USERS_TTL SECURITY_VIEW_AUTH_NEED_MFA = CONFIG.SECURITY_VIEW_AUTH_NEED_MFA SECURITY_SERVICE_ACCOUNT_REGISTRATION = CONFIG.SECURITY_SERVICE_ACCOUNT_REGISTRATION SECURITY_LOGIN_CAPTCHA_ENABLED = CONFIG.SECURITY_LOGIN_CAPTCHA_ENABLED diff --git a/apps/settings/serializers/security.py b/apps/settings/serializers/security.py index 329cc8ebe..8c000cd8e 100644 --- a/apps/settings/serializers/security.py +++ b/apps/settings/serializers/security.py @@ -190,6 +190,11 @@ class SecuritySettingSerializer(SecurityPasswordRuleSerializer, SecurityAuthSeri required=True, label=_('Session share'), help_text=_("Enabled, Allows user active session to be shared with other users") ) + SECURITY_UNCOMMON_USERS_TTL = serializers.IntegerField( + min_value=30, max_value=99999, required=False, + label=_('Unused user timeout (day)'), + help_text=_("Detect infrequent users daily and disable them if they exceed the predetermined time limit.") + ) SECURITY_CHECK_DIFFERENT_CITY_LOGIN = serializers.BooleanField( required=False, label=_('Remote Login Protection'), help_text=_( diff --git a/apps/users/tasks.py b/apps/users/tasks.py index bc146bf12..c363940fe 100644 --- a/apps/users/tasks.py +++ b/apps/users/tasks.py @@ -2,15 +2,18 @@ # from celery import shared_task +from django.conf import settings +from django.db.models import Max from django.utils import timezone from django.utils.translation import gettext_lazy as _ +from audits.models import UserLoginLog from common.const.crontab import CRONTAB_AT_AM_TEN, CRONTAB_AT_PM_TWO from common.utils import get_logger -from ops.celery.decorator import after_app_ready_start -from ops.celery.utils import ( - create_or_update_celery_periodic_tasks -) +from common.utils.timezone import utc_now +from ops.celery.decorator import after_app_ready_start, register_as_period_task +from ops.celery.utils import create_or_update_celery_periodic_tasks +from orgs.utils import tmp_to_root_org from users.notifications import PasswordExpirationReminderMsg from users.notifications import UserExpirationReminderMsg from .models import User @@ -75,3 +78,23 @@ def check_user_expired_periodic(): } } create_or_update_celery_periodic_tasks(tasks) + + +@shared_task(verbose_name=_('Check unused users')) +@register_as_period_task(crontab=CRONTAB_AT_PM_TWO) +@tmp_to_root_org() +def check_unused_users(): + now = utc_now() + unused_usernames = [] + usernames_max_datetime = UserLoginLog.objects.values('username').annotate(max_datetime=Max('datetime')) + for i in usernames_max_datetime: + username = i['username'] + max_datetime = i['max_datetime'] + uncommon_users_ttl = settings.SECURITY_UNCOMMON_USERS_TTL + if (now - max_datetime).seconds > uncommon_users_ttl * 24 * 60 * 60: + unused_usernames.append(username) + + if not unused_usernames: + return + + User.objects.filter(username__in=unused_usernames).update(is_active=False) From 0a9726d84540cea853970c7b204911fb4da5c204 Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Mon, 7 Aug 2023 15:50:09 +0800 Subject: [PATCH 104/177] =?UTF-8?q?feat:=20=E8=B4=A6=E5=8F=B7=E5=A4=87?= =?UTF-8?q?=E4=BB=BD=E5=AF=86=E9=92=A5=E6=8B=86=E5=88=86=20(#11199)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: feng <1304903146@qq.com> --- .../automations/backup_account/handlers.py | 36 +++++++++-- .../0013_account_backup_recipients.py | 59 +++++++++++++++++++ .../models/automations/backup_account.py | 33 ++++++----- apps/accounts/serializers/account/backup.py | 6 +- 4 files changed, 109 insertions(+), 25 deletions(-) create mode 100644 apps/accounts/migrations/0013_account_backup_recipients.py diff --git a/apps/accounts/automations/backup_account/handlers.py b/apps/accounts/automations/backup_account/handlers.py index 7b087b101..e708e8d2d 100644 --- a/apps/accounts/automations/backup_account/handlers.py +++ b/apps/accounts/automations/backup_account/handlers.py @@ -71,8 +71,22 @@ class AssetAccountHandler(BaseAccountHandler): ) return filename + @staticmethod + def handler_secret(data, section): + for account_data in data: + secret = account_data.get('secret') + if not secret: + continue + length = len(secret) + index = length // 2 + if section == "front": + secret = secret[:index] + '*' * (length - index) + elif section == "back": + secret = '*' * (length - index) + secret[index:] + account_data['secret'] = secret + @classmethod - def create_data_map(cls, accounts): + def create_data_map(cls, accounts, section): data_map = defaultdict(list) if not accounts.exists(): @@ -92,6 +106,7 @@ class AssetAccountHandler(BaseAccountHandler): for tp, _accounts in account_type_map.items(): sheet_name = type_dict.get(tp, tp) data = AccountSecretSerializer(_accounts, many=True).data + cls.handler_secret(data, section) data_map.update(cls.add_rows(data, header_fields, sheet_name)) print('\n\033[33m- 共备份 {} 条账号\033[0m'.format(accounts.count())) @@ -104,7 +119,7 @@ class AccountBackupHandler: self.plan_name = self.execution.plan.name self.is_frozen = False # 任务状态冻结标志 - def create_excel(self): + def create_excel(self, section='complete'): print( '\n' '\033[32m>>> 正在生成资产或应用相关备份信息文件\033[0m' @@ -114,7 +129,7 @@ class AccountBackupHandler: time_start = time.time() files = [] accounts = self.execution.backup_accounts - data_map = AssetAccountHandler.create_data_map(accounts) + data_map = AssetAccountHandler.create_data_map(accounts, section) if not data_map: return files @@ -160,7 +175,8 @@ class AccountBackupHandler: self.execution.save() print('已完成对任务状态的更新') - def step_finished(self, is_success): + @staticmethod + def step_finished(is_success): if is_success: print('任务执行成功') else: @@ -170,14 +186,22 @@ class AccountBackupHandler: is_success = False error = '-' try: - recipients = self.execution.plan_snapshot.get('recipients') - if not recipients: + recipients_part_one = self.execution.snapshot.get('recipients_part_one', []) + recipients_part_two = self.execution.snapshot.get('recipients_part_two', []) + if not recipients_part_one and not recipients_part_two: print( '\n' '\033[32m>>> 该备份任务未分配收件人\033[0m' '' ) + if recipients_part_one and recipients_part_two: + files = self.create_excel(section='front') + self.send_backup_mail(files, recipients_part_one) + + files = self.create_excel(section='back') + self.send_backup_mail(files, recipients_part_two) else: + recipients = recipients_part_one or recipients_part_two files = self.create_excel() self.send_backup_mail(files, recipients) except Exception as e: diff --git a/apps/accounts/migrations/0013_account_backup_recipients.py b/apps/accounts/migrations/0013_account_backup_recipients.py new file mode 100644 index 000000000..ac9956b76 --- /dev/null +++ b/apps/accounts/migrations/0013_account_backup_recipients.py @@ -0,0 +1,59 @@ +# Generated by Django 4.1.10 on 2023-08-03 08:28 + +from django.conf import settings +from django.db import migrations, models + + +def migrate_recipients(apps, schema_editor): + account_backup_model = apps.get_model('accounts', 'AccountBackupAutomation') + execution_model = apps.get_model('accounts', 'AccountBackupExecution') + for account_backup in account_backup_model.objects.all(): + recipients = list(account_backup.recipients.all()) + if not recipients: + continue + account_backup.recipients_part_one.set(recipients) + + execution_bojs = [] + for execution in execution_model.objects.all(): + snapshot = execution.snapshot + recipients = snapshot.pop('recipients', {}) + snapshot.update({'recipients_part_one': recipients, 'recipients_part_two': {}}) + execution_bojs.append(execution) + execution_model.objects.bulk_update(execution_bojs, ['snapshot']) + + +class Migration(migrations.Migration): + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('accounts', '0012_auto_20230621_1456'), + ] + + operations = [ + migrations.AddField( + model_name='accountbackupautomation', + name='recipients_part_one', + field=models.ManyToManyField( + blank=True, related_name='recipient_part_one_plans', + to=settings.AUTH_USER_MODEL, verbose_name='Recipient part one' + ), + ), + migrations.AddField( + model_name='accountbackupautomation', + name='recipients_part_two', + field=models.ManyToManyField( + blank=True, related_name='recipient_part_two_plans', + to=settings.AUTH_USER_MODEL, verbose_name='Recipient part two' + ), + ), + migrations.RenameField( + model_name='accountbackupexecution', + old_name='plan_snapshot', + new_name='snapshot', + ), + migrations.RunPython(migrate_recipients), + migrations.RemoveField( + model_name='accountbackupautomation', + name='recipients', + ), + + ] diff --git a/apps/accounts/models/automations/backup_account.py b/apps/accounts/models/automations/backup_account.py index c72e0daef..c99c9e220 100644 --- a/apps/accounts/models/automations/backup_account.py +++ b/apps/accounts/models/automations/backup_account.py @@ -22,9 +22,13 @@ logger = get_logger(__file__) class AccountBackupAutomation(PeriodTaskModelMixin, JMSOrgBaseModel): types = models.JSONField(default=list) - recipients = models.ManyToManyField( - 'users.User', related_name='recipient_escape_route_plans', blank=True, - verbose_name=_("Recipient") + recipients_part_one = models.ManyToManyField( + 'users.User', related_name='recipient_part_one_plans', blank=True, + verbose_name=_("Recipient part one") + ) + recipients_part_two = models.ManyToManyField( + 'users.User', related_name='recipient_part_two_plans', blank=True, + verbose_name=_("Recipient part two") ) def __str__(self): @@ -52,9 +56,13 @@ class AccountBackupAutomation(PeriodTaskModelMixin, JMSOrgBaseModel): 'org_id': self.org_id, 'created_by': self.created_by, 'types': self.types, - 'recipients': { - str(recipient.id): (str(recipient), bool(recipient.secret_key)) - for recipient in self.recipients.all() + 'recipients_part_one': { + str(user.id): (str(user), bool(user.secret_key)) + for user in self.recipients_part_one.all() + }, + 'recipients_part_two': { + str(user.id): (str(user), bool(user.secret_key)) + for user in self.recipients_part_two.all() } } @@ -68,7 +76,7 @@ class AccountBackupAutomation(PeriodTaskModelMixin, JMSOrgBaseModel): except AttributeError: hid = str(uuid.uuid4()) execution = AccountBackupExecution.objects.create( - id=hid, plan=self, plan_snapshot=self.to_attr_json(), trigger=trigger + id=hid, plan=self, snapshot=self.to_attr_json(), trigger=trigger ) return execution.start() @@ -85,7 +93,7 @@ class AccountBackupExecution(OrgModelMixin): timedelta = models.FloatField( default=0.0, verbose_name=_('Time'), null=True ) - plan_snapshot = models.JSONField( + snapshot = models.JSONField( encoder=ModelJSONFieldEncoder, default=dict, blank=True, null=True, verbose_name=_('Account backup snapshot') ) @@ -108,16 +116,9 @@ class AccountBackupExecution(OrgModelMixin): @property def types(self): - types = self.plan_snapshot.get('types') + types = self.snapshot.get('types') return types - @property - def recipients(self): - recipients = self.plan_snapshot.get('recipients') - if not recipients: - return [] - return recipients.values() - @lazyproperty def backup_accounts(self): from accounts.models import Account diff --git a/apps/accounts/serializers/account/backup.py b/apps/accounts/serializers/account/backup.py index b6ec22203..f11861fa3 100644 --- a/apps/accounts/serializers/account/backup.py +++ b/apps/accounts/serializers/account/backup.py @@ -24,7 +24,7 @@ class AccountBackupSerializer(PeriodTaskSerializerMixin, BulkOrgResourceModelSer ] fields = read_only_fields + [ 'id', 'name', 'is_periodic', 'interval', 'crontab', - 'comment', 'recipients', 'types' + 'comment', 'types', 'recipients_part_one', 'recipients_part_two' ] extra_kwargs = { 'name': {'required': True}, @@ -44,7 +44,7 @@ class AccountBackupPlanExecutionSerializer(serializers.ModelSerializer): class Meta: model = AccountBackupExecution read_only_fields = [ - 'id', 'date_start', 'timedelta', 'plan_snapshot', - 'trigger', 'reason', 'is_success', 'org_id', 'recipients' + 'id', 'date_start', 'timedelta', 'snapshot', + 'trigger', 'reason', 'is_success', 'org_id' ] fields = read_only_fields + ['plan'] From e939776da0ac1873b6912f5d6df79f942cbd43b9 Mon Sep 17 00:00:00 2001 From: Eric Date: Mon, 7 Aug 2023 17:34:15 +0800 Subject: [PATCH 105/177] =?UTF-8?q?chore:=20=E6=9B=B4=E6=96=B0=20poetry.lo?= =?UTF-8?q?ck?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- poetry.lock | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/poetry.lock b/poetry.lock index 11440434f..39b36a989 100644 --- a/poetry.lock +++ b/poetry.lock @@ -463,7 +463,9 @@ version = "2.14.1" description = "Radically simple IT automation" optional = false python-versions = ">=3.9" -files = [] +files = [ + {file = "ansible-2.14.1.2.zip", hash = "sha256:813b39d8e03d5ea23b47703b3ba4d0372f68141b33e2b1be28deb6ad28b31c73"}, +] [package.dependencies] cryptography = "*" @@ -1821,7 +1823,9 @@ version = "4.3.0" description = "" optional = false python-versions = ">=3.7" -files = [] +files = [ + {file = "django-cas-ng-4.3.1.zip", hash = "sha256:c3c068b979927333475fb82b8f3597210384ca9ba764496874fc532463d40e3d"}, +] [package.dependencies] Django = ">=2.2" @@ -1953,7 +1957,9 @@ version = "1.4.0" description = "Django authentication backend for RADIUS" optional = false python-versions = "*" -files = [] +files = [ + {file = "1.5.0.zip", hash = "sha256:b50680dd1c577a099f90d510856b3e55aa496d8c876beabb5b0a79fc94fcfae9"}, +] [package.dependencies] pyrad = ">=1.2,<2.2 || >2.2" @@ -5141,13 +5147,13 @@ reference = "tsinghua" [[package]] name = "pygments" -version = "2.15.1" +version = "2.16.1" description = "Pygments is a syntax highlighting package written in Python." optional = false python-versions = ">=3.7" files = [ - {file = "Pygments-2.15.1-py3-none-any.whl", hash = "sha256:db2db3deb4b4179f399a09054b023b6a586b76499d36965813c71aa8ed7b5fd1"}, - {file = "Pygments-2.15.1.tar.gz", hash = "sha256:8ace4d3c1dd481894b2005f560ead0f9f19ee64fe983366be1a21e171d12775c"}, + {file = "Pygments-2.16.1-py3-none-any.whl", hash = "sha256:13fc09fa63bc8d8671a6d247e1eb303c4b343eaee81d861f3404db2935653692"}, + {file = "Pygments-2.16.1.tar.gz", hash = "sha256:1daff0494820c69bc8941e407aa20f577374ee88364ee10a98fdbe0aece96e29"}, ] [package.extras] From a261b2de3c11a98cf443b17d11551dce535e6ba0 Mon Sep 17 00:00:00 2001 From: Eric Date: Mon, 7 Aug 2023 17:00:01 +0800 Subject: [PATCH 106/177] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E4=B8=AA=E4=BA=BA=20ssh=20=E5=85=AC=E9=92=A5=E6=A0=A1?= =?UTF-8?q?=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/users/models/user.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/apps/users/models/user.py b/apps/users/models/user.py index 4a7dccd05..4e1f2757b 100644 --- a/apps/users/models/user.py +++ b/apps/users/models/user.py @@ -8,6 +8,7 @@ import string import uuid from typing import Callable +import sshpubkeys from django.conf import settings from django.contrib.auth.hashers import check_password from django.contrib.auth.models import AbstractUser @@ -105,7 +106,6 @@ class AuthMixin: return '' if self.public_key: - import sshpubkeys try: return sshpubkeys.SSHKey(self.public_key) except (TabError, TypeError): @@ -153,21 +153,21 @@ class AuthMixin: return False @staticmethod - def get_public_key_body(key): - for i in key.split(): - if len(i) > 256: - return i - return key + def get_public_key_md5(key): + try: + key_obj = sshpubkeys.SSHKey(key) + return key_obj.hash_md5() + except Exception as e: + return '' def check_public_key(self, key): if not self.public_key: return False - key = self.get_public_key_body(key) - key_saved = self.get_public_key_body(self.public_key) - if key == key_saved: - return True - else: + key_md5 = self.get_public_key_md5(key) + if not key_md5: return False + self_key_md5 = self.get_public_key_md5(self.public_key) + return key_md5 == self_key_md5 class RoleManager(models.Manager): From b764827003b7f877ec2840aff18fdbe97417667e Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Tue, 8 Aug 2023 10:16:23 +0800 Subject: [PATCH 107/177] =?UTF-8?q?perf:=20=E8=99=9A=E6=8B=9F=E8=B4=A6?= =?UTF-8?q?=E5=8F=B7=E5=A2=9E=E5=8A=A0=E5=AF=86=E7=A0=81=E9=80=89=E9=A1=B9?= =?UTF-8?q?=20(#11201)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * perf: 修改账号配置 * perf: 修改 account * perf: 修改 virtual account * perf: 虚拟账号增加密码选项 * perf: 修改获取虚拟账号 * perf: 修改 virtual account * perf: 修改一些写法 * perf: 添加说明 --------- Co-authored-by: ibuler --- apps/accounts/api/account/__init__.py | 1 + apps/accounts/api/account/virtual.py | 20 + apps/accounts/const/account.py | 4 + apps/accounts/const/vault.py | 2 +- .../migrations/0013_virtualaccount.py | 30 ++ apps/accounts/models/__init__.py | 2 + apps/accounts/models/account.py | 106 +---- apps/accounts/models/template.py | 86 ++++ apps/accounts/models/virtual.py | 103 +++++ apps/accounts/serializers/account/__init__.py | 3 +- apps/accounts/serializers/account/virtual.py | 26 ++ apps/accounts/urls.py | 1 + apps/authentication/api/access_key.py | 5 +- apps/authentication/mixins.py | 1 + .../authentication/models/connection_token.py | 25 +- apps/jumpserver/conf.py | 4 + apps/jumpserver/settings/custom.py | 5 + apps/locale/ja/LC_MESSAGES/django.mo | 4 +- apps/locale/ja/LC_MESSAGES/django.po | 372 +++++++++-------- apps/locale/zh/LC_MESSAGES/django.mo | 4 +- apps/locale/zh/LC_MESSAGES/django.po | 375 ++++++++++-------- apps/perms/utils/account.py | 15 +- apps/rbac/models/rolebinding.py | 8 + apps/settings/serializers/public.py | 1 + apps/users/models/user.py | 34 ++ apps/users/serializers/user.py | 1 + 26 files changed, 775 insertions(+), 463 deletions(-) create mode 100644 apps/accounts/api/account/virtual.py create mode 100644 apps/accounts/migrations/0013_virtualaccount.py create mode 100644 apps/accounts/models/template.py create mode 100644 apps/accounts/models/virtual.py create mode 100644 apps/accounts/serializers/account/virtual.py diff --git a/apps/accounts/api/account/__init__.py b/apps/accounts/api/account/__init__.py index f6d8376a6..7f90c23c7 100644 --- a/apps/accounts/api/account/__init__.py +++ b/apps/accounts/api/account/__init__.py @@ -1,3 +1,4 @@ from .account import * from .task import * from .template import * +from .virtual import * diff --git a/apps/accounts/api/account/virtual.py b/apps/accounts/api/account/virtual.py new file mode 100644 index 000000000..79dec3f78 --- /dev/null +++ b/apps/accounts/api/account/virtual.py @@ -0,0 +1,20 @@ +from django.shortcuts import get_object_or_404 + +from accounts.models import VirtualAccount +from accounts.serializers import VirtualAccountSerializer +from common.utils import is_uuid +from orgs.mixins.api import OrgBulkModelViewSet + + +class VirtualAccountViewSet(OrgBulkModelViewSet): + serializer_class = VirtualAccountSerializer + search_fields = ('alias',) + filterset_fields = ('alias',) + + def get_queryset(self): + return VirtualAccount.get_or_init_queryset() + + def get_object(self, ): + pk = self.kwargs.get('pk') + kwargs = {'pk': pk} if is_uuid(pk) else {'alias': pk} + return get_object_or_404(VirtualAccount, **kwargs) diff --git a/apps/accounts/const/account.py b/apps/accounts/const/account.py index 44caa2889..b1d3e348e 100644 --- a/apps/accounts/const/account.py +++ b/apps/accounts/const/account.py @@ -16,6 +16,10 @@ class AliasAccount(TextChoices): USER = '@USER', _('Dynamic user') ANON = '@ANON', _('Anonymous account') + @classmethod + def virtual_choices(cls): + return [(k, v) for k, v in cls.choices if k not in (cls.ALL,)] + class Source(TextChoices): LOCAL = 'local', _('Local') diff --git a/apps/accounts/const/vault.py b/apps/accounts/const/vault.py index 1da2a591b..1e41b6d86 100644 --- a/apps/accounts/const/vault.py +++ b/apps/accounts/const/vault.py @@ -5,5 +5,5 @@ __all__ = ['VaultTypeChoices'] class VaultTypeChoices(models.TextChoices): - local = 'local', _('Local Vault') + local = 'local', _('Database') hcp = 'hcp', _('HCP Vault') diff --git a/apps/accounts/migrations/0013_virtualaccount.py b/apps/accounts/migrations/0013_virtualaccount.py new file mode 100644 index 000000000..9b3b02b7c --- /dev/null +++ b/apps/accounts/migrations/0013_virtualaccount.py @@ -0,0 +1,30 @@ +# Generated by Django 4.1.10 on 2023-08-01 09:12 + +from django.db import migrations, models +import uuid + + +class Migration(migrations.Migration): + + dependencies = [ + ('accounts', '0012_auto_20230621_1456'), + ] + + operations = [ + migrations.CreateModel( + name='VirtualAccount', + fields=[ + ('created_by', models.CharField(blank=True, max_length=128, null=True, verbose_name='Created by')), + ('updated_by', models.CharField(blank=True, max_length=128, null=True, verbose_name='Updated by')), + ('date_created', models.DateTimeField(auto_now_add=True, null=True, verbose_name='Date created')), + ('date_updated', models.DateTimeField(auto_now=True, verbose_name='Date updated')), + ('id', models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False)), + ('org_id', models.CharField(blank=True, db_index=True, default='', max_length=36, verbose_name='Organization')), + ('alias', models.CharField(choices=[('@INPUT', 'Manual input'), ('@USER', 'Dynamic user'), ('@ANON', 'Anonymous account')], max_length=128, verbose_name='Alias')), + ('secret_from_login', models.BooleanField(default=None, null=True, verbose_name='Secret from login')), + ], + options={ + 'unique_together': {('alias', 'org_id')}, + }, + ), + ] diff --git a/apps/accounts/models/__init__.py b/apps/accounts/models/__init__.py index df686a50b..9a3b780c8 100644 --- a/apps/accounts/models/__init__.py +++ b/apps/accounts/models/__init__.py @@ -1,3 +1,5 @@ from .account import * from .automations import * from .base import * +from .template import * +from .virtual import * diff --git a/apps/accounts/models/account.py b/apps/accounts/models/account.py index 0f4077536..1bdf6e83d 100644 --- a/apps/accounts/models/account.py +++ b/apps/accounts/models/account.py @@ -1,6 +1,4 @@ from django.db import models -from django.db.models import Count, Q -from django.utils import timezone from django.utils.translation import gettext_lazy as _ from simple_history.models import HistoricalRecords @@ -8,9 +6,9 @@ from assets.models.base import AbsConnectivity from common.utils import lazyproperty from .base import BaseAccount from .mixins import VaultModelMixin -from ..const import AliasAccount, Source +from ..const import Source -__all__ = ['Account', 'AccountTemplate', 'AccountHistoricalRecords'] +__all__ = ['Account', 'AccountHistoricalRecords'] class AccountHistoricalRecords(HistoricalRecords): @@ -89,29 +87,6 @@ class Account(AbsConnectivity, BaseAccount): def has_secret(self): return bool(self.secret) - @classmethod - def get_special_account(cls, name): - if name == AliasAccount.INPUT.value: - return cls.get_manual_account() - elif name == AliasAccount.ANON.value: - return cls.get_anonymous_account() - else: - return cls(name=name, username=name, secret=None) - - @classmethod - def get_manual_account(cls): - """ @INPUT 手动登录的账号(any) """ - return cls(name=AliasAccount.INPUT.label, username=AliasAccount.INPUT.value, secret=None) - - @classmethod - def get_anonymous_account(cls): - return cls(name=AliasAccount.ANON.label, username=AliasAccount.ANON.value, secret=None) - - @classmethod - def get_user_account(cls): - """ @USER 动态用户的账号(self) """ - return cls(name=AliasAccount.USER.label, username=AliasAccount.USER.value, secret=None) - @lazyproperty def versions(self): return self.history.count() @@ -121,83 +96,6 @@ class Account(AbsConnectivity, BaseAccount): return self.asset.accounts.exclude(id=self.id).exclude(su_from=self) -class AccountTemplate(BaseAccount): - su_from = models.ForeignKey( - 'self', related_name='su_to', null=True, - on_delete=models.SET_NULL, verbose_name=_("Su from") - ) - - class Meta: - verbose_name = _('Account template') - unique_together = ( - ('name', 'org_id'), - ) - permissions = [ - ('view_accounttemplatesecret', _('Can view asset account template secret')), - ('change_accounttemplatesecret', _('Can change asset account template secret')), - ] - - @classmethod - def get_su_from_account_templates(cls, pk=None): - if pk is None: - return cls.objects.all() - return cls.objects.exclude(Q(id=pk) | Q(su_from_id=pk)) - - def __str__(self): - return f'{self.name}({self.username})' - - def get_su_from_account(self, asset): - su_from = self.su_from - if su_from and asset.platform.su_enabled: - account = asset.accounts.filter( - username=su_from.username, - secret_type=su_from.secret_type - ).first() - return account - - @staticmethod - def bulk_update_accounts(accounts, data): - history_model = Account.history.model - account_ids = accounts.values_list('id', flat=True) - history_accounts = history_model.objects.filter(id__in=account_ids) - account_id_count_map = { - str(i['id']): i['count'] - for i in history_accounts.values('id').order_by('id') - .annotate(count=Count(1)).values('id', 'count') - } - - for account in accounts: - account_id = str(account.id) - account.version = account_id_count_map.get(account_id) + 1 - for k, v in data.items(): - setattr(account, k, v) - Account.objects.bulk_update(accounts, ['version', 'secret']) - - @staticmethod - def bulk_create_history_accounts(accounts, user_id): - history_model = Account.history.model - history_account_objs = [] - for account in accounts: - history_account_objs.append( - history_model( - id=account.id, - version=account.version, - secret=account.secret, - secret_type=account.secret_type, - history_user_id=user_id, - history_date=timezone.now() - ) - ) - history_model.objects.bulk_create(history_account_objs) - - def bulk_sync_account_secret(self, accounts, user_id): - """ 批量同步账号密码 """ - if not accounts: - return - self.bulk_update_accounts(accounts, {'secret': self.secret}) - self.bulk_create_history_accounts(accounts, user_id) - - def replace_history_model_with_mixin(): """ 替换历史模型中的父类为指定的Mixin类。 diff --git a/apps/accounts/models/template.py b/apps/accounts/models/template.py new file mode 100644 index 000000000..adee261e6 --- /dev/null +++ b/apps/accounts/models/template.py @@ -0,0 +1,86 @@ +from django.db import models +from django.db.models import Count, Q +from django.utils import timezone +from django.utils.translation import gettext_lazy as _ + +from .account import Account +from .base import BaseAccount + +__all__ = ['AccountTemplate', ] + + +class AccountTemplate(BaseAccount): + su_from = models.ForeignKey( + 'self', related_name='su_to', null=True, + on_delete=models.SET_NULL, verbose_name=_("Su from") + ) + + class Meta: + verbose_name = _('Account template') + unique_together = ( + ('name', 'org_id'), + ) + permissions = [ + ('view_accounttemplatesecret', _('Can view asset account template secret')), + ('change_accounttemplatesecret', _('Can change asset account template secret')), + ] + + @classmethod + def get_su_from_account_templates(cls, pk=None): + if pk is None: + return cls.objects.all() + return cls.objects.exclude(Q(id=pk) | Q(su_from_id=pk)) + + def __str__(self): + return f'{self.name}({self.username})' + + def get_su_from_account(self, asset): + su_from = self.su_from + if su_from and asset.platform.su_enabled: + account = asset.accounts.filter( + username=su_from.username, + secret_type=su_from.secret_type + ).first() + return account + + @staticmethod + def bulk_update_accounts(accounts, data): + history_model = Account.history.model + account_ids = accounts.values_list('id', flat=True) + history_accounts = history_model.objects.filter(id__in=account_ids) + account_id_count_map = { + str(i['id']): i['count'] + for i in history_accounts.values('id').order_by('id') + .annotate(count=Count(1)).values('id', 'count') + } + + for account in accounts: + account_id = str(account.id) + account.version = account_id_count_map.get(account_id) + 1 + for k, v in data.items(): + setattr(account, k, v) + Account.objects.bulk_update(accounts, ['version', 'secret']) + + @staticmethod + def bulk_create_history_accounts(accounts, user_id): + history_model = Account.history.model + history_account_objs = [] + for account in accounts: + history_account_objs.append( + history_model( + id=account.id, + version=account.version, + secret=account.secret, + secret_type=account.secret_type, + history_user_id=user_id, + history_date=timezone.now() + ) + ) + history_model.objects.bulk_create(history_account_objs) + + def bulk_sync_account_secret(self, accounts, user_id): + """ 批量同步账号密码 """ + if not accounts: + return + self.bulk_update_accounts(accounts, {'secret': self.secret}) + self.bulk_create_history_accounts(accounts, user_id) diff --git a/apps/accounts/models/virtual.py b/apps/accounts/models/virtual.py new file mode 100644 index 000000000..88cf1b605 --- /dev/null +++ b/apps/accounts/models/virtual.py @@ -0,0 +1,103 @@ +from django.db import models +from django.utils.translation import gettext_lazy as _ + +from accounts.const import AliasAccount +from orgs.mixins.models import JMSOrgBaseModel + +__all__ = ['VirtualAccount'] + +from orgs.utils import tmp_to_org + + +class VirtualAccount(JMSOrgBaseModel): + alias = models.CharField(max_length=128, choices=AliasAccount.virtual_choices(), verbose_name=_('Alias'), ) + secret_from_login = models.BooleanField(default=None, null=True, verbose_name=_("Secret from login"), ) + + class Meta: + unique_together = [('alias', 'org_id')] + + @property + def name(self): + return self.get_alias_display() + + @property + def username(self): + usernames_map = { + AliasAccount.INPUT: _("Manual input"), + AliasAccount.USER: _("Same with user"), + AliasAccount.ANON: '' + } + usernames_map = {str(k): v for k, v in usernames_map.items()} + return usernames_map.get(self.alias, '') + + @property + def comment(self): + comments_map = { + AliasAccount.INPUT: _('Non-asset account, Input username/password on connect'), + AliasAccount.USER: _('The account username name same with user on connect'), + AliasAccount.ANON: _('Connect asset without using a username and password, ' + 'and it only supports web-based and custom-type assets'), + } + comments_map = {str(k): v for k, v in comments_map.items()} + return comments_map.get(self.alias, '') + + @classmethod + def get_or_init_queryset(cls): + aliases = [i[0] for i in AliasAccount.virtual_choices()] + alias_created = cls.objects.all().values_list('alias', flat=True) + need_created = set(aliases) - set(alias_created) + + if need_created: + accounts = [cls(alias=alias) for alias in need_created] + cls.objects.bulk_create(accounts, ignore_conflicts=True) + return cls.objects.all() + + @classmethod + def get_special_account(cls, alias, user, asset, input_username='', input_secret='', from_permed=True): + if alias == AliasAccount.INPUT.value: + account = cls.get_manual_account(input_username, input_secret, from_permed) + elif alias == AliasAccount.ANON.value: + account = cls.get_anonymous_account() + elif alias == AliasAccount.USER.value: + account = cls.get_same_account(user, asset, input_secret=input_secret, from_permed=from_permed) + else: + account = cls(name=alias, username=alias, secret=None) + account.alias = alias + if asset: + account.asset = asset + account.org_id = asset.org_id + return account + + @classmethod + def get_manual_account(cls, input_username='', input_secret='', from_permed=True): + """ @INPUT 手动登录的账号(any) """ + from .account import Account + if from_permed: + username = AliasAccount.INPUT.value + secret = '' + else: + username = input_username + secret = input_secret + return Account(name=AliasAccount.INPUT.label, username=username, secret=secret) + + @classmethod + def get_anonymous_account(cls): + from .account import Account + return Account(name=AliasAccount.ANON.label, username=AliasAccount.ANON.value, secret=None) + + @classmethod + def get_same_account(cls, user, asset, input_secret='', from_permed=True): + """ @USER 动态用户的账号(self) """ + from .account import Account + username = user.username + + with tmp_to_org(asset.org): + same_account = cls.objects.filter(alias='@USER').first() + + secret = '' + if same_account and same_account.secret_from_login: + secret = user.get_cached_password_if_has() + + if not secret and not from_permed: + secret = input_secret + return Account(name=AliasAccount.USER.label, username=username, secret=secret) diff --git a/apps/accounts/serializers/account/__init__.py b/apps/accounts/serializers/account/__init__.py index 2829931b2..207029047 100644 --- a/apps/accounts/serializers/account/__init__.py +++ b/apps/accounts/serializers/account/__init__.py @@ -1,5 +1,6 @@ from .account import * from .backup import * from .base import * -from .template import * from .gathered_account import * +from .template import * +from .virtual import * diff --git a/apps/accounts/serializers/account/virtual.py b/apps/accounts/serializers/account/virtual.py new file mode 100644 index 000000000..d4bd42589 --- /dev/null +++ b/apps/accounts/serializers/account/virtual.py @@ -0,0 +1,26 @@ +from django.utils.translation import gettext_lazy as _ +from rest_framework import serializers + +from accounts.models import VirtualAccount + +__all__ = ['VirtualAccountSerializer'] + + +class VirtualAccountSerializer(serializers.ModelSerializer): + class Meta: + model = VirtualAccount + field_mini = ['id', 'alias', 'username', 'name'] + common_fields = ['date_created', 'date_updated', 'comment'] + fields = field_mini + [ + 'secret_from_login', + ] + common_fields + read_only_fields = common_fields + common_fields + extra_kwargs = { + 'comment': {'label': _('Comment')}, + 'name': {'label': _('Name')}, + 'username': {'label': _('Username')}, + 'secret_from_login': {'help_text': _('Current only support login from AD/LDAP. Secret priority: ' + 'Same account in asset secret > Login secret > Manual input') + }, + 'alias': {'required': False}, + } diff --git a/apps/accounts/urls.py b/apps/accounts/urls.py index 94c8311e0..12d04274e 100644 --- a/apps/accounts/urls.py +++ b/apps/accounts/urls.py @@ -9,6 +9,7 @@ app_name = 'accounts' router = BulkRouter() router.register(r'accounts', api.AccountViewSet, 'account') +router.register(r'virtual-accounts', api.VirtualAccountViewSet, 'virtual-account') router.register(r'gathered-accounts', api.GatheredAccountViewSet, 'gathered-account') router.register(r'account-secrets', api.AccountSecretsViewSet, 'account-secret') router.register(r'account-templates', api.AccountTemplateViewSet, 'account-template') diff --git a/apps/authentication/api/access_key.py b/apps/authentication/api/access_key.py index bbda04c02..9253f449d 100644 --- a/apps/authentication/api/access_key.py +++ b/apps/authentication/api/access_key.py @@ -2,12 +2,13 @@ # from rest_framework.viewsets import ModelViewSet -from .. import serializers + from rbac.permissions import RBACPermission +from ..serializers import AccessKeySerializer class AccessKeyViewSet(ModelViewSet): - serializer_class = serializers.AccessKeySerializer + serializer_class = AccessKeySerializer search_fields = ['^id', '^secret'] permission_classes = [RBACPermission] diff --git a/apps/authentication/mixins.py b/apps/authentication/mixins.py index 518e4aeb4..f7d3856b0 100644 --- a/apps/authentication/mixins.py +++ b/apps/authentication/mixins.py @@ -460,6 +460,7 @@ class AuthMixin(CommonMixin, AuthPreCheckMixin, AuthACLMixin, MFAMixin, AuthPost self._check_password_require_reset_or_not(user) self._check_passwd_is_too_simple(user, password) self._check_passwd_need_update(user) + user.cache_login_password_if_need(password) # 校验login-mfa, 如果登录页面上显示 mfa 的话 self._check_login_page_mfa_if_need(user) diff --git a/apps/authentication/models/connection_token.py b/apps/authentication/models/connection_token.py index c8919b3a5..29f0c28f1 100644 --- a/apps/authentication/models/connection_token.py +++ b/apps/authentication/models/connection_token.py @@ -9,7 +9,7 @@ from django.utils import timezone from django.utils.translation import gettext_lazy as _ from rest_framework.exceptions import PermissionDenied -from accounts.const import AliasAccount +from accounts.models import VirtualAccount from assets.const import Protocol from assets.const.host import GATEWAY_NAME from common.db.fields import EncryptTextField @@ -216,29 +216,14 @@ class ConnectionToken(JMSOrgBaseModel): @lazyproperty def account_object(self): - from accounts.models import Account if not self.asset: return None if self.account.startswith('@'): - account = Account.get_special_account(self.account) - account.asset = self.asset - account.org_id = self.asset.org_id - - # 手动账号 - if self.account == AliasAccount.INPUT: - account.username = self.input_username - account.secret = self.input_secret - - # 同名账号 - elif self.account == AliasAccount.USER: - account.username = self.user.username - account.secret = self.input_secret - - # 匿名账号 - elif self.account == AliasAccount.ANON: - account.username = '' - account.secret = '' + account = VirtualAccount.get_special_account( + self.account, self.user, self.asset, input_username=self.input_username, + input_secret=self.input_secret, from_permed=False + ) else: account = self.asset.accounts.filter(name=self.account).first() if not account.secret and self.input_secret: diff --git a/apps/jumpserver/conf.py b/apps/jumpserver/conf.py index a76d02075..92355bdb3 100644 --- a/apps/jumpserver/conf.py +++ b/apps/jumpserver/conf.py @@ -257,6 +257,10 @@ class Config(dict): 'VAULT_HCP_TOKEN': '', 'VAULT_HCP_MOUNT_POINT': 'jumpserver', + # Cache login password + 'CACHE_LOGIN_PASSWORD_ENABLED': False, + 'CACHE_LOGIN_PASSWORD_TTL': 60 * 60 * 24, + # Auth LDAP settings 'AUTH_LDAP': False, 'AUTH_LDAP_SERVER_URI': 'ldap://localhost:389', diff --git a/apps/jumpserver/settings/custom.py b/apps/jumpserver/settings/custom.py index 78b888ced..e1f5c5709 100644 --- a/apps/jumpserver/settings/custom.py +++ b/apps/jumpserver/settings/custom.py @@ -74,6 +74,11 @@ SECURITY_LOGIN_IP_WHITE_LIST = CONFIG.SECURITY_LOGIN_IP_WHITE_LIST SECURITY_LOGIN_IP_LIMIT_COUNT = CONFIG.SECURITY_LOGIN_IP_LIMIT_COUNT SECURITY_LOGIN_IP_LIMIT_TIME = CONFIG.SECURITY_LOGIN_IP_LIMIT_TIME # Unit: minute +# Authentication settings +# 缓存后可以给账号使用 +CACHE_LOGIN_PASSWORD_ENABLED = CONFIG.CACHE_LOGIN_PASSWORD_ENABLED +CACHE_LOGIN_PASSWORD_TTL = CONFIG.CACHE_LOGIN_PASSWORD_TTL + # Terminal other setting TERMINAL_PASSWORD_AUTH = CONFIG.TERMINAL_PASSWORD_AUTH TERMINAL_PUBLIC_KEY_AUTH = CONFIG.TERMINAL_PUBLIC_KEY_AUTH diff --git a/apps/locale/ja/LC_MESSAGES/django.mo b/apps/locale/ja/LC_MESSAGES/django.mo index 0d745e972..9cd3ce2c1 100644 --- a/apps/locale/ja/LC_MESSAGES/django.mo +++ b/apps/locale/ja/LC_MESSAGES/django.mo @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cebc816d765d1b53b4984dabe689b73e25ebea0bbd053625d5f7d94e0bf66852 -size 151070 +oid sha256:555045fe297b59d9a9f813738679419f34ae9296013f4576ee1e0037985c0f1c +size 152487 diff --git a/apps/locale/ja/LC_MESSAGES/django.po b/apps/locale/ja/LC_MESSAGES/django.po index 1f95b728e..8c13d0567 100644 --- a/apps/locale/ja/LC_MESSAGES/django.po +++ b/apps/locale/ja/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-08-03 15:51+0800\n" +"POT-Creation-Date: 2023-08-08 10:08+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -58,7 +58,7 @@ msgstr "" msgid "All" msgstr "すべて" -#: accounts/const/account.py:15 +#: accounts/const/account.py:15 accounts/models/virtual.py:26 msgid "Manual input" msgstr "手動入力" @@ -70,29 +70,29 @@ msgstr "動的コード" msgid "Anonymous account" msgstr "匿名ユーザー" -#: accounts/const/account.py:21 users/models/user.py:699 +#: accounts/const/account.py:25 users/models/user.py:733 msgid "Local" msgstr "ローカル" -#: accounts/const/account.py:22 +#: accounts/const/account.py:26 msgid "Collected" msgstr "集めました" -#: accounts/const/account.py:23 accounts/serializers/account/account.py:27 +#: accounts/const/account.py:27 accounts/serializers/account/account.py:27 #: settings/serializers/auth/sms.py:75 msgid "Template" msgstr "テンプレート" -#: accounts/const/account.py:27 ops/const.py:45 +#: accounts/const/account.py:31 ops/const.py:45 msgid "Skip" msgstr "スキップ" -#: accounts/const/account.py:28 audits/const.py:24 rbac/tree.py:230 +#: accounts/const/account.py:32 audits/const.py:24 rbac/tree.py:230 #: templates/_csv_import_export.html:18 templates/_csv_update_modal.html:6 msgid "Update" msgstr "更新" -#: accounts/const/account.py:29 +#: accounts/const/account.py:33 #: accounts/serializers/automations/change_secret.py:156 audits/const.py:54 #: audits/signal_handlers/activity_log.py:33 common/const/choices.py:19 #: ops/const.py:58 terminal/const.py:77 xpack/plugins/cloud/const.py:43 @@ -187,17 +187,16 @@ msgstr "作成してプッシュ" msgid "Only create" msgstr "作成のみ" -#: accounts/const/vault.py:8 -#, fuzzy -#| msgid "Local" -msgid "Local Vault" -msgstr "ローカル" +#: accounts/const/vault.py:8 assets/const/category.py:12 +#: assets/models/asset/database.py:9 assets/models/asset/database.py:24 +msgid "Database" +msgstr "データベース" #: accounts/const/vault.py:9 msgid "HCP Vault" -msgstr "" +msgstr "HashiCorp Vault" -#: accounts/models/account.py:50 +#: accounts/models/account.py:48 #: accounts/models/automations/gather_account.py:16 #: accounts/serializers/account/account.py:200 #: accounts/serializers/account/account.py:245 @@ -218,7 +217,7 @@ msgstr "" msgid "Asset" msgstr "資産" -#: accounts/models/account.py:54 accounts/models/account.py:127 +#: accounts/models/account.py:52 accounts/models/template.py:15 #: accounts/serializers/account/account.py:207 #: accounts/serializers/account/account.py:255 #: accounts/serializers/account/template.py:16 @@ -226,21 +225,21 @@ msgstr "資産" msgid "Su from" msgstr "から切り替え" -#: accounts/models/account.py:56 settings/serializers/auth/cas.py:20 +#: accounts/models/account.py:54 settings/serializers/auth/cas.py:20 #: settings/serializers/auth/feishu.py:20 terminal/models/applet/applet.py:34 msgid "Version" msgstr "バージョン" -#: accounts/models/account.py:58 accounts/serializers/account/account.py:202 -#: users/models/user.py:804 +#: accounts/models/account.py:56 accounts/serializers/account/account.py:202 +#: users/models/user.py:838 msgid "Source" msgstr "ソース" -#: accounts/models/account.py:59 +#: accounts/models/account.py:57 msgid "Source ID" msgstr "ソース ID" -#: accounts/models/account.py:62 +#: accounts/models/account.py:60 #: accounts/serializers/automations/change_secret.py:113 #: accounts/serializers/automations/change_secret.py:133 #: acls/serializers/base.py:124 assets/serializers/asset/common.py:125 @@ -253,51 +252,44 @@ msgstr "ソース ID" msgid "Account" msgstr "アカウント" -#: accounts/models/account.py:68 +#: accounts/models/account.py:66 msgid "Can view asset account secret" msgstr "資産アカウントの秘密を表示できます" -#: accounts/models/account.py:69 +#: accounts/models/account.py:67 msgid "Can view asset history account" msgstr "資産履歴アカウントを表示できます" -#: accounts/models/account.py:70 +#: accounts/models/account.py:68 msgid "Can view asset history account secret" msgstr "資産履歴アカウントパスワードを表示できます" -#: accounts/models/account.py:71 +#: accounts/models/account.py:69 msgid "Can verify account" msgstr "アカウントを確認できます" -#: accounts/models/account.py:72 +#: accounts/models/account.py:70 msgid "Can push account" msgstr "アカウントをプッシュできます" -#: accounts/models/account.py:131 -msgid "Account template" -msgstr "アカウント テンプレート" - -#: accounts/models/account.py:136 -msgid "Can view asset account template secret" -msgstr "アセット アカウント テンプレートのパスワードを表示できます" - -#: accounts/models/account.py:137 -msgid "Can change asset account template secret" -msgstr "アセット アカウント テンプレートのパスワードを変更できます" - #: accounts/models/automations/backup_account.py:27 -#: accounts/models/automations/change_secret.py:64 -#: accounts/serializers/account/backup.py:34 -#: accounts/serializers/automations/change_secret.py:57 -msgid "Recipient" +#, fuzzy +#| msgid "Recipient" +msgid "Recipient part one" msgstr "受信者" -#: accounts/models/automations/backup_account.py:36 -#: accounts/models/automations/backup_account.py:102 +#: accounts/models/automations/backup_account.py:31 +#, fuzzy +#| msgid "Recipient" +msgid "Recipient part two" +msgstr "受信者" + +#: accounts/models/automations/backup_account.py:40 +#: accounts/models/automations/backup_account.py:110 msgid "Account backup plan" msgstr "アカウントバックアップ計画" -#: accounts/models/automations/backup_account.py:83 +#: accounts/models/automations/backup_account.py:91 #: assets/models/automations/base.py:115 audits/models.py:60 #: ops/models/base.py:55 ops/models/celery.py:63 ops/models/job.py:194 #: ops/templates/ops/celery_task_log.html:75 @@ -308,17 +300,17 @@ msgstr "アカウントバックアップ計画" msgid "Date start" msgstr "開始日" -#: accounts/models/automations/backup_account.py:86 +#: accounts/models/automations/backup_account.py:94 #: authentication/templates/authentication/_msg_oauth_bind.html:11 #: notifications/notifications.py:186 msgid "Time" msgstr "時間" -#: accounts/models/automations/backup_account.py:90 +#: accounts/models/automations/backup_account.py:98 msgid "Account backup snapshot" msgstr "アカウントのバックアップスナップショット" -#: accounts/models/automations/backup_account.py:94 +#: accounts/models/automations/backup_account.py:102 #: accounts/serializers/account/backup.py:42 #: accounts/serializers/automations/base.py:55 #: assets/models/automations/base.py:122 @@ -326,19 +318,19 @@ msgstr "アカウントのバックアップスナップショット" msgid "Trigger mode" msgstr "トリガーモード" -#: accounts/models/automations/backup_account.py:97 audits/models.py:194 +#: accounts/models/automations/backup_account.py:105 audits/models.py:194 #: terminal/models/session/sharing.py:121 xpack/plugins/cloud/models.py:168 msgid "Reason" msgstr "理由" -#: accounts/models/automations/backup_account.py:99 +#: accounts/models/automations/backup_account.py:107 #: accounts/serializers/automations/change_secret.py:111 #: accounts/serializers/automations/change_secret.py:134 #: ops/serializers/job.py:56 terminal/serializers/session.py:46 msgid "Is success" msgstr "成功は" -#: accounts/models/automations/backup_account.py:107 +#: accounts/models/automations/backup_account.py:115 msgid "Account backup execution" msgstr "アカウントバックアップの実行" @@ -409,6 +401,12 @@ msgstr "パスワードルール" msgid "SSH key change strategy" msgstr "SSHキープッシュ方式" +#: accounts/models/automations/change_secret.py:64 +#: accounts/serializers/account/backup.py:34 +#: accounts/serializers/automations/change_secret.py:57 +msgid "Recipient" +msgstr "受信者" + #: accounts/models/automations/change_secret.py:71 msgid "Change secret automation" msgstr "自動暗号化" @@ -449,13 +447,14 @@ msgstr "最終ログイン日" #: accounts/models/automations/gather_account.py:17 #: accounts/models/automations/push_account.py:15 accounts/models/base.py:34 -#: acls/serializers/base.py:19 acls/serializers/base.py:50 -#: assets/models/_user.py:23 audits/models.py:179 authentication/forms.py:25 -#: authentication/forms.py:27 authentication/models/temp_token.py:9 +#: accounts/serializers/account/virtual.py:21 acls/serializers/base.py:19 +#: acls/serializers/base.py:50 assets/models/_user.py:23 audits/models.py:179 +#: authentication/forms.py:25 authentication/forms.py:27 +#: authentication/models/temp_token.py:9 #: authentication/templates/authentication/_msg_different_city.html:9 #: authentication/templates/authentication/_msg_oauth_bind.html:9 #: users/forms/profile.py:32 users/forms/profile.py:115 -#: users/models/user.py:751 users/templates/users/_msg_user_created.html:12 +#: users/models/user.py:785 users/templates/users/_msg_user_created.html:12 #: xpack/plugins/cloud/serializers/account_attrs.py:26 msgid "Username" msgstr "ユーザー名" @@ -497,15 +496,15 @@ msgstr "アカウントプッシュ" msgid "Verify asset account" msgstr "アカウントの確認" -#: accounts/models/base.py:33 acls/models/base.py:35 acls/models/base.py:96 -#: acls/models/command_acl.py:21 acls/serializers/base.py:35 -#: applications/models.py:9 assets/models/_user.py:22 -#: assets/models/asset/common.py:91 assets/models/asset/common.py:149 -#: assets/models/cmd_filter.py:21 assets/models/domain.py:18 -#: assets/models/group.py:17 assets/models/label.py:18 -#: assets/models/platform.py:15 assets/models/platform.py:88 -#: assets/serializers/asset/common.py:146 assets/serializers/platform.py:110 -#: assets/serializers/platform.py:223 +#: accounts/models/base.py:33 accounts/serializers/account/virtual.py:20 +#: acls/models/base.py:35 acls/models/base.py:96 acls/models/command_acl.py:21 +#: acls/serializers/base.py:35 applications/models.py:9 +#: assets/models/_user.py:22 assets/models/asset/common.py:91 +#: assets/models/asset/common.py:149 assets/models/cmd_filter.py:21 +#: assets/models/domain.py:18 assets/models/group.py:17 +#: assets/models/label.py:18 assets/models/platform.py:15 +#: assets/models/platform.py:88 assets/serializers/asset/common.py:146 +#: assets/serializers/platform.py:110 assets/serializers/platform.py:223 #: authentication/serializers/connect_token_secret.py:110 ops/mixin.py:21 #: ops/models/adhoc.py:20 ops/models/celery.py:15 ops/models/celery.py:57 #: ops/models/job.py:94 ops/models/playbook.py:28 ops/serializers/job.py:20 @@ -515,7 +514,7 @@ msgstr "アカウントの確認" #: terminal/models/component/endpoint.py:92 #: terminal/models/component/storage.py:26 terminal/models/component/task.py:13 #: terminal/models/component/terminal.py:84 users/forms/profile.py:33 -#: users/models/group.py:13 users/models/user.py:753 +#: users/models/group.py:13 users/models/user.py:787 #: xpack/plugins/cloud/models.py:28 msgid "Name" msgstr "名前" @@ -533,6 +532,47 @@ msgstr "特権アカウント" msgid "Is active" msgstr "アクティブです。" +#: accounts/models/template.py:19 +msgid "Account template" +msgstr "アカウント テンプレート" + +#: accounts/models/template.py:24 +msgid "Can view asset account template secret" +msgstr "アセット アカウント テンプレートのパスワードを表示できます" + +#: accounts/models/template.py:25 +msgid "Can change asset account template secret" +msgstr "アセット アカウント テンプレートのパスワードを変更できます" + +#: accounts/models/virtual.py:13 +msgid "Alias" +msgstr "別名" + +#: accounts/models/virtual.py:14 +msgid "Secret from login" +msgstr "ログインからのパスワード" + +#: accounts/models/virtual.py:27 +msgid "Same with user" +msgstr "ユーザーと同じユーザー名" + +#: accounts/models/virtual.py:36 +msgid "Non-asset account, Input username/password on connect" +msgstr "" +"アセットアカウントではない場合、接続時にユーザー名/パスワードを入力します" + +#: accounts/models/virtual.py:37 +msgid "The account username name same with user on connect" +msgstr "接続時にユーザー名と同じユーザー名を使用します" + +#: accounts/models/virtual.py:38 +msgid "" +"Connect asset without using a username and password, and it only supports " +"web-based and custom-type assets" +msgstr "" +"ユーザー名とパスワードを使用せずにアセットに接続します。Webベースとカスタムタ" +"イプのアセットのみをサポートします" + #: accounts/notifications.py:8 msgid "Notification of account backup route task results" msgstr "アカウントバックアップルートタスクの結果の通知" @@ -672,8 +712,8 @@ msgstr "ID" #: terminal/notifications.py:205 terminal/serializers/command.py:16 #: terminal/templates/terminal/_msg_command_warning.html:6 #: terminal/templates/terminal/_msg_session_sharing.html:6 -#: tickets/models/comment.py:21 users/const.py:14 users/models/user.py:947 -#: users/models/user.py:983 users/serializers/group.py:18 +#: tickets/models/comment.py:21 users/const.py:14 users/models/user.py:981 +#: users/models/user.py:1017 users/serializers/group.py:18 msgid "User" msgstr "ユーザー" @@ -721,6 +761,26 @@ msgstr "" "ヒント: 認証にユーザー名が必要ない場合は、`null`を入力します。ADアカウントの" "場合は、`username@domain`のようになります。" +#: accounts/serializers/account/virtual.py:19 assets/models/_user.py:27 +#: assets/models/cmd_filter.py:40 assets/models/cmd_filter.py:88 +#: assets/models/group.py:20 common/db/models.py:36 ops/models/adhoc.py:26 +#: ops/models/job.py:113 ops/models/playbook.py:31 rbac/models/role.py:37 +#: settings/models.py:37 terminal/models/applet/applet.py:44 +#: terminal/models/applet/applet.py:250 terminal/models/applet/host.py:141 +#: terminal/models/component/endpoint.py:24 +#: terminal/models/component/endpoint.py:102 +#: terminal/models/session/session.py:46 tickets/models/comment.py:32 +#: tickets/models/ticket/general.py:297 users/models/user.py:826 +#: xpack/plugins/cloud/models.py:35 xpack/plugins/cloud/models.py:111 +msgid "Comment" +msgstr "コメント" + +#: accounts/serializers/account/virtual.py:22 +msgid "" +"Current only support login from AD/LDAP. Secret priority: Same account in " +"asset secret > Login secret > Manual input" +msgstr "現在、AD/LDAPからのログインのみをサポートしています。シークレットの優先順位: 資産シークレット内の同じアカウント > ログインシークレット > 手動入力" + #: accounts/serializers/automations/base.py:23 #: assets/models/asset/common.py:155 assets/models/automations/base.py:18 #: assets/models/cmd_filter.py:32 assets/serializers/automations/base.py:21 @@ -780,10 +840,8 @@ msgid "Push accounts to assets" msgstr "アカウントをアセットにプッシュ:" #: accounts/tasks/vault.py:15 -#, fuzzy -#| msgid "Sync instance detail" msgid "Sync secret to vault" -msgstr "同期インスタンスの詳細" +msgstr "秘密をVaultに同期する" #: accounts/tasks/verify_account.py:49 msgid "Verify asset account availability" @@ -1116,11 +1174,6 @@ msgstr "ホスト" msgid "Device" msgstr "インターネット機器" -#: assets/const/category.py:12 assets/models/asset/database.py:9 -#: assets/models/asset/database.py:24 -msgid "Database" -msgstr "データベース" - #: assets/const/category.py:13 msgid "Cloud service" msgstr "クラウド サービス" @@ -1249,7 +1302,9 @@ msgstr "安全モード" msgid "" "When safe mode is enabled, some operations will be disabled, such as: New " "tab, right click, visit other website, etc." -msgstr "安全モードが有効になっている場合、新しいタブ、右クリック、他のウェブサイトへのアクセスなど、一部の操作が無効になります" +msgstr "" +"安全モードが有効になっている場合、新しいタブ、右クリック、他のウェブサイトへ" +"のアクセスなど、一部の操作が無効になります" #: assets/const/protocol.py:207 assets/models/asset/web.py:9 #: assets/serializers/asset/info/spec.py:16 @@ -1292,34 +1347,21 @@ msgstr "SSH秘密鍵" msgid "SSH public key" msgstr "SSHパブリックキー" -#: assets/models/_user.py:27 assets/models/cmd_filter.py:40 -#: assets/models/cmd_filter.py:88 assets/models/group.py:20 -#: common/db/models.py:36 ops/models/adhoc.py:26 ops/models/job.py:113 -#: ops/models/playbook.py:31 rbac/models/role.py:37 settings/models.py:37 -#: terminal/models/applet/applet.py:44 terminal/models/applet/applet.py:250 -#: terminal/models/applet/host.py:141 terminal/models/component/endpoint.py:24 -#: terminal/models/component/endpoint.py:102 -#: terminal/models/session/session.py:46 tickets/models/comment.py:32 -#: tickets/models/ticket/general.py:297 users/models/user.py:792 -#: xpack/plugins/cloud/models.py:35 xpack/plugins/cloud/models.py:111 -msgid "Comment" -msgstr "コメント" - #: assets/models/_user.py:28 assets/models/automations/base.py:114 #: assets/models/cmd_filter.py:41 assets/models/group.py:19 #: common/db/models.py:34 ops/models/base.py:54 ops/models/job.py:193 -#: users/models/user.py:984 +#: users/models/user.py:1018 msgid "Date created" msgstr "作成された日付" #: assets/models/_user.py:29 assets/models/cmd_filter.py:42 -#: common/db/models.py:35 users/models/user.py:813 +#: common/db/models.py:35 users/models/user.py:847 msgid "Date updated" msgstr "更新日" #: assets/models/_user.py:30 assets/models/cmd_filter.py:44 #: assets/models/cmd_filter.py:91 assets/models/group.py:18 -#: common/db/models.py:32 users/models/user.py:799 +#: common/db/models.py:32 users/models/user.py:833 #: users/serializers/group.py:29 msgid "Created by" msgstr "によって作成された" @@ -1517,7 +1559,7 @@ msgstr "確認済みの日付" #: assets/models/cmd_filter.py:28 perms/models/asset_permission.py:61 #: perms/serializers/permission.py:32 users/models/group.py:25 -#: users/models/user.py:759 +#: users/models/user.py:793 msgid "User group" msgstr "ユーザーグループ" @@ -1567,7 +1609,7 @@ msgstr "デフォルト" msgid "Default asset group" msgstr "デフォルトアセットグループ" -#: assets/models/label.py:15 rbac/const.py:6 users/models/user.py:969 +#: assets/models/label.py:15 rbac/const.py:6 users/models/user.py:1003 msgid "System" msgstr "システム" @@ -2207,7 +2249,7 @@ msgstr "ユーザーエージェント" #: audits/models.py:191 audits/serializers.py:48 #: authentication/templates/authentication/_mfa_confirm_modal.html:14 -#: users/forms/profile.py:65 users/models/user.py:776 +#: users/forms/profile.py:65 users/models/user.py:810 #: users/serializers/profile.py:126 msgid "MFA" msgstr "MFA" @@ -2263,22 +2305,22 @@ msgstr "認証トークン" #: audits/signal_handlers/login_log.py:31 authentication/notifications.py:73 #: authentication/views/login.py:75 authentication/views/wecom.py:159 #: notifications/backends/__init__.py:11 settings/serializers/auth/wecom.py:10 -#: users/models/user.py:706 users/models/user.py:814 +#: users/models/user.py:740 users/models/user.py:848 msgid "WeCom" msgstr "企業微信" #: audits/signal_handlers/login_log.py:32 authentication/views/feishu.py:122 #: authentication/views/login.py:87 notifications/backends/__init__.py:14 #: settings/serializers/auth/feishu.py:10 -#: settings/serializers/auth/feishu.py:13 users/models/user.py:708 -#: users/models/user.py:816 +#: settings/serializers/auth/feishu.py:13 users/models/user.py:742 +#: users/models/user.py:850 msgid "FeiShu" msgstr "本を飛ばす" #: audits/signal_handlers/login_log.py:33 authentication/views/dingtalk.py:159 #: authentication/views/login.py:81 notifications/backends/__init__.py:12 -#: settings/serializers/auth/dingtalk.py:10 users/models/user.py:707 -#: users/models/user.py:815 +#: settings/serializers/auth/dingtalk.py:10 users/models/user.py:741 +#: users/models/user.py:849 msgid "DingTalk" msgstr "DingTalk" @@ -2739,7 +2781,7 @@ msgstr "再利用可能" #: authentication/models/connection_token.py:47 #: authentication/models/temp_token.py:13 perms/models/asset_permission.py:74 #: tickets/models/ticket/apply_application.py:31 -#: tickets/models/ticket/apply_asset.py:20 users/models/user.py:797 +#: tickets/models/ticket/apply_asset.py:20 users/models/user.py:831 msgid "Date expired" msgstr "期限切れの日付" @@ -2776,11 +2818,11 @@ msgstr "ユーザーなしまたは期限切れのユーザー" msgid "No asset or inactive asset" msgstr "アセットがないか、有効化されていないアセット" -#: authentication/models/connection_token.py:280 +#: authentication/models/connection_token.py:265 msgid "Can view super connection token secret" msgstr "スーパー接続トークンのシークレットを表示できます" -#: authentication/models/connection_token.py:282 +#: authentication/models/connection_token.py:267 msgid "Super connection token" msgstr "スーパー接続トークン" @@ -2842,7 +2884,7 @@ msgstr "アクション" #: authentication/serializers/connection_token.py:42 #: perms/serializers/permission.py:38 perms/serializers/permission.py:57 -#: users/serializers/user.py:96 users/serializers/user.py:172 +#: users/serializers/user.py:96 users/serializers/user.py:173 msgid "Is expired" msgstr "期限切れです" @@ -2850,7 +2892,7 @@ msgstr "期限切れです" #: authentication/serializers/password_mfa.py:24 #: notifications/backends/__init__.py:10 settings/serializers/email.py:19 #: settings/serializers/email.py:50 users/forms/profile.py:102 -#: users/forms/profile.py:109 users/models/user.py:755 +#: users/forms/profile.py:109 users/models/user.py:789 #: users/templates/users/forgot_password.html:117 #: users/views/profile/reset.py:73 msgid "Email" @@ -2888,14 +2930,14 @@ msgid "Show" msgstr "表示" #: authentication/templates/authentication/_access_key_modal.html:66 -#: settings/serializers/security.py:39 users/models/user.py:601 +#: settings/serializers/security.py:39 users/models/user.py:635 #: users/serializers/profile.py:116 #: users/templates/users/user_verify_mfa.html:36 msgid "Disable" msgstr "無効化" #: authentication/templates/authentication/_access_key_modal.html:67 -#: users/models/user.py:602 users/serializers/profile.py:117 +#: users/models/user.py:636 users/serializers/profile.py:117 #: users/templates/users/mfa_setting.html:26 #: users/templates/users/mfa_setting.html:68 msgid "Enable" @@ -2940,7 +2982,7 @@ msgstr "コードエラー" #: authentication/templates/authentication/_msg_reset_password_code.html:9 #: authentication/templates/authentication/_msg_rest_password_success.html:2 #: authentication/templates/authentication/_msg_rest_public_key_success.html:2 -#: jumpserver/conf.py:437 +#: jumpserver/conf.py:441 #: perms/templates/perms/_msg_item_permissions_expire.html:3 #: perms/templates/perms/_msg_permed_items_expire.html:3 #: tickets/templates/tickets/approve_check_password.html:33 @@ -3333,7 +3375,7 @@ msgstr "は破棄されます" msgid "discard time" msgstr "時間を捨てる" -#: common/db/models.py:33 users/models/user.py:800 +#: common/db/models.py:33 users/models/user.py:834 msgid "Updated by" msgstr "によって更新" @@ -3535,11 +3577,11 @@ msgstr "検索のエクスポート: %s" msgid "User %s view/export secret" msgstr "ユーザー %s がパスワードを閲覧/導き出しました" -#: jumpserver/conf.py:436 +#: jumpserver/conf.py:440 msgid "Create account successfully" msgstr "アカウントを正常に作成" -#: jumpserver/conf.py:438 +#: jumpserver/conf.py:442 msgid "Your account has been created successfully" msgstr "アカウントが正常に作成されました" @@ -4195,7 +4237,7 @@ msgid "Scope" msgstr "スコープ" #: rbac/models/role.py:46 rbac/models/rolebinding.py:52 -#: users/models/user.py:763 +#: users/models/user.py:797 msgid "Role" msgstr "ロール" @@ -4211,22 +4253,22 @@ msgstr "組織の役割" msgid "Role binding" msgstr "ロールバインディング" -#: rbac/models/rolebinding.py:153 +#: rbac/models/rolebinding.py:161 msgid "All organizations" msgstr "全ての組織" -#: rbac/models/rolebinding.py:182 +#: rbac/models/rolebinding.py:190 msgid "" "User last role in org, can not be delete, you can remove user from org " "instead" msgstr "" "ユーザーの最後のロールは削除できません。ユーザーを組織から削除できます。" -#: rbac/models/rolebinding.py:189 +#: rbac/models/rolebinding.py:197 msgid "Organization role binding" msgstr "組織の役割バインディング" -#: rbac/models/rolebinding.py:204 +#: rbac/models/rolebinding.py:212 msgid "System role binding" msgstr "システムロールバインディング" @@ -4374,10 +4416,8 @@ msgid "Can change auth setting" msgstr "資格認定の設定" #: settings/models.py:162 -#, fuzzy -#| msgid "Can change auth setting" msgid "Can change vault setting" -msgstr "資格認定の設定" +msgstr "金庫の設定を変えることができます" #: settings/models.py:163 msgid "Can change system msg sub setting" @@ -5334,11 +5374,21 @@ msgid "Enabled, Allows user active session to be shared with other users" msgstr "" "ユーザーのアクティブなセッションを他のユーザーと共有できるようにします。" -#: settings/serializers/security.py:194 +#: settings/serializers/security.py:195 +msgid "Unused user timeout (day)" +msgstr "" + +#: settings/serializers/security.py:196 +msgid "" +"Detect infrequent users daily and disable them if they exceed the " +"predetermined time limit." +msgstr "" + +#: settings/serializers/security.py:199 msgid "Remote Login Protection" msgstr "リモートログイン保護" -#: settings/serializers/security.py:196 +#: settings/serializers/security.py:201 msgid "" "The system determines whether the login IP address belongs to a common login " "city. If the account is logged in from a common login city, the system sends " @@ -6962,78 +7012,78 @@ msgstr "公開鍵は古いものと同じであってはなりません。" msgid "Not a valid ssh public key" msgstr "有効なssh公開鍵ではありません" -#: users/forms/profile.py:173 users/models/user.py:786 +#: users/forms/profile.py:173 users/models/user.py:820 #: xpack/plugins/cloud/serializers/account_attrs.py:206 msgid "Public key" msgstr "公開キー" -#: users/models/user.py:603 users/serializers/profile.py:118 +#: users/models/user.py:637 users/serializers/profile.py:118 msgid "Force enable" msgstr "強制有効" -#: users/models/user.py:765 users/serializers/user.py:171 +#: users/models/user.py:799 users/serializers/user.py:171 msgid "Is service account" msgstr "サービスアカウントです" -#: users/models/user.py:767 +#: users/models/user.py:801 msgid "Avatar" msgstr "アバター" -#: users/models/user.py:770 +#: users/models/user.py:804 msgid "Wechat" msgstr "微信" -#: users/models/user.py:773 users/serializers/user.py:108 +#: users/models/user.py:807 users/serializers/user.py:108 msgid "Phone" msgstr "電話" -#: users/models/user.py:779 +#: users/models/user.py:813 msgid "OTP secret key" msgstr "OTP 秘密" -#: users/models/user.py:783 +#: users/models/user.py:817 #: xpack/plugins/cloud/serializers/account_attrs.py:209 msgid "Private key" msgstr "ssh秘密鍵" -#: users/models/user.py:789 +#: users/models/user.py:823 msgid "Secret key" msgstr "秘密キー" -#: users/models/user.py:794 users/serializers/profile.py:149 +#: users/models/user.py:828 users/serializers/profile.py:149 #: users/serializers/user.py:168 msgid "Is first login" msgstr "最初のログインです" -#: users/models/user.py:808 +#: users/models/user.py:842 msgid "Date password last updated" msgstr "最終更新日パスワード" -#: users/models/user.py:811 +#: users/models/user.py:845 msgid "Need update password" msgstr "更新パスワードが必要" -#: users/models/user.py:954 +#: users/models/user.py:988 msgid "Can invite user" msgstr "ユーザーを招待できます" -#: users/models/user.py:955 +#: users/models/user.py:989 msgid "Can remove user" msgstr "ユーザーを削除できます" -#: users/models/user.py:956 +#: users/models/user.py:990 msgid "Can match user" msgstr "ユーザーに一致できます" -#: users/models/user.py:965 +#: users/models/user.py:999 msgid "Administrator" msgstr "管理者" -#: users/models/user.py:968 +#: users/models/user.py:1002 msgid "Administrator is the super user of system" msgstr "管理者はシステムのスーパーユーザーです" -#: users/models/user.py:993 +#: users/models/user.py:1027 msgid "User password history" msgstr "ユーザーパスワード履歴" @@ -7108,7 +7158,7 @@ msgstr "MFAフォース有効化" msgid "Login blocked" msgstr "ログインがロックされました" -#: users/serializers/user.py:98 users/serializers/user.py:176 +#: users/serializers/user.py:98 users/serializers/user.py:177 msgid "Is OTP bound" msgstr "仮想MFAがバインドされているか" @@ -7116,23 +7166,27 @@ msgstr "仮想MFAがバインドされているか" msgid "Can public key authentication" msgstr "公開鍵認証が可能" -#: users/serializers/user.py:173 +#: users/serializers/user.py:172 +msgid "Is org admin" +msgstr "組織管理者です" + +#: users/serializers/user.py:174 msgid "Avatar url" msgstr "アバターURL" -#: users/serializers/user.py:177 +#: users/serializers/user.py:178 msgid "MFA level" msgstr "MFA レベル" -#: users/serializers/user.py:283 +#: users/serializers/user.py:284 msgid "Select users" msgstr "ユーザーの選択" -#: users/serializers/user.py:284 +#: users/serializers/user.py:285 msgid "For security, only list several users" msgstr "セキュリティのために、複数のユーザーのみをリストします" -#: users/serializers/user.py:317 +#: users/serializers/user.py:318 msgid "name not unique" msgstr "名前が一意ではない" @@ -7145,22 +7199,28 @@ msgstr "" "管理者は「既存のユーザーのみログインを許可」をオンにしており、現在のユーザー" "はユーザーリストにありません。管理者に連絡してください。" -#: users/tasks.py:21 +#: users/tasks.py:24 msgid "Check password expired" msgstr "パスワードの有効期限が切れていることを確認する" -#: users/tasks.py:35 +#: users/tasks.py:38 msgid "Periodic check password expired" msgstr "定期認証パスワードの有効期限" -#: users/tasks.py:49 +#: users/tasks.py:52 msgid "Check user expired" msgstr "ユーザーの有効期限が切れていることを確認する" -#: users/tasks.py:66 +#: users/tasks.py:69 msgid "Periodic check user expired" msgstr "ユーザーの有効期限の定期的な検出" +#: users/tasks.py:83 +#, fuzzy +#| msgid "Check user expired" +msgid "Check unused users" +msgstr "ユーザーの有効期限が切れていることを確認する" + #: users/templates/users/_msg_account_expire_reminder.html:7 msgid "Your account will expire in" msgstr "アカウントの有効期限は" @@ -7997,18 +8057,8 @@ msgstr "究極のエディション" msgid "Community edition" msgstr "コミュニティ版" -#~ msgid "Telnet login regex" -#~ msgstr "Telnetログインregex" - -#~ msgid "" -#~ "Tips: The login success message varies with devices. if you cannot log in " -#~ "to the device through Telnet, set this parameter" -#~ msgstr "" -#~ "ヒント: ログイン成功メッセージはデバイスによって異なります。Telnet経由でデ" -#~ "バイスにログインできない場合は、このパラメーターを設定します。" - -#~ msgid "Role display" -#~ msgstr "ロール表示" +#~ msgid "Current only support login from AD/LDAP" +#~ msgstr "現在、AD/LDAPからのログインのみサポートしています" #~ msgid "SFTP enabled" #~ msgstr "SFTP が有効" diff --git a/apps/locale/zh/LC_MESSAGES/django.mo b/apps/locale/zh/LC_MESSAGES/django.mo index 9823d5f58..e2d64b74a 100644 --- a/apps/locale/zh/LC_MESSAGES/django.mo +++ b/apps/locale/zh/LC_MESSAGES/django.mo @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1b7a963a93db87dd16ca9d63423b2f277dd6bc0a95abfae1533e6bf65e624da4 -size 123404 +oid sha256:ecbfbaa09e20e182a7804f2b60d7241cae6f81dbc58abede1e7a4a863b18777a +size 124596 diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po index 17a4c6e5e..969a82ed2 100644 --- a/apps/locale/zh/LC_MESSAGES/django.po +++ b/apps/locale/zh/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: JumpServer 0.3.3\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-08-03 15:51+0800\n" +"POT-Creation-Date: 2023-08-08 10:08+0800\n" "PO-Revision-Date: 2021-05-20 10:54+0800\n" "Last-Translator: ibuler \n" "Language-Team: JumpServer team\n" @@ -57,7 +57,7 @@ msgstr "" msgid "All" msgstr "全部" -#: accounts/const/account.py:15 +#: accounts/const/account.py:15 accounts/models/virtual.py:26 msgid "Manual input" msgstr "手动输入" @@ -69,29 +69,29 @@ msgstr "同名账号" msgid "Anonymous account" msgstr "匿名账号" -#: accounts/const/account.py:21 users/models/user.py:699 +#: accounts/const/account.py:25 users/models/user.py:733 msgid "Local" msgstr "数据库" -#: accounts/const/account.py:22 +#: accounts/const/account.py:26 msgid "Collected" msgstr "收集" -#: accounts/const/account.py:23 accounts/serializers/account/account.py:27 +#: accounts/const/account.py:27 accounts/serializers/account/account.py:27 #: settings/serializers/auth/sms.py:75 msgid "Template" msgstr "模板" -#: accounts/const/account.py:27 ops/const.py:45 +#: accounts/const/account.py:31 ops/const.py:45 msgid "Skip" msgstr "跳过" -#: accounts/const/account.py:28 audits/const.py:24 rbac/tree.py:230 +#: accounts/const/account.py:32 audits/const.py:24 rbac/tree.py:230 #: templates/_csv_import_export.html:18 templates/_csv_update_modal.html:6 msgid "Update" msgstr "更新" -#: accounts/const/account.py:29 +#: accounts/const/account.py:33 #: accounts/serializers/automations/change_secret.py:156 audits/const.py:54 #: audits/signal_handlers/activity_log.py:33 common/const/choices.py:19 #: ops/const.py:58 terminal/const.py:77 xpack/plugins/cloud/const.py:43 @@ -186,17 +186,16 @@ msgstr "创建并推送" msgid "Only create" msgstr "仅创建" -#: accounts/const/vault.py:8 -#, fuzzy -#| msgid "Local" -msgid "Local Vault" +#: accounts/const/vault.py:8 assets/const/category.py:12 +#: assets/models/asset/database.py:9 assets/models/asset/database.py:24 +msgid "Database" msgstr "数据库" #: accounts/const/vault.py:9 msgid "HCP Vault" -msgstr "" +msgstr "HashiCorp Vault" -#: accounts/models/account.py:50 +#: accounts/models/account.py:48 #: accounts/models/automations/gather_account.py:16 #: accounts/serializers/account/account.py:200 #: accounts/serializers/account/account.py:245 @@ -217,7 +216,7 @@ msgstr "" msgid "Asset" msgstr "资产" -#: accounts/models/account.py:54 accounts/models/account.py:127 +#: accounts/models/account.py:52 accounts/models/template.py:15 #: accounts/serializers/account/account.py:207 #: accounts/serializers/account/account.py:255 #: accounts/serializers/account/template.py:16 @@ -225,21 +224,21 @@ msgstr "资产" msgid "Su from" msgstr "切换自" -#: accounts/models/account.py:56 settings/serializers/auth/cas.py:20 +#: accounts/models/account.py:54 settings/serializers/auth/cas.py:20 #: settings/serializers/auth/feishu.py:20 terminal/models/applet/applet.py:34 msgid "Version" msgstr "版本" -#: accounts/models/account.py:58 accounts/serializers/account/account.py:202 -#: users/models/user.py:804 +#: accounts/models/account.py:56 accounts/serializers/account/account.py:202 +#: users/models/user.py:838 msgid "Source" msgstr "来源" -#: accounts/models/account.py:59 +#: accounts/models/account.py:57 msgid "Source ID" msgstr "来源 ID" -#: accounts/models/account.py:62 +#: accounts/models/account.py:60 #: accounts/serializers/automations/change_secret.py:113 #: accounts/serializers/automations/change_secret.py:133 #: acls/serializers/base.py:124 assets/serializers/asset/common.py:125 @@ -252,51 +251,44 @@ msgstr "来源 ID" msgid "Account" msgstr "账号" -#: accounts/models/account.py:68 +#: accounts/models/account.py:66 msgid "Can view asset account secret" msgstr "可以查看资产账号密码" -#: accounts/models/account.py:69 +#: accounts/models/account.py:67 msgid "Can view asset history account" msgstr "可以查看资产历史账号" -#: accounts/models/account.py:70 +#: accounts/models/account.py:68 msgid "Can view asset history account secret" msgstr "可以查看资产历史账号密码" -#: accounts/models/account.py:71 +#: accounts/models/account.py:69 msgid "Can verify account" msgstr "可以验证账号" -#: accounts/models/account.py:72 +#: accounts/models/account.py:70 msgid "Can push account" msgstr "可以推送账号" -#: accounts/models/account.py:131 -msgid "Account template" -msgstr "账号模版" - -#: accounts/models/account.py:136 -msgid "Can view asset account template secret" -msgstr "可以查看资产账号模版密码" - -#: accounts/models/account.py:137 -msgid "Can change asset account template secret" -msgstr "可以更改资产账号模版密码" - #: accounts/models/automations/backup_account.py:27 -#: accounts/models/automations/change_secret.py:64 -#: accounts/serializers/account/backup.py:34 -#: accounts/serializers/automations/change_secret.py:57 -msgid "Recipient" +#, fuzzy +#| msgid "Recipient" +msgid "Recipient part one" msgstr "收件人" -#: accounts/models/automations/backup_account.py:36 -#: accounts/models/automations/backup_account.py:102 +#: accounts/models/automations/backup_account.py:31 +#, fuzzy +#| msgid "Recipient" +msgid "Recipient part two" +msgstr "收件人" + +#: accounts/models/automations/backup_account.py:40 +#: accounts/models/automations/backup_account.py:110 msgid "Account backup plan" msgstr "账号备份计划" -#: accounts/models/automations/backup_account.py:83 +#: accounts/models/automations/backup_account.py:91 #: assets/models/automations/base.py:115 audits/models.py:60 #: ops/models/base.py:55 ops/models/celery.py:63 ops/models/job.py:194 #: ops/templates/ops/celery_task_log.html:75 @@ -307,17 +299,17 @@ msgstr "账号备份计划" msgid "Date start" msgstr "开始日期" -#: accounts/models/automations/backup_account.py:86 +#: accounts/models/automations/backup_account.py:94 #: authentication/templates/authentication/_msg_oauth_bind.html:11 #: notifications/notifications.py:186 msgid "Time" msgstr "时间" -#: accounts/models/automations/backup_account.py:90 +#: accounts/models/automations/backup_account.py:98 msgid "Account backup snapshot" msgstr "账号备份快照" -#: accounts/models/automations/backup_account.py:94 +#: accounts/models/automations/backup_account.py:102 #: accounts/serializers/account/backup.py:42 #: accounts/serializers/automations/base.py:55 #: assets/models/automations/base.py:122 @@ -325,19 +317,19 @@ msgstr "账号备份快照" msgid "Trigger mode" msgstr "触发模式" -#: accounts/models/automations/backup_account.py:97 audits/models.py:194 +#: accounts/models/automations/backup_account.py:105 audits/models.py:194 #: terminal/models/session/sharing.py:121 xpack/plugins/cloud/models.py:168 msgid "Reason" msgstr "原因" -#: accounts/models/automations/backup_account.py:99 +#: accounts/models/automations/backup_account.py:107 #: accounts/serializers/automations/change_secret.py:111 #: accounts/serializers/automations/change_secret.py:134 #: ops/serializers/job.py:56 terminal/serializers/session.py:46 msgid "Is success" msgstr "是否成功" -#: accounts/models/automations/backup_account.py:107 +#: accounts/models/automations/backup_account.py:115 msgid "Account backup execution" msgstr "账号备份执行" @@ -408,6 +400,12 @@ msgstr "密码规则" msgid "SSH key change strategy" msgstr "SSH 密钥推送方式" +#: accounts/models/automations/change_secret.py:64 +#: accounts/serializers/account/backup.py:34 +#: accounts/serializers/automations/change_secret.py:57 +msgid "Recipient" +msgstr "收件人" + #: accounts/models/automations/change_secret.py:71 msgid "Change secret automation" msgstr "自动化改密" @@ -448,13 +446,14 @@ msgstr "最后登录日期" #: accounts/models/automations/gather_account.py:17 #: accounts/models/automations/push_account.py:15 accounts/models/base.py:34 -#: acls/serializers/base.py:19 acls/serializers/base.py:50 -#: assets/models/_user.py:23 audits/models.py:179 authentication/forms.py:25 -#: authentication/forms.py:27 authentication/models/temp_token.py:9 +#: accounts/serializers/account/virtual.py:21 acls/serializers/base.py:19 +#: acls/serializers/base.py:50 assets/models/_user.py:23 audits/models.py:179 +#: authentication/forms.py:25 authentication/forms.py:27 +#: authentication/models/temp_token.py:9 #: authentication/templates/authentication/_msg_different_city.html:9 #: authentication/templates/authentication/_msg_oauth_bind.html:9 #: users/forms/profile.py:32 users/forms/profile.py:115 -#: users/models/user.py:751 users/templates/users/_msg_user_created.html:12 +#: users/models/user.py:785 users/templates/users/_msg_user_created.html:12 #: xpack/plugins/cloud/serializers/account_attrs.py:26 msgid "Username" msgstr "用户名" @@ -496,15 +495,15 @@ msgstr "账号推送" msgid "Verify asset account" msgstr "账号验证" -#: accounts/models/base.py:33 acls/models/base.py:35 acls/models/base.py:96 -#: acls/models/command_acl.py:21 acls/serializers/base.py:35 -#: applications/models.py:9 assets/models/_user.py:22 -#: assets/models/asset/common.py:91 assets/models/asset/common.py:149 -#: assets/models/cmd_filter.py:21 assets/models/domain.py:18 -#: assets/models/group.py:17 assets/models/label.py:18 -#: assets/models/platform.py:15 assets/models/platform.py:88 -#: assets/serializers/asset/common.py:146 assets/serializers/platform.py:110 -#: assets/serializers/platform.py:223 +#: accounts/models/base.py:33 accounts/serializers/account/virtual.py:20 +#: acls/models/base.py:35 acls/models/base.py:96 acls/models/command_acl.py:21 +#: acls/serializers/base.py:35 applications/models.py:9 +#: assets/models/_user.py:22 assets/models/asset/common.py:91 +#: assets/models/asset/common.py:149 assets/models/cmd_filter.py:21 +#: assets/models/domain.py:18 assets/models/group.py:17 +#: assets/models/label.py:18 assets/models/platform.py:15 +#: assets/models/platform.py:88 assets/serializers/asset/common.py:146 +#: assets/serializers/platform.py:110 assets/serializers/platform.py:223 #: authentication/serializers/connect_token_secret.py:110 ops/mixin.py:21 #: ops/models/adhoc.py:20 ops/models/celery.py:15 ops/models/celery.py:57 #: ops/models/job.py:94 ops/models/playbook.py:28 ops/serializers/job.py:20 @@ -514,7 +513,7 @@ msgstr "账号验证" #: terminal/models/component/endpoint.py:92 #: terminal/models/component/storage.py:26 terminal/models/component/task.py:13 #: terminal/models/component/terminal.py:84 users/forms/profile.py:33 -#: users/models/group.py:13 users/models/user.py:753 +#: users/models/group.py:13 users/models/user.py:787 #: xpack/plugins/cloud/models.py:28 msgid "Name" msgstr "名称" @@ -532,6 +531,51 @@ msgstr "特权账号" msgid "Is active" msgstr "激活" +#: accounts/models/template.py:19 +msgid "Account template" +msgstr "账号模版" + +# msgid "Account template" +# msgstr "账号模版" +#: accounts/models/template.py:24 +msgid "Can view asset account template secret" +msgstr "可以查看资产账号模版密码" + +#: accounts/models/template.py:25 +msgid "Can change asset account template secret" +msgstr "可以更改资产账号模版密码" + +# msgid "Can view asset account template secret" +# msgstr "可以查看资产账号模版密码" +# msgid "Can change asset account template secret" +# msgstr "可以更改资产账号模版密码" +#: accounts/models/virtual.py:13 +msgid "Alias" +msgstr "别名" + +#: accounts/models/virtual.py:14 +msgid "Secret from login" +msgstr "与用户登录时相同" + +#: accounts/models/virtual.py:27 +msgid "Same with user" +msgstr "用户名与用户相同" + +#: accounts/models/virtual.py:36 +msgid "Non-asset account, Input username/password on connect" +msgstr "登录时手动输入 用户名/密码 来连接的账号" + +#: accounts/models/virtual.py:37 +msgid "The account username name same with user on connect" +msgstr "登录资产时,账号用户名与使用者用户名相同的账号" + +#: accounts/models/virtual.py:38 +msgid "" +"Connect asset without using a username and password, and it only supports " +"web-based and custom-type assets" +msgstr "" +"连接资产时不使用用户名和密码的账号,仅支持 web类型 和 自定义类型 的资产" + #: accounts/notifications.py:8 msgid "Notification of account backup route task results" msgstr "账号备份任务结果通知" @@ -668,8 +712,8 @@ msgstr "ID" #: terminal/notifications.py:205 terminal/serializers/command.py:16 #: terminal/templates/terminal/_msg_command_warning.html:6 #: terminal/templates/terminal/_msg_session_sharing.html:6 -#: tickets/models/comment.py:21 users/const.py:14 users/models/user.py:947 -#: users/models/user.py:983 users/serializers/group.py:18 +#: tickets/models/comment.py:21 users/const.py:14 users/models/user.py:981 +#: users/models/user.py:1017 users/serializers/group.py:18 msgid "User" msgstr "用户" @@ -717,6 +761,26 @@ msgstr "" "提示: 如果认证时不需要用户名,可填写为 null, 如果是 AD 账号,格式为 " "username@domain" +#: accounts/serializers/account/virtual.py:19 assets/models/_user.py:27 +#: assets/models/cmd_filter.py:40 assets/models/cmd_filter.py:88 +#: assets/models/group.py:20 common/db/models.py:36 ops/models/adhoc.py:26 +#: ops/models/job.py:113 ops/models/playbook.py:31 rbac/models/role.py:37 +#: settings/models.py:37 terminal/models/applet/applet.py:44 +#: terminal/models/applet/applet.py:250 terminal/models/applet/host.py:141 +#: terminal/models/component/endpoint.py:24 +#: terminal/models/component/endpoint.py:102 +#: terminal/models/session/session.py:46 tickets/models/comment.py:32 +#: tickets/models/ticket/general.py:297 users/models/user.py:826 +#: xpack/plugins/cloud/models.py:35 xpack/plugins/cloud/models.py:111 +msgid "Comment" +msgstr "备注" + +#: accounts/serializers/account/virtual.py:22 +msgid "" +"Current only support login from AD/LDAP. Secret priority: Same account in " +"asset secret > Login secret > Manual input" +msgstr "当前仅支持 AD/LDAP 登录方式用户。 同名账号密码生效顺序: 资产上存在的同名账号密码 > 登录密码 > 手动输入" + #: accounts/serializers/automations/base.py:23 #: assets/models/asset/common.py:155 assets/models/automations/base.py:18 #: assets/models/cmd_filter.py:32 assets/serializers/automations/base.py:21 @@ -776,10 +840,8 @@ msgid "Push accounts to assets" msgstr "推送账号到资产" #: accounts/tasks/vault.py:15 -#, fuzzy -#| msgid "Sync instance detail" msgid "Sync secret to vault" -msgstr "同步实例详情" +msgstr "同步密文到 vault" #: accounts/tasks/verify_account.py:49 msgid "Verify asset account availability" @@ -1109,11 +1171,6 @@ msgstr "主机" msgid "Device" msgstr "网络设备" -#: assets/const/category.py:12 assets/models/asset/database.py:9 -#: assets/models/asset/database.py:24 -msgid "Database" -msgstr "数据库" - #: assets/const/category.py:13 msgid "Cloud service" msgstr "云服务" @@ -1242,7 +1299,8 @@ msgstr "安全模式" msgid "" "When safe mode is enabled, some operations will be disabled, such as: New " "tab, right click, visit other website, etc." -msgstr "当安全模式启用时,一些操作将被禁用,例如:新建标签页、右键、访问其它网站 等" +msgstr "" +"当安全模式启用时,一些操作将被禁用,例如:新建标签页、右键、访问其它网站 等" #: assets/const/protocol.py:207 assets/models/asset/web.py:9 #: assets/serializers/asset/info/spec.py:16 @@ -1285,34 +1343,23 @@ msgstr "SSH密钥" msgid "SSH public key" msgstr "SSH公钥" -#: assets/models/_user.py:27 assets/models/cmd_filter.py:40 -#: assets/models/cmd_filter.py:88 assets/models/group.py:20 -#: common/db/models.py:36 ops/models/adhoc.py:26 ops/models/job.py:113 -#: ops/models/playbook.py:31 rbac/models/role.py:37 settings/models.py:37 -#: terminal/models/applet/applet.py:44 terminal/models/applet/applet.py:250 -#: terminal/models/applet/host.py:141 terminal/models/component/endpoint.py:24 -#: terminal/models/component/endpoint.py:102 -#: terminal/models/session/session.py:46 tickets/models/comment.py:32 -#: tickets/models/ticket/general.py:297 users/models/user.py:792 -#: xpack/plugins/cloud/models.py:35 xpack/plugins/cloud/models.py:111 -msgid "Comment" -msgstr "备注" - +# msgid "Comment" +# msgstr "备注" #: assets/models/_user.py:28 assets/models/automations/base.py:114 #: assets/models/cmd_filter.py:41 assets/models/group.py:19 #: common/db/models.py:34 ops/models/base.py:54 ops/models/job.py:193 -#: users/models/user.py:984 +#: users/models/user.py:1018 msgid "Date created" msgstr "创建日期" #: assets/models/_user.py:29 assets/models/cmd_filter.py:42 -#: common/db/models.py:35 users/models/user.py:813 +#: common/db/models.py:35 users/models/user.py:847 msgid "Date updated" msgstr "更新日期" #: assets/models/_user.py:30 assets/models/cmd_filter.py:44 #: assets/models/cmd_filter.py:91 assets/models/group.py:18 -#: common/db/models.py:32 users/models/user.py:799 +#: common/db/models.py:32 users/models/user.py:833 #: users/serializers/group.py:29 msgid "Created by" msgstr "创建者" @@ -1510,7 +1557,7 @@ msgstr "校验日期" #: assets/models/cmd_filter.py:28 perms/models/asset_permission.py:61 #: perms/serializers/permission.py:32 users/models/group.py:25 -#: users/models/user.py:759 +#: users/models/user.py:793 msgid "User group" msgstr "用户组" @@ -1560,7 +1607,7 @@ msgstr "默认" msgid "Default asset group" msgstr "默认资产组" -#: assets/models/label.py:15 rbac/const.py:6 users/models/user.py:969 +#: assets/models/label.py:15 rbac/const.py:6 users/models/user.py:1003 msgid "System" msgstr "系统" @@ -2191,7 +2238,7 @@ msgstr "用户代理" #: audits/models.py:191 audits/serializers.py:48 #: authentication/templates/authentication/_mfa_confirm_modal.html:14 -#: users/forms/profile.py:65 users/models/user.py:776 +#: users/forms/profile.py:65 users/models/user.py:810 #: users/serializers/profile.py:126 msgid "MFA" msgstr "MFA" @@ -2247,22 +2294,22 @@ msgstr "认证令牌" #: audits/signal_handlers/login_log.py:31 authentication/notifications.py:73 #: authentication/views/login.py:75 authentication/views/wecom.py:159 #: notifications/backends/__init__.py:11 settings/serializers/auth/wecom.py:10 -#: users/models/user.py:706 users/models/user.py:814 +#: users/models/user.py:740 users/models/user.py:848 msgid "WeCom" msgstr "企业微信" #: audits/signal_handlers/login_log.py:32 authentication/views/feishu.py:122 #: authentication/views/login.py:87 notifications/backends/__init__.py:14 #: settings/serializers/auth/feishu.py:10 -#: settings/serializers/auth/feishu.py:13 users/models/user.py:708 -#: users/models/user.py:816 +#: settings/serializers/auth/feishu.py:13 users/models/user.py:742 +#: users/models/user.py:850 msgid "FeiShu" msgstr "飞书" #: audits/signal_handlers/login_log.py:33 authentication/views/dingtalk.py:159 #: authentication/views/login.py:81 notifications/backends/__init__.py:12 -#: settings/serializers/auth/dingtalk.py:10 users/models/user.py:707 -#: users/models/user.py:815 +#: settings/serializers/auth/dingtalk.py:10 users/models/user.py:741 +#: users/models/user.py:849 msgid "DingTalk" msgstr "钉钉" @@ -2707,7 +2754,7 @@ msgstr "可以重复使用" #: authentication/models/connection_token.py:47 #: authentication/models/temp_token.py:13 perms/models/asset_permission.py:74 #: tickets/models/ticket/apply_application.py:31 -#: tickets/models/ticket/apply_asset.py:20 users/models/user.py:797 +#: tickets/models/ticket/apply_asset.py:20 users/models/user.py:831 msgid "Date expired" msgstr "失效日期" @@ -2744,11 +2791,11 @@ msgstr "没有用户或用户失效" msgid "No asset or inactive asset" msgstr "没有资产或资产未激活" -#: authentication/models/connection_token.py:280 +#: authentication/models/connection_token.py:265 msgid "Can view super connection token secret" msgstr "可以查看超级连接令牌密文" -#: authentication/models/connection_token.py:282 +#: authentication/models/connection_token.py:267 msgid "Super connection token" msgstr "超级连接令牌" @@ -2810,7 +2857,7 @@ msgstr "动作" #: authentication/serializers/connection_token.py:42 #: perms/serializers/permission.py:38 perms/serializers/permission.py:57 -#: users/serializers/user.py:96 users/serializers/user.py:172 +#: users/serializers/user.py:96 users/serializers/user.py:173 msgid "Is expired" msgstr "已过期" @@ -2818,7 +2865,7 @@ msgstr "已过期" #: authentication/serializers/password_mfa.py:24 #: notifications/backends/__init__.py:10 settings/serializers/email.py:19 #: settings/serializers/email.py:50 users/forms/profile.py:102 -#: users/forms/profile.py:109 users/models/user.py:755 +#: users/forms/profile.py:109 users/models/user.py:789 #: users/templates/users/forgot_password.html:117 #: users/views/profile/reset.py:73 msgid "Email" @@ -2856,14 +2903,14 @@ msgid "Show" msgstr "显示" #: authentication/templates/authentication/_access_key_modal.html:66 -#: settings/serializers/security.py:39 users/models/user.py:601 +#: settings/serializers/security.py:39 users/models/user.py:635 #: users/serializers/profile.py:116 #: users/templates/users/user_verify_mfa.html:36 msgid "Disable" msgstr "禁用" #: authentication/templates/authentication/_access_key_modal.html:67 -#: users/models/user.py:602 users/serializers/profile.py:117 +#: users/models/user.py:636 users/serializers/profile.py:117 #: users/templates/users/mfa_setting.html:26 #: users/templates/users/mfa_setting.html:68 msgid "Enable" @@ -2908,7 +2955,7 @@ msgstr "代码错误" #: authentication/templates/authentication/_msg_reset_password_code.html:9 #: authentication/templates/authentication/_msg_rest_password_success.html:2 #: authentication/templates/authentication/_msg_rest_public_key_success.html:2 -#: jumpserver/conf.py:437 +#: jumpserver/conf.py:441 #: perms/templates/perms/_msg_item_permissions_expire.html:3 #: perms/templates/perms/_msg_permed_items_expire.html:3 #: tickets/templates/tickets/approve_check_password.html:33 @@ -3293,7 +3340,7 @@ msgstr "忽略的" msgid "discard time" msgstr "忽略时间" -#: common/db/models.py:33 users/models/user.py:800 +#: common/db/models.py:33 users/models/user.py:834 msgid "Updated by" msgstr "最后更新者" @@ -3493,11 +3540,11 @@ msgstr "导出搜素: %s" msgid "User %s view/export secret" msgstr "用户 %s 查看/导出 了密码" -#: jumpserver/conf.py:436 +#: jumpserver/conf.py:440 msgid "Create account successfully" msgstr "创建账号成功" -#: jumpserver/conf.py:438 +#: jumpserver/conf.py:442 msgid "Your account has been created successfully" msgstr "你的账号已创建成功" @@ -4147,7 +4194,7 @@ msgid "Scope" msgstr "范围" #: rbac/models/role.py:46 rbac/models/rolebinding.py:52 -#: users/models/user.py:763 +#: users/models/user.py:797 msgid "Role" msgstr "角色" @@ -4163,21 +4210,21 @@ msgstr "组织角色" msgid "Role binding" msgstr "角色绑定" -#: rbac/models/rolebinding.py:153 +#: rbac/models/rolebinding.py:161 msgid "All organizations" msgstr "所有组织" -#: rbac/models/rolebinding.py:182 +#: rbac/models/rolebinding.py:190 msgid "" "User last role in org, can not be delete, you can remove user from org " "instead" msgstr "用户最后一个角色,不能删除,你可以将用户从组织移除" -#: rbac/models/rolebinding.py:189 +#: rbac/models/rolebinding.py:197 msgid "Organization role binding" msgstr "组织角色绑定" -#: rbac/models/rolebinding.py:204 +#: rbac/models/rolebinding.py:212 msgid "System role binding" msgstr "系统角色绑定" @@ -4325,10 +4372,8 @@ msgid "Can change auth setting" msgstr "认证设置" #: settings/models.py:162 -#, fuzzy -#| msgid "Can change auth setting" msgid "Can change vault setting" -msgstr "认证设置" +msgstr "可以更改 vault 设置" #: settings/models.py:163 msgid "Can change system msg sub setting" @@ -5261,11 +5306,21 @@ msgstr "会话分享" msgid "Enabled, Allows user active session to be shared with other users" msgstr "开启后允许用户分享已连接的资产会话给他人,协同工作" -#: settings/serializers/security.py:194 +#: settings/serializers/security.py:195 +msgid "Unused user timeout (day)" +msgstr "" + +#: settings/serializers/security.py:196 +msgid "" +"Detect infrequent users daily and disable them if they exceed the " +"predetermined time limit." +msgstr "" + +#: settings/serializers/security.py:199 msgid "Remote Login Protection" msgstr "异地登录保护" -#: settings/serializers/security.py:196 +#: settings/serializers/security.py:201 msgid "" "The system determines whether the login IP address belongs to a common login " "city. If the account is logged in from a common login city, the system sends " @@ -6863,78 +6918,78 @@ msgstr "不能和原来的密钥相同" msgid "Not a valid ssh public key" msgstr "SSH密钥不合法" -#: users/forms/profile.py:173 users/models/user.py:786 +#: users/forms/profile.py:173 users/models/user.py:820 #: xpack/plugins/cloud/serializers/account_attrs.py:206 msgid "Public key" msgstr "SSH公钥" -#: users/models/user.py:603 users/serializers/profile.py:118 +#: users/models/user.py:637 users/serializers/profile.py:118 msgid "Force enable" msgstr "强制启用" -#: users/models/user.py:765 users/serializers/user.py:171 +#: users/models/user.py:799 users/serializers/user.py:171 msgid "Is service account" msgstr "服务账号" -#: users/models/user.py:767 +#: users/models/user.py:801 msgid "Avatar" msgstr "头像" -#: users/models/user.py:770 +#: users/models/user.py:804 msgid "Wechat" msgstr "微信" -#: users/models/user.py:773 users/serializers/user.py:108 +#: users/models/user.py:807 users/serializers/user.py:108 msgid "Phone" msgstr "手机" -#: users/models/user.py:779 +#: users/models/user.py:813 msgid "OTP secret key" msgstr "OTP 密钥" -#: users/models/user.py:783 +#: users/models/user.py:817 #: xpack/plugins/cloud/serializers/account_attrs.py:209 msgid "Private key" msgstr "ssh私钥" -#: users/models/user.py:789 +#: users/models/user.py:823 msgid "Secret key" msgstr "Secret key" -#: users/models/user.py:794 users/serializers/profile.py:149 +#: users/models/user.py:828 users/serializers/profile.py:149 #: users/serializers/user.py:168 msgid "Is first login" msgstr "首次登录" -#: users/models/user.py:808 +#: users/models/user.py:842 msgid "Date password last updated" msgstr "最后更新密码日期" -#: users/models/user.py:811 +#: users/models/user.py:845 msgid "Need update password" msgstr "需要更新密码" -#: users/models/user.py:954 +#: users/models/user.py:988 msgid "Can invite user" msgstr "可以邀请用户" -#: users/models/user.py:955 +#: users/models/user.py:989 msgid "Can remove user" msgstr "可以移除用户" -#: users/models/user.py:956 +#: users/models/user.py:990 msgid "Can match user" msgstr "可以匹配用户" -#: users/models/user.py:965 +#: users/models/user.py:999 msgid "Administrator" msgstr "管理员" -#: users/models/user.py:968 +#: users/models/user.py:1002 msgid "Administrator is the super user of system" msgstr "Administrator是初始的超级管理员" -#: users/models/user.py:993 +#: users/models/user.py:1027 msgid "User password history" msgstr "用户密码历史" @@ -7009,7 +7064,7 @@ msgstr "强制 MFA" msgid "Login blocked" msgstr "登录被锁定" -#: users/serializers/user.py:98 users/serializers/user.py:176 +#: users/serializers/user.py:98 users/serializers/user.py:177 msgid "Is OTP bound" msgstr "是否绑定了虚拟 MFA" @@ -7017,23 +7072,27 @@ msgstr "是否绑定了虚拟 MFA" msgid "Can public key authentication" msgstr "可以使用公钥认证" -#: users/serializers/user.py:173 +#: users/serializers/user.py:172 +msgid "Is org admin" +msgstr "组织管理员" + +#: users/serializers/user.py:174 msgid "Avatar url" msgstr "头像路径" -#: users/serializers/user.py:177 +#: users/serializers/user.py:178 msgid "MFA level" msgstr "MFA 级别" -#: users/serializers/user.py:283 +#: users/serializers/user.py:284 msgid "Select users" msgstr "选择用户" -#: users/serializers/user.py:284 +#: users/serializers/user.py:285 msgid "For security, only list several users" msgstr "为了安全,仅列出几个用户" -#: users/serializers/user.py:317 +#: users/serializers/user.py:318 msgid "name not unique" msgstr "名称重复" @@ -7045,22 +7104,28 @@ msgid "" msgstr "" "管理员已开启'仅允许已存在用户登录',当前用户不在用户列表中,请联系管理员。" -#: users/tasks.py:21 +#: users/tasks.py:24 msgid "Check password expired" msgstr "校验密码已过期" -#: users/tasks.py:35 +#: users/tasks.py:38 msgid "Periodic check password expired" msgstr "周期校验密码过期" -#: users/tasks.py:49 +#: users/tasks.py:52 msgid "Check user expired" msgstr "校验用户已过期" -#: users/tasks.py:66 +#: users/tasks.py:69 msgid "Periodic check user expired" msgstr "周期检测用户过期" +#: users/tasks.py:83 +#, fuzzy +#| msgid "Check user expired" +msgid "Check unused users" +msgstr "校验用户已过期" + #: users/templates/users/_msg_account_expire_reminder.html:7 msgid "Your account will expire in" msgstr "您的账号即将过期" @@ -7882,18 +7947,8 @@ msgstr "旗舰版" msgid "Community edition" msgstr "社区版" -#~ msgid "Telnet login regex" -#~ msgstr "Telnet 成功正则表达式" - -#~ msgid "" -#~ "Tips: The login success message varies with devices. if you cannot log in " -#~ "to the device through Telnet, set this parameter" -#~ msgstr "" -#~ "提示: 不同设备登录成功提示不一样,所以如果 telnet 不能正常登录,可以这里设" -#~ "置" - -#~ msgid "Role display" -#~ msgstr "角色显示" +#~ msgid "Current only support login from AD/LDAP" +#~ msgstr "当前仅支持 AD/LDAP 方式登录的用户" #~ msgid "SFTP enabled" #~ msgstr "SFTP 已启用" diff --git a/apps/perms/utils/account.py b/apps/perms/utils/account.py index d97343372..302552315 100644 --- a/apps/perms/utils/account.py +++ b/apps/perms/utils/account.py @@ -1,7 +1,7 @@ from collections import defaultdict from accounts.const import AliasAccount -from accounts.models import Account +from accounts.models import VirtualAccount from orgs.utils import tmp_to_org from .permission import AssetPermissionUtil @@ -61,17 +61,12 @@ class PermAccountUtil(AssetPermissionUtil): for alias, action_bit in alias_action_bit_mapper.items(): account = None _accounts = [] - if alias == AliasAccount.USER: - if user.username in username_accounts_mapper: - _accounts = username_accounts_mapper[user.username] - else: - account = Account.get_user_account() - elif alias == AliasAccount.INPUT: - account = Account.get_manual_account() - elif alias == AliasAccount.ANON: - account = Account.get_anonymous_account() + if alias == AliasAccount.USER and user.username in username_accounts_mapper: + account = username_accounts_mapper[user.username] elif alias in username_accounts_mapper: _accounts = username_accounts_mapper[alias] + elif alias in ['@INPUT', '@ANON', '@USER']: + account = VirtualAccount.get_special_account(alias, user, asset, from_permed=True) elif alias.startswith('@'): continue diff --git a/apps/rbac/models/rolebinding.py b/apps/rbac/models/rolebinding.py index 72b36e5dd..e9d636354 100644 --- a/apps/rbac/models/rolebinding.py +++ b/apps/rbac/models/rolebinding.py @@ -116,6 +116,14 @@ class RoleBinding(JMSBaseModel): default_system_orgs = orgs.filter(id__in=default_system_org_ids) return default_system_orgs | orgs.exclude(id__in=default_system_org_ids).order_by('name') + @classmethod + def get_user_joined_orgs(cls, user): + from orgs.models import Organization + org_ids = cls.objects.filter(user=user, scope=Scope.org) \ + .values_list('org', flat=True) \ + .distinct() + return Organization.objects.filter(id__in=org_ids) + @classmethod def get_user_has_the_perm_orgs(cls, perm, user): from orgs.models import Organization diff --git a/apps/settings/serializers/public.py b/apps/settings/serializers/public.py index 3d61bd98c..49ee3e1e1 100644 --- a/apps/settings/serializers/public.py +++ b/apps/settings/serializers/public.py @@ -52,6 +52,7 @@ class PrivateSettingSerializer(PublicSettingSerializer): TICKETS_ENABLED = serializers.BooleanField() CONNECTION_TOKEN_REUSABLE = serializers.BooleanField() + CACHE_LOGIN_PASSWORD_ENABLED = serializers.BooleanField() class ServerInfoSerializer(serializers.Serializer): diff --git a/apps/users/models/user.py b/apps/users/models/user.py index 4e1f2757b..69ed7fa80 100644 --- a/apps/users/models/user.py +++ b/apps/users/models/user.py @@ -44,6 +44,8 @@ class AuthMixin: set_password: Callable save: Callable history_passwords: models.Manager + sect_cache_tpl = 'user_sect_{}' + id: str | uuid.UUID @property def password_raw(self): @@ -169,6 +171,33 @@ class AuthMixin: self_key_md5 = self.get_public_key_md5(self.public_key) return key_md5 == self_key_md5 + def cache_login_password_if_need(self, password): + from common.utils import signer + if not settings.CACHE_LOGIN_PASSWORD_ENABLED: + return + backend = getattr(self, 'backend', '') + if backend.lower().find('ldap') < 0: + return + if not password: + return + key = self.sect_cache_tpl.format(self.id) + ttl = settings.CACHE_LOGIN_PASSWORD_TTL + if not isinstance(ttl, int) or ttl <= 0: + return + secret = signer.sign(password) + cache.set(key, secret, ttl) + + def get_cached_password_if_has(self): + from common.utils import signer + if not settings.CACHE_LOGIN_PASSWORD_ENABLED: + return '' + key = self.sect_cache_tpl.format(self.id) + secret = cache.get(key) + if not secret: + return '' + password = signer.unsign(secret) + return password + class RoleManager(models.Manager): scope = None @@ -359,6 +388,11 @@ class RoleMixin: def workbench_orgs(self): return self.cached_orgs['workbench_orgs'] + @lazyproperty + def joined_orgs(self): + from rbac.models import RoleBinding + return RoleBinding.get_user_joined_orgs(self) + @lazyproperty def cached_orgs(self): from rbac.models import RoleBinding diff --git a/apps/users/serializers/user.py b/apps/users/serializers/user.py index ee10ddf74..ea7568622 100644 --- a/apps/users/serializers/user.py +++ b/apps/users/serializers/user.py @@ -169,6 +169,7 @@ class UserSerializer(RolesSerializerMixin, CommonBulkSerializerMixin, serializer "is_active": {"label": _("Is active")}, "is_valid": {"label": _("Is valid")}, "is_service_account": {"label": _("Is service account")}, + "is_org_admin": {"label": _("Is org admin")}, "is_expired": {"label": _("Is expired")}, "avatar_url": {"label": _("Avatar url")}, "created_by": {"read_only": True, "allow_blank": True}, From c72ec5ea780e1eb18fa55dfadabc2b34a9e4432e Mon Sep 17 00:00:00 2001 From: ibuler Date: Tue, 8 Aug 2023 10:25:27 +0800 Subject: [PATCH 108/177] =?UTF-8?q?perf:=20=E7=BB=84=E7=BB=87=E5=B1=9E?= =?UTF-8?q?=E6=80=A7=E6=B7=BB=E5=8A=A0=20internal?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/orgs/models.py | 8 ++++++++ apps/orgs/serializers.py | 6 +++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/apps/orgs/models.py b/apps/orgs/models.py index 66286e38e..2e2bbcc29 100644 --- a/apps/orgs/models.py +++ b/apps/orgs/models.py @@ -1,5 +1,6 @@ from django.db import models from django.utils.translation import gettext_lazy as _ +from rest_framework.serializers import ValidationError from common.db.models import JMSBaseModel from common.tree import TreeNode @@ -15,6 +16,7 @@ class OrgRoleMixin: DEFAULT_NAME = _('DEFAULT') SYSTEM_ID = '00000000-0000-0000-0000-000000000004' SYSTEM_NAME = _('SYSTEM') + VIRTUAL_IDS = [ROOT_ID, DEFAULT_ID, SYSTEM_ID] members: models.Manager id: str @@ -171,6 +173,10 @@ class Organization(OrgRoleMixin, JMSBaseModel): def is_default(self): return str(self.id) == self.DEFAULT_ID + @property + def internal(self): + return str(self.id) in self.VIRTUAL_IDS + def change_to(self): from .utils import set_current_org set_current_org(self) @@ -223,5 +229,7 @@ class Organization(OrgRoleMixin, JMSBaseModel): TicketFlow.objects.filter(org_id=self.id).delete() def delete(self, *args, **kwargs): + if str(self.id) in self.VIRTUAL_IDS: + raise ValidationError(_('Can not delete virtual org')) self.delete_related_models() return super().delete(*args, **kwargs) diff --git a/apps/orgs/serializers.py b/apps/orgs/serializers.py index c080332dd..efa1fa311 100644 --- a/apps/orgs/serializers.py +++ b/apps/orgs/serializers.py @@ -1,8 +1,8 @@ -from rest_framework.serializers import ModelSerializer from rest_framework import serializers +from rest_framework.serializers import ModelSerializer -from .utils import get_current_org from .models import Organization +from .utils import get_current_org class ResourceStatisticsSerializer(serializers.Serializer): @@ -25,7 +25,7 @@ class OrgSerializer(ModelSerializer): fields_mini = ['id', 'name'] fields_small = fields_mini + [ 'resource_statistics', - 'is_default', 'is_root', + 'is_default', 'is_root', 'internal', 'date_created', 'created_by', 'comment', 'created_by', ] From e8912839252d655dc5f01b5af9eb6254b3e9a6b3 Mon Sep 17 00:00:00 2001 From: ibuler Date: Tue, 8 Aug 2023 10:29:22 +0800 Subject: [PATCH 109/177] =?UTF-8?q?perf:=20System=20=E7=BB=84=E7=BB=87?= =?UTF-8?q?=E4=B8=8D=E5=85=81=E8=AE=B8=E5=88=A0=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/orgs/models.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/orgs/models.py b/apps/orgs/models.py index 2e2bbcc29..e667ac4d7 100644 --- a/apps/orgs/models.py +++ b/apps/orgs/models.py @@ -16,7 +16,7 @@ class OrgRoleMixin: DEFAULT_NAME = _('DEFAULT') SYSTEM_ID = '00000000-0000-0000-0000-000000000004' SYSTEM_NAME = _('SYSTEM') - VIRTUAL_IDS = [ROOT_ID, DEFAULT_ID, SYSTEM_ID] + INTERNAL_IDS = [ROOT_ID, DEFAULT_ID, SYSTEM_ID] members: models.Manager id: str @@ -175,7 +175,7 @@ class Organization(OrgRoleMixin, JMSBaseModel): @property def internal(self): - return str(self.id) in self.VIRTUAL_IDS + return str(self.id) in self.INTERNAL_IDS def change_to(self): from .utils import set_current_org @@ -229,7 +229,7 @@ class Organization(OrgRoleMixin, JMSBaseModel): TicketFlow.objects.filter(org_id=self.id).delete() def delete(self, *args, **kwargs): - if str(self.id) in self.VIRTUAL_IDS: + if str(self.id) in self.INTERNAL_IDS: raise ValidationError(_('Can not delete virtual org')) self.delete_related_models() return super().delete(*args, **kwargs) From a297355a0d09d1b6da2c66dcfde6299505ad1765 Mon Sep 17 00:00:00 2001 From: Bai Date: Tue, 8 Aug 2023 11:34:25 +0800 Subject: [PATCH 110/177] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=20accounts=20?= =?UTF-8?q?=E8=BF=81=E7=A7=BB=E6=96=87=E4=BB=B6=E7=BC=96=E5=8F=B7=E5=86=B2?= =?UTF-8?q?=E7=AA=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../{0013_virtualaccount.py => 0014_virtualaccount.py} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename apps/accounts/migrations/{0013_virtualaccount.py => 0014_virtualaccount.py} (96%) diff --git a/apps/accounts/migrations/0013_virtualaccount.py b/apps/accounts/migrations/0014_virtualaccount.py similarity index 96% rename from apps/accounts/migrations/0013_virtualaccount.py rename to apps/accounts/migrations/0014_virtualaccount.py index 9b3b02b7c..b2c344fce 100644 --- a/apps/accounts/migrations/0013_virtualaccount.py +++ b/apps/accounts/migrations/0014_virtualaccount.py @@ -7,7 +7,7 @@ import uuid class Migration(migrations.Migration): dependencies = [ - ('accounts', '0012_auto_20230621_1456'), + ('accounts', '0013_account_backup_recipients'), ] operations = [ From 680d31dad2370200912e1f7e9bc7a1e9f667aa87 Mon Sep 17 00:00:00 2001 From: ibuler Date: Tue, 8 Aug 2023 14:30:14 +0800 Subject: [PATCH 111/177] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=20applet=20?= =?UTF-8?q?=E8=B4=A6=E5=8F=B7=E9=80=89=E6=8B=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../migrations/0061_applet_can_concurrent.py | 2 +- apps/terminal/models/applet/applet.py | 71 ++++++++++++------- 2 files changed, 47 insertions(+), 26 deletions(-) diff --git a/apps/terminal/migrations/0061_applet_can_concurrent.py b/apps/terminal/migrations/0061_applet_can_concurrent.py index 4ca762e65..5041e5425 100644 --- a/apps/terminal/migrations/0061_applet_can_concurrent.py +++ b/apps/terminal/migrations/0061_applet_can_concurrent.py @@ -13,6 +13,6 @@ class Migration(migrations.Migration): migrations.AddField( model_name='applet', name='can_concurrent', - field=models.BooleanField(default=True, verbose_name='Can concurrent'), + field=models.BooleanField(default=False, verbose_name='Can concurrent'), ), ] diff --git a/apps/terminal/models/applet/applet.py b/apps/terminal/models/applet/applet.py index be6b397ff..07d63bce1 100644 --- a/apps/terminal/models/applet/applet.py +++ b/apps/terminal/models/applet/applet.py @@ -39,7 +39,7 @@ class Applet(JMSBaseModel): is_active = models.BooleanField(default=True, verbose_name=_('Is active')) builtin = models.BooleanField(default=False, verbose_name=_('Builtin')) protocols = models.JSONField(default=list, verbose_name=_('Protocol')) - can_concurrent = models.BooleanField(default=True, verbose_name=_('Can concurrent')) + can_concurrent = models.BooleanField(default=False, verbose_name=_('Can concurrent')) tags = models.JSONField(default=list, verbose_name=_('Tags')) comment = models.TextField(default='', blank=True, verbose_name=_('Comment')) hosts = models.ManyToManyField( @@ -193,38 +193,59 @@ class Applet(JMSBaseModel): cache.set(prefer_host_account_key, account.id, timeout=None) return account + accounts_using_key_tmpl = 'applet_host_accounts_{}_{}_{}' + + def select_a_public_account(self, user, host, valid_accounts): + using_keys = cache.keys(self.accounts_using_key_tmpl.format(host.id, '*', '*')) or [] + accounts_username_used = list(cache.get_many(using_keys).values()) + logger.debug('Applet host account using: {}: {}'.format(host.name, accounts_username_used)) + accounts = valid_accounts.exclude(username__in=accounts_username_used) + public_accounts = accounts.filter(username__startswith='jms_') + if not public_accounts: + public_accounts = accounts.exclude(username__in=['Administrator', 'root']) + account = self.random_select_prefer_account(user, host, public_accounts) + return account + + def try_to_use_private_account(self, user, host, valid_accounts): + host_can_concurrent = str(host.deploy_options.get('RDS_fSingleSessionPerUser', 0)) == '0' + app_can_concurrent = self.can_concurrent or self.type == 'web' + all_can_concurrent = host_can_concurrent and app_can_concurrent + + private_account = valid_accounts.filter(username='js_{}'.format(user.username)).first() + if not private_account: + return None + # 优先使用 private account,支持并发或者不支持并发时,如果私有没有被占用,则使用私有 + account = None + # 如果都支持,不管私有是否被占用,都使用私有 + if all_can_concurrent: + account = private_account + # 如果主机都不支持并发,则查询一下私有账号有没有任何应用使用,如果没有被使用,则使用私有 + elif not host_can_concurrent: + private_using_key = self.accounts_using_key_tmpl.format(host.id, private_account.username, '*') + private_is_using = len(cache.keys(private_using_key, [])) > 0 + if not private_is_using: + account = private_account + # 如果主机支持,但是应用不支持并发,则查询一下私有账号有没有被这个应用使用, 如果没有被使用,则使用私有 + elif host_can_concurrent and not app_can_concurrent: + private_app_using_key = self.accounts_using_key_tmpl.format(host.id, private_account.username, self.name) + private_is_using_by_this_app = cache.get(private_app_using_key, False) + if not private_is_using_by_this_app: + account = private_account + return account + def select_host_account(self, user, asset): # 选择激活的发布机 host = self.select_host(user, asset) if not host: return None - host_concurrent = str(host.deploy_options.get('RDS_fSingleSessionPerUser', 0)) == '0' - can_concurrent = (self.can_concurrent or self.type == 'web') and host_concurrent - accounts = host.accounts.all().filter(is_active=True, privileged=False) - private_account = accounts.filter(username='js_{}'.format(user.username)).first() - accounts_using_key_tmpl = 'applet_host_accounts_{}_{}' + valid_accounts = host.accounts.all().filter(is_active=True, privileged=False) + account = self.try_to_use_private_account(user, host, valid_accounts) + if not account: + account = self.select_a_public_account(user, host, valid_accounts) - if private_account and can_concurrent: - account = private_account - else: - using_keys = cache.keys(accounts_using_key_tmpl.format(host.id, '*')) or [] - accounts_username_used = list(cache.get_many(using_keys).values()) - logger.debug('Applet host account using: {}: {}'.format(host.name, accounts_username_used)) - - # 优先使用 private account - if private_account and private_account.username not in accounts_username_used: - account = private_account - else: - accounts = accounts.exclude(username__in=accounts_username_used) - public_accounts = accounts.filter(username__startswith='jms_') - if not public_accounts: - public_accounts = accounts.exclude(username__in=['Administrator', 'root']) - account = self.random_select_prefer_account(user, host, public_accounts) - if not account: - return ttl = 60 * 60 * 24 - lock_key = accounts_using_key_tmpl.format(host.id, account.username) + lock_key = self.accounts_using_key_tmpl.format(host.id, account.username, self.name) cache.set(lock_key, account.username, ttl) return { From a33540710eddc9a12a85a8f701a466ed8e367f68 Mon Sep 17 00:00:00 2001 From: ibuler Date: Tue, 8 Aug 2023 15:41:55 +0800 Subject: [PATCH 112/177] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=20applet=20?= =?UTF-8?q?=E9=80=89=E6=8B=A9=E8=B4=A6=E5=8F=B7=E8=B0=83=E5=BA=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/accounts/filters.py | 1 + apps/terminal/models/applet/applet.py | 23 ++++++++++++++++++----- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/apps/accounts/filters.py b/apps/accounts/filters.py index dc28d78aa..e71a5b9fb 100644 --- a/apps/accounts/filters.py +++ b/apps/accounts/filters.py @@ -14,6 +14,7 @@ class AccountFilterSet(BaseFilterSet): username = drf_filters.CharFilter(field_name="username", lookup_expr='exact') address = drf_filters.CharFilter(field_name="asset__address", lookup_expr='exact') asset_id = drf_filters.CharFilter(field_name="asset", lookup_expr='exact') + asset = drf_filters.CharFilter(field_name='asset', lookup_expr='exact') assets = drf_filters.CharFilter(field_name='asset_id', lookup_expr='exact') nodes = drf_filters.CharFilter(method='filter_nodes') node_id = drf_filters.CharFilter(method='filter_nodes') diff --git a/apps/terminal/models/applet/applet.py b/apps/terminal/models/applet/applet.py index 07d63bce1..ccd1a8e52 100644 --- a/apps/terminal/models/applet/applet.py +++ b/apps/terminal/models/applet/applet.py @@ -156,10 +156,11 @@ class Applet(JMSBaseModel): spec_label = asset.labels.filter(name__in=['AppletHost', '发布机']).first() if spec_label: - host = [host for host in hosts if host.name == spec_label.value] - if host: - return host[0] + matched = [host for host in hosts if host.name == spec_label.value] + if matched: + return matched[0] + hosts = [h for h in hosts if h.auto_create_accounts] prefer_key = 'applet_host_prefer_{}'.format(user.id) prefer_host_id = cache.get(prefer_key, None) pref_host = [host for host in hosts if host.id == prefer_host_id] @@ -213,22 +214,26 @@ class Applet(JMSBaseModel): private_account = valid_accounts.filter(username='js_{}'.format(user.username)).first() if not private_account: + logger.debug('Private account not found ...') return None # 优先使用 private account,支持并发或者不支持并发时,如果私有没有被占用,则使用私有 account = None # 如果都支持,不管私有是否被占用,都使用私有 if all_can_concurrent: + logger.debug('All can concurrent, use private account') account = private_account # 如果主机都不支持并发,则查询一下私有账号有没有任何应用使用,如果没有被使用,则使用私有 elif not host_can_concurrent: private_using_key = self.accounts_using_key_tmpl.format(host.id, private_account.username, '*') - private_is_using = len(cache.keys(private_using_key, [])) > 0 + private_is_using = len(cache.keys(private_using_key)) + logger.debug("Private account is using: {}".format(private_is_using)) if not private_is_using: account = private_account # 如果主机支持,但是应用不支持并发,则查询一下私有账号有没有被这个应用使用, 如果没有被使用,则使用私有 elif host_can_concurrent and not app_can_concurrent: private_app_using_key = self.accounts_using_key_tmpl.format(host.id, private_account.username, self.name) private_is_using_by_this_app = cache.get(private_app_using_key, False) + logger.debug("Private account is using {} by {}".format(private_is_using_by_this_app, self.name)) if not private_is_using_by_this_app: account = private_account return account @@ -236,24 +241,32 @@ class Applet(JMSBaseModel): def select_host_account(self, user, asset): # 选择激活的发布机 host = self.select_host(user, asset) + logger.info('Select applet host: {}'.format(host.name)) if not host: return None valid_accounts = host.accounts.all().filter(is_active=True, privileged=False) account = self.try_to_use_private_account(user, host, valid_accounts) if not account: + logger.debug('No private account, try to use public account') account = self.select_a_public_account(user, host, valid_accounts) + if not account: + logger.debug('No available account for applet host: {}'.format(host.name)) + return None + ttl = 60 * 60 * 24 lock_key = self.accounts_using_key_tmpl.format(host.id, account.username, self.name) cache.set(lock_key, account.username, ttl) - return { + res = { 'host': host, 'account': account, 'lock_key': lock_key, 'ttl': ttl } + logger.debug('Select host and account: {}'.format(res)) + return res def delete(self, using=None, keep_parents=False): platform = self.get_related_platform() From 9bf76ae07a59dcfafc7e91c12f6fcba4a0b4d2bd Mon Sep 17 00:00:00 2001 From: ibuler Date: Tue, 8 Aug 2023 15:41:55 +0800 Subject: [PATCH 113/177] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=20applet=20?= =?UTF-8?q?=E9=80=89=E6=8B=A9=E8=B4=A6=E5=8F=B7=E8=B0=83=E5=BA=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/accounts/filters.py | 1 + apps/locale/zh/LC_MESSAGES/django.mo | 4 ++-- apps/locale/zh/LC_MESSAGES/django.po | 7 ++++--- apps/terminal/models/applet/applet.py | 23 ++++++++++++++++++----- 4 files changed, 25 insertions(+), 10 deletions(-) diff --git a/apps/accounts/filters.py b/apps/accounts/filters.py index dc28d78aa..e71a5b9fb 100644 --- a/apps/accounts/filters.py +++ b/apps/accounts/filters.py @@ -14,6 +14,7 @@ class AccountFilterSet(BaseFilterSet): username = drf_filters.CharFilter(field_name="username", lookup_expr='exact') address = drf_filters.CharFilter(field_name="asset__address", lookup_expr='exact') asset_id = drf_filters.CharFilter(field_name="asset", lookup_expr='exact') + asset = drf_filters.CharFilter(field_name='asset', lookup_expr='exact') assets = drf_filters.CharFilter(field_name='asset_id', lookup_expr='exact') nodes = drf_filters.CharFilter(method='filter_nodes') node_id = drf_filters.CharFilter(method='filter_nodes') diff --git a/apps/locale/zh/LC_MESSAGES/django.mo b/apps/locale/zh/LC_MESSAGES/django.mo index e2d64b74a..c9e28a258 100644 --- a/apps/locale/zh/LC_MESSAGES/django.mo +++ b/apps/locale/zh/LC_MESSAGES/django.mo @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ecbfbaa09e20e182a7804f2b60d7241cae6f81dbc58abede1e7a4a863b18777a -size 124596 +oid sha256:6a49d0a2a96656a3f98a0d13f64d426be5f60110ef629bed8d871c6525c16d82 +size 124739 diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po index 969a82ed2..054fca398 100644 --- a/apps/locale/zh/LC_MESSAGES/django.po +++ b/apps/locale/zh/LC_MESSAGES/django.po @@ -6241,9 +6241,10 @@ msgid "" "support multiple open and the special has been used, the public account will " "be used to connect" msgstr "" -"这些账号用于连接发布的应用,账号现在分为两种类型,一种是专用的,每个用户都有" -"一个专用账号。 另一种是公共的,当应用不支持多开且专用的已经被使用时,会使用公" -"共账号连接" +"这些账号用于连接发布的应用,账号现在分为两种类型:
" +"一种是专用的,每个用户都有一个专用账号。 " +"另一种是公共的,当应用不支持多开且专用的已经被使用时,会使用公共账号连接;
" +"注意: 如果不开启自动创建账号, 当前发布机仅能被指定标签的资产调度到,默认不会放到调度池中" #: terminal/serializers/applet_host.py:77 msgid "The number of public accounts created automatically" diff --git a/apps/terminal/models/applet/applet.py b/apps/terminal/models/applet/applet.py index 07d63bce1..ccd1a8e52 100644 --- a/apps/terminal/models/applet/applet.py +++ b/apps/terminal/models/applet/applet.py @@ -156,10 +156,11 @@ class Applet(JMSBaseModel): spec_label = asset.labels.filter(name__in=['AppletHost', '发布机']).first() if spec_label: - host = [host for host in hosts if host.name == spec_label.value] - if host: - return host[0] + matched = [host for host in hosts if host.name == spec_label.value] + if matched: + return matched[0] + hosts = [h for h in hosts if h.auto_create_accounts] prefer_key = 'applet_host_prefer_{}'.format(user.id) prefer_host_id = cache.get(prefer_key, None) pref_host = [host for host in hosts if host.id == prefer_host_id] @@ -213,22 +214,26 @@ class Applet(JMSBaseModel): private_account = valid_accounts.filter(username='js_{}'.format(user.username)).first() if not private_account: + logger.debug('Private account not found ...') return None # 优先使用 private account,支持并发或者不支持并发时,如果私有没有被占用,则使用私有 account = None # 如果都支持,不管私有是否被占用,都使用私有 if all_can_concurrent: + logger.debug('All can concurrent, use private account') account = private_account # 如果主机都不支持并发,则查询一下私有账号有没有任何应用使用,如果没有被使用,则使用私有 elif not host_can_concurrent: private_using_key = self.accounts_using_key_tmpl.format(host.id, private_account.username, '*') - private_is_using = len(cache.keys(private_using_key, [])) > 0 + private_is_using = len(cache.keys(private_using_key)) + logger.debug("Private account is using: {}".format(private_is_using)) if not private_is_using: account = private_account # 如果主机支持,但是应用不支持并发,则查询一下私有账号有没有被这个应用使用, 如果没有被使用,则使用私有 elif host_can_concurrent and not app_can_concurrent: private_app_using_key = self.accounts_using_key_tmpl.format(host.id, private_account.username, self.name) private_is_using_by_this_app = cache.get(private_app_using_key, False) + logger.debug("Private account is using {} by {}".format(private_is_using_by_this_app, self.name)) if not private_is_using_by_this_app: account = private_account return account @@ -236,24 +241,32 @@ class Applet(JMSBaseModel): def select_host_account(self, user, asset): # 选择激活的发布机 host = self.select_host(user, asset) + logger.info('Select applet host: {}'.format(host.name)) if not host: return None valid_accounts = host.accounts.all().filter(is_active=True, privileged=False) account = self.try_to_use_private_account(user, host, valid_accounts) if not account: + logger.debug('No private account, try to use public account') account = self.select_a_public_account(user, host, valid_accounts) + if not account: + logger.debug('No available account for applet host: {}'.format(host.name)) + return None + ttl = 60 * 60 * 24 lock_key = self.accounts_using_key_tmpl.format(host.id, account.username, self.name) cache.set(lock_key, account.username, ttl) - return { + res = { 'host': host, 'account': account, 'lock_key': lock_key, 'ttl': ttl } + logger.debug('Select host and account: {}'.format(res)) + return res def delete(self, using=None, keep_parents=False): platform = self.get_related_platform() From 8ea3c3288bbed194e1052e80f61fd83d8d13c6fe Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Tue, 8 Aug 2023 17:26:29 +0800 Subject: [PATCH 114/177] =?UTF-8?q?perf:=20=E6=94=B9=E5=AF=86=E6=9B=BF?= =?UTF-8?q?=E6=8D=A2=E6=A0=A1=E9=AA=8C=E5=8F=AF=E8=BF=9E=E6=8E=A5=E6=80=A7?= =?UTF-8?q?=E6=96=B9=E6=B3=95=20(#11224)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: feng <1304903146@qq.com> --- .../change_secret/host/aix/main.yml | 32 +++++++----- .../change_secret/host/posix/main.yml | 32 +++++++----- .../push_account/host/aix/main.yml | 33 +++++++----- .../push_account/host/posix/main.yml | 33 +++++++----- apps/ops/ansible/inventory.py | 4 +- .../ansible/modules_utils/custom_common.py | 52 ++++++++++++++++++- 6 files changed, 128 insertions(+), 58 deletions(-) diff --git a/apps/accounts/automations/change_secret/host/aix/main.yml b/apps/accounts/automations/change_secret/host/aix/main.yml index 8593c7534..56fde8a2c 100644 --- a/apps/accounts/automations/change_secret/host/aix/main.yml +++ b/apps/accounts/automations/change_secret/host/aix/main.yml @@ -73,20 +73,24 @@ - name: Refresh connection ansible.builtin.meta: reset_connection - - name: "Verify {{ account.username }} password" - ansible.builtin.ping: - become: no - vars: - ansible_user: "{{ account.username }}" - ansible_password: "{{ account.secret }}" - ansible_become: no + - name: "Verify {{ account.username }} password (paramiko)" + ssh_ping: + login_user: "{{ account.username }}" + login_password: "{{ account.secret }}" + login_host: "{{ jms_asset.address }}" + login_port: "{{ jms_asset.port }}" + gateway_args: "{{ jms_asset.ansible_ssh_common_args | default('') }}" + become: false when: account.secret_type == "password" + delegate_to: localhost - - name: "Verify {{ account.username }} SSH key" - ansible.builtin.ping: - become: no - vars: - ansible_user: "{{ account.username }}" - ansible_ssh_private_key_file: "{{ account.private_key_path }}" - ansible_become: no + - name: "Verify {{ account.username }} SSH KEY (paramiko)" + ssh_ping: + login_host: "{{ jms_asset.address }}" + login_port: "{{ jms_asset.port }}" + login_user: "{{ account.username }}" + login_private_key_path: "{{ account.private_key_path }}" + gateway_args: "{{ jms_asset.ansible_ssh_common_args | default('') }}" + become: false when: account.secret_type == "ssh_key" + delegate_to: localhost diff --git a/apps/accounts/automations/change_secret/host/posix/main.yml b/apps/accounts/automations/change_secret/host/posix/main.yml index 5ed6a10b4..1dca70a5a 100644 --- a/apps/accounts/automations/change_secret/host/posix/main.yml +++ b/apps/accounts/automations/change_secret/host/posix/main.yml @@ -73,20 +73,24 @@ - name: Refresh connection ansible.builtin.meta: reset_connection - - name: "Verify {{ account.username }} password" - ansible.builtin.ping: - become: no - vars: - ansible_user: "{{ account.username }}" - ansible_password: "{{ account.secret }}" - ansible_become: no + - name: "Verify {{ account.username }} password (paramiko)" + ssh_ping: + login_user: "{{ account.username }}" + login_password: "{{ account.secret }}" + login_host: "{{ jms_asset.address }}" + login_port: "{{ jms_asset.port }}" + gateway_args: "{{ jms_asset.ansible_ssh_common_args | default('') }}" + become: false when: account.secret_type == "password" + delegate_to: localhost - - name: "Verify {{ account.username }} SSH key" - ansible.builtin.ping: - become: no - vars: - ansible_user: "{{ account.username }}" - ansible_ssh_private_key_file: "{{ account.private_key_path }}" - ansible_become: no + - name: "Verify {{ account.username }} SSH KEY (paramiko)" + ssh_ping: + login_host: "{{ jms_asset.address }}" + login_port: "{{ jms_asset.port }}" + login_user: "{{ account.username }}" + login_private_key_path: "{{ account.private_key_path }}" + gateway_args: "{{ jms_asset.ansible_ssh_common_args | default('') }}" + become: false when: account.secret_type == "ssh_key" + delegate_to: localhost diff --git a/apps/accounts/automations/push_account/host/aix/main.yml b/apps/accounts/automations/push_account/host/aix/main.yml index 8593c7534..0e6fba5c5 100644 --- a/apps/accounts/automations/push_account/host/aix/main.yml +++ b/apps/accounts/automations/push_account/host/aix/main.yml @@ -73,20 +73,25 @@ - name: Refresh connection ansible.builtin.meta: reset_connection - - name: "Verify {{ account.username }} password" - ansible.builtin.ping: - become: no - vars: - ansible_user: "{{ account.username }}" - ansible_password: "{{ account.secret }}" - ansible_become: no + - name: "Verify {{ account.username }} password (paramiko)" + ssh_ping: + login_user: "{{ account.username }}" + login_password: "{{ account.secret }}" + login_host: "{{ jms_asset.address }}" + login_port: "{{ jms_asset.port }}" + gateway_args: "{{ jms_asset.ansible_ssh_common_args | default('') }}" + become: false when: account.secret_type == "password" + delegate_to: localhost - - name: "Verify {{ account.username }} SSH key" - ansible.builtin.ping: - become: no - vars: - ansible_user: "{{ account.username }}" - ansible_ssh_private_key_file: "{{ account.private_key_path }}" - ansible_become: no + - name: "Verify {{ account.username }} SSH KEY (paramiko)" + ssh_ping: + login_host: "{{ jms_asset.address }}" + login_port: "{{ jms_asset.port }}" + login_user: "{{ account.username }}" + login_private_key_path: "{{ account.private_key_path }}" + gateway_args: "{{ jms_asset.ansible_ssh_common_args | default('') }}" + become: false when: account.secret_type == "ssh_key" + delegate_to: localhost + diff --git a/apps/accounts/automations/push_account/host/posix/main.yml b/apps/accounts/automations/push_account/host/posix/main.yml index 5ed6a10b4..ea5128b17 100644 --- a/apps/accounts/automations/push_account/host/posix/main.yml +++ b/apps/accounts/automations/push_account/host/posix/main.yml @@ -73,20 +73,25 @@ - name: Refresh connection ansible.builtin.meta: reset_connection - - name: "Verify {{ account.username }} password" - ansible.builtin.ping: - become: no - vars: - ansible_user: "{{ account.username }}" - ansible_password: "{{ account.secret }}" - ansible_become: no + - name: "Verify {{ account.username }} password (paramiko)" + ssh_ping: + login_user: "{{ account.username }}" + login_password: "{{ account.secret }}" + login_host: "{{ jms_asset.address }}" + login_port: "{{ jms_asset.port }}" + gateway_args: "{{ jms_asset.ansible_ssh_common_args | default('') }}" + become: false when: account.secret_type == "password" + delegate_to: localhost - - name: "Verify {{ account.username }} SSH key" - ansible.builtin.ping: - become: no - vars: - ansible_user: "{{ account.username }}" - ansible_ssh_private_key_file: "{{ account.private_key_path }}" - ansible_become: no + - name: "Verify {{ account.username }} SSH KEY (paramiko)" + ssh_ping: + login_host: "{{ jms_asset.address }}" + login_port: "{{ jms_asset.port }}" + login_user: "{{ account.username }}" + login_private_key_path: "{{ account.private_key_path }}" + gateway_args: "{{ jms_asset.ansible_ssh_common_args | default('') }}" + become: false when: account.secret_type == "ssh_key" + delegate_to: localhost + diff --git a/apps/ops/ansible/inventory.py b/apps/ops/ansible/inventory.py index 3f3dc19b0..a650b158e 100644 --- a/apps/ops/ansible/inventory.py +++ b/apps/ops/ansible/inventory.py @@ -127,7 +127,9 @@ class JMSInventory: } host['jms_asset']['port'] = port else: - host.update(self.make_proxy_command(gateway)) + ansible_ssh_common_args = self.make_proxy_command(gateway) + host['jms_asset'].update(ansible_ssh_common_args) + host.update(ansible_ssh_common_args) @staticmethod def get_primary_protocol(ansible_config, protocols): diff --git a/apps/ops/ansible/modules_utils/custom_common.py b/apps/ops/ansible/modules_utils/custom_common.py index 01546ff33..0eb454e5a 100644 --- a/apps/ops/ansible/modules_utils/custom_common.py +++ b/apps/ops/ansible/modules_utils/custom_common.py @@ -1,6 +1,8 @@ +import re import time import paramiko +from sshtunnel import SSHTunnelForwarder def common_argument_spec(): @@ -12,6 +14,7 @@ def common_argument_spec(): login_secret_type=dict(type='str', required=False, default='password'), login_private_key_path=dict(type='str', required=False, no_log=True), first_conn_delay_time=dict(type='float', required=False, default=0.5), + gateway_args=dict(type='str', required=False, default=''), become=dict(type='bool', default=False, required=False), become_method=dict(type='str', required=False), @@ -27,8 +30,10 @@ class SSHClient: self.module = module self.channel = None self.is_connect = False + self.gateway_server = None self.client = paramiko.SSHClient() self.client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) + self.connect_params = self.get_connect_params() def get_connect_params(self): params = { @@ -90,11 +95,56 @@ class SSHClient: err_msg = su_output return err_msg + def local_gateway_prepare(self): + gateway_args = self.module.params['gateway_args'] or '' + pattern = r"(?:sshpass -p ([\w@]+))?\s*ssh -o Port=(\d+)\s+-o StrictHostKeyChecking=no\s+([\w@]+)@([" \ + r"\d.]+)\s+-W %h:%p -q(?: -i (.+))?'" + match = re.search(pattern, gateway_args) + + if not match: + return + + password, port, username, address, private_key_path = match.groups() + password = password if password else None + private_key_path = private_key_path if private_key_path else None + remote_hostname = self.module.params['login_host'] + remote_port = self.module.params['login_port'] + + server = SSHTunnelForwarder( + (address, int(port)), + ssh_username=username, + ssh_password=password, + ssh_pkey=private_key_path, + remote_bind_address=(remote_hostname, remote_port) + ) + + server.start() + self.connect_params['hostname'] = '127.0.0.1' + self.connect_params['port'] = server.local_bind_port + self.gateway_server = server + + def local_gateway_clean(self): + gateway_server = self.gateway_server + if not gateway_server: + return + try: + gateway_server.stop() + except Exception: + pass + + def before_runner_start(self): + self.local_gateway_prepare() + + def after_runner_end(self): + self.local_gateway_clean() + def connect(self): try: - self.client.connect(**self.get_connect_params()) + self.before_runner_start() + self.client.connect(**self.connect_params) self.is_connect = True err_msg = self.switch_user() + self.after_runner_end() except Exception as err: err_msg = str(err) return err_msg From 419806aa57989074918e3bb2418166022bbc618f Mon Sep 17 00:00:00 2001 From: ibuler Date: Tue, 8 Aug 2023 17:14:59 +0800 Subject: [PATCH 115/177] =?UTF-8?q?perf:=20=E5=8E=BB=E6=8E=89=20requiremen?= =?UTF-8?q?ts.txt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- requirements/requirements.txt | 138 ---------------------------- requirements/requirements_xpack.txt | 23 ----- 2 files changed, 161 deletions(-) delete mode 100644 requirements/requirements.txt delete mode 100644 requirements/requirements_xpack.txt diff --git a/requirements/requirements.txt b/requirements/requirements.txt deleted file mode 100644 index 50b2fea41..000000000 --- a/requirements/requirements.txt +++ /dev/null @@ -1,138 +0,0 @@ -# 临时解决 cython 3.0 造成的错误 -cython==3.0.0 -aiofiles==23.1.0 -amqp==5.1.1 -ansible-core@https://github.com/jumpserver/ansible/releases/download/v2.14.1.2/ansible-2.14.1.2.zip -ansible==7.1.0 -ansible-runner==2.3.3 -asn1crypto==1.5.1 -bcrypt==4.0.1 -billiard==4.1.0 -certifi==2023.7.22 -cffi==1.15.1 -chardet==5.1.0 -configparser==6.0.0 -decorator==5.1.1 -docutils==0.20.1 -ecdsa==0.18.0 -enum-compat==0.0.3 -ephem==4.1.4 -future==0.18.3 -idna==3.4 -itypes==1.2.0 -Jinja2==3.1.2 -#jmespath==0.9.3 -MarkupSafe==2.1.3 -olefile==0.46 -paramiko==3.2.0 -passlib==1.7.4 -pyasn1==0.5.0 -pycparser==2.21 -cryptography==41.0.2 -pycryptodome==3.18.0 -pycryptodomex==3.18.0 -phonenumbers==8.13.17 -gmssl==3.2.2 -itsdangerous==1.1.0 -pyotp==2.8.0 -PyNaCl==1.5.0 -python-dateutil==2.8.2 -PyYAML==6.0.1 -requests==2.31.0 -jms-storage==0.0.50 -simplejson==3.19.1 -six==1.16.0 -sshtunnel==0.4.0 -sshpubkeys==3.3.1 -uritemplate==4.1.1 -urllib3==1.26.16 -vine==5.0.0 -Werkzeug==2.3.6 -unicodecsv==0.14.1 -httpsig==1.3.0 -treelib==1.6.4 -psutil==5.9.5 -msrestazure==0.6.4 -adal==1.2.7 -openpyxl==3.0.10 -pyexcel==0.7.0 -pyexcel-xlsx==0.6.0 -data-tree==0.0.1 -pyvmomi==8.0.1.0.2 -termcolor==2.3.0 -html2text==2020.1.16 -pyzipper==0.3.6 -python3-saml==1.15.0 -websocket-client==1.6.1 -pyjwkest==1.4.2 -jsonfield2==4.0.0.post0 -geoip2==4.7.0 -ipip-ipdb==1.6.1 -IPy==1.1 -pywinrm==0.4.3 -python-nmap==0.7.1 -# Django environment -Django==4.1.10 -django-bootstrap3==23.4 -django-filter==23.2 -django-formtools==2.4.1 -django-ranged-response==0.2.0 -django-rest-swagger==2.2.0 -django-simple-captcha==0.5.18 -django-timezone-field==5.1 -djangorestframework==3.14.0 -djangorestframework-bulk==0.2.1 -django-simple-history==3.3.0 -django-private-storage==3.1 -drf-nested-routers==0.93.4 -drf-writable-nested==0.7.0 -rest_condition==1.0.3 -drf-yasg==1.21.7 -coreapi==2.3.3 -coreschema==0.0.4 -openapi-codec==1.3.2 -Pillow==10.0.0 -pytz==2023.3 -# Runtime -netifaces==0.11.0 -django-proxy==1.2.2 -channels-redis==4.1.0 -python-daemon==3.0.1 -eventlet==0.33.3 -greenlet==2.0.2 -gunicorn==21.2.0 -celery==5.3.1 -flower==2.0.0 -django-celery-beat==2.5.0 -kombu==5.3.1 -uvicorn==0.22.0 -websockets==11.0.3 -# Auth -python-ldap==3.4.3 -ldap3==2.9.1 -django-radius@https://github.com/ibuler/django-radius/archive/refs/tags/1.5.0.zip -django-cas-ng@https://github.com/ibuler/django-cas-ng/releases/download/v4.3.1/django-cas-ng-4.3.1.zip -python-cas==1.6.0 -django-auth-ldap==4.4.0 -# Cloud req -boto3==1.28.9 -botocore==1.31.9 -s3transfer==0.6.1 -kubernetes==27.2.0 -# DB requirements -mysqlclient==2.2.0 -PyMySQL==1.1.0 -django-redis==5.3.0 -python-redis-lock==4.0.0 -pyOpenSSL==23.2.0 -redis==4.6.0 -pyOpenSSL==23.2.0 -pymongo==4.4.1 -pyfreerdp==0.0.1 -# Debug -ipython==8.14.0 -ForgeryPy3==0.3.1 -django-debug-toolbar==4.1.0 -Pympler==1.0.1 -hvac==1.1.1 -pyhcl==0.4.4 diff --git a/requirements/requirements_xpack.txt b/requirements/requirements_xpack.txt deleted file mode 100644 index e77e836a3..000000000 --- a/requirements/requirements_xpack.txt +++ /dev/null @@ -1,23 +0,0 @@ -# Cloud req -qingcloud-sdk==1.2.15 -azure-mgmt-subscription==3.1.1 -azure-identity==1.13.0 -azure-mgmt-compute==30.0.0 -azure-mgmt-network==23.1.0 -google-cloud-compute==1.13.0 -grpcio==1.56.2 -alibabacloud_dysmsapi20170525==2.0.24 -python-novaclient==18.3.0 -python-keystoneclient==5.1.0 -bce-python-sdk==0.8.87 -tencentcloud-sdk-python==3.0.941 -aliyun-python-sdk-core-v3==2.13.33 -aliyun-python-sdk-ecs==4.24.64 -#huaweicloud-sdk-python==1.0.28 -keystoneauth1==5.2.1 -# DB requirements -# oracledb==1.4.0 -psycopg2-binary==2.9.6 -pymssql==2.2.8 -psycopg2==2.9.6 -ucloud-sdk-python3==0.11.50 From 33ee84633feff7ba3918f7d1ccd1d3af62b66215 Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Tue, 8 Aug 2023 18:45:10 +0800 Subject: [PATCH 116/177] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9terminal=20me?= =?UTF-8?q?trics=E6=8E=A5=E5=8F=A3=20=E5=8A=A0=E5=85=A5terminal=20name=20(?= =?UTF-8?q?#11228)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: feng <1304903146@qq.com> --- apps/terminal/utils/components.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/apps/terminal/utils/components.py b/apps/terminal/utils/components.py index 100391dbd..2c3786dbf 100644 --- a/apps/terminal/utils/components.py +++ b/apps/terminal/utils/components.py @@ -68,11 +68,16 @@ class TypedComponentsStatusMetricsUtil(object): metrics = [] for _tp, components in self.grouped_components: metric = { - 'normal': 0, 'high': 0, 'critical': 0, 'offline': 0, - 'total': 0, 'session_active': 0, 'type': _tp + 'total': 0, + 'type': _tp, + 'session_active': 0, + ComponentLoad.high: [], + ComponentLoad.normal: [], + ComponentLoad.offline: [], + ComponentLoad.critical: [], } for component in components: - metric[component.load] += 1 + metric[component.load].append(component.name) metric['total'] += 1 metric['session_active'] += component.get_online_session_count() metrics.append(metric) From 90038e41f98b14866bf255edffe1c718c4cffece Mon Sep 17 00:00:00 2001 From: halo Date: Tue, 8 Aug 2023 19:09:24 +0800 Subject: [PATCH 117/177] =?UTF-8?q?perf:=20=E6=9B=B4=E6=96=B0clients?= =?UTF-8?q?=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/templates/resource_download.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/templates/resource_download.html b/apps/templates/resource_download.html index a477df5ba..0ca87d29c 100644 --- a/apps/templates/resource_download.html +++ b/apps/templates/resource_download.html @@ -15,12 +15,13 @@ p {
-

JumpServer {% trans 'Client' %} v1.1.8

+

JumpServer {% trans 'Client' %} v2.0.0

{% trans 'JumpServer Client, currently used to launch the client, now only support launch RDP SSH client, The Telnet client will next' %}

  • jumpserver-client-windows-x86_64.msi
  • +
  • jumpserver-client-windows-x86_64.exe
  • jumpserver-client-darwin.dmg(Intel)
  • jumpserver-client-darwin.dmg(Apple Silicon)
  • jumpserver-client-linux-amd64.run
  • From f486c843bf665aae648e43b6da99ea6107cff8d8 Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Wed, 9 Aug 2023 10:36:54 +0800 Subject: [PATCH 118/177] =?UTF-8?q?feat:=20=E6=94=AF=E6=8C=81=E6=8B=89?= =?UTF-8?q?=E8=B5=B7=E6=9C=AC=E5=9C=B0=E5=AE=A2=E6=88=B7=E7=AB=AF=20(#1086?= =?UTF-8?q?5)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * perf: 拉起本地客户端应用接口提供更多数据 * fix: rdp客户端拉起后窗口标题中文乱码 * perf: ssh客户端连接选项显示优化 * feat: 增加本地sftp客户端选项 * perf: 合并支持sftp协议 * perf: sftp与ssh使用相同端口 --------- Co-authored-by: halo --- apps/authentication/api/connection_token.py | 15 ++++++++++----- apps/terminal/models/component/endpoint.py | 2 ++ 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/apps/authentication/api/connection_token.py b/apps/authentication/api/connection_token.py index a04c2218a..e805069d2 100644 --- a/apps/authentication/api/connection_token.py +++ b/apps/authentication/api/connection_token.py @@ -148,16 +148,25 @@ class RDPFileClientProtocolURLMixin: if connect_method_dict is None: raise ValueError('Connect method not support: {}'.format(connect_method_name)) + endpoint = self.get_smart_endpoint( + protocol=connect_method_dict['endpoint_protocol'], + asset=token.asset + ) data = { 'id': str(token.id), - 'value': token.value, + 'name': f'{endpoint.host}-{str(token.id)[:18]}', 'protocol': token.protocol, + 'host': endpoint.host, + 'port': endpoint.get_port(token.asset, token.protocol), + 'username': f'JMS-{str(token.id)}', + 'value': token.value, 'command': '', 'file': {} } if connect_method_name == NativeClient.mstsc or connect_method_dict['type'] == 'applet': filename, content = self.get_rdp_file_info(token) + filename = urllib.parse.unquote(filename) data.update({ 'protocol': 'rdp', 'file': { @@ -166,10 +175,6 @@ class RDPFileClientProtocolURLMixin: } }) else: - endpoint = self.get_smart_endpoint( - protocol=connect_method_dict['endpoint_protocol'], - asset=token.asset - ) cmd = NativeClient.get_launch_command(connect_method_name, token, endpoint) data.update({'command': cmd}) return data diff --git a/apps/terminal/models/component/endpoint.py b/apps/terminal/models/component/endpoint.py index 8daf75a57..88d2f6c8f 100644 --- a/apps/terminal/models/component/endpoint.py +++ b/apps/terminal/models/component/endpoint.py @@ -41,6 +41,8 @@ class Endpoint(JMSBaseModel): protocol == Protocol.oracle: port = db_port_manager.get_port_by_db(target_instance) else: + if protocol == Protocol.sftp: + protocol = Protocol.ssh port = getattr(self, f'{protocol}_port', 0) return port From 7bef4b07ff68fc36d09a2d98ca8fcd7e91f2db79 Mon Sep 17 00:00:00 2001 From: Eric Date: Tue, 8 Aug 2023 18:11:25 +0800 Subject: [PATCH 119/177] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E4=BC=9A?= =?UTF-8?q?=E8=AF=9D=E6=9C=80=E5=A4=A7=E8=BF=9E=E6=8E=A5=E6=97=B6=E9=95=BF?= =?UTF-8?q?=E8=AE=BE=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/jumpserver/conf.py | 1 + apps/jumpserver/settings/custom.py | 1 + apps/locale/ja/LC_MESSAGES/django.po | 377 +++++++++++++-------- apps/locale/zh/LC_MESSAGES/django.po | 370 ++++++++++++-------- apps/settings/serializers/security.py | 5 + apps/terminal/models/component/terminal.py | 1 + 6 files changed, 476 insertions(+), 279 deletions(-) diff --git a/apps/jumpserver/conf.py b/apps/jumpserver/conf.py index 92355bdb3..cab2ebf3a 100644 --- a/apps/jumpserver/conf.py +++ b/apps/jumpserver/conf.py @@ -475,6 +475,7 @@ class Config(dict): 'SECURITY_SERVICE_ACCOUNT_REGISTRATION': True, 'SECURITY_VIEW_AUTH_NEED_MFA': True, 'SECURITY_MAX_IDLE_TIME': 30, + 'SECURITY_MAX_SESSION_TIME': 24, 'SECURITY_PASSWORD_EXPIRATION_TIME': 9999, 'SECURITY_PASSWORD_MIN_LENGTH': 6, 'SECURITY_ADMIN_USER_PASSWORD_MIN_LENGTH': 6, diff --git a/apps/jumpserver/settings/custom.py b/apps/jumpserver/settings/custom.py index e1f5c5709..9688f2c82 100644 --- a/apps/jumpserver/settings/custom.py +++ b/apps/jumpserver/settings/custom.py @@ -35,6 +35,7 @@ FTP_FILE_MAX_STORE = CONFIG.FTP_FILE_MAX_STORE SECURITY_MFA_AUTH = CONFIG.SECURITY_MFA_AUTH SECURITY_MFA_AUTH_ENABLED_FOR_THIRD_PARTY = CONFIG.SECURITY_MFA_AUTH_ENABLED_FOR_THIRD_PARTY SECURITY_MAX_IDLE_TIME = CONFIG.SECURITY_MAX_IDLE_TIME # Unit: minute +SECURITY_MAX_SESSION_TIME = CONFIG.SECURITY_MAX_SESSION_TIME # Unit: hour SECURITY_COMMAND_EXECUTION = CONFIG.SECURITY_COMMAND_EXECUTION SECURITY_COMMAND_BLACKLIST = CONFIG.SECURITY_COMMAND_BLACKLIST SECURITY_PASSWORD_EXPIRATION_TIME = CONFIG.SECURITY_PASSWORD_EXPIRATION_TIME # Unit: day diff --git a/apps/locale/ja/LC_MESSAGES/django.po b/apps/locale/ja/LC_MESSAGES/django.po index 8c13d0567..1c315331d 100644 --- a/apps/locale/ja/LC_MESSAGES/django.po +++ b/apps/locale/ja/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-08-08 10:08+0800\n" +"POT-Creation-Date: 2023-08-08 17:55+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -213,7 +213,7 @@ msgstr "HashiCorp Vault" #: terminal/serializers/session.py:26 #: terminal/templates/terminal/_msg_command_warning.html:4 #: terminal/templates/terminal/_msg_session_sharing.html:4 -#: tickets/models/ticket/apply_asset.py:16 xpack/plugins/cloud/models.py:212 +#: tickets/models/ticket/apply_asset.py:16 xpack/plugins/cloud/models.py:253 msgid "Asset" msgstr "資産" @@ -248,7 +248,7 @@ msgstr "ソース ID" #: terminal/backends/command/models.py:18 terminal/models/session/session.py:33 #: terminal/templates/terminal/_msg_command_warning.html:8 #: terminal/templates/terminal/_msg_session_sharing.html:8 -#: tickets/models/ticket/command_confirm.py:13 xpack/plugins/cloud/models.py:85 +#: tickets/models/ticket/command_confirm.py:13 xpack/plugins/cloud/models.py:89 msgid "Account" msgstr "アカウント" @@ -273,16 +273,12 @@ msgid "Can push account" msgstr "アカウントをプッシュできます" #: accounts/models/automations/backup_account.py:27 -#, fuzzy -#| msgid "Recipient" msgid "Recipient part one" -msgstr "受信者" +msgstr "受信者 1" #: accounts/models/automations/backup_account.py:31 -#, fuzzy -#| msgid "Recipient" msgid "Recipient part two" -msgstr "受信者" +msgstr "受信者 2" #: accounts/models/automations/backup_account.py:40 #: accounts/models/automations/backup_account.py:110 @@ -319,7 +315,7 @@ msgid "Trigger mode" msgstr "トリガーモード" #: accounts/models/automations/backup_account.py:105 audits/models.py:194 -#: terminal/models/session/sharing.py:121 xpack/plugins/cloud/models.py:168 +#: terminal/models/session/sharing.py:121 xpack/plugins/cloud/models.py:205 msgid "Reason" msgstr "理由" @@ -508,14 +504,15 @@ msgstr "アカウントの確認" #: authentication/serializers/connect_token_secret.py:110 ops/mixin.py:21 #: ops/models/adhoc.py:20 ops/models/celery.py:15 ops/models/celery.py:57 #: ops/models/job.py:94 ops/models/playbook.py:28 ops/serializers/job.py:20 -#: orgs/models.py:80 perms/models/asset_permission.py:56 rbac/models/role.py:29 +#: orgs/models.py:82 perms/models/asset_permission.py:56 rbac/models/role.py:29 #: settings/models.py:32 settings/serializers/sms.py:6 #: terminal/models/applet/applet.py:32 terminal/models/component/endpoint.py:12 #: terminal/models/component/endpoint.py:92 #: terminal/models/component/storage.py:26 terminal/models/component/task.py:13 #: terminal/models/component/terminal.py:84 users/forms/profile.py:33 #: users/models/group.py:13 users/models/user.py:787 -#: xpack/plugins/cloud/models.py:28 +#: xpack/plugins/cloud/models.py:32 xpack/plugins/cloud/models.py:273 +#: xpack/plugins/cloud/serializers/task.py:68 msgid "Name" msgstr "名前" @@ -532,7 +529,7 @@ msgstr "特権アカウント" msgid "Is active" msgstr "アクティブです。" -#: accounts/models/template.py:19 +#: accounts/models/template.py:19 xpack/plugins/cloud/models.py:325 msgid "Account template" msgstr "アカウント テンプレート" @@ -771,7 +768,7 @@ msgstr "" #: terminal/models/component/endpoint.py:102 #: terminal/models/session/session.py:46 tickets/models/comment.py:32 #: tickets/models/ticket/general.py:297 users/models/user.py:826 -#: xpack/plugins/cloud/models.py:35 xpack/plugins/cloud/models.py:111 +#: xpack/plugins/cloud/models.py:39 xpack/plugins/cloud/models.py:109 msgid "Comment" msgstr "コメント" @@ -779,7 +776,9 @@ msgstr "コメント" msgid "" "Current only support login from AD/LDAP. Secret priority: Same account in " "asset secret > Login secret > Manual input" -msgstr "現在、AD/LDAPからのログインのみをサポートしています。シークレットの優先順位: 資産シークレット内の同じアカウント > ログインシークレット > 手動入力" +msgstr "" +"現在、AD/LDAPからのログインのみをサポートしています。シークレットの優先順位: " +"資産シークレット内の同じアカウント > ログインシークレット > 手動入力" #: accounts/serializers/automations/base.py:23 #: assets/models/asset/common.py:155 assets/models/automations/base.py:18 @@ -890,11 +889,13 @@ msgstr "警告" #: acls/models/base.py:37 assets/models/_user.py:51 #: assets/models/cmd_filter.py:76 terminal/models/component/endpoint.py:95 +#: xpack/plugins/cloud/models.py:275 msgid "Priority" msgstr "優先順位" #: acls/models/base.py:38 assets/models/_user.py:51 #: assets/models/cmd_filter.py:76 terminal/models/component/endpoint.py:96 +#: xpack/plugins/cloud/models.py:276 msgid "1-100, the lower the value will be match first" msgstr "1-100、低い値は最初に一致します" @@ -931,6 +932,7 @@ msgid "Command" msgstr "コマンド" #: acls/models/command_acl.py:17 assets/models/cmd_filter.py:59 +#: xpack/plugins/cloud/models.py:291 msgid "Regex" msgstr "正規情報" @@ -1027,7 +1029,7 @@ msgid "None of the reviewers belong to Organization `{}`" msgstr "いずれのレビューアも組織 '{}' に属していません" #: acls/serializers/rules/rules.py:20 -#: xpack/plugins/cloud/serializers/task.py:22 +#: xpack/plugins/cloud/serializers/task.py:133 msgid "IP address invalid: `{}`" msgstr "IPアドレスが無効: '{}'" @@ -1055,7 +1057,7 @@ msgstr "期間" msgid "Applications" msgstr "アプリケーション" -#: applications/models.py:16 xpack/plugins/cloud/models.py:33 +#: applications/models.py:16 xpack/plugins/cloud/models.py:37 #: xpack/plugins/cloud/serializers/account.py:63 msgid "Attrs" msgstr "ツールバーの" @@ -1453,14 +1455,13 @@ msgstr "アドレス" #: assets/models/asset/common.py:151 assets/models/platform.py:119 #: authentication/serializers/connect_token_secret.py:115 -#: perms/serializers/user_permission.py:24 -#: xpack/plugins/cloud/serializers/account_attrs.py:196 +#: perms/serializers/user_permission.py:24 xpack/plugins/cloud/models.py:321 msgid "Platform" msgstr "プラットフォーム" #: assets/models/asset/common.py:153 assets/models/domain.py:21 #: authentication/serializers/connect_token_secret.py:133 -#: perms/serializers/user_permission.py:29 +#: perms/serializers/user_permission.py:29 xpack/plugins/cloud/models.py:323 msgid "Domain" msgstr "ドメイン" @@ -1536,8 +1537,8 @@ msgstr "アセットの自動化タスク" #: terminal/models/component/status.py:30 terminal/serializers/applet.py:18 #: terminal/serializers/applet_host.py:115 tickets/models/ticket/general.py:283 #: tickets/serializers/super_ticket.py:13 -#: tickets/serializers/ticket/ticket.py:20 xpack/plugins/cloud/models.py:164 -#: xpack/plugins/cloud/models.py:216 +#: tickets/serializers/ticket/ticket.py:20 xpack/plugins/cloud/models.py:201 +#: xpack/plugins/cloud/models.py:257 msgid "Status" msgstr "ステータス" @@ -1601,7 +1602,7 @@ msgstr "資産グループ" #: assets/models/group.py:31 assets/models/platform.py:19 #: assets/serializers/platform.py:113 -#: xpack/plugins/cloud/providers/nutanix.py:32 +#: xpack/plugins/cloud/providers/nutanix.py:30 msgid "Default" msgstr "デフォルト" @@ -1651,7 +1652,7 @@ msgid "Parent key" msgstr "親キー" #: assets/models/node.py:558 perms/serializers/permission.py:35 -#: tickets/models/ticket/apply_asset.py:14 xpack/plugins/cloud/models.py:96 +#: tickets/models/ticket/apply_asset.py:14 xpack/plugins/cloud/models.py:322 msgid "Node" msgstr "ノード" @@ -1792,7 +1793,8 @@ msgstr "" #: assets/serializers/asset/common.py:124 assets/serializers/platform.py:129 #: authentication/serializers/connect_token_secret.py:29 #: authentication/serializers/connect_token_secret.py:72 -#: perms/serializers/user_permission.py:25 xpack/plugins/cloud/models.py:99 +#: perms/serializers/user_permission.py:25 xpack/plugins/cloud/models.py:324 +#: xpack/plugins/cloud/serializers/task.py:31 msgid "Protocols" msgstr "プロトコル" @@ -2123,7 +2125,7 @@ msgid "Change password" msgstr "パスワードを変更する" #: audits/const.py:35 settings/serializers/terminal.py:6 -#: terminal/models/applet/host.py:26 terminal/models/component/terminal.py:163 +#: terminal/models/applet/host.py:26 terminal/models/component/terminal.py:164 #: terminal/serializers/session.py:49 terminal/serializers/session.py:63 msgid "Terminal" msgstr "ターミナル" @@ -3806,7 +3808,7 @@ msgid "Date last run" msgstr "最終実行日" #: ops/models/base.py:51 ops/models/job.py:190 -#: xpack/plugins/cloud/models.py:162 +#: xpack/plugins/cloud/models.py:199 msgid "Result" msgstr "結果" @@ -4022,7 +4024,7 @@ msgstr "組織のリソース ({}) は削除できません" msgid "App organizations" msgstr "アプリ組織" -#: orgs/mixins/models.py:57 orgs/mixins/serializers.py:25 orgs/models.py:89 +#: orgs/mixins/models.py:57 orgs/mixins/serializers.py:25 orgs/models.py:91 #: rbac/const.py:7 rbac/models/rolebinding.py:56 #: rbac/serializers/rolebinding.py:44 settings/serializers/auth/ldap.py:63 #: terminal/templates/terminal/_msg_command_warning.html:21 @@ -4035,30 +4037,34 @@ msgstr "組織" msgid "Org name" msgstr "組織名" -#: orgs/models.py:13 +#: orgs/models.py:14 msgid "GLOBAL" msgstr "グローバル組織" -#: orgs/models.py:15 +#: orgs/models.py:16 msgid "DEFAULT" msgstr "デフォルト組織" -#: orgs/models.py:17 +#: orgs/models.py:18 msgid "SYSTEM" msgstr "システム組織" -#: orgs/models.py:81 rbac/models/role.py:36 terminal/models/applet/applet.py:40 +#: orgs/models.py:83 rbac/models/role.py:36 terminal/models/applet/applet.py:40 msgid "Builtin" msgstr "ビルトイン" -#: orgs/models.py:91 +#: orgs/models.py:93 msgid "Can view root org" msgstr "グローバル組織を表示できます" -#: orgs/models.py:92 +#: orgs/models.py:94 msgid "Can view all joined org" msgstr "参加しているすべての組織を表示できます" +#: orgs/models.py:233 +msgid "Can not delete virtual org" +msgstr "" + #: orgs/tasks.py:9 msgid "Refresh organization cache" msgstr "組織キャッシュを更新する" @@ -5333,62 +5339,71 @@ msgstr "接続最大アイドル時間(分)" msgid "If idle time more than it, disconnect connection." msgstr "この設定以上の操作がない場合、接続は切断されます" -#: settings/serializers/security.py:171 +#: settings/serializers/security.py:172 + +msgid "Session max connection time (hour)" +msgstr "セッション最大接続時間(時間)" + +#: settings/serializers/security.py:173 +msgid "If session connection time more than it, disconnect connection." +msgstr "セッション接続時間がこれを超えると、接続が切断されます" + +#: settings/serializers/security.py:176 msgid "Remember manual auth" msgstr "手動入力パスワードの保存" -#: settings/serializers/security.py:174 +#: settings/serializers/security.py:179 msgid "Insecure command alert" msgstr "安全でないコマンドアラート" -#: settings/serializers/security.py:177 +#: settings/serializers/security.py:182 msgid "Email recipient" msgstr "メール受信者" -#: settings/serializers/security.py:178 +#: settings/serializers/security.py:183 msgid "Multiple user using , split" msgstr "複数のユーザーを使用して、分割" -#: settings/serializers/security.py:181 +#: settings/serializers/security.py:186 msgid "Operation center" msgstr "職業センター" -#: settings/serializers/security.py:182 +#: settings/serializers/security.py:187 msgid "Allow user run batch command or not using ansible" msgstr "ユーザー実行バッチコマンドを許可するか、ansibleを使用しない" -#: settings/serializers/security.py:186 +#: settings/serializers/security.py:191 msgid "Operation center command blacklist" msgstr "オペレーション センター コマンド ブラックリスト" -#: settings/serializers/security.py:187 +#: settings/serializers/security.py:192 msgid "Commands that are not allowed execute." msgstr "実行が許可されていないコマンド" -#: settings/serializers/security.py:190 +#: settings/serializers/security.py:195 msgid "Session share" msgstr "セッション共有" -#: settings/serializers/security.py:191 +#: settings/serializers/security.py:196 msgid "Enabled, Allows user active session to be shared with other users" msgstr "" "ユーザーのアクティブなセッションを他のユーザーと共有できるようにします。" -#: settings/serializers/security.py:195 +#: settings/serializers/security.py:200 msgid "Unused user timeout (day)" msgstr "" -#: settings/serializers/security.py:196 +#: settings/serializers/security.py:201 msgid "" "Detect infrequent users daily and disable them if they exceed the " "predetermined time limit." msgstr "" -#: settings/serializers/security.py:199 +#: settings/serializers/security.py:204 msgid "Remote Login Protection" msgstr "リモートログイン保護" -#: settings/serializers/security.py:201 +#: settings/serializers/security.py:206 msgid "" "The system determines whether the login IP address belongs to a common login " "city. If the account is logged in from a common login city, the system sends " @@ -5657,8 +5672,8 @@ msgstr "期限切れです。" #, python-format msgid "" "\n" -" Your password has expired, please click this link update password.\n" +" Your password has expired, please click this link update password.\n" " " msgstr "" "\n" @@ -5679,34 +5694,34 @@ msgid "" " " msgstr "" "\n" -" クリックしてください リンク パスワードの更新\n" +" クリックしてください リンク パスワードの更新\n" " " #: templates/_message.html:43 #, python-format msgid "" "\n" -" Your information was incomplete. Please click this link to complete your information.\n" +" Your information was incomplete. Please click this link to complete your information.\n" " " msgstr "" "\n" -" あなたの情報が不完全なので、クリックしてください。 リンク 補完\n" +" あなたの情報が不完全なので、クリックしてください。 リンク 補完\n" " " #: templates/_message.html:56 #, python-format msgid "" "\n" -" Your ssh public key not set or expired. Please click this link to update\n" +" Your ssh public key not set or expired. Please click this link to update\n" " " msgstr "" "\n" -" SSHキーが設定されていないか無効になっている場合は、 リンク 更新\n" +" SSHキーが設定されていないか無効になっている場合は、 リンク 更新\n" " " #: templates/_mfa_login_field.html:28 @@ -6098,7 +6113,7 @@ msgstr "リモートアドレス" msgid "Application User" msgstr "ユーザーの適用" -#: terminal/models/component/terminal.py:165 +#: terminal/models/component/terminal.py:166 msgid "Can view terminal config" msgstr "ターミナル構成を表示できます" @@ -6455,7 +6470,7 @@ msgstr "アクセスキー" msgid "Access key secret" msgstr "アクセスキーシークレット" -#: terminal/serializers/storage.py:67 xpack/plugins/cloud/models.py:209 +#: terminal/serializers/storage.py:67 xpack/plugins/cloud/models.py:250 msgid "Region" msgstr "リージョン" @@ -7013,7 +7028,7 @@ msgid "Not a valid ssh public key" msgstr "有効なssh公開鍵ではありません" #: users/forms/profile.py:173 users/models/user.py:820 -#: xpack/plugins/cloud/serializers/account_attrs.py:206 +#: xpack/plugins/cloud/serializers/account_attrs.py:203 msgid "Public key" msgstr "公開キー" @@ -7042,7 +7057,7 @@ msgid "OTP secret key" msgstr "OTP 秘密" #: users/models/user.py:817 -#: xpack/plugins/cloud/serializers/account_attrs.py:209 +#: xpack/plugins/cloud/serializers/account_attrs.py:206 msgid "Private key" msgstr "ssh秘密鍵" @@ -7216,10 +7231,8 @@ msgid "Periodic check user expired" msgstr "ユーザーの有効期限の定期的な検出" #: users/tasks.py:83 -#, fuzzy -#| msgid "Check user expired" msgid "Check unused users" -msgstr "ユーザーの有効期限が切れていることを確認する" +msgstr "未使用のユーザーを確認する" #: users/templates/users/_msg_account_expire_reminder.html:7 msgid "Your account will expire in" @@ -7483,11 +7496,11 @@ msgstr "パスワードの成功をリセットし、ログインページに戻 msgid "XPACK" msgstr "XPack" -#: xpack/plugins/cloud/api.py:38 +#: xpack/plugins/cloud/api.py:56 msgid "Test connection successful" msgstr "テスト接続成功" -#: xpack/plugins/cloud/api.py:40 +#: xpack/plugins/cloud/api.py:58 msgid "Test connection failed: {}" msgstr "テスト接続に失敗しました: {}" @@ -7575,7 +7588,7 @@ msgstr "プライベートIP" msgid "Public IP" msgstr "パブリックIP" -#: xpack/plugins/cloud/const.py:38 +#: xpack/plugins/cloud/const.py:38 xpack/plugins/cloud/models.py:295 msgid "Instance name" msgstr "インスタンス名" @@ -7603,78 +7616,158 @@ msgstr "同期済み" msgid "Released" msgstr "リリース済み" +#: xpack/plugins/cloud/manager.py:53 +msgid "Account unavailable" +msgstr "利用できないアカウント" + #: xpack/plugins/cloud/meta.py:9 msgid "Cloud center" msgstr "クラウドセンター" -#: xpack/plugins/cloud/models.py:30 +#: xpack/plugins/cloud/models.py:34 msgid "Provider" msgstr "プロバイダー" -#: xpack/plugins/cloud/models.py:34 +#: xpack/plugins/cloud/models.py:38 msgid "Validity" msgstr "有効性" -#: xpack/plugins/cloud/models.py:39 +#: xpack/plugins/cloud/models.py:43 msgid "Cloud account" msgstr "クラウドアカウント" -#: xpack/plugins/cloud/models.py:41 +#: xpack/plugins/cloud/models.py:45 msgid "Test cloud account" msgstr "クラウドアカウントのテスト" -#: xpack/plugins/cloud/models.py:88 xpack/plugins/cloud/serializers/task.py:36 +#: xpack/plugins/cloud/models.py:92 xpack/plugins/cloud/serializers/task.py:147 msgid "Regions" msgstr "リージョン" -#: xpack/plugins/cloud/models.py:91 +#: xpack/plugins/cloud/models.py:95 msgid "Hostname strategy" msgstr "ホスト名戦略" -#: xpack/plugins/cloud/models.py:102 xpack/plugins/cloud/serializers/task.py:39 +#: xpack/plugins/cloud/models.py:100 +#: xpack/plugins/cloud/serializers/task.py:150 msgid "IP network segment group" msgstr "IPネットワークセグメントグループ" -#: xpack/plugins/cloud/models.py:105 xpack/plugins/cloud/serializers/task.py:44 +#: xpack/plugins/cloud/models.py:103 +#: xpack/plugins/cloud/serializers/task.py:155 msgid "Sync IP type" msgstr "同期IPタイプ" -#: xpack/plugins/cloud/models.py:108 xpack/plugins/cloud/serializers/task.py:61 +#: xpack/plugins/cloud/models.py:106 +#: xpack/plugins/cloud/serializers/task.py:173 msgid "Always update" msgstr "常に更新" -#: xpack/plugins/cloud/models.py:114 +#: xpack/plugins/cloud/models.py:112 msgid "Date last sync" msgstr "最終同期日" -#: xpack/plugins/cloud/models.py:119 xpack/plugins/cloud/models.py:160 +#: xpack/plugins/cloud/models.py:115 xpack/plugins/cloud/models.py:313 +#: xpack/plugins/cloud/models.py:337 +msgid "Strategy" +msgstr "戦略" + +#: xpack/plugins/cloud/models.py:120 xpack/plugins/cloud/models.py:197 msgid "Sync instance task" msgstr "インスタンスの同期タスク" -#: xpack/plugins/cloud/models.py:171 xpack/plugins/cloud/models.py:219 +#: xpack/plugins/cloud/models.py:208 xpack/plugins/cloud/models.py:260 msgid "Date sync" msgstr "日付の同期" -#: xpack/plugins/cloud/models.py:175 +#: xpack/plugins/cloud/models.py:212 +msgid "Sync instance snapshot" +msgstr "インスタンススナップショットの同期" + +#: xpack/plugins/cloud/models.py:216 msgid "Sync instance task execution" msgstr "インスタンスタスクの同期実行" -#: xpack/plugins/cloud/models.py:199 +#: xpack/plugins/cloud/models.py:240 msgid "Sync task" msgstr "同期タスク" -#: xpack/plugins/cloud/models.py:203 +#: xpack/plugins/cloud/models.py:244 msgid "Sync instance task history" msgstr "インスタンスタスク履歴の同期" -#: xpack/plugins/cloud/models.py:206 +#: xpack/plugins/cloud/models.py:247 msgid "Instance" msgstr "インスタンス" -#: xpack/plugins/cloud/models.py:223 +#: xpack/plugins/cloud/models.py:264 msgid "Sync instance detail" msgstr "同期インスタンスの詳細" +#: xpack/plugins/cloud/models.py:281 +msgid "Task strategy" +msgstr "タスク戦略" + +#: xpack/plugins/cloud/models.py:285 +msgid "Exact" +msgstr "" + +#: xpack/plugins/cloud/models.py:286 +msgid "Not" +msgstr "否" + +#: xpack/plugins/cloud/models.py:287 +msgid "In" +msgstr "イン" + +#: xpack/plugins/cloud/models.py:288 +msgid "Contains" +msgstr "含む" + +#: xpack/plugins/cloud/models.py:289 +msgid "Startswith" +msgstr "始まる" + +#: xpack/plugins/cloud/models.py:290 +msgid "Endswith" +msgstr "終わる" + +#: xpack/plugins/cloud/models.py:296 +msgid "Instance platform" +msgstr "インスタンス名" + +#: xpack/plugins/cloud/models.py:297 +msgid "Instance address" +msgstr "インスタンスアドレス" + +#: xpack/plugins/cloud/models.py:304 +msgid "Rule attr" +msgstr "ルール属性" + +#: xpack/plugins/cloud/models.py:308 +msgid "Rule match" +msgstr "ルール一致" + +#: xpack/plugins/cloud/models.py:310 +msgid "Rule value" +msgstr "ルール値" + +#: xpack/plugins/cloud/models.py:317 +msgid "Strategy rule" +msgstr "戦略ルール" + +#: xpack/plugins/cloud/models.py:332 +msgid "Action attr" +msgstr "アクション属性" + +#: xpack/plugins/cloud/models.py:334 +msgid "Action value" +msgstr "アクション値" + +#: xpack/plugins/cloud/models.py:341 +msgid "Strategy action" +msgstr "戦略アクション" + #: xpack/plugins/cloud/providers/aws_international.py:18 msgid "China (Beijing)" msgstr "中国 (北京)" @@ -7783,7 +7876,7 @@ msgid "CN East-Suzhou" msgstr "華東-蘇州" #: xpack/plugins/cloud/providers/baiducloud.py:57 -#: xpack/plugins/cloud/providers/huaweicloud.py:50 +#: xpack/plugins/cloud/providers/huaweicloud.py:49 msgid "CN-Hong Kong" msgstr "中国-香港" @@ -7801,66 +7894,66 @@ msgid "CN East-Shanghai" msgstr "華東-上海" #: xpack/plugins/cloud/providers/baiducloud.py:61 -#: xpack/plugins/cloud/providers/huaweicloud.py:49 +#: xpack/plugins/cloud/providers/huaweicloud.py:51 msgid "AP-Singapore" msgstr "アジア太平洋-シンガポール" -#: xpack/plugins/cloud/providers/huaweicloud.py:37 -msgid "AF-Johannesburg" -msgstr "アフリカ-ヨハネスブルク" - -#: xpack/plugins/cloud/providers/huaweicloud.py:38 -msgid "CN North-Beijing4" -msgstr "華北-北京4" - #: xpack/plugins/cloud/providers/huaweicloud.py:39 msgid "CN North-Beijing1" msgstr "華北-北京1" #: xpack/plugins/cloud/providers/huaweicloud.py:40 -msgid "CN East-Shanghai2" -msgstr "華東-上海2" +msgid "CN North-Beijing4" +msgstr "華北-北京4" #: xpack/plugins/cloud/providers/huaweicloud.py:41 -msgid "CN East-Shanghai1" -msgstr "華東-上海1" - -#: xpack/plugins/cloud/providers/huaweicloud.py:43 -msgid "LA-Mexico City1" -msgstr "LA-メキシコCity1" - -#: xpack/plugins/cloud/providers/huaweicloud.py:44 -msgid "LA-Santiago" -msgstr "ラテンアメリカ-サンディエゴ" - -#: xpack/plugins/cloud/providers/huaweicloud.py:45 -msgid "LA-Sao Paulo1" -msgstr "ラミー・サンパウロ1" - -#: xpack/plugins/cloud/providers/huaweicloud.py:46 -msgid "EU-Paris" -msgstr "ヨーロッパ-パリ" - -#: xpack/plugins/cloud/providers/huaweicloud.py:47 -msgid "CN Southwest-Guiyang1" -msgstr "南西-貴陽1" - -#: xpack/plugins/cloud/providers/huaweicloud.py:48 -msgid "AP-Bangkok" -msgstr "アジア太平洋-バンコク" - -#: xpack/plugins/cloud/providers/huaweicloud.py:52 -msgid "CN Northeast-Dalian" -msgstr "华北-大连" - -#: xpack/plugins/cloud/providers/huaweicloud.py:53 msgid "CN North-Ulanqab1" msgstr "華北-ウランチャブ一" -#: xpack/plugins/cloud/providers/huaweicloud.py:54 +#: xpack/plugins/cloud/providers/huaweicloud.py:43 +msgid "CN South-Shenzhen" +msgstr "華南-広州" + +#: xpack/plugins/cloud/providers/huaweicloud.py:44 msgid "CN South-Guangzhou-InvitationOnly" msgstr "華南-広州-友好ユーザー環境" +#: xpack/plugins/cloud/providers/huaweicloud.py:45 +msgid "CN East-Shanghai2" +msgstr "華東-上海2" + +#: xpack/plugins/cloud/providers/huaweicloud.py:46 +msgid "CN East-Shanghai1" +msgstr "華東-上海1" + +#: xpack/plugins/cloud/providers/huaweicloud.py:48 +msgid "CN Southwest-Guiyang1" +msgstr "南西-貴陽1" + +#: xpack/plugins/cloud/providers/huaweicloud.py:50 +msgid "AP-Bangkok" +msgstr "アジア太平洋-バンコク" + +#: xpack/plugins/cloud/providers/huaweicloud.py:53 +msgid "AF-Johannesburg" +msgstr "アフリカ-ヨハネスブルク" + +#: xpack/plugins/cloud/providers/huaweicloud.py:54 +msgid "LA-Mexico City1" +msgstr "LA-メキシコCity1" + +#: xpack/plugins/cloud/providers/huaweicloud.py:55 +msgid "LA-Santiago" +msgstr "ラテンアメリカ-サンディエゴ" + +#: xpack/plugins/cloud/providers/huaweicloud.py:56 +msgid "LA-Sao Paulo1" +msgstr "ラミー・サンパウロ1" + +#: xpack/plugins/cloud/providers/huaweicloud.py:58 +msgid "TR-Istanbul" +msgstr "" + #: xpack/plugins/cloud/providers/jdcloud.py:126 msgid "CN East-Suqian" msgstr "華東-宿遷" @@ -7889,7 +7982,7 @@ msgstr "サブスクリプションID" #: xpack/plugins/cloud/serializers/account_attrs.py:103 #: xpack/plugins/cloud/serializers/account_attrs.py:119 #: xpack/plugins/cloud/serializers/account_attrs.py:149 -#: xpack/plugins/cloud/serializers/account_attrs.py:202 +#: xpack/plugins/cloud/serializers/account_attrs.py:199 msgid "API Endpoint" msgstr "APIエンドポイント" @@ -7955,11 +8048,11 @@ msgstr "テストポート" msgid "Test timeout" msgstr "テストタイムアウト" -#: xpack/plugins/cloud/serializers/account_attrs.py:212 +#: xpack/plugins/cloud/serializers/account_attrs.py:209 msgid "Project" msgstr "project" -#: xpack/plugins/cloud/serializers/task.py:28 +#: xpack/plugins/cloud/serializers/task.py:139 msgid "" "Only instances matching the IP range will be synced.
    If the instance " "contains multiple IP addresses, the first IP address that matches will be " @@ -7973,11 +8066,11 @@ msgstr "" "ドレスをランダムに一致させることを意味します。
    例: " "192.168.1.0/24,10.1.1.1-10.1.1.20。" -#: xpack/plugins/cloud/serializers/task.py:34 +#: xpack/plugins/cloud/serializers/task.py:145 msgid "History count" msgstr "実行回数" -#: xpack/plugins/cloud/serializers/task.py:35 +#: xpack/plugins/cloud/serializers/task.py:146 msgid "Instance count" msgstr "インスタンス数" @@ -7989,10 +8082,6 @@ msgstr "同期インスタンス タスクを実行する" msgid "Period clean sync instance task execution" msgstr "同期インスタンス タスクの実行記録を定期的にクリアする" -#: xpack/plugins/cloud/utils.py:68 -msgid "Account unavailable" -msgstr "利用できないアカウント" - #: xpack/plugins/interface/api.py:52 msgid "Restore default successfully." msgstr "デフォルトの復元に成功しました。" @@ -8057,6 +8146,12 @@ msgstr "究極のエディション" msgid "Community edition" msgstr "コミュニティ版" +#~ msgid "EU-Paris" +#~ msgstr "ヨーロッパ-パリ" + +#~ msgid "CN Northeast-Dalian" +#~ msgstr "华北-大连" + #~ msgid "Current only support login from AD/LDAP" #~ msgstr "現在、AD/LDAPからのログインのみサポートしています" diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po index 054fca398..7eeae8dc5 100644 --- a/apps/locale/zh/LC_MESSAGES/django.po +++ b/apps/locale/zh/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: JumpServer 0.3.3\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-08-08 10:08+0800\n" +"POT-Creation-Date: 2023-08-08 17:55+0800\n" "PO-Revision-Date: 2021-05-20 10:54+0800\n" "Last-Translator: ibuler \n" "Language-Team: JumpServer team\n" @@ -212,7 +212,7 @@ msgstr "HashiCorp Vault" #: terminal/serializers/session.py:26 #: terminal/templates/terminal/_msg_command_warning.html:4 #: terminal/templates/terminal/_msg_session_sharing.html:4 -#: tickets/models/ticket/apply_asset.py:16 xpack/plugins/cloud/models.py:212 +#: tickets/models/ticket/apply_asset.py:16 xpack/plugins/cloud/models.py:253 msgid "Asset" msgstr "资产" @@ -247,7 +247,7 @@ msgstr "来源 ID" #: terminal/backends/command/models.py:18 terminal/models/session/session.py:33 #: terminal/templates/terminal/_msg_command_warning.html:8 #: terminal/templates/terminal/_msg_session_sharing.html:8 -#: tickets/models/ticket/command_confirm.py:13 xpack/plugins/cloud/models.py:85 +#: tickets/models/ticket/command_confirm.py:13 xpack/plugins/cloud/models.py:89 msgid "Account" msgstr "账号" @@ -272,16 +272,12 @@ msgid "Can push account" msgstr "可以推送账号" #: accounts/models/automations/backup_account.py:27 -#, fuzzy -#| msgid "Recipient" msgid "Recipient part one" -msgstr "收件人" +msgstr "收件人部分一" #: accounts/models/automations/backup_account.py:31 -#, fuzzy -#| msgid "Recipient" msgid "Recipient part two" -msgstr "收件人" +msgstr "收件人部分二" #: accounts/models/automations/backup_account.py:40 #: accounts/models/automations/backup_account.py:110 @@ -318,7 +314,7 @@ msgid "Trigger mode" msgstr "触发模式" #: accounts/models/automations/backup_account.py:105 audits/models.py:194 -#: terminal/models/session/sharing.py:121 xpack/plugins/cloud/models.py:168 +#: terminal/models/session/sharing.py:121 xpack/plugins/cloud/models.py:205 msgid "Reason" msgstr "原因" @@ -507,14 +503,15 @@ msgstr "账号验证" #: authentication/serializers/connect_token_secret.py:110 ops/mixin.py:21 #: ops/models/adhoc.py:20 ops/models/celery.py:15 ops/models/celery.py:57 #: ops/models/job.py:94 ops/models/playbook.py:28 ops/serializers/job.py:20 -#: orgs/models.py:80 perms/models/asset_permission.py:56 rbac/models/role.py:29 +#: orgs/models.py:82 perms/models/asset_permission.py:56 rbac/models/role.py:29 #: settings/models.py:32 settings/serializers/sms.py:6 #: terminal/models/applet/applet.py:32 terminal/models/component/endpoint.py:12 #: terminal/models/component/endpoint.py:92 #: terminal/models/component/storage.py:26 terminal/models/component/task.py:13 #: terminal/models/component/terminal.py:84 users/forms/profile.py:33 #: users/models/group.py:13 users/models/user.py:787 -#: xpack/plugins/cloud/models.py:28 +#: xpack/plugins/cloud/models.py:32 xpack/plugins/cloud/models.py:273 +#: xpack/plugins/cloud/serializers/task.py:68 msgid "Name" msgstr "名称" @@ -531,7 +528,7 @@ msgstr "特权账号" msgid "Is active" msgstr "激活" -#: accounts/models/template.py:19 +#: accounts/models/template.py:19 xpack/plugins/cloud/models.py:325 msgid "Account template" msgstr "账号模版" @@ -771,7 +768,7 @@ msgstr "" #: terminal/models/component/endpoint.py:102 #: terminal/models/session/session.py:46 tickets/models/comment.py:32 #: tickets/models/ticket/general.py:297 users/models/user.py:826 -#: xpack/plugins/cloud/models.py:35 xpack/plugins/cloud/models.py:111 +#: xpack/plugins/cloud/models.py:39 xpack/plugins/cloud/models.py:109 msgid "Comment" msgstr "备注" @@ -779,7 +776,9 @@ msgstr "备注" msgid "" "Current only support login from AD/LDAP. Secret priority: Same account in " "asset secret > Login secret > Manual input" -msgstr "当前仅支持 AD/LDAP 登录方式用户。 同名账号密码生效顺序: 资产上存在的同名账号密码 > 登录密码 > 手动输入" +msgstr "" +"当前仅支持 AD/LDAP 登录方式用户。 同名账号密码生效顺序: 资产上存在的同名账号" +"密码 > 登录密码 > 手动输入" #: accounts/serializers/automations/base.py:23 #: assets/models/asset/common.py:155 assets/models/automations/base.py:18 @@ -890,11 +889,13 @@ msgstr "告警" #: acls/models/base.py:37 assets/models/_user.py:51 #: assets/models/cmd_filter.py:76 terminal/models/component/endpoint.py:95 +#: xpack/plugins/cloud/models.py:275 msgid "Priority" msgstr "优先级" #: acls/models/base.py:38 assets/models/_user.py:51 #: assets/models/cmd_filter.py:76 terminal/models/component/endpoint.py:96 +#: xpack/plugins/cloud/models.py:276 msgid "1-100, the lower the value will be match first" msgstr "优先级可选范围为 1-100 (数值越小越优先)" @@ -931,6 +932,7 @@ msgid "Command" msgstr "命令" #: acls/models/command_acl.py:17 assets/models/cmd_filter.py:59 +#: xpack/plugins/cloud/models.py:291 msgid "Regex" msgstr "正则表达式" @@ -1026,7 +1028,7 @@ msgid "None of the reviewers belong to Organization `{}`" msgstr "所有复核人都不属于组织 `{}`" #: acls/serializers/rules/rules.py:20 -#: xpack/plugins/cloud/serializers/task.py:22 +#: xpack/plugins/cloud/serializers/task.py:133 msgid "IP address invalid: `{}`" msgstr "IP 地址无效: `{}`" @@ -1054,7 +1056,7 @@ msgstr "时段" msgid "Applications" msgstr "应用管理" -#: applications/models.py:16 xpack/plugins/cloud/models.py:33 +#: applications/models.py:16 xpack/plugins/cloud/models.py:37 #: xpack/plugins/cloud/serializers/account.py:63 msgid "Attrs" msgstr "属性" @@ -1451,14 +1453,13 @@ msgstr "地址" #: assets/models/asset/common.py:151 assets/models/platform.py:119 #: authentication/serializers/connect_token_secret.py:115 -#: perms/serializers/user_permission.py:24 -#: xpack/plugins/cloud/serializers/account_attrs.py:196 +#: perms/serializers/user_permission.py:24 xpack/plugins/cloud/models.py:321 msgid "Platform" msgstr "系统平台" #: assets/models/asset/common.py:153 assets/models/domain.py:21 #: authentication/serializers/connect_token_secret.py:133 -#: perms/serializers/user_permission.py:29 +#: perms/serializers/user_permission.py:29 xpack/plugins/cloud/models.py:323 msgid "Domain" msgstr "网域" @@ -1534,8 +1535,8 @@ msgstr "资产自动化任务" #: terminal/models/component/status.py:30 terminal/serializers/applet.py:18 #: terminal/serializers/applet_host.py:115 tickets/models/ticket/general.py:283 #: tickets/serializers/super_ticket.py:13 -#: tickets/serializers/ticket/ticket.py:20 xpack/plugins/cloud/models.py:164 -#: xpack/plugins/cloud/models.py:216 +#: tickets/serializers/ticket/ticket.py:20 xpack/plugins/cloud/models.py:201 +#: xpack/plugins/cloud/models.py:257 msgid "Status" msgstr "状态" @@ -1599,7 +1600,7 @@ msgstr "资产组" #: assets/models/group.py:31 assets/models/platform.py:19 #: assets/serializers/platform.py:113 -#: xpack/plugins/cloud/providers/nutanix.py:32 +#: xpack/plugins/cloud/providers/nutanix.py:30 msgid "Default" msgstr "默认" @@ -1649,7 +1650,7 @@ msgid "Parent key" msgstr "ssh私钥" #: assets/models/node.py:558 perms/serializers/permission.py:35 -#: tickets/models/ticket/apply_asset.py:14 xpack/plugins/cloud/models.py:96 +#: tickets/models/ticket/apply_asset.py:14 xpack/plugins/cloud/models.py:322 msgid "Node" msgstr "节点" @@ -1788,7 +1789,8 @@ msgstr "资产中批量更新平台,不符合平台类型跳过的资产" #: assets/serializers/asset/common.py:124 assets/serializers/platform.py:129 #: authentication/serializers/connect_token_secret.py:29 #: authentication/serializers/connect_token_secret.py:72 -#: perms/serializers/user_permission.py:25 xpack/plugins/cloud/models.py:99 +#: perms/serializers/user_permission.py:25 xpack/plugins/cloud/models.py:324 +#: xpack/plugins/cloud/serializers/task.py:31 msgid "Protocols" msgstr "协议组" @@ -2112,7 +2114,7 @@ msgid "Change password" msgstr "改密" #: audits/const.py:35 settings/serializers/terminal.py:6 -#: terminal/models/applet/host.py:26 terminal/models/component/terminal.py:163 +#: terminal/models/applet/host.py:26 terminal/models/component/terminal.py:164 #: terminal/serializers/session.py:49 terminal/serializers/session.py:63 msgid "Terminal" msgstr "终端" @@ -3764,7 +3766,7 @@ msgid "Date last run" msgstr "最后运行日期" #: ops/models/base.py:51 ops/models/job.py:190 -#: xpack/plugins/cloud/models.py:162 +#: xpack/plugins/cloud/models.py:199 msgid "Result" msgstr "结果" @@ -3979,7 +3981,7 @@ msgstr "组织存在资源 ({}) 不能被删除" msgid "App organizations" msgstr "组织管理" -#: orgs/mixins/models.py:57 orgs/mixins/serializers.py:25 orgs/models.py:89 +#: orgs/mixins/models.py:57 orgs/mixins/serializers.py:25 orgs/models.py:91 #: rbac/const.py:7 rbac/models/rolebinding.py:56 #: rbac/serializers/rolebinding.py:44 settings/serializers/auth/ldap.py:63 #: terminal/templates/terminal/_msg_command_warning.html:21 @@ -3992,30 +3994,34 @@ msgstr "组织" msgid "Org name" msgstr "组织名称" -#: orgs/models.py:13 +#: orgs/models.py:14 msgid "GLOBAL" msgstr "全局组织" -#: orgs/models.py:15 +#: orgs/models.py:16 msgid "DEFAULT" msgstr "默认组织" -#: orgs/models.py:17 +#: orgs/models.py:18 msgid "SYSTEM" msgstr "系统组织" -#: orgs/models.py:81 rbac/models/role.py:36 terminal/models/applet/applet.py:40 +#: orgs/models.py:83 rbac/models/role.py:36 terminal/models/applet/applet.py:40 msgid "Builtin" msgstr "内置的" -#: orgs/models.py:91 +#: orgs/models.py:93 msgid "Can view root org" msgstr "可以查看全局组织" -#: orgs/models.py:92 +#: orgs/models.py:94 msgid "Can view all joined org" msgstr "可以查看所有加入的组织" +#: orgs/models.py:233 +msgid "Can not delete virtual org" +msgstr "" + #: orgs/tasks.py:9 msgid "Refresh organization cache" msgstr "刷新组织缓存" @@ -5266,61 +5272,69 @@ msgstr "连接最大空闲时间(分)" msgid "If idle time more than it, disconnect connection." msgstr "提示:如果超过该配置没有操作,连接会被断开" -#: settings/serializers/security.py:171 +#: settings/serializers/security.py:172 +msgid "Session max connection time (hour)" +msgstr "会话连接最大时间(时)" + +#: settings/serializers/security.py:173 +msgid "If session connection time more than it, disconnect connection." +msgstr "提示:如果会话连接超过该配置,连接会被断开" + +#: settings/serializers/security.py:176 msgid "Remember manual auth" msgstr "保存手动输入密码" -#: settings/serializers/security.py:174 +#: settings/serializers/security.py:179 msgid "Insecure command alert" msgstr "危险命令告警" -#: settings/serializers/security.py:177 +#: settings/serializers/security.py:182 msgid "Email recipient" msgstr "邮件收件人" -#: settings/serializers/security.py:178 +#: settings/serializers/security.py:183 msgid "Multiple user using , split" msgstr "多个用户,使用 , 分割" -#: settings/serializers/security.py:181 +#: settings/serializers/security.py:186 msgid "Operation center" msgstr "作业中心" -#: settings/serializers/security.py:182 +#: settings/serializers/security.py:187 msgid "Allow user run batch command or not using ansible" msgstr "是否允许用户使用 ansible 执行批量命令" -#: settings/serializers/security.py:186 +#: settings/serializers/security.py:191 msgid "Operation center command blacklist" msgstr "作业中心命令黑名单" -#: settings/serializers/security.py:187 +#: settings/serializers/security.py:192 msgid "Commands that are not allowed execute." msgstr "不允许执行的命令" -#: settings/serializers/security.py:190 +#: settings/serializers/security.py:195 msgid "Session share" msgstr "会话分享" -#: settings/serializers/security.py:191 +#: settings/serializers/security.py:196 msgid "Enabled, Allows user active session to be shared with other users" msgstr "开启后允许用户分享已连接的资产会话给他人,协同工作" -#: settings/serializers/security.py:195 +#: settings/serializers/security.py:200 msgid "Unused user timeout (day)" msgstr "" -#: settings/serializers/security.py:196 +#: settings/serializers/security.py:201 msgid "" "Detect infrequent users daily and disable them if they exceed the " "predetermined time limit." msgstr "" -#: settings/serializers/security.py:199 +#: settings/serializers/security.py:204 msgid "Remote Login Protection" msgstr "异地登录保护" -#: settings/serializers/security.py:201 +#: settings/serializers/security.py:206 msgid "" "The system determines whether the login IP address belongs to a common login " "city. If the account is logged in from a common login city, the system sends " @@ -5581,13 +5595,13 @@ msgstr "过期。" #, python-format msgid "" "\n" -" Your password has expired, please click this link update password.\n" +" Your password has expired, please click this link update password.\n" " " msgstr "" "\n" -" 您的密码已经过期,请点击 链接 更新密码\n" +" 您的密码已经过期,请点击 链接 更新密码\n" " " #: templates/_message.html:30 @@ -5611,8 +5625,8 @@ msgstr "" #, python-format msgid "" "\n" -" Your information was incomplete. Please click this link to complete your information.\n" +" Your information was incomplete. Please click this link to complete your information.\n" " " msgstr "" "\n" @@ -5624,13 +5638,13 @@ msgstr "" #, python-format msgid "" "\n" -" Your ssh public key not set or expired. Please click this link to update\n" +" Your ssh public key not set or expired. Please click this link to update\n" " " msgstr "" "\n" -" 您的SSH密钥没有设置或已失效,请点击 链接 更新\n" +" 您的SSH密钥没有设置或已失效,请点击 链接 更新\n" " " #: templates/_mfa_login_field.html:28 @@ -6017,7 +6031,7 @@ msgstr "远端地址" msgid "Application User" msgstr "应用用户" -#: terminal/models/component/terminal.py:165 +#: terminal/models/component/terminal.py:166 msgid "Can view terminal config" msgstr "可以查看终端配置" @@ -6368,7 +6382,7 @@ msgstr "Access key ID(AK)" msgid "Access key secret" msgstr "Access key secret(SK)" -#: terminal/serializers/storage.py:67 xpack/plugins/cloud/models.py:209 +#: terminal/serializers/storage.py:67 xpack/plugins/cloud/models.py:250 msgid "Region" msgstr "地域" @@ -6920,7 +6934,7 @@ msgid "Not a valid ssh public key" msgstr "SSH密钥不合法" #: users/forms/profile.py:173 users/models/user.py:820 -#: xpack/plugins/cloud/serializers/account_attrs.py:206 +#: xpack/plugins/cloud/serializers/account_attrs.py:203 msgid "Public key" msgstr "SSH公钥" @@ -6949,7 +6963,7 @@ msgid "OTP secret key" msgstr "OTP 密钥" #: users/models/user.py:817 -#: xpack/plugins/cloud/serializers/account_attrs.py:209 +#: xpack/plugins/cloud/serializers/account_attrs.py:206 msgid "Private key" msgstr "ssh私钥" @@ -7122,8 +7136,6 @@ msgid "Periodic check user expired" msgstr "周期检测用户过期" #: users/tasks.py:83 -#, fuzzy -#| msgid "Check user expired" msgid "Check unused users" msgstr "校验用户已过期" @@ -7377,11 +7389,11 @@ msgstr "重置密码成功,返回到登录页面" msgid "XPACK" msgstr "XPack" -#: xpack/plugins/cloud/api.py:38 +#: xpack/plugins/cloud/api.py:56 msgid "Test connection successful" msgstr "测试成功" -#: xpack/plugins/cloud/api.py:40 +#: xpack/plugins/cloud/api.py:58 msgid "Test connection failed: {}" msgstr "测试连接失败:{}" @@ -7469,7 +7481,7 @@ msgstr "私有IP" msgid "Public IP" msgstr "公网IP" -#: xpack/plugins/cloud/const.py:38 +#: xpack/plugins/cloud/const.py:38 xpack/plugins/cloud/models.py:295 msgid "Instance name" msgstr "实例名称" @@ -7497,78 +7509,158 @@ msgstr "已同步" msgid "Released" msgstr "已释放" +#: xpack/plugins/cloud/manager.py:53 +msgid "Account unavailable" +msgstr "账号无效" + #: xpack/plugins/cloud/meta.py:9 msgid "Cloud center" msgstr "云管中心" -#: xpack/plugins/cloud/models.py:30 +#: xpack/plugins/cloud/models.py:34 msgid "Provider" msgstr "云服务商" -#: xpack/plugins/cloud/models.py:34 +#: xpack/plugins/cloud/models.py:38 msgid "Validity" msgstr "有效" -#: xpack/plugins/cloud/models.py:39 +#: xpack/plugins/cloud/models.py:43 msgid "Cloud account" msgstr "云账号" -#: xpack/plugins/cloud/models.py:41 +#: xpack/plugins/cloud/models.py:45 msgid "Test cloud account" msgstr "测试云账号" -#: xpack/plugins/cloud/models.py:88 xpack/plugins/cloud/serializers/task.py:36 +#: xpack/plugins/cloud/models.py:92 xpack/plugins/cloud/serializers/task.py:147 msgid "Regions" msgstr "地域" -#: xpack/plugins/cloud/models.py:91 +#: xpack/plugins/cloud/models.py:95 msgid "Hostname strategy" msgstr "主机名策略" -#: xpack/plugins/cloud/models.py:102 xpack/plugins/cloud/serializers/task.py:39 +#: xpack/plugins/cloud/models.py:100 +#: xpack/plugins/cloud/serializers/task.py:150 msgid "IP network segment group" msgstr "IP网段组" -#: xpack/plugins/cloud/models.py:105 xpack/plugins/cloud/serializers/task.py:44 +#: xpack/plugins/cloud/models.py:103 +#: xpack/plugins/cloud/serializers/task.py:155 msgid "Sync IP type" msgstr "同步IP类型" -#: xpack/plugins/cloud/models.py:108 xpack/plugins/cloud/serializers/task.py:61 +#: xpack/plugins/cloud/models.py:106 +#: xpack/plugins/cloud/serializers/task.py:173 msgid "Always update" msgstr "总是更新" -#: xpack/plugins/cloud/models.py:114 +#: xpack/plugins/cloud/models.py:112 msgid "Date last sync" msgstr "最后同步日期" -#: xpack/plugins/cloud/models.py:119 xpack/plugins/cloud/models.py:160 +#: xpack/plugins/cloud/models.py:115 xpack/plugins/cloud/models.py:313 +#: xpack/plugins/cloud/models.py:337 +msgid "Strategy" +msgstr "策略" + +#: xpack/plugins/cloud/models.py:120 xpack/plugins/cloud/models.py:197 msgid "Sync instance task" msgstr "同步实例任务" -#: xpack/plugins/cloud/models.py:171 xpack/plugins/cloud/models.py:219 +#: xpack/plugins/cloud/models.py:208 xpack/plugins/cloud/models.py:260 msgid "Date sync" msgstr "同步日期" -#: xpack/plugins/cloud/models.py:175 +#: xpack/plugins/cloud/models.py:212 +msgid "Sync instance snapshot" +msgstr "同步实例快照" + +#: xpack/plugins/cloud/models.py:216 msgid "Sync instance task execution" msgstr "同步实例任务执行" -#: xpack/plugins/cloud/models.py:199 +#: xpack/plugins/cloud/models.py:240 msgid "Sync task" msgstr "同步任务" -#: xpack/plugins/cloud/models.py:203 +#: xpack/plugins/cloud/models.py:244 msgid "Sync instance task history" msgstr "同步实例任务历史" -#: xpack/plugins/cloud/models.py:206 +#: xpack/plugins/cloud/models.py:247 msgid "Instance" msgstr "实例" -#: xpack/plugins/cloud/models.py:223 +#: xpack/plugins/cloud/models.py:264 msgid "Sync instance detail" msgstr "同步实例详情" +#: xpack/plugins/cloud/models.py:281 +msgid "Task strategy" +msgstr "密码策略" + +#: xpack/plugins/cloud/models.py:285 +msgid "Exact" +msgstr "" + +#: xpack/plugins/cloud/models.py:286 +msgid "Not" +msgstr "否" + +#: xpack/plugins/cloud/models.py:287 +msgid "In" +msgstr "在..里面" + +#: xpack/plugins/cloud/models.py:288 +msgid "Contains" +msgstr "包含" + +#: xpack/plugins/cloud/models.py:289 +msgid "Startswith" +msgstr "以..开头" + +#: xpack/plugins/cloud/models.py:290 +msgid "Endswith" +msgstr "以..结尾" + +#: xpack/plugins/cloud/models.py:296" +msgid "Instance platform" +msgstr "实例平台" + +#: xpack/plugins/cloud/models.py:297 +msgid "Instance address" +msgstr "实例地址" + +#: xpack/plugins/cloud/models.py:304 +msgid "Rule attr" +msgstr "规则属性" + +#: xpack/plugins/cloud/models.py:308 +msgid "Rule match" +msgstr "规则匹配" + +#: xpack/plugins/cloud/models.py:310 +msgid "Rule value" +msgstr "规则值" + +#: xpack/plugins/cloud/models.py:317 +msgid "Strategy rule" +msgstr "策略规则" + +#: xpack/plugins/cloud/models.py:332 +msgid "Action attr" +msgstr "动作属性" + +#: xpack/plugins/cloud/models.py:334 +msgid "Action value" +msgstr "动作值" + +#: xpack/plugins/cloud/models.py:341 +msgid "Strategy action" +msgstr "策略动作" + #: xpack/plugins/cloud/providers/aws_international.py:18 msgid "China (Beijing)" msgstr "中国(北京)" @@ -7677,7 +7769,7 @@ msgid "CN East-Suzhou" msgstr "华东-苏州" #: xpack/plugins/cloud/providers/baiducloud.py:57 -#: xpack/plugins/cloud/providers/huaweicloud.py:50 +#: xpack/plugins/cloud/providers/huaweicloud.py:49 msgid "CN-Hong Kong" msgstr "中国-香港" @@ -7695,66 +7787,66 @@ msgid "CN East-Shanghai" msgstr "华东-上海" #: xpack/plugins/cloud/providers/baiducloud.py:61 -#: xpack/plugins/cloud/providers/huaweicloud.py:49 +#: xpack/plugins/cloud/providers/huaweicloud.py:51 msgid "AP-Singapore" msgstr "亚太-新加坡" -#: xpack/plugins/cloud/providers/huaweicloud.py:37 -msgid "AF-Johannesburg" -msgstr "非洲-约翰内斯堡" - -#: xpack/plugins/cloud/providers/huaweicloud.py:38 -msgid "CN North-Beijing4" -msgstr "华北-北京4" - #: xpack/plugins/cloud/providers/huaweicloud.py:39 msgid "CN North-Beijing1" msgstr "华北-北京1" #: xpack/plugins/cloud/providers/huaweicloud.py:40 -msgid "CN East-Shanghai2" -msgstr "华东-上海2" +msgid "CN North-Beijing4" +msgstr "华北-北京4" #: xpack/plugins/cloud/providers/huaweicloud.py:41 -msgid "CN East-Shanghai1" -msgstr "华东-上海1" - -#: xpack/plugins/cloud/providers/huaweicloud.py:43 -msgid "LA-Mexico City1" -msgstr "拉美-墨西哥城一" - -#: xpack/plugins/cloud/providers/huaweicloud.py:44 -msgid "LA-Santiago" -msgstr "拉美-圣地亚哥" - -#: xpack/plugins/cloud/providers/huaweicloud.py:45 -msgid "LA-Sao Paulo1" -msgstr "拉美-圣保罗一" - -#: xpack/plugins/cloud/providers/huaweicloud.py:46 -msgid "EU-Paris" -msgstr "欧洲-巴黎" - -#: xpack/plugins/cloud/providers/huaweicloud.py:47 -msgid "CN Southwest-Guiyang1" -msgstr "西南-贵阳1" - -#: xpack/plugins/cloud/providers/huaweicloud.py:48 -msgid "AP-Bangkok" -msgstr "亚太-曼谷" - -#: xpack/plugins/cloud/providers/huaweicloud.py:52 -msgid "CN Northeast-Dalian" -msgstr "华北-大连" - -#: xpack/plugins/cloud/providers/huaweicloud.py:53 msgid "CN North-Ulanqab1" msgstr "华北-乌兰察布一" -#: xpack/plugins/cloud/providers/huaweicloud.py:54 +#: xpack/plugins/cloud/providers/huaweicloud.py:43 +msgid "CN South-Shenzhen" +msgstr "华南-广州" + +#: xpack/plugins/cloud/providers/huaweicloud.py:44 msgid "CN South-Guangzhou-InvitationOnly" msgstr "华南-广州-友好用户环境" +#: xpack/plugins/cloud/providers/huaweicloud.py:45 +msgid "CN East-Shanghai2" +msgstr "华东-上海2" + +#: xpack/plugins/cloud/providers/huaweicloud.py:46 +msgid "CN East-Shanghai1" +msgstr "华东-上海1" + +#: xpack/plugins/cloud/providers/huaweicloud.py:48 +msgid "CN Southwest-Guiyang1" +msgstr "西南-贵阳1" + +#: xpack/plugins/cloud/providers/huaweicloud.py:50 +msgid "AP-Bangkok" +msgstr "亚太-曼谷" + +#: xpack/plugins/cloud/providers/huaweicloud.py:53 +msgid "AF-Johannesburg" +msgstr "非洲-约翰内斯堡" + +#: xpack/plugins/cloud/providers/huaweicloud.py:54 +msgid "LA-Mexico City1" +msgstr "拉美-墨西哥城一" + +#: xpack/plugins/cloud/providers/huaweicloud.py:55 +msgid "LA-Santiago" +msgstr "拉美-圣地亚哥" + +#: xpack/plugins/cloud/providers/huaweicloud.py:56 +msgid "LA-Sao Paulo1" +msgstr "拉美-圣保罗一" + +#: xpack/plugins/cloud/providers/huaweicloud.py:58 +msgid "TR-Istanbul" +msgstr "" + #: xpack/plugins/cloud/providers/jdcloud.py:126 msgid "CN East-Suqian" msgstr "华东-宿迁" @@ -7783,7 +7875,7 @@ msgstr "订阅 ID" #: xpack/plugins/cloud/serializers/account_attrs.py:103 #: xpack/plugins/cloud/serializers/account_attrs.py:119 #: xpack/plugins/cloud/serializers/account_attrs.py:149 -#: xpack/plugins/cloud/serializers/account_attrs.py:202 +#: xpack/plugins/cloud/serializers/account_attrs.py:199 msgid "API Endpoint" msgstr "API 端点" @@ -7848,11 +7940,11 @@ msgstr "测试端口" msgid "Test timeout" msgstr "测试超时时间" -#: xpack/plugins/cloud/serializers/account_attrs.py:212 +#: xpack/plugins/cloud/serializers/account_attrs.py:209 msgid "Project" msgstr "project" -#: xpack/plugins/cloud/serializers/task.py:28 +#: xpack/plugins/cloud/serializers/task.py:139 msgid "" "Only instances matching the IP range will be synced.
    If the instance " "contains multiple IP addresses, the first IP address that matches will be " @@ -7864,11 +7956,11 @@ msgstr "" "到的 IP 地址将被用作创建的资产的 IP。
    默认值 * 表示同步所有实例和随机匹配 " "IP 地址。
    例如: 192.168.1.0/24,10.1.1.1-10.1.1.20。" -#: xpack/plugins/cloud/serializers/task.py:34 +#: xpack/plugins/cloud/serializers/task.py:145 msgid "History count" msgstr "执行次数" -#: xpack/plugins/cloud/serializers/task.py:35 +#: xpack/plugins/cloud/serializers/task.py:146 msgid "Instance count" msgstr "实例个数" @@ -7880,10 +7972,6 @@ msgstr "执行同步实例任务" msgid "Period clean sync instance task execution" msgstr "定期清除同步实例任务执行记录" -#: xpack/plugins/cloud/utils.py:68 -msgid "Account unavailable" -msgstr "账号无效" - #: xpack/plugins/interface/api.py:52 msgid "Restore default successfully." msgstr "恢复默认成功!" @@ -7948,6 +8036,12 @@ msgstr "旗舰版" msgid "Community edition" msgstr "社区版" +#~ msgid "EU-Paris" +#~ msgstr "欧洲-巴黎" + +#~ msgid "CN Northeast-Dalian" +#~ msgstr "华北-大连" + #~ msgid "Current only support login from AD/LDAP" #~ msgstr "当前仅支持 AD/LDAP 方式登录的用户" diff --git a/apps/settings/serializers/security.py b/apps/settings/serializers/security.py index 8c000cd8e..e2571415e 100644 --- a/apps/settings/serializers/security.py +++ b/apps/settings/serializers/security.py @@ -167,6 +167,11 @@ class SecuritySettingSerializer(SecurityPasswordRuleSerializer, SecurityAuthSeri label=_('Connection max idle time (minute)'), help_text=_('If idle time more than it, disconnect connection.') ) + SECURITY_MAX_SESSION_TIME = serializers.IntegerField( + min_value=1, max_value=99999, required=False, + label=_('Session max connection time (hour)'), + help_text=_('If session connection time more than it, disconnect connection.') + ) SECURITY_LUNA_REMEMBER_AUTH = serializers.BooleanField( label=_("Remember manual auth") ) diff --git a/apps/terminal/models/component/terminal.py b/apps/terminal/models/component/terminal.py index f2b0f9148..9955abf03 100644 --- a/apps/terminal/models/component/terminal.py +++ b/apps/terminal/models/component/terminal.py @@ -131,6 +131,7 @@ class Terminal(StorageMixin, TerminalStatusMixin, JMSBaseModel): 'SECURITY_MAX_IDLE_TIME': settings.SECURITY_MAX_IDLE_TIME, 'SECURITY_SESSION_SHARE': settings.SECURITY_SESSION_SHARE, 'FTP_FILE_MAX_STORE': settings.FTP_FILE_MAX_STORE, + 'SECURITY_MAX_SESSION_TIME': settings.SECURITY_MAX_SESSION_TIME, }) return configs From ab6d0d248476d0fd62e97844dc825cd1fa0380ae Mon Sep 17 00:00:00 2001 From: Bai Date: Wed, 9 Aug 2023 17:02:41 +0800 Subject: [PATCH 120/177] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=E8=B4=A6?= =?UTF-8?q?=E5=8F=B7=20API=20=E6=94=AF=E6=8C=81=20comment=20=E6=A8=A1?= =?UTF-8?q?=E7=B3=8A=E6=90=9C=E7=B4=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/accounts/api/account/account.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/accounts/api/account/account.py b/apps/accounts/api/account/account.py index 573f731cc..a0d38039b 100644 --- a/apps/accounts/api/account/account.py +++ b/apps/accounts/api/account/account.py @@ -22,7 +22,7 @@ __all__ = [ class AccountViewSet(OrgBulkModelViewSet): model = Account - search_fields = ('username', 'name', 'asset__name', 'asset__address') + search_fields = ('username', 'name', 'asset__name', 'asset__address', 'comment') filterset_class = AccountFilterSet serializer_classes = { 'default': serializers.AccountSerializer, From dcf113b87c16c8d3240993e790e46f141fcb6d20 Mon Sep 17 00:00:00 2001 From: Aaron3S Date: Wed, 9 Aug 2023 17:25:54 +0800 Subject: [PATCH 121/177] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E4=BD=9C?= =?UTF-8?q?=E4=B8=9A=E4=B8=AD=E5=BF=83=20sql=20=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/ops/const.py | 3 ++ apps/ops/models/job.py | 62 ++++++++++++++++++++++++++++++++++----- apps/users/models/user.py | 2 +- 3 files changed, 58 insertions(+), 9 deletions(-) diff --git a/apps/ops/const.py b/apps/ops/const.py index 6bb8ee750..01889a4b2 100644 --- a/apps/ops/const.py +++ b/apps/ops/const.py @@ -49,6 +49,9 @@ class Modules(models.TextChoices): shell = 'shell', _('Shell') winshell = 'win_shell', _('Powershell') python = 'python', _('Python') + mysql = 'mysql', _('MySQL') + postgresql = 'postgresql', _('PostgreSQL') + sqlserver = 'sqlserver', _('SQLServer') class JobStatus(models.TextChoices): diff --git a/apps/ops/models/job.py b/apps/ops/models/job.py index 3cd63e293..23105f297 100644 --- a/apps/ops/models/job.py +++ b/apps/ops/models/job.py @@ -19,6 +19,7 @@ from simple_history.models import HistoricalRecords from accounts.models import Account from acls.models import CommandFilterACL from assets.models import Asset +from common.db.encoder import ModelJSONFieldEncoder from ops.ansible import JMSInventory, AdHocRunner, PlaybookRunner, CommandInBlackListException from ops.mixin import PeriodTaskModelMixin from ops.variables import * @@ -42,12 +43,36 @@ def get_parent_keys(key, include_self=True): class JMSPermedInventory(JMSInventory): - def __init__(self, assets, account_policy='privileged_first', - account_prefer='root,Administrator', host_callback=None, user=None): + def __init__(self, + assets, + account_policy='privileged_first', + account_prefer='root,Administrator', + module=None, + host_callback=None, + user=None): super().__init__(assets, account_policy, account_prefer, host_callback, exclude_localhost=True) self.user = user + self.module = module self.assets_accounts_mapper = self.get_assets_accounts_mapper() + def make_account_vars(self, host, asset, account, automation, protocol, platform, gateway): + if not account: + host['error'] = _("No account available") + return host + + if protocol.name != self.module: + host['error'] = "Module {} is not suitable for this asset".format(self.module) + return host + + if protocol.name in ('mysql', 'postgresql', 'sqlserver'): + host['login_host'] = asset.address + host['login_port'] = protocol.port + host['login_user'] = account.username + host['login_password'] = account.secret + host['login_db'] = asset.spec_info.get('db_name', '') + return host + return super().make_account_vars(host, asset, account, automation, protocol, platform, gateway) + def get_asset_sorted_accounts(self, asset): accounts = self.assets_accounts_mapper.get(asset.id, []) return list(accounts) @@ -158,7 +183,9 @@ class Job(JMSOrgBaseModel, PeriodTaskModelMixin): @property def inventory(self): - return JMSPermedInventory(self.assets.all(), self.runas_policy, self.runas, user=self.creator) + return JMSPermedInventory(self.assets.all(), + self.runas_policy, self.runas, + user=self.creator, module=self.module) @property def material(self): @@ -187,8 +214,8 @@ class JobExecution(JMSOrgBaseModel): job = models.ForeignKey(Job, on_delete=models.SET_NULL, related_name='executions', null=True) job_version = models.IntegerField(default=0) parameters = models.JSONField(default=dict, verbose_name=_('Parameters')) - result = models.JSONField(blank=True, null=True, verbose_name=_('Result')) - summary = models.JSONField(default=dict, verbose_name=_('Summary')) + result = models.JSONField(encoder=ModelJSONFieldEncoder, blank=True, null=True, verbose_name=_('Result')) + summary = models.JSONField(encoder=ModelJSONFieldEncoder, default=dict, verbose_name=_('Summary')) creator = models.ForeignKey('users.User', verbose_name=_("Creator"), on_delete=models.SET_NULL, null=True) date_created = models.DateTimeField(auto_now_add=True, verbose_name=_('Date created')) date_start = models.DateTimeField(null=True, verbose_name=_('Date start'), db_index=True) @@ -256,7 +283,28 @@ class JobExecution(JMSOrgBaseModel): return module = self.current_job.module - # replace win_shell + + db_modules = ('mysql', 'postgresql', 'sqlserver', 'oracle') + db_module_name_map = { + 'mysql': 'community.mysql.mysql_query', + 'postgresql': 'community.postgresql.postgresql_query', + 'sqlserver': 'community.general.mssql_script:', + } + + if module in db_modules: + module = db_module_name_map.get(module, None) + if not module: + print('not support db module: {}'.format(module)) + raise Exception('not support db module: {}'.format(module)) + + login_args = "login_host={{login_host}} " \ + "login_user={{login_user}} " \ + "login_password={{login_password}} " \ + "login_port={{login_port}} " \ + "login_db={{login_db}}" + shell = "{} query=\"{}\" ".format(login_args, self.current_job.args) + return module, shell + if module == 'win_shell': module = 'ansible.windows.win_shell' @@ -284,12 +332,10 @@ class JobExecution(JMSOrgBaseModel): extra_vars = json.loads(self.parameters) else: extra_vars = {} - static_variables = self.gather_static_variables() extra_vars.update(static_variables) if self.current_job.type == 'adhoc': - module, args = self.compile_shell() runner = AdHocRunner( diff --git a/apps/users/models/user.py b/apps/users/models/user.py index 69ed7fa80..05c8ea084 100644 --- a/apps/users/models/user.py +++ b/apps/users/models/user.py @@ -45,7 +45,7 @@ class AuthMixin: save: Callable history_passwords: models.Manager sect_cache_tpl = 'user_sect_{}' - id: str | uuid.UUID + id: str @property def password_raw(self): From 4b72099053b49b15352ad57b23ea94ef5b1b0dae Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Wed, 9 Aug 2023 22:59:53 +0800 Subject: [PATCH 122/177] =?UTF-8?q?perf:=20=E8=BF=9E=E6=8E=A5=E6=96=B9?= =?UTF-8?q?=E5=BC=8F=E6=96=B0=E5=A2=9E=20guide=20=E6=A8=A1=E5=BC=8F=20(#11?= =?UTF-8?q?237)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: ibuler --- apps/assets/models/asset/common.py | 7 ++- apps/authentication/api/connection_token.py | 63 +++++++++++++------ .../commands/services/services/flower.py | 12 +--- apps/terminal/connect_methods.py | 53 ++++------------ 4 files changed, 62 insertions(+), 73 deletions(-) diff --git a/apps/assets/models/asset/common.py b/apps/assets/models/asset/common.py index b7425b870..6d845f05b 100644 --- a/apps/assets/models/asset/common.py +++ b/apps/assets/models/asset/common.py @@ -221,8 +221,11 @@ class Asset(NodesRelationMixin, AbsConnectivity, JSONFilterMixin, JMSOrgBaseMode return self.address def get_target_ssh_port(self): - protocol = self.protocols.all().filter(name='ssh').first() - return protocol.port if protocol else 22 + return self.get_protocol_port('ssh') + + def get_protocol_port(self, protocol): + protocol = self.protocols.all().filter(name=protocol).first() + return protocol.port if protocol else 0 @property def is_valid(self): diff --git a/apps/authentication/api/connection_token.py b/apps/authentication/api/connection_token.py index e805069d2..e424fe7e3 100644 --- a/apps/authentication/api/connection_token.py +++ b/apps/authentication/api/connection_token.py @@ -126,12 +126,16 @@ class RDPFileClientProtocolURLMixin: return filename, content @staticmethod - def get_connect_filename(prefix_name): - prefix_name = prefix_name.replace('/', '_') - prefix_name = prefix_name.replace('\\', '_') - prefix_name = prefix_name.replace('.', '_') + def escape_name(name): + name = name.replace('/', '_') + name = name.replace('\\', '_') + name = name.replace('.', '_') + name = urllib.parse.quote(name) + return name + + def get_connect_filename(self, prefix_name): filename = f'{prefix_name}-jumpserver' - filename = urllib.parse.quote(filename) + filename = self.escape_name(filename) return filename @staticmethod @@ -145,28 +149,29 @@ class RDPFileClientProtocolURLMixin: connect_method_dict = ConnectMethodUtil.get_connect_method( token.connect_method, token.protocol, _os ) + asset = token.asset if connect_method_dict is None: raise ValueError('Connect method not support: {}'.format(connect_method_name)) - endpoint = self.get_smart_endpoint( - protocol=connect_method_dict['endpoint_protocol'], - asset=token.asset - ) + account = token.account or token.input_username + datetime = timezone.localtime(timezone.now()).strftime('%Y-%m-%d_%H:%M:%S') + name = account + '@' + str(asset) + '[' + datetime + ']' data = { - 'id': str(token.id), - 'name': f'{endpoint.host}-{str(token.id)[:18]}', + 'version': 2, + 'id': str(token.id), # 兼容老的,未来几个版本删掉 + 'value': token.value, # 兼容老的,未来几个版本删掉 + 'name': self.escape_name(name), 'protocol': token.protocol, - 'host': endpoint.host, - 'port': endpoint.get_port(token.asset, token.protocol), - 'username': f'JMS-{str(token.id)}', - 'value': token.value, - 'command': '', - 'file': {} + 'token': { + 'id': str(token.id), + 'value': token.value, + }, + 'file': {}, + 'command': '' } if connect_method_name == NativeClient.mstsc or connect_method_dict['type'] == 'applet': filename, content = self.get_rdp_file_info(token) - filename = urllib.parse.unquote(filename) data.update({ 'protocol': 'rdp', 'file': { @@ -175,8 +180,26 @@ class RDPFileClientProtocolURLMixin: } }) else: - cmd = NativeClient.get_launch_command(connect_method_name, token, endpoint) - data.update({'command': cmd}) + endpoint = self.get_smart_endpoint( + protocol=connect_method_dict['endpoint_protocol'], + asset=asset + ) + data.update({ + 'asset': { + 'id': str(asset.id), + 'category': asset.category, + 'type': asset.type, + 'name': asset.name, + 'address': asset.address, + 'info': { + **asset.spec_info, + } + }, + 'endpoint': { + 'host': endpoint.host, + 'port': endpoint.get_port(token.asset, token.protocol), + } + }) return data def get_smart_endpoint(self, protocol, asset=None): diff --git a/apps/common/management/commands/services/services/flower.py b/apps/common/management/commands/services/services/flower.py index 94dd8e2f0..db859a78a 100644 --- a/apps/common/management/commands/services/services/flower.py +++ b/apps/common/management/commands/services/services/flower.py @@ -1,18 +1,10 @@ -from ..hands import * from .base import BaseService +from ..hands import * __all__ = ['FlowerService'] class FlowerService(BaseService): - - def __init__(self, **kwargs): - super().__init__(**kwargs) - - @property - def db_file(self): - return os.path.join(BASE_DIR, 'data', 'flower.db') - @property def cmd(self): print("\n- Start Flower as Task Monitor") @@ -24,11 +16,9 @@ class FlowerService(BaseService): '-A', 'ops', 'flower', '-logging=info', - '-db={}'.format(self.db_file), '--url_prefix=/core/flower', '--auto_refresh=False', '--max_tasks=1000', - '--persistent=True', '--state_save_interval=600000' ] return cmd diff --git a/apps/terminal/connect_methods.py b/apps/terminal/connect_methods.py index aab6f6c75..c793bb7a1 100644 --- a/apps/terminal/connect_methods.py +++ b/apps/terminal/connect_methods.py @@ -26,34 +26,29 @@ class WebMethod(TextChoices): class NativeClient(TextChoices): # Koko - ssh = 'ssh', 'SSH CLI' - sftp = 'sftp', 'SFTP CLI' - putty = 'putty', 'PuTTY' - xshell = 'xshell', 'Xshell' - + ssh_client = 'ssh_client', _('SSH Client') + ssh_guide = 'ssh_guide', _('SSH Guide') + sftp_client = 'sftp_client', _('SFTP Client') # Magnus + db_guide = 'db_guide', _('DB Guide') db_client = 'db_client', _('DB Client') - # Razor - mstsc = 'mstsc', 'Remote Desktop' + mstsc = 'mstsc', _('Remote Desktop') @classmethod def get_native_clients(cls): # native client 关注的是 endpoint 的 protocol, # 比如 telnet mysql, koko 都支持,到那时暴露的是 ssh 协议 clients = { - Protocol.ssh: { - 'default': [cls.ssh], - 'windows': [cls.putty], - }, - Protocol.sftp: [cls.sftp], + Protocol.ssh: [cls.ssh_client, cls.ssh_guide], + Protocol.sftp: [cls.sftp_client], Protocol.rdp: [cls.mstsc], - Protocol.mysql: [cls.db_client], - Protocol.mariadb: [cls.db_client], - Protocol.redis: [cls.db_client], - Protocol.mongodb: [cls.db_client], - Protocol.oracle: [cls.db_client], - Protocol.postgresql: [cls.db_client], + Protocol.mysql: [cls.db_client, cls.db_guide], + Protocol.mariadb: [cls.db_client, cls.db_guide], + Protocol.redis: [cls.db_client, cls.db_guide], + Protocol.mongodb: [cls.db_client, cls.db_guide], + Protocol.oracle: [cls.db_client, cls.db_guide], + Protocol.postgresql: [cls.db_client, cls.db_guide], } return clients @@ -97,28 +92,6 @@ class NativeClient(TextChoices): }) return methods - @classmethod - def get_launch_command(cls, name, token, endpoint, os='windows'): - username = f'JMS-{token.id}' - commands = { - cls.ssh: f'ssh {username}@{endpoint.host} -p {endpoint.ssh_port}', - cls.sftp: f'sftp {username}@{endpoint.host} -P {endpoint.ssh_port}', - cls.putty: f'putty.exe -ssh {username}@{endpoint.host} -P {endpoint.ssh_port}', - cls.xshell: f'xshell.exe -url ssh://{username}:{token.value}@{endpoint.host}:{endpoint.ssh_port}', - # 前端自己处理了 - # cls.mysql: 'mysql -h {hostname} -P {port} -u {username} -p', - # cls.psql: { - # 'default': 'psql -h {hostname} -p {port} -U {username} -W', - # 'windows': 'psql /h {hostname} /p {port} /U {username} -W', - # }, - # cls.sqlplus: 'sqlplus {username}/{password}@{hostname}:{port}', - # cls.redis: 'redis-cli -h {hostname} -p {port} -a {password}', - } - command = commands.get(name) - if isinstance(command, dict): - command = command.get(os, command.get('default')) - return command - class AppletMethod: @classmethod From 1944e80418e816b704c30f1606e59eb685900ea9 Mon Sep 17 00:00:00 2001 From: ibuler Date: Thu, 10 Aug 2023 11:19:17 +0800 Subject: [PATCH 123/177] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=E7=BF=BB?= =?UTF-8?q?=E8=AF=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/locale/ja/LC_MESSAGES/django.mo | 4 +- apps/locale/ja/LC_MESSAGES/django.po | 537 +++++++++--------- apps/locale/zh/LC_MESSAGES/django.mo | 4 +- apps/locale/zh/LC_MESSAGES/django.po | 524 ++++++++--------- .../ops/migrations/0026_auto_20230810_1039.py | 39 ++ apps/settings/serializers/security.py | 2 +- .../migrations/0066_auto_20230810_1118.py | 27 + apps/terminal/models/applet/applet.py | 3 +- apps/terminal/serializers/applet.py | 4 +- 9 files changed, 613 insertions(+), 531 deletions(-) create mode 100644 apps/ops/migrations/0026_auto_20230810_1039.py create mode 100644 apps/terminal/migrations/0066_auto_20230810_1118.py diff --git a/apps/locale/ja/LC_MESSAGES/django.mo b/apps/locale/ja/LC_MESSAGES/django.mo index 9cd3ce2c1..b71df6d0d 100644 --- a/apps/locale/ja/LC_MESSAGES/django.mo +++ b/apps/locale/ja/LC_MESSAGES/django.mo @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:555045fe297b59d9a9f813738679419f34ae9296013f4576ee1e0037985c0f1c -size 152487 +oid sha256:50d8a03cc8991f92c9e649b4eb1685a9bc862671e013a11ba7683a1b7fcd0ae4 +size 152899 diff --git a/apps/locale/ja/LC_MESSAGES/django.po b/apps/locale/ja/LC_MESSAGES/django.po index 1c315331d..cb98e8c6e 100644 --- a/apps/locale/ja/LC_MESSAGES/django.po +++ b/apps/locale/ja/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-08-08 17:55+0800\n" +"POT-Creation-Date: 2023-08-10 11:06+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -95,7 +95,7 @@ msgstr "更新" #: accounts/const/account.py:33 #: accounts/serializers/automations/change_secret.py:156 audits/const.py:54 #: audits/signal_handlers/activity_log.py:33 common/const/choices.py:19 -#: ops/const.py:58 terminal/const.py:77 xpack/plugins/cloud/const.py:43 +#: ops/const.py:61 terminal/const.py:77 xpack/plugins/cloud/const.py:43 msgid "Failed" msgstr "失敗しました" @@ -204,7 +204,7 @@ msgstr "HashiCorp Vault" #: accounts/serializers/automations/change_secret.py:112 #: accounts/serializers/automations/change_secret.py:132 #: acls/serializers/base.py:123 assets/models/asset/common.py:93 -#: assets/models/asset/common.py:331 assets/models/cmd_filter.py:36 +#: assets/models/asset/common.py:334 assets/models/cmd_filter.py:36 #: assets/serializers/domain.py:19 assets/serializers/label.py:27 #: audits/models.py:53 authentication/models/connection_token.py:36 #: perms/models/asset_permission.py:64 perms/serializers/permission.py:34 @@ -213,7 +213,7 @@ msgstr "HashiCorp Vault" #: terminal/serializers/session.py:26 #: terminal/templates/terminal/_msg_command_warning.html:4 #: terminal/templates/terminal/_msg_session_sharing.html:4 -#: tickets/models/ticket/apply_asset.py:16 xpack/plugins/cloud/models.py:253 +#: tickets/models/ticket/apply_asset.py:16 xpack/plugins/cloud/models.py:212 msgid "Asset" msgstr "資産" @@ -248,7 +248,7 @@ msgstr "ソース ID" #: terminal/backends/command/models.py:18 terminal/models/session/session.py:33 #: terminal/templates/terminal/_msg_command_warning.html:8 #: terminal/templates/terminal/_msg_session_sharing.html:8 -#: tickets/models/ticket/command_confirm.py:13 xpack/plugins/cloud/models.py:89 +#: tickets/models/ticket/command_confirm.py:13 xpack/plugins/cloud/models.py:85 msgid "Account" msgstr "アカウント" @@ -287,7 +287,7 @@ msgstr "アカウントバックアップ計画" #: accounts/models/automations/backup_account.py:91 #: assets/models/automations/base.py:115 audits/models.py:60 -#: ops/models/base.py:55 ops/models/celery.py:63 ops/models/job.py:194 +#: ops/models/base.py:55 ops/models/celery.py:63 ops/models/job.py:221 #: ops/templates/ops/celery_task_log.html:75 #: perms/models/asset_permission.py:72 terminal/models/applet/host.py:139 #: terminal/models/session/session.py:44 @@ -315,7 +315,7 @@ msgid "Trigger mode" msgstr "トリガーモード" #: accounts/models/automations/backup_account.py:105 audits/models.py:194 -#: terminal/models/session/sharing.py:121 xpack/plugins/cloud/models.py:205 +#: terminal/models/session/sharing.py:121 xpack/plugins/cloud/models.py:168 msgid "Reason" msgstr "理由" @@ -417,7 +417,7 @@ msgstr "開始日" #: accounts/models/automations/change_secret.py:91 #: assets/models/automations/base.py:116 ops/models/base.py:56 -#: ops/models/celery.py:64 ops/models/job.py:195 +#: ops/models/celery.py:64 ops/models/job.py:222 #: terminal/models/applet/host.py:140 msgid "Date finished" msgstr "終了日" @@ -503,16 +503,15 @@ msgstr "アカウントの確認" #: assets/serializers/platform.py:110 assets/serializers/platform.py:223 #: authentication/serializers/connect_token_secret.py:110 ops/mixin.py:21 #: ops/models/adhoc.py:20 ops/models/celery.py:15 ops/models/celery.py:57 -#: ops/models/job.py:94 ops/models/playbook.py:28 ops/serializers/job.py:20 +#: ops/models/job.py:119 ops/models/playbook.py:28 ops/serializers/job.py:20 #: orgs/models.py:82 perms/models/asset_permission.py:56 rbac/models/role.py:29 #: settings/models.py:32 settings/serializers/sms.py:6 #: terminal/models/applet/applet.py:32 terminal/models/component/endpoint.py:12 -#: terminal/models/component/endpoint.py:92 +#: terminal/models/component/endpoint.py:94 #: terminal/models/component/storage.py:26 terminal/models/component/task.py:13 #: terminal/models/component/terminal.py:84 users/forms/profile.py:33 #: users/models/group.py:13 users/models/user.py:787 -#: xpack/plugins/cloud/models.py:32 xpack/plugins/cloud/models.py:273 -#: xpack/plugins/cloud/serializers/task.py:68 +#: xpack/plugins/cloud/models.py:28 msgid "Name" msgstr "名前" @@ -524,12 +523,12 @@ msgstr "特権アカウント" #: assets/models/automations/base.py:21 assets/models/cmd_filter.py:39 #: assets/models/label.py:22 #: authentication/serializers/connect_token_secret.py:114 -#: terminal/models/applet/applet.py:39 -#: terminal/models/component/endpoint.py:103 users/serializers/user.py:169 +#: terminal/models/applet/applet.py:38 +#: terminal/models/component/endpoint.py:105 users/serializers/user.py:169 msgid "Is active" msgstr "アクティブです。" -#: accounts/models/template.py:19 xpack/plugins/cloud/models.py:325 +#: accounts/models/template.py:19 msgid "Account template" msgstr "アカウント テンプレート" @@ -635,9 +634,9 @@ msgstr "カテゴリ" #: assets/models/cmd_filter.py:74 assets/models/platform.py:90 #: assets/serializers/asset/common.py:122 assets/serializers/platform.py:112 #: assets/serializers/platform.py:127 audits/serializers.py:49 -#: authentication/serializers/connect_token_secret.py:123 ops/models/job.py:105 +#: authentication/serializers/connect_token_secret.py:123 ops/models/job.py:130 #: perms/serializers/user_permission.py:27 settings/serializers/vault.py:13 -#: terminal/models/applet/applet.py:38 terminal/models/component/storage.py:57 +#: terminal/models/applet/applet.py:37 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:226 #: terminal/serializers/storage.py:238 tickets/models/comment.py:26 @@ -670,7 +669,7 @@ msgstr "編集済み" #: accounts/serializers/automations/base.py:22 acls/models/base.py:97 #: assets/models/automations/base.py:19 #: assets/serializers/automations/base.py:20 ops/models/base.py:17 -#: ops/models/job.py:107 ops/serializers/job.py:21 +#: ops/models/job.py:132 ops/serializers/job.py:21 #: terminal/templates/terminal/_msg_command_execute_alert.html:16 msgid "Assets" msgstr "資産" @@ -761,14 +760,14 @@ msgstr "" #: accounts/serializers/account/virtual.py:19 assets/models/_user.py:27 #: assets/models/cmd_filter.py:40 assets/models/cmd_filter.py:88 #: assets/models/group.py:20 common/db/models.py:36 ops/models/adhoc.py:26 -#: ops/models/job.py:113 ops/models/playbook.py:31 rbac/models/role.py:37 -#: settings/models.py:37 terminal/models/applet/applet.py:44 -#: terminal/models/applet/applet.py:250 terminal/models/applet/host.py:141 +#: ops/models/job.py:138 ops/models/playbook.py:31 rbac/models/role.py:37 +#: settings/models.py:37 terminal/models/applet/applet.py:43 +#: terminal/models/applet/applet.py:283 terminal/models/applet/host.py:141 #: terminal/models/component/endpoint.py:24 -#: terminal/models/component/endpoint.py:102 +#: terminal/models/component/endpoint.py:104 #: terminal/models/session/session.py:46 tickets/models/comment.py:32 #: tickets/models/ticket/general.py:297 users/models/user.py:826 -#: xpack/plugins/cloud/models.py:39 xpack/plugins/cloud/models.py:109 +#: xpack/plugins/cloud/models.py:35 xpack/plugins/cloud/models.py:111 msgid "Comment" msgstr "コメント" @@ -816,7 +815,7 @@ msgstr "自動タスク実行履歴" #: accounts/serializers/automations/change_secret.py:155 audits/const.py:53 #: audits/models.py:59 audits/signal_handlers/activity_log.py:33 -#: common/const/choices.py:18 ops/const.py:56 ops/serializers/celery.py:40 +#: common/const/choices.py:18 ops/const.py:59 ops/serializers/celery.py:40 #: terminal/const.py:76 terminal/models/session/sharing.py:117 #: tickets/views/approve.py:115 msgid "Success" @@ -888,14 +887,12 @@ msgid "Warning" msgstr "警告" #: acls/models/base.py:37 assets/models/_user.py:51 -#: assets/models/cmd_filter.py:76 terminal/models/component/endpoint.py:95 -#: xpack/plugins/cloud/models.py:275 +#: assets/models/cmd_filter.py:76 terminal/models/component/endpoint.py:97 msgid "Priority" msgstr "優先順位" #: acls/models/base.py:38 assets/models/_user.py:51 -#: assets/models/cmd_filter.py:76 terminal/models/component/endpoint.py:96 -#: xpack/plugins/cloud/models.py:276 +#: assets/models/cmd_filter.py:76 terminal/models/component/endpoint.py:98 msgid "1-100, the lower the value will be match first" msgstr "1-100、低い値は最初に一致します" @@ -932,7 +929,6 @@ msgid "Command" msgstr "コマンド" #: acls/models/command_acl.py:17 assets/models/cmd_filter.py:59 -#: xpack/plugins/cloud/models.py:291 msgid "Regex" msgstr "正規情報" @@ -1029,7 +1025,7 @@ msgid "None of the reviewers belong to Organization `{}`" msgstr "いずれのレビューアも組織 '{}' に属していません" #: acls/serializers/rules/rules.py:20 -#: xpack/plugins/cloud/serializers/task.py:133 +#: xpack/plugins/cloud/serializers/task.py:22 msgid "IP address invalid: `{}`" msgstr "IPアドレスが無効: '{}'" @@ -1057,7 +1053,7 @@ msgstr "期間" msgid "Applications" msgstr "アプリケーション" -#: applications/models.py:16 xpack/plugins/cloud/models.py:37 +#: applications/models.py:16 xpack/plugins/cloud/models.py:33 #: xpack/plugins/cloud/serializers/account.py:63 msgid "Attrs" msgstr "ツールバーの" @@ -1351,7 +1347,7 @@ msgstr "SSHパブリックキー" #: assets/models/_user.py:28 assets/models/automations/base.py:114 #: assets/models/cmd_filter.py:41 assets/models/group.py:19 -#: common/db/models.py:34 ops/models/base.py:54 ops/models/job.py:193 +#: common/db/models.py:34 ops/models/base.py:54 ops/models/job.py:220 #: users/models/user.py:1018 msgid "Date created" msgstr "作成された日付" @@ -1390,7 +1386,7 @@ msgstr "ユーザーと同じユーザー名" #: assets/models/_user.py:52 authentication/models/connection_token.py:41 #: authentication/serializers/connect_token_secret.py:111 -#: terminal/models/applet/applet.py:41 terminal/serializers/session.py:19 +#: terminal/models/applet/applet.py:40 terminal/serializers/session.py:19 #: terminal/serializers/session.py:42 terminal/serializers/storage.py:70 msgid "Protocol" msgstr "プロトコル" @@ -1455,13 +1451,14 @@ msgstr "アドレス" #: assets/models/asset/common.py:151 assets/models/platform.py:119 #: authentication/serializers/connect_token_secret.py:115 -#: perms/serializers/user_permission.py:24 xpack/plugins/cloud/models.py:321 +#: perms/serializers/user_permission.py:24 +#: xpack/plugins/cloud/serializers/account_attrs.py:196 msgid "Platform" msgstr "プラットフォーム" #: assets/models/asset/common.py:153 assets/models/domain.py:21 #: authentication/serializers/connect_token_secret.py:133 -#: perms/serializers/user_permission.py:29 xpack/plugins/cloud/models.py:323 +#: perms/serializers/user_permission.py:29 msgid "Domain" msgstr "ドメイン" @@ -1478,19 +1475,19 @@ msgstr "資産ハードウェア情報の収集" msgid "Custom info" msgstr "カスタム属性" -#: assets/models/asset/common.py:334 +#: assets/models/asset/common.py:337 msgid "Can refresh asset hardware info" msgstr "資産ハードウェア情報を更新できます" -#: assets/models/asset/common.py:335 +#: assets/models/asset/common.py:338 msgid "Can test asset connectivity" msgstr "資産接続をテストできます" -#: assets/models/asset/common.py:336 +#: assets/models/asset/common.py:339 msgid "Can match asset" msgstr "アセットを一致させることができます" -#: assets/models/asset/common.py:337 +#: assets/models/asset/common.py:340 msgid "Can change asset nodes" msgstr "資産ノードを変更できます" @@ -1518,7 +1515,7 @@ msgstr "証明書チェックを無視" msgid "Proxy" msgstr "プロキシー" -#: assets/models/automations/base.py:22 ops/models/job.py:189 +#: assets/models/automations/base.py:22 ops/models/job.py:216 #: settings/serializers/auth/sms.py:99 msgid "Parameters" msgstr "パラメータ" @@ -1532,13 +1529,13 @@ msgid "Asset automation task" msgstr "アセットの自動化タスク" #: assets/models/automations/base.py:113 audits/models.py:199 -#: audits/serializers.py:50 ops/models/base.py:49 ops/models/job.py:186 -#: terminal/models/applet/applet.py:249 terminal/models/applet/host.py:138 +#: audits/serializers.py:50 ops/models/base.py:49 ops/models/job.py:213 +#: terminal/models/applet/applet.py:282 terminal/models/applet/host.py:138 #: terminal/models/component/status.py:30 terminal/serializers/applet.py:18 #: terminal/serializers/applet_host.py:115 tickets/models/ticket/general.py:283 #: tickets/serializers/super_ticket.py:13 -#: tickets/serializers/ticket/ticket.py:20 xpack/plugins/cloud/models.py:201 -#: xpack/plugins/cloud/models.py:257 +#: tickets/serializers/ticket/ticket.py:20 xpack/plugins/cloud/models.py:164 +#: xpack/plugins/cloud/models.py:216 msgid "Status" msgstr "ステータス" @@ -1602,7 +1599,7 @@ msgstr "資産グループ" #: assets/models/group.py:31 assets/models/platform.py:19 #: assets/serializers/platform.py:113 -#: xpack/plugins/cloud/providers/nutanix.py:30 +#: xpack/plugins/cloud/providers/nutanix.py:32 msgid "Default" msgstr "デフォルト" @@ -1652,7 +1649,7 @@ msgid "Parent key" msgstr "親キー" #: assets/models/node.py:558 perms/serializers/permission.py:35 -#: tickets/models/ticket/apply_asset.py:14 xpack/plugins/cloud/models.py:322 +#: tickets/models/ticket/apply_asset.py:14 xpack/plugins/cloud/models.py:96 msgid "Node" msgstr "ノード" @@ -1793,8 +1790,7 @@ msgstr "" #: assets/serializers/asset/common.py:124 assets/serializers/platform.py:129 #: authentication/serializers/connect_token_secret.py:29 #: authentication/serializers/connect_token_secret.py:72 -#: perms/serializers/user_permission.py:25 xpack/plugins/cloud/models.py:324 -#: xpack/plugins/cloud/serializers/task.py:31 +#: perms/serializers/user_permission.py:25 xpack/plugins/cloud/models.py:99 msgid "Protocols" msgstr "プロトコル" @@ -2343,29 +2339,29 @@ msgstr "外部ストレージへのFTPファイルのアップロード" msgid "This action require verify your MFA" msgstr "この操作には、MFAを検証する必要があります" -#: authentication/api/connection_token.py:230 +#: authentication/api/connection_token.py:258 msgid "Reusable connection token is not allowed, global setting not enabled" msgstr "" "再使用可能な接続トークンの使用は許可されていません。グローバル設定は有効に" "なっていません" -#: authentication/api/connection_token.py:310 +#: authentication/api/connection_token.py:338 msgid "Anonymous account is not supported for this asset" msgstr "匿名アカウントはこのプロパティではサポートされていません" -#: authentication/api/connection_token.py:329 +#: authentication/api/connection_token.py:357 msgid "Account not found" msgstr "アカウントが見つかりません" -#: authentication/api/connection_token.py:332 +#: authentication/api/connection_token.py:360 msgid "Permission expired" msgstr "承認の有効期限が切れています" -#: authentication/api/connection_token.py:346 +#: authentication/api/connection_token.py:374 msgid "ACL action is reject: {}({})" msgstr "ACL アクションは拒否です: {}({})" -#: authentication/api/connection_token.py:350 +#: authentication/api/connection_token.py:378 msgid "ACL action is review" msgstr "ACL アクションはレビューです" @@ -2932,8 +2928,7 @@ msgid "Show" msgstr "表示" #: authentication/templates/authentication/_access_key_modal.html:66 -#: settings/serializers/security.py:39 users/models/user.py:635 -#: users/serializers/profile.py:116 +#: users/models/user.py:635 users/serializers/profile.py:116 #: users/templates/users/user_verify_mfa.html:36 msgid "Disable" msgstr "無効化" @@ -3293,7 +3288,7 @@ msgstr "の準備を" msgid "Pending" msgstr "未定" -#: common/const/choices.py:17 ops/const.py:55 +#: common/const/choices.py:17 ops/const.py:58 msgid "Running" msgstr "ランニング" @@ -3651,15 +3646,15 @@ msgstr "システムメッセージ" msgid "Publish the station message" msgstr "投稿サイトニュース" -#: ops/ansible/inventory.py:92 +#: ops/ansible/inventory.py:92 ops/models/job.py:60 msgid "No account available" msgstr "利用可能なアカウントがありません" -#: ops/ansible/inventory.py:258 +#: ops/ansible/inventory.py:260 msgid "Ansible disabled" msgstr "Ansible 無効" -#: ops/ansible/inventory.py:274 +#: ops/ansible/inventory.py:276 msgid "Skip hosts below:" msgstr "次のホストをスキップします: " @@ -3723,7 +3718,7 @@ msgstr "VCS" msgid "Adhoc" msgstr "コマンド#コマンド#" -#: ops/const.py:39 ops/models/job.py:103 +#: ops/const.py:39 ops/models/job.py:128 msgid "Playbook" msgstr "Playbook" @@ -3743,7 +3738,25 @@ msgstr "PowerShell" msgid "Python" msgstr "Python" -#: ops/const.py:57 +#: ops/const.py:52 +#, fuzzy +#| msgid "MySQL port" +msgid "MySQL" +msgstr "MySQL ポート" + +#: ops/const.py:53 +#, fuzzy +#| msgid "PostgreSQL port" +msgid "PostgreSQL" +msgstr "PostgreSQL ポート" + +#: ops/const.py:54 +#, fuzzy +#| msgid "Server url" +msgid "SQLServer" +msgstr "サービス側アドレス" + +#: ops/const.py:60 msgid "Timeout" msgstr "タイムアウト" @@ -3780,17 +3793,17 @@ msgstr "定期的または定期的に設定を行う必要があります" msgid "Pattern" msgstr "パターン" -#: ops/models/adhoc.py:23 ops/models/job.py:98 +#: ops/models/adhoc.py:23 ops/models/job.py:123 msgid "Module" msgstr "モジュール" -#: ops/models/adhoc.py:24 ops/models/celery.py:58 ops/models/job.py:97 +#: ops/models/adhoc.py:24 ops/models/celery.py:58 ops/models/job.py:122 #: terminal/models/component/task.py:14 msgid "Args" msgstr "アルグ" #: ops/models/adhoc.py:25 ops/models/base.py:16 ops/models/base.py:53 -#: ops/models/job.py:106 ops/models/job.py:192 ops/models/playbook.py:30 +#: ops/models/job.py:131 ops/models/job.py:219 ops/models/playbook.py:30 #: terminal/models/session/sharing.py:24 msgid "Creator" msgstr "作成者" @@ -3807,12 +3820,12 @@ msgstr "最後の実行" msgid "Date last run" msgstr "最終実行日" -#: ops/models/base.py:51 ops/models/job.py:190 -#: xpack/plugins/cloud/models.py:199 +#: ops/models/base.py:51 ops/models/job.py:217 +#: xpack/plugins/cloud/models.py:162 msgid "Result" msgstr "結果" -#: ops/models/base.py:52 ops/models/job.py:191 +#: ops/models/base.py:52 ops/models/job.py:218 msgid "Summary" msgstr "概要" @@ -3845,43 +3858,43 @@ msgstr "発売日" msgid "Celery Task Execution" msgstr "Celery タスク実行" -#: ops/models/job.py:100 +#: ops/models/job.py:125 msgid "Chdir" msgstr "実行ディレクトリ" -#: ops/models/job.py:101 +#: ops/models/job.py:126 msgid "Timeout (Seconds)" msgstr "タイムアウト(秒)" -#: ops/models/job.py:108 +#: ops/models/job.py:133 msgid "Use Parameter Define" msgstr "パラメータ定義を使用する" -#: ops/models/job.py:109 +#: ops/models/job.py:134 msgid "Parameters define" msgstr "パラメータ定義" -#: ops/models/job.py:110 +#: ops/models/job.py:135 msgid "Runas" msgstr "ユーザーとして実行" -#: ops/models/job.py:112 +#: ops/models/job.py:137 msgid "Runas policy" msgstr "ユーザー ポリシー" -#: ops/models/job.py:174 +#: ops/models/job.py:201 msgid "Job" msgstr "ジョブ#ジョブ#" -#: ops/models/job.py:197 +#: ops/models/job.py:224 msgid "Material" msgstr "Material" -#: ops/models/job.py:199 +#: ops/models/job.py:226 msgid "Material Type" msgstr "Material を選択してオプションを設定します。" -#: ops/models/job.py:480 +#: ops/models/job.py:526 msgid "Job Execution" msgstr "ジョブ実行" @@ -4049,7 +4062,7 @@ msgstr "デフォルト組織" msgid "SYSTEM" msgstr "システム組織" -#: orgs/models.py:83 rbac/models/role.py:36 terminal/models/applet/applet.py:40 +#: orgs/models.py:83 rbac/models/role.py:36 terminal/models/applet/applet.py:39 msgid "Builtin" msgstr "ビルトイン" @@ -4346,8 +4359,8 @@ msgstr "タスクセンター" msgid "My assets" msgstr "私の資産" -#: rbac/tree.py:56 terminal/models/applet/applet.py:51 -#: terminal/models/applet/applet.py:246 terminal/models/applet/host.py:29 +#: rbac/tree.py:56 terminal/models/applet/applet.py:50 +#: terminal/models/applet/applet.py:279 terminal/models/applet/host.py:29 #: terminal/serializers/applet.py:15 msgid "Applet" msgstr "リモートアプリケーション" @@ -5152,6 +5165,12 @@ msgstr "" "ユーザーが限られた回数だけログインできなかった場合、この時間間隔ではログイン" "はできません。" +#: settings/serializers/security.py:39 +#, fuzzy +#| msgid "MFA not enabled" +msgid "Not enabled" +msgstr "MFAが有効化されていません" + #: settings/serializers/security.py:40 msgid "All users" msgstr "すべてのユーザー" @@ -5340,7 +5359,6 @@ msgid "If idle time more than it, disconnect connection." msgstr "この設定以上の操作がない場合、接続は切断されます" #: settings/serializers/security.py:172 - msgid "Session max connection time (hour)" msgstr "セッション最大接続時間(時間)" @@ -5672,8 +5690,8 @@ msgstr "期限切れです。" #, python-format msgid "" "\n" -" Your password has expired, please click this link update password.\n" +" Your password has expired, please click this link update password.\n" " " msgstr "" "\n" @@ -5694,34 +5712,34 @@ msgid "" " " msgstr "" "\n" -" クリックしてください リンク パスワードの更新\n" +" クリックしてください リンク パスワードの更新\n" " " #: templates/_message.html:43 #, python-format msgid "" "\n" -" Your information was incomplete. Please click this link to complete your information.\n" +" Your information was incomplete. Please click this link to complete your information.\n" " " msgstr "" "\n" -" あなたの情報が不完全なので、クリックしてください。 リンク 補完\n" +" あなたの情報が不完全なので、クリックしてください。 リンク 補完\n" " " #: templates/_message.html:56 #, python-format msgid "" "\n" -" Your ssh public key not set or expired. Please click this link to update\n" +" Your ssh public key not set or expired. Please click this link to update\n" " " msgstr "" "\n" -" SSHキーが設定されていないか無効になっている場合は、 リンク 更新\n" +" SSHキーが設定されていないか無効になっている場合は、 リンク 更新\n" " " #: templates/_mfa_login_field.html:28 @@ -5861,10 +5879,38 @@ msgstr "出力" msgid "Risk level" msgstr "リスクレベル" -#: terminal/connect_methods.py:35 +#: terminal/connect_methods.py:29 +#, fuzzy +#| msgid "Client" +msgid "SSH Client" +msgstr "クライアント" + +#: terminal/connect_methods.py:30 +#, fuzzy +#| msgid "SSH key" +msgid "SSH Guide" +msgstr "SSH キー" + +#: terminal/connect_methods.py:31 +#, fuzzy +#| msgid "Client" +msgid "SFTP Client" +msgstr "クライアント" + +#: terminal/connect_methods.py:33 +msgid "DB Guide" +msgstr "" + +#: terminal/connect_methods.py:34 msgid "DB Client" msgstr "データベース クライアント" +#: terminal/connect_methods.py:36 +#, fuzzy +#| msgid "Remote Address" +msgid "Remote Desktop" +msgstr "リモートアドレス" + #: terminal/const.py:12 msgid "Review & Reject" msgstr "レビューと拒否" @@ -5938,7 +5984,7 @@ msgstr "ストレージが無効です" msgid "Community" msgstr "コミュニティ版" -#: terminal/models/applet/applet.py:30 +#: terminal/models/applet/applet.py:30 terminal/models/applet/applet.py:36 msgid "Enterprise" msgstr "エンタープライズ版" @@ -5946,39 +5992,35 @@ msgstr "エンタープライズ版" msgid "Author" msgstr "著者" -#: terminal/models/applet/applet.py:37 terminal/serializers/applet.py:30 -msgid "Edition" -msgstr "バージョン" - -#: terminal/models/applet/applet.py:42 +#: terminal/models/applet/applet.py:41 msgid "Can concurrent" msgstr "同時実行可能" -#: terminal/models/applet/applet.py:43 +#: terminal/models/applet/applet.py:42 msgid "Tags" msgstr "ラベル" -#: terminal/models/applet/applet.py:47 terminal/serializers/storage.py:159 +#: terminal/models/applet/applet.py:46 terminal/serializers/storage.py:159 msgid "Hosts" msgstr "ホスト" -#: terminal/models/applet/applet.py:92 +#: terminal/models/applet/applet.py:91 msgid "Applet pkg not valid, Missing file {}" msgstr "無効なアプレット パッケージ、ファイル {} がありません" -#: terminal/models/applet/applet.py:111 +#: terminal/models/applet/applet.py:110 msgid "Load platform.yml failed: {}" msgstr "platform.ymlのロードに失敗しました:{}" -#: terminal/models/applet/applet.py:114 +#: terminal/models/applet/applet.py:113 msgid "Only support custom platform" msgstr "カスタムプラットフォームのみをサポート" -#: terminal/models/applet/applet.py:119 +#: terminal/models/applet/applet.py:118 msgid "Missing type in platform.yml" msgstr "platform.ymlにタイプがありません" -#: terminal/models/applet/applet.py:248 terminal/models/applet/host.py:35 +#: terminal/models/applet/applet.py:281 terminal/models/applet/host.py:35 #: terminal/models/applet/host.py:136 msgid "Hosting" msgstr "ホスト マシン" @@ -6044,18 +6086,18 @@ msgid "Redis port" msgstr "Redis ポート" #: terminal/models/component/endpoint.py:29 -#: terminal/models/component/endpoint.py:100 +#: terminal/models/component/endpoint.py:102 #: terminal/serializers/endpoint.py:73 terminal/serializers/storage.py:40 #: terminal/serializers/storage.py:52 terminal/serializers/storage.py:82 #: terminal/serializers/storage.py:92 terminal/serializers/storage.py:100 msgid "Endpoint" msgstr "エンドポイント" -#: terminal/models/component/endpoint.py:93 +#: terminal/models/component/endpoint.py:95 msgid "IP group" msgstr "IP グループ" -#: terminal/models/component/endpoint.py:106 +#: terminal/models/component/endpoint.py:108 msgid "Endpoint rule" msgstr "エンドポイントルール" @@ -6470,7 +6512,7 @@ msgstr "アクセスキー" msgid "Access key secret" msgstr "アクセスキーシークレット" -#: terminal/serializers/storage.py:67 xpack/plugins/cloud/models.py:250 +#: terminal/serializers/storage.py:67 xpack/plugins/cloud/models.py:209 msgid "Region" msgstr "リージョン" @@ -7028,7 +7070,7 @@ msgid "Not a valid ssh public key" msgstr "有効なssh公開鍵ではありません" #: users/forms/profile.py:173 users/models/user.py:820 -#: xpack/plugins/cloud/serializers/account_attrs.py:203 +#: xpack/plugins/cloud/serializers/account_attrs.py:206 msgid "Public key" msgstr "公開キー" @@ -7057,7 +7099,7 @@ msgid "OTP secret key" msgstr "OTP 秘密" #: users/models/user.py:817 -#: xpack/plugins/cloud/serializers/account_attrs.py:206 +#: xpack/plugins/cloud/serializers/account_attrs.py:209 msgid "Private key" msgstr "ssh秘密鍵" @@ -7496,11 +7538,11 @@ msgstr "パスワードの成功をリセットし、ログインページに戻 msgid "XPACK" msgstr "XPack" -#: xpack/plugins/cloud/api.py:56 +#: xpack/plugins/cloud/api.py:38 msgid "Test connection successful" msgstr "テスト接続成功" -#: xpack/plugins/cloud/api.py:58 +#: xpack/plugins/cloud/api.py:40 msgid "Test connection failed: {}" msgstr "テスト接続に失敗しました: {}" @@ -7588,7 +7630,7 @@ msgstr "プライベートIP" msgid "Public IP" msgstr "パブリックIP" -#: xpack/plugins/cloud/const.py:38 xpack/plugins/cloud/models.py:295 +#: xpack/plugins/cloud/const.py:38 msgid "Instance name" msgstr "インスタンス名" @@ -7616,158 +7658,78 @@ msgstr "同期済み" msgid "Released" msgstr "リリース済み" -#: xpack/plugins/cloud/manager.py:53 -msgid "Account unavailable" -msgstr "利用できないアカウント" - #: xpack/plugins/cloud/meta.py:9 msgid "Cloud center" msgstr "クラウドセンター" -#: xpack/plugins/cloud/models.py:34 +#: xpack/plugins/cloud/models.py:30 msgid "Provider" msgstr "プロバイダー" -#: xpack/plugins/cloud/models.py:38 +#: xpack/plugins/cloud/models.py:34 msgid "Validity" msgstr "有効性" -#: xpack/plugins/cloud/models.py:43 +#: xpack/plugins/cloud/models.py:39 msgid "Cloud account" msgstr "クラウドアカウント" -#: xpack/plugins/cloud/models.py:45 +#: xpack/plugins/cloud/models.py:41 msgid "Test cloud account" msgstr "クラウドアカウントのテスト" -#: xpack/plugins/cloud/models.py:92 xpack/plugins/cloud/serializers/task.py:147 +#: xpack/plugins/cloud/models.py:88 xpack/plugins/cloud/serializers/task.py:36 msgid "Regions" msgstr "リージョン" -#: xpack/plugins/cloud/models.py:95 +#: xpack/plugins/cloud/models.py:91 msgid "Hostname strategy" msgstr "ホスト名戦略" -#: xpack/plugins/cloud/models.py:100 -#: xpack/plugins/cloud/serializers/task.py:150 +#: xpack/plugins/cloud/models.py:102 xpack/plugins/cloud/serializers/task.py:39 msgid "IP network segment group" msgstr "IPネットワークセグメントグループ" -#: xpack/plugins/cloud/models.py:103 -#: xpack/plugins/cloud/serializers/task.py:155 +#: xpack/plugins/cloud/models.py:105 xpack/plugins/cloud/serializers/task.py:44 msgid "Sync IP type" msgstr "同期IPタイプ" -#: xpack/plugins/cloud/models.py:106 -#: xpack/plugins/cloud/serializers/task.py:173 +#: xpack/plugins/cloud/models.py:108 xpack/plugins/cloud/serializers/task.py:61 msgid "Always update" msgstr "常に更新" -#: xpack/plugins/cloud/models.py:112 +#: xpack/plugins/cloud/models.py:114 msgid "Date last sync" msgstr "最終同期日" -#: xpack/plugins/cloud/models.py:115 xpack/plugins/cloud/models.py:313 -#: xpack/plugins/cloud/models.py:337 -msgid "Strategy" -msgstr "戦略" - -#: xpack/plugins/cloud/models.py:120 xpack/plugins/cloud/models.py:197 +#: xpack/plugins/cloud/models.py:119 xpack/plugins/cloud/models.py:160 msgid "Sync instance task" msgstr "インスタンスの同期タスク" -#: xpack/plugins/cloud/models.py:208 xpack/plugins/cloud/models.py:260 +#: xpack/plugins/cloud/models.py:171 xpack/plugins/cloud/models.py:219 msgid "Date sync" msgstr "日付の同期" -#: xpack/plugins/cloud/models.py:212 -msgid "Sync instance snapshot" -msgstr "インスタンススナップショットの同期" - -#: xpack/plugins/cloud/models.py:216 +#: xpack/plugins/cloud/models.py:175 msgid "Sync instance task execution" msgstr "インスタンスタスクの同期実行" -#: xpack/plugins/cloud/models.py:240 +#: xpack/plugins/cloud/models.py:199 msgid "Sync task" msgstr "同期タスク" -#: xpack/plugins/cloud/models.py:244 +#: xpack/plugins/cloud/models.py:203 msgid "Sync instance task history" msgstr "インスタンスタスク履歴の同期" -#: xpack/plugins/cloud/models.py:247 +#: xpack/plugins/cloud/models.py:206 msgid "Instance" msgstr "インスタンス" -#: xpack/plugins/cloud/models.py:264 +#: xpack/plugins/cloud/models.py:223 msgid "Sync instance detail" msgstr "同期インスタンスの詳細" -#: xpack/plugins/cloud/models.py:281 -msgid "Task strategy" -msgstr "タスク戦略" - -#: xpack/plugins/cloud/models.py:285 -msgid "Exact" -msgstr "" - -#: xpack/plugins/cloud/models.py:286 -msgid "Not" -msgstr "否" - -#: xpack/plugins/cloud/models.py:287 -msgid "In" -msgstr "イン" - -#: xpack/plugins/cloud/models.py:288 -msgid "Contains" -msgstr "含む" - -#: xpack/plugins/cloud/models.py:289 -msgid "Startswith" -msgstr "始まる" - -#: xpack/plugins/cloud/models.py:290 -msgid "Endswith" -msgstr "終わる" - -#: xpack/plugins/cloud/models.py:296 -msgid "Instance platform" -msgstr "インスタンス名" - -#: xpack/plugins/cloud/models.py:297 -msgid "Instance address" -msgstr "インスタンスアドレス" - -#: xpack/plugins/cloud/models.py:304 -msgid "Rule attr" -msgstr "ルール属性" - -#: xpack/plugins/cloud/models.py:308 -msgid "Rule match" -msgstr "ルール一致" - -#: xpack/plugins/cloud/models.py:310 -msgid "Rule value" -msgstr "ルール値" - -#: xpack/plugins/cloud/models.py:317 -msgid "Strategy rule" -msgstr "戦略ルール" - -#: xpack/plugins/cloud/models.py:332 -msgid "Action attr" -msgstr "アクション属性" - -#: xpack/plugins/cloud/models.py:334 -msgid "Action value" -msgstr "アクション値" - -#: xpack/plugins/cloud/models.py:341 -msgid "Strategy action" -msgstr "戦略アクション" - #: xpack/plugins/cloud/providers/aws_international.py:18 msgid "China (Beijing)" msgstr "中国 (北京)" @@ -7876,7 +7838,7 @@ msgid "CN East-Suzhou" msgstr "華東-蘇州" #: xpack/plugins/cloud/providers/baiducloud.py:57 -#: xpack/plugins/cloud/providers/huaweicloud.py:49 +#: xpack/plugins/cloud/providers/huaweicloud.py:50 msgid "CN-Hong Kong" msgstr "中国-香港" @@ -7894,65 +7856,65 @@ msgid "CN East-Shanghai" msgstr "華東-上海" #: xpack/plugins/cloud/providers/baiducloud.py:61 -#: xpack/plugins/cloud/providers/huaweicloud.py:51 +#: xpack/plugins/cloud/providers/huaweicloud.py:49 msgid "AP-Singapore" msgstr "アジア太平洋-シンガポール" +#: xpack/plugins/cloud/providers/huaweicloud.py:37 +msgid "AF-Johannesburg" +msgstr "アフリカ-ヨハネスブルク" + +#: xpack/plugins/cloud/providers/huaweicloud.py:38 +msgid "CN North-Beijing4" +msgstr "華北-北京4" + #: xpack/plugins/cloud/providers/huaweicloud.py:39 msgid "CN North-Beijing1" msgstr "華北-北京1" #: xpack/plugins/cloud/providers/huaweicloud.py:40 -msgid "CN North-Beijing4" -msgstr "華北-北京4" - -#: xpack/plugins/cloud/providers/huaweicloud.py:41 -msgid "CN North-Ulanqab1" -msgstr "華北-ウランチャブ一" - -#: xpack/plugins/cloud/providers/huaweicloud.py:43 -msgid "CN South-Shenzhen" -msgstr "華南-広州" - -#: xpack/plugins/cloud/providers/huaweicloud.py:44 -msgid "CN South-Guangzhou-InvitationOnly" -msgstr "華南-広州-友好ユーザー環境" - -#: xpack/plugins/cloud/providers/huaweicloud.py:45 msgid "CN East-Shanghai2" msgstr "華東-上海2" -#: xpack/plugins/cloud/providers/huaweicloud.py:46 +#: xpack/plugins/cloud/providers/huaweicloud.py:41 msgid "CN East-Shanghai1" msgstr "華東-上海1" -#: xpack/plugins/cloud/providers/huaweicloud.py:48 -msgid "CN Southwest-Guiyang1" -msgstr "南西-貴陽1" - -#: xpack/plugins/cloud/providers/huaweicloud.py:50 -msgid "AP-Bangkok" -msgstr "アジア太平洋-バンコク" - -#: xpack/plugins/cloud/providers/huaweicloud.py:53 -msgid "AF-Johannesburg" -msgstr "アフリカ-ヨハネスブルク" - -#: xpack/plugins/cloud/providers/huaweicloud.py:54 +#: xpack/plugins/cloud/providers/huaweicloud.py:43 msgid "LA-Mexico City1" msgstr "LA-メキシコCity1" -#: xpack/plugins/cloud/providers/huaweicloud.py:55 +#: xpack/plugins/cloud/providers/huaweicloud.py:44 msgid "LA-Santiago" msgstr "ラテンアメリカ-サンディエゴ" -#: xpack/plugins/cloud/providers/huaweicloud.py:56 +#: xpack/plugins/cloud/providers/huaweicloud.py:45 msgid "LA-Sao Paulo1" msgstr "ラミー・サンパウロ1" -#: xpack/plugins/cloud/providers/huaweicloud.py:58 -msgid "TR-Istanbul" -msgstr "" +#: xpack/plugins/cloud/providers/huaweicloud.py:46 +msgid "EU-Paris" +msgstr "ヨーロッパ-パリ" + +#: xpack/plugins/cloud/providers/huaweicloud.py:47 +msgid "CN Southwest-Guiyang1" +msgstr "南西-貴陽1" + +#: xpack/plugins/cloud/providers/huaweicloud.py:48 +msgid "AP-Bangkok" +msgstr "アジア太平洋-バンコク" + +#: xpack/plugins/cloud/providers/huaweicloud.py:52 +msgid "CN Northeast-Dalian" +msgstr "华北-大连" + +#: xpack/plugins/cloud/providers/huaweicloud.py:53 +msgid "CN North-Ulanqab1" +msgstr "華北-ウランチャブ一" + +#: xpack/plugins/cloud/providers/huaweicloud.py:54 +msgid "CN South-Guangzhou-InvitationOnly" +msgstr "華南-広州-友好ユーザー環境" #: xpack/plugins/cloud/providers/jdcloud.py:126 msgid "CN East-Suqian" @@ -7982,7 +7944,7 @@ msgstr "サブスクリプションID" #: xpack/plugins/cloud/serializers/account_attrs.py:103 #: xpack/plugins/cloud/serializers/account_attrs.py:119 #: xpack/plugins/cloud/serializers/account_attrs.py:149 -#: xpack/plugins/cloud/serializers/account_attrs.py:199 +#: xpack/plugins/cloud/serializers/account_attrs.py:202 msgid "API Endpoint" msgstr "APIエンドポイント" @@ -8048,11 +8010,11 @@ msgstr "テストポート" msgid "Test timeout" msgstr "テストタイムアウト" -#: xpack/plugins/cloud/serializers/account_attrs.py:209 +#: xpack/plugins/cloud/serializers/account_attrs.py:212 msgid "Project" msgstr "project" -#: xpack/plugins/cloud/serializers/task.py:139 +#: xpack/plugins/cloud/serializers/task.py:28 msgid "" "Only instances matching the IP range will be synced.
    If the instance " "contains multiple IP addresses, the first IP address that matches will be " @@ -8066,11 +8028,11 @@ msgstr "" "ドレスをランダムに一致させることを意味します。
    例: " "192.168.1.0/24,10.1.1.1-10.1.1.20。" -#: xpack/plugins/cloud/serializers/task.py:145 +#: xpack/plugins/cloud/serializers/task.py:34 msgid "History count" msgstr "実行回数" -#: xpack/plugins/cloud/serializers/task.py:146 +#: xpack/plugins/cloud/serializers/task.py:35 msgid "Instance count" msgstr "インスタンス数" @@ -8082,6 +8044,10 @@ msgstr "同期インスタンス タスクを実行する" msgid "Period clean sync instance task execution" msgstr "同期インスタンス タスクの実行記録を定期的にクリアする" +#: xpack/plugins/cloud/utils.py:68 +msgid "Account unavailable" +msgstr "利用できないアカウント" + #: xpack/plugins/interface/api.py:52 msgid "Restore default successfully." msgstr "デフォルトの復元に成功しました。" @@ -8146,11 +8112,62 @@ msgstr "究極のエディション" msgid "Community edition" msgstr "コミュニティ版" -#~ msgid "EU-Paris" -#~ msgstr "ヨーロッパ-パリ" +#~ msgid "Edition" +#~ msgstr "バージョン" -#~ msgid "CN Northeast-Dalian" -#~ msgstr "华北-大连" +#~ msgid "Strategy" +#~ msgstr "戦略" + +#~ msgid "Sync instance snapshot" +#~ msgstr "インスタンススナップショットの同期" + +#~ msgid "Task strategy" +#~ msgstr "タスク戦略" + +#~ msgid "Not" +#~ msgstr "否" + +#~ msgid "In" +#~ msgstr "イン" + +#~ msgid "Contains" +#~ msgstr "含む" + +#~ msgid "Startswith" +#~ msgstr "始まる" + +#~ msgid "Endswith" +#~ msgstr "終わる" + +#~ msgid "Instance platform" +#~ msgstr "インスタンス名" + +#~ msgid "Instance address" +#~ msgstr "インスタンスアドレス" + +#~ msgid "Rule attr" +#~ msgstr "ルール属性" + +#~ msgid "Rule match" +#~ msgstr "ルール一致" + +#~ msgid "Rule value" +#~ msgstr "ルール値" + +#~ msgid "Strategy rule" +#~ msgstr "戦略ルール" + +#~ msgid "Action attr" +#~ msgstr "アクション属性" + +#~ msgid "Action value" +#~ msgstr "アクション値" + +#~ msgid "Strategy action" +#~ msgstr "戦略アクション" + +#~ msgid "CN South-Shenzhen" +#~ msgstr "華南-広州" #~ msgid "Current only support login from AD/LDAP" #~ msgstr "現在、AD/LDAPからのログインのみサポートしています" diff --git a/apps/locale/zh/LC_MESSAGES/django.mo b/apps/locale/zh/LC_MESSAGES/django.mo index c9e28a258..fea8bac2a 100644 --- a/apps/locale/zh/LC_MESSAGES/django.mo +++ b/apps/locale/zh/LC_MESSAGES/django.mo @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6a49d0a2a96656a3f98a0d13f64d426be5f60110ef629bed8d871c6525c16d82 -size 124739 +oid sha256:7ece6510d9392a16daca6d2729518ed6cf5df3a8c40c6e9e7881207df72a326b +size 125537 diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po index 7eeae8dc5..87fc95037 100644 --- a/apps/locale/zh/LC_MESSAGES/django.po +++ b/apps/locale/zh/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: JumpServer 0.3.3\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-08-08 17:55+0800\n" +"POT-Creation-Date: 2023-08-10 11:06+0800\n" "PO-Revision-Date: 2021-05-20 10:54+0800\n" "Last-Translator: ibuler \n" "Language-Team: JumpServer team\n" @@ -94,7 +94,7 @@ msgstr "更新" #: accounts/const/account.py:33 #: accounts/serializers/automations/change_secret.py:156 audits/const.py:54 #: audits/signal_handlers/activity_log.py:33 common/const/choices.py:19 -#: ops/const.py:58 terminal/const.py:77 xpack/plugins/cloud/const.py:43 +#: ops/const.py:61 terminal/const.py:77 xpack/plugins/cloud/const.py:43 msgid "Failed" msgstr "失败" @@ -203,7 +203,7 @@ msgstr "HashiCorp Vault" #: accounts/serializers/automations/change_secret.py:112 #: accounts/serializers/automations/change_secret.py:132 #: acls/serializers/base.py:123 assets/models/asset/common.py:93 -#: assets/models/asset/common.py:331 assets/models/cmd_filter.py:36 +#: assets/models/asset/common.py:334 assets/models/cmd_filter.py:36 #: assets/serializers/domain.py:19 assets/serializers/label.py:27 #: audits/models.py:53 authentication/models/connection_token.py:36 #: perms/models/asset_permission.py:64 perms/serializers/permission.py:34 @@ -212,7 +212,7 @@ msgstr "HashiCorp Vault" #: terminal/serializers/session.py:26 #: terminal/templates/terminal/_msg_command_warning.html:4 #: terminal/templates/terminal/_msg_session_sharing.html:4 -#: tickets/models/ticket/apply_asset.py:16 xpack/plugins/cloud/models.py:253 +#: tickets/models/ticket/apply_asset.py:16 xpack/plugins/cloud/models.py:212 msgid "Asset" msgstr "资产" @@ -247,7 +247,7 @@ msgstr "来源 ID" #: terminal/backends/command/models.py:18 terminal/models/session/session.py:33 #: terminal/templates/terminal/_msg_command_warning.html:8 #: terminal/templates/terminal/_msg_session_sharing.html:8 -#: tickets/models/ticket/command_confirm.py:13 xpack/plugins/cloud/models.py:89 +#: tickets/models/ticket/command_confirm.py:13 xpack/plugins/cloud/models.py:85 msgid "Account" msgstr "账号" @@ -286,7 +286,7 @@ msgstr "账号备份计划" #: accounts/models/automations/backup_account.py:91 #: assets/models/automations/base.py:115 audits/models.py:60 -#: ops/models/base.py:55 ops/models/celery.py:63 ops/models/job.py:194 +#: ops/models/base.py:55 ops/models/celery.py:63 ops/models/job.py:221 #: ops/templates/ops/celery_task_log.html:75 #: perms/models/asset_permission.py:72 terminal/models/applet/host.py:139 #: terminal/models/session/session.py:44 @@ -314,7 +314,7 @@ msgid "Trigger mode" msgstr "触发模式" #: accounts/models/automations/backup_account.py:105 audits/models.py:194 -#: terminal/models/session/sharing.py:121 xpack/plugins/cloud/models.py:205 +#: terminal/models/session/sharing.py:121 xpack/plugins/cloud/models.py:168 msgid "Reason" msgstr "原因" @@ -416,7 +416,7 @@ msgstr "开始日期" #: accounts/models/automations/change_secret.py:91 #: assets/models/automations/base.py:116 ops/models/base.py:56 -#: ops/models/celery.py:64 ops/models/job.py:195 +#: ops/models/celery.py:64 ops/models/job.py:222 #: terminal/models/applet/host.py:140 msgid "Date finished" msgstr "结束日期" @@ -502,16 +502,15 @@ msgstr "账号验证" #: assets/serializers/platform.py:110 assets/serializers/platform.py:223 #: authentication/serializers/connect_token_secret.py:110 ops/mixin.py:21 #: ops/models/adhoc.py:20 ops/models/celery.py:15 ops/models/celery.py:57 -#: ops/models/job.py:94 ops/models/playbook.py:28 ops/serializers/job.py:20 +#: ops/models/job.py:119 ops/models/playbook.py:28 ops/serializers/job.py:20 #: orgs/models.py:82 perms/models/asset_permission.py:56 rbac/models/role.py:29 #: settings/models.py:32 settings/serializers/sms.py:6 #: terminal/models/applet/applet.py:32 terminal/models/component/endpoint.py:12 -#: terminal/models/component/endpoint.py:92 +#: terminal/models/component/endpoint.py:94 #: terminal/models/component/storage.py:26 terminal/models/component/task.py:13 #: terminal/models/component/terminal.py:84 users/forms/profile.py:33 #: users/models/group.py:13 users/models/user.py:787 -#: xpack/plugins/cloud/models.py:32 xpack/plugins/cloud/models.py:273 -#: xpack/plugins/cloud/serializers/task.py:68 +#: xpack/plugins/cloud/models.py:28 msgid "Name" msgstr "名称" @@ -523,12 +522,12 @@ msgstr "特权账号" #: assets/models/automations/base.py:21 assets/models/cmd_filter.py:39 #: assets/models/label.py:22 #: authentication/serializers/connect_token_secret.py:114 -#: terminal/models/applet/applet.py:39 -#: terminal/models/component/endpoint.py:103 users/serializers/user.py:169 +#: terminal/models/applet/applet.py:38 +#: terminal/models/component/endpoint.py:105 users/serializers/user.py:169 msgid "Is active" msgstr "激活" -#: accounts/models/template.py:19 xpack/plugins/cloud/models.py:325 +#: accounts/models/template.py:19 msgid "Account template" msgstr "账号模版" @@ -635,9 +634,9 @@ msgstr "类别" #: assets/models/cmd_filter.py:74 assets/models/platform.py:90 #: assets/serializers/asset/common.py:122 assets/serializers/platform.py:112 #: assets/serializers/platform.py:127 audits/serializers.py:49 -#: authentication/serializers/connect_token_secret.py:123 ops/models/job.py:105 +#: authentication/serializers/connect_token_secret.py:123 ops/models/job.py:130 #: perms/serializers/user_permission.py:27 settings/serializers/vault.py:13 -#: terminal/models/applet/applet.py:38 terminal/models/component/storage.py:57 +#: terminal/models/applet/applet.py:37 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:226 #: terminal/serializers/storage.py:238 tickets/models/comment.py:26 @@ -670,7 +669,7 @@ msgstr "已修改" #: accounts/serializers/automations/base.py:22 acls/models/base.py:97 #: assets/models/automations/base.py:19 #: assets/serializers/automations/base.py:20 ops/models/base.py:17 -#: ops/models/job.py:107 ops/serializers/job.py:21 +#: ops/models/job.py:132 ops/serializers/job.py:21 #: terminal/templates/terminal/_msg_command_execute_alert.html:16 msgid "Assets" msgstr "资产" @@ -761,14 +760,14 @@ msgstr "" #: accounts/serializers/account/virtual.py:19 assets/models/_user.py:27 #: assets/models/cmd_filter.py:40 assets/models/cmd_filter.py:88 #: assets/models/group.py:20 common/db/models.py:36 ops/models/adhoc.py:26 -#: ops/models/job.py:113 ops/models/playbook.py:31 rbac/models/role.py:37 -#: settings/models.py:37 terminal/models/applet/applet.py:44 -#: terminal/models/applet/applet.py:250 terminal/models/applet/host.py:141 +#: ops/models/job.py:138 ops/models/playbook.py:31 rbac/models/role.py:37 +#: settings/models.py:37 terminal/models/applet/applet.py:43 +#: terminal/models/applet/applet.py:283 terminal/models/applet/host.py:141 #: terminal/models/component/endpoint.py:24 -#: terminal/models/component/endpoint.py:102 +#: terminal/models/component/endpoint.py:104 #: terminal/models/session/session.py:46 tickets/models/comment.py:32 #: tickets/models/ticket/general.py:297 users/models/user.py:826 -#: xpack/plugins/cloud/models.py:39 xpack/plugins/cloud/models.py:109 +#: xpack/plugins/cloud/models.py:35 xpack/plugins/cloud/models.py:111 msgid "Comment" msgstr "备注" @@ -816,7 +815,7 @@ msgstr "自动化任务执行历史" #: accounts/serializers/automations/change_secret.py:155 audits/const.py:53 #: audits/models.py:59 audits/signal_handlers/activity_log.py:33 -#: common/const/choices.py:18 ops/const.py:56 ops/serializers/celery.py:40 +#: common/const/choices.py:18 ops/const.py:59 ops/serializers/celery.py:40 #: terminal/const.py:76 terminal/models/session/sharing.py:117 #: tickets/views/approve.py:115 msgid "Success" @@ -888,14 +887,12 @@ msgid "Warning" msgstr "告警" #: acls/models/base.py:37 assets/models/_user.py:51 -#: assets/models/cmd_filter.py:76 terminal/models/component/endpoint.py:95 -#: xpack/plugins/cloud/models.py:275 +#: assets/models/cmd_filter.py:76 terminal/models/component/endpoint.py:97 msgid "Priority" msgstr "优先级" #: acls/models/base.py:38 assets/models/_user.py:51 -#: assets/models/cmd_filter.py:76 terminal/models/component/endpoint.py:96 -#: xpack/plugins/cloud/models.py:276 +#: assets/models/cmd_filter.py:76 terminal/models/component/endpoint.py:98 msgid "1-100, the lower the value will be match first" msgstr "优先级可选范围为 1-100 (数值越小越优先)" @@ -932,7 +929,6 @@ msgid "Command" msgstr "命令" #: acls/models/command_acl.py:17 assets/models/cmd_filter.py:59 -#: xpack/plugins/cloud/models.py:291 msgid "Regex" msgstr "正则表达式" @@ -1028,7 +1024,7 @@ msgid "None of the reviewers belong to Organization `{}`" msgstr "所有复核人都不属于组织 `{}`" #: acls/serializers/rules/rules.py:20 -#: xpack/plugins/cloud/serializers/task.py:133 +#: xpack/plugins/cloud/serializers/task.py:22 msgid "IP address invalid: `{}`" msgstr "IP 地址无效: `{}`" @@ -1056,7 +1052,7 @@ msgstr "时段" msgid "Applications" msgstr "应用管理" -#: applications/models.py:16 xpack/plugins/cloud/models.py:37 +#: applications/models.py:16 xpack/plugins/cloud/models.py:33 #: xpack/plugins/cloud/serializers/account.py:63 msgid "Attrs" msgstr "属性" @@ -1349,7 +1345,7 @@ msgstr "SSH公钥" # msgstr "备注" #: assets/models/_user.py:28 assets/models/automations/base.py:114 #: assets/models/cmd_filter.py:41 assets/models/group.py:19 -#: common/db/models.py:34 ops/models/base.py:54 ops/models/job.py:193 +#: common/db/models.py:34 ops/models/base.py:54 ops/models/job.py:220 #: users/models/user.py:1018 msgid "Date created" msgstr "创建日期" @@ -1388,7 +1384,7 @@ msgstr "用户名与用户相同" #: assets/models/_user.py:52 authentication/models/connection_token.py:41 #: authentication/serializers/connect_token_secret.py:111 -#: terminal/models/applet/applet.py:41 terminal/serializers/session.py:19 +#: terminal/models/applet/applet.py:40 terminal/serializers/session.py:19 #: terminal/serializers/session.py:42 terminal/serializers/storage.py:70 msgid "Protocol" msgstr "协议" @@ -1453,13 +1449,14 @@ msgstr "地址" #: assets/models/asset/common.py:151 assets/models/platform.py:119 #: authentication/serializers/connect_token_secret.py:115 -#: perms/serializers/user_permission.py:24 xpack/plugins/cloud/models.py:321 +#: perms/serializers/user_permission.py:24 +#: xpack/plugins/cloud/serializers/account_attrs.py:196 msgid "Platform" msgstr "系统平台" #: assets/models/asset/common.py:153 assets/models/domain.py:21 #: authentication/serializers/connect_token_secret.py:133 -#: perms/serializers/user_permission.py:29 xpack/plugins/cloud/models.py:323 +#: perms/serializers/user_permission.py:29 msgid "Domain" msgstr "网域" @@ -1476,19 +1473,19 @@ msgstr "收集资产硬件信息" msgid "Custom info" msgstr "自定义属性" -#: assets/models/asset/common.py:334 +#: assets/models/asset/common.py:337 msgid "Can refresh asset hardware info" msgstr "可以更新资产硬件信息" -#: assets/models/asset/common.py:335 +#: assets/models/asset/common.py:338 msgid "Can test asset connectivity" msgstr "可以测试资产连接性" -#: assets/models/asset/common.py:336 +#: assets/models/asset/common.py:339 msgid "Can match asset" msgstr "可以匹配资产" -#: assets/models/asset/common.py:337 +#: assets/models/asset/common.py:340 msgid "Can change asset nodes" msgstr "可以修改资产节点" @@ -1516,7 +1513,7 @@ msgstr "忽略证书校验" msgid "Proxy" msgstr "代理" -#: assets/models/automations/base.py:22 ops/models/job.py:189 +#: assets/models/automations/base.py:22 ops/models/job.py:216 #: settings/serializers/auth/sms.py:99 msgid "Parameters" msgstr "参数" @@ -1530,13 +1527,13 @@ msgid "Asset automation task" msgstr "资产自动化任务" #: assets/models/automations/base.py:113 audits/models.py:199 -#: audits/serializers.py:50 ops/models/base.py:49 ops/models/job.py:186 -#: terminal/models/applet/applet.py:249 terminal/models/applet/host.py:138 +#: audits/serializers.py:50 ops/models/base.py:49 ops/models/job.py:213 +#: terminal/models/applet/applet.py:282 terminal/models/applet/host.py:138 #: terminal/models/component/status.py:30 terminal/serializers/applet.py:18 #: terminal/serializers/applet_host.py:115 tickets/models/ticket/general.py:283 #: tickets/serializers/super_ticket.py:13 -#: tickets/serializers/ticket/ticket.py:20 xpack/plugins/cloud/models.py:201 -#: xpack/plugins/cloud/models.py:257 +#: tickets/serializers/ticket/ticket.py:20 xpack/plugins/cloud/models.py:164 +#: xpack/plugins/cloud/models.py:216 msgid "Status" msgstr "状态" @@ -1600,7 +1597,7 @@ msgstr "资产组" #: assets/models/group.py:31 assets/models/platform.py:19 #: assets/serializers/platform.py:113 -#: xpack/plugins/cloud/providers/nutanix.py:30 +#: xpack/plugins/cloud/providers/nutanix.py:32 msgid "Default" msgstr "默认" @@ -1650,7 +1647,7 @@ msgid "Parent key" msgstr "ssh私钥" #: assets/models/node.py:558 perms/serializers/permission.py:35 -#: tickets/models/ticket/apply_asset.py:14 xpack/plugins/cloud/models.py:322 +#: tickets/models/ticket/apply_asset.py:14 xpack/plugins/cloud/models.py:96 msgid "Node" msgstr "节点" @@ -1789,8 +1786,7 @@ msgstr "资产中批量更新平台,不符合平台类型跳过的资产" #: assets/serializers/asset/common.py:124 assets/serializers/platform.py:129 #: authentication/serializers/connect_token_secret.py:29 #: authentication/serializers/connect_token_secret.py:72 -#: perms/serializers/user_permission.py:25 xpack/plugins/cloud/models.py:324 -#: xpack/plugins/cloud/serializers/task.py:31 +#: perms/serializers/user_permission.py:25 xpack/plugins/cloud/models.py:99 msgid "Protocols" msgstr "协议组" @@ -2332,27 +2328,27 @@ msgstr "上传 FTP 文件到外部存储" msgid "This action require verify your MFA" msgstr "该操作需要验证您的 MFA, 请先开启并配置" -#: authentication/api/connection_token.py:230 +#: authentication/api/connection_token.py:258 msgid "Reusable connection token is not allowed, global setting not enabled" msgstr "不允许使用可重复使用的连接令牌,未启用全局设置" -#: authentication/api/connection_token.py:310 +#: authentication/api/connection_token.py:338 msgid "Anonymous account is not supported for this asset" msgstr "匿名账号不支持当前资产" -#: authentication/api/connection_token.py:329 +#: authentication/api/connection_token.py:357 msgid "Account not found" msgstr "账号未找到" -#: authentication/api/connection_token.py:332 +#: authentication/api/connection_token.py:360 msgid "Permission expired" msgstr "授权已过期" -#: authentication/api/connection_token.py:346 +#: authentication/api/connection_token.py:374 msgid "ACL action is reject: {}({})" msgstr "ACL 动作是拒绝: {}({})" -#: authentication/api/connection_token.py:350 +#: authentication/api/connection_token.py:378 msgid "ACL action is review" msgstr "ACL 动作是复核" @@ -2905,8 +2901,7 @@ msgid "Show" msgstr "显示" #: authentication/templates/authentication/_access_key_modal.html:66 -#: settings/serializers/security.py:39 users/models/user.py:635 -#: users/serializers/profile.py:116 +#: users/models/user.py:635 users/serializers/profile.py:116 #: users/templates/users/user_verify_mfa.html:36 msgid "Disable" msgstr "禁用" @@ -3258,7 +3253,7 @@ msgstr "准备" msgid "Pending" msgstr "待定的" -#: common/const/choices.py:17 ops/const.py:55 +#: common/const/choices.py:17 ops/const.py:58 msgid "Running" msgstr "运行中" @@ -3609,15 +3604,15 @@ msgstr "系统信息" msgid "Publish the station message" msgstr "发布站内消息" -#: ops/ansible/inventory.py:92 +#: ops/ansible/inventory.py:92 ops/models/job.py:60 msgid "No account available" msgstr "无可用账号" -#: ops/ansible/inventory.py:258 +#: ops/ansible/inventory.py:260 msgid "Ansible disabled" msgstr "Ansible 已禁用" -#: ops/ansible/inventory.py:274 +#: ops/ansible/inventory.py:276 msgid "Skip hosts below:" msgstr "跳过以下主机: " @@ -3681,7 +3676,7 @@ msgstr "VCS" msgid "Adhoc" msgstr "命令" -#: ops/const.py:39 ops/models/job.py:103 +#: ops/const.py:39 ops/models/job.py:128 msgid "Playbook" msgstr "Playbook" @@ -3701,7 +3696,19 @@ msgstr "PowerShell" msgid "Python" msgstr "Python" -#: ops/const.py:57 +#: ops/const.py:52 +msgid "MySQL" +msgstr "MySQL" + +#: ops/const.py:53 +msgid "PostgreSQL" +msgstr "PostgreSQL" + +#: ops/const.py:54 +msgid "SQLServer" +msgstr "SQLServer" + +#: ops/const.py:60 msgid "Timeout" msgstr "超时" @@ -3738,17 +3745,17 @@ msgstr "需要周期或定期设置" msgid "Pattern" msgstr "模式" -#: ops/models/adhoc.py:23 ops/models/job.py:98 +#: ops/models/adhoc.py:23 ops/models/job.py:123 msgid "Module" msgstr "模块" -#: ops/models/adhoc.py:24 ops/models/celery.py:58 ops/models/job.py:97 +#: ops/models/adhoc.py:24 ops/models/celery.py:58 ops/models/job.py:122 #: terminal/models/component/task.py:14 msgid "Args" msgstr "参数" #: ops/models/adhoc.py:25 ops/models/base.py:16 ops/models/base.py:53 -#: ops/models/job.py:106 ops/models/job.py:192 ops/models/playbook.py:30 +#: ops/models/job.py:131 ops/models/job.py:219 ops/models/playbook.py:30 #: terminal/models/session/sharing.py:24 msgid "Creator" msgstr "创建者" @@ -3765,12 +3772,12 @@ msgstr "最后执行" msgid "Date last run" msgstr "最后运行日期" -#: ops/models/base.py:51 ops/models/job.py:190 -#: xpack/plugins/cloud/models.py:199 +#: ops/models/base.py:51 ops/models/job.py:217 +#: xpack/plugins/cloud/models.py:162 msgid "Result" msgstr "结果" -#: ops/models/base.py:52 ops/models/job.py:191 +#: ops/models/base.py:52 ops/models/job.py:218 msgid "Summary" msgstr "汇总" @@ -3803,43 +3810,43 @@ msgstr "发布日期" msgid "Celery Task Execution" msgstr "Celery 任务执行" -#: ops/models/job.py:100 +#: ops/models/job.py:125 msgid "Chdir" msgstr "运行目录" -#: ops/models/job.py:101 +#: ops/models/job.py:126 msgid "Timeout (Seconds)" msgstr "超时时间(秒)" -#: ops/models/job.py:108 +#: ops/models/job.py:133 msgid "Use Parameter Define" msgstr "使用参数定义" -#: ops/models/job.py:109 +#: ops/models/job.py:134 msgid "Parameters define" msgstr "参数定义" -#: ops/models/job.py:110 +#: ops/models/job.py:135 msgid "Runas" msgstr "运行用户" -#: ops/models/job.py:112 +#: ops/models/job.py:137 msgid "Runas policy" msgstr "用户策略" -#: ops/models/job.py:174 +#: ops/models/job.py:201 msgid "Job" msgstr "作业" -#: ops/models/job.py:197 +#: ops/models/job.py:224 msgid "Material" msgstr "Material" -#: ops/models/job.py:199 +#: ops/models/job.py:226 msgid "Material Type" msgstr "Material 类型" -#: ops/models/job.py:480 +#: ops/models/job.py:526 msgid "Job Execution" msgstr "作业执行" @@ -4006,7 +4013,7 @@ msgstr "默认组织" msgid "SYSTEM" msgstr "系统组织" -#: orgs/models.py:83 rbac/models/role.py:36 terminal/models/applet/applet.py:40 +#: orgs/models.py:83 rbac/models/role.py:36 terminal/models/applet/applet.py:39 msgid "Builtin" msgstr "内置的" @@ -4302,8 +4309,8 @@ msgstr "任务中心" msgid "My assets" msgstr "我的资产" -#: rbac/tree.py:56 terminal/models/applet/applet.py:51 -#: terminal/models/applet/applet.py:246 terminal/models/applet/host.py:29 +#: rbac/tree.py:56 terminal/models/applet/applet.py:50 +#: terminal/models/applet/applet.py:279 terminal/models/applet/host.py:29 #: terminal/serializers/applet.py:15 msgid "Applet" msgstr "远程应用" @@ -5096,6 +5103,10 @@ msgid "" "allowed during this time interval." msgstr "当用户登录失败次数达到限制后,那么在此时间间隔内禁止登录" +#: settings/serializers/security.py:39 +msgid "Not enabled" +msgstr "未启用" + #: settings/serializers/security.py:40 msgid "All users" msgstr "所有用户" @@ -5595,13 +5606,13 @@ msgstr "过期。" #, python-format msgid "" "\n" -" Your password has expired, please click this link update password.\n" +" Your password has expired, please click this link update password.\n" " " msgstr "" "\n" -" 您的密码已经过期,请点击 链接 更新密码\n" +" 您的密码已经过期,请点击 链接 更新密码\n" " " #: templates/_message.html:30 @@ -5625,8 +5636,8 @@ msgstr "" #, python-format msgid "" "\n" -" Your information was incomplete. Please click this link to complete your information.\n" +" Your information was incomplete. Please click this link to complete your information.\n" " " msgstr "" "\n" @@ -5638,13 +5649,13 @@ msgstr "" #, python-format msgid "" "\n" -" Your ssh public key not set or expired. Please click this link to update\n" +" Your ssh public key not set or expired. Please click this link to update\n" " " msgstr "" "\n" -" 您的SSH密钥没有设置或已失效,请点击 链接 更新\n" +" 您的SSH密钥没有设置或已失效,请点击 链接 更新\n" " " #: templates/_mfa_login_field.html:28 @@ -5779,10 +5790,30 @@ msgstr "输出" msgid "Risk level" msgstr "风险等级" -#: terminal/connect_methods.py:35 +#: terminal/connect_methods.py:29 +msgid "SSH Client" +msgstr "SSH 客户端" + +#: terminal/connect_methods.py:30 +msgid "SSH Guide" +msgstr "SSH 向导" + +#: terminal/connect_methods.py:31 +msgid "SFTP Client" +msgstr "SFTP 客户端" + +#: terminal/connect_methods.py:33 +msgid "DB Guide" +msgstr "DB 连接向导" + +#: terminal/connect_methods.py:34 msgid "DB Client" msgstr "数据库客户端" +#: terminal/connect_methods.py:36 +msgid "Remote Desktop" +msgstr "远程桌面客户端" + #: terminal/const.py:12 msgid "Review & Reject" msgstr "审批 & 拒绝" @@ -5856,7 +5887,7 @@ msgstr "存储无效" msgid "Community" msgstr "社区版" -#: terminal/models/applet/applet.py:30 +#: terminal/models/applet/applet.py:30 terminal/models/applet/applet.py:36 msgid "Enterprise" msgstr "企业版" @@ -5864,39 +5895,35 @@ msgstr "企业版" msgid "Author" msgstr "作者" -#: terminal/models/applet/applet.py:37 terminal/serializers/applet.py:30 -msgid "Edition" -msgstr "版本" - -#: terminal/models/applet/applet.py:42 +#: terminal/models/applet/applet.py:41 msgid "Can concurrent" msgstr "可以并发" -#: terminal/models/applet/applet.py:43 +#: terminal/models/applet/applet.py:42 msgid "Tags" msgstr "标签" -#: terminal/models/applet/applet.py:47 terminal/serializers/storage.py:159 +#: terminal/models/applet/applet.py:46 terminal/serializers/storage.py:159 msgid "Hosts" msgstr "主机" -#: terminal/models/applet/applet.py:92 +#: terminal/models/applet/applet.py:91 msgid "Applet pkg not valid, Missing file {}" msgstr "Applet pkg 无效,缺少文件 {}" -#: terminal/models/applet/applet.py:111 +#: terminal/models/applet/applet.py:110 msgid "Load platform.yml failed: {}" msgstr "加载 platform.yml 失败: {}" -#: terminal/models/applet/applet.py:114 +#: terminal/models/applet/applet.py:113 msgid "Only support custom platform" msgstr "只支持自定义平台" -#: terminal/models/applet/applet.py:119 +#: terminal/models/applet/applet.py:118 msgid "Missing type in platform.yml" msgstr "在 platform.yml 中缺少类型" -#: terminal/models/applet/applet.py:248 terminal/models/applet/host.py:35 +#: terminal/models/applet/applet.py:281 terminal/models/applet/host.py:35 #: terminal/models/applet/host.py:136 msgid "Hosting" msgstr "宿主机" @@ -5962,18 +5989,18 @@ msgid "Redis port" msgstr "Redis 端口" #: terminal/models/component/endpoint.py:29 -#: terminal/models/component/endpoint.py:100 +#: terminal/models/component/endpoint.py:102 #: terminal/serializers/endpoint.py:73 terminal/serializers/storage.py:40 #: terminal/serializers/storage.py:52 terminal/serializers/storage.py:82 #: terminal/serializers/storage.py:92 terminal/serializers/storage.py:100 msgid "Endpoint" msgstr "端点" -#: terminal/models/component/endpoint.py:93 +#: terminal/models/component/endpoint.py:95 msgid "IP group" msgstr "IP 组" -#: terminal/models/component/endpoint.py:106 +#: terminal/models/component/endpoint.py:108 msgid "Endpoint rule" msgstr "端点规则" @@ -6255,10 +6282,10 @@ msgid "" "support multiple open and the special has been used, the public account will " "be used to connect" msgstr "" -"这些账号用于连接发布的应用,账号现在分为两种类型:
    " -"一种是专用的,每个用户都有一个专用账号。 " -"另一种是公共的,当应用不支持多开且专用的已经被使用时,会使用公共账号连接;
    " -"注意: 如果不开启自动创建账号, 当前发布机仅能被指定标签的资产调度到,默认不会放到调度池中" +"这些账号用于连接发布的应用,账号现在分为两种类型:
    一种是专用的,每个用" +"户都有一个专用账号。 另一种是公共的,当应用不支持多开且专用的已经被使用时,会" +"使用公共账号连接;
    注意: 如果不开启自动创建账号, 当前发布机仅能被指定标" +"签的资产调度到,默认不会放到调度池中" #: terminal/serializers/applet_host.py:77 msgid "The number of public accounts created automatically" @@ -6382,7 +6409,7 @@ msgstr "Access key ID(AK)" msgid "Access key secret" msgstr "Access key secret(SK)" -#: terminal/serializers/storage.py:67 xpack/plugins/cloud/models.py:250 +#: terminal/serializers/storage.py:67 xpack/plugins/cloud/models.py:209 msgid "Region" msgstr "地域" @@ -6934,7 +6961,7 @@ msgid "Not a valid ssh public key" msgstr "SSH密钥不合法" #: users/forms/profile.py:173 users/models/user.py:820 -#: xpack/plugins/cloud/serializers/account_attrs.py:203 +#: xpack/plugins/cloud/serializers/account_attrs.py:206 msgid "Public key" msgstr "SSH公钥" @@ -6963,7 +6990,7 @@ msgid "OTP secret key" msgstr "OTP 密钥" #: users/models/user.py:817 -#: xpack/plugins/cloud/serializers/account_attrs.py:206 +#: xpack/plugins/cloud/serializers/account_attrs.py:209 msgid "Private key" msgstr "ssh私钥" @@ -7389,11 +7416,11 @@ msgstr "重置密码成功,返回到登录页面" msgid "XPACK" msgstr "XPack" -#: xpack/plugins/cloud/api.py:56 +#: xpack/plugins/cloud/api.py:38 msgid "Test connection successful" msgstr "测试成功" -#: xpack/plugins/cloud/api.py:58 +#: xpack/plugins/cloud/api.py:40 msgid "Test connection failed: {}" msgstr "测试连接失败:{}" @@ -7481,7 +7508,7 @@ msgstr "私有IP" msgid "Public IP" msgstr "公网IP" -#: xpack/plugins/cloud/const.py:38 xpack/plugins/cloud/models.py:295 +#: xpack/plugins/cloud/const.py:38 msgid "Instance name" msgstr "实例名称" @@ -7509,158 +7536,78 @@ msgstr "已同步" msgid "Released" msgstr "已释放" -#: xpack/plugins/cloud/manager.py:53 -msgid "Account unavailable" -msgstr "账号无效" - #: xpack/plugins/cloud/meta.py:9 msgid "Cloud center" msgstr "云管中心" -#: xpack/plugins/cloud/models.py:34 +#: xpack/plugins/cloud/models.py:30 msgid "Provider" msgstr "云服务商" -#: xpack/plugins/cloud/models.py:38 +#: xpack/plugins/cloud/models.py:34 msgid "Validity" msgstr "有效" -#: xpack/plugins/cloud/models.py:43 +#: xpack/plugins/cloud/models.py:39 msgid "Cloud account" msgstr "云账号" -#: xpack/plugins/cloud/models.py:45 +#: xpack/plugins/cloud/models.py:41 msgid "Test cloud account" msgstr "测试云账号" -#: xpack/plugins/cloud/models.py:92 xpack/plugins/cloud/serializers/task.py:147 +#: xpack/plugins/cloud/models.py:88 xpack/plugins/cloud/serializers/task.py:36 msgid "Regions" msgstr "地域" -#: xpack/plugins/cloud/models.py:95 +#: xpack/plugins/cloud/models.py:91 msgid "Hostname strategy" msgstr "主机名策略" -#: xpack/plugins/cloud/models.py:100 -#: xpack/plugins/cloud/serializers/task.py:150 +#: xpack/plugins/cloud/models.py:102 xpack/plugins/cloud/serializers/task.py:39 msgid "IP network segment group" msgstr "IP网段组" -#: xpack/plugins/cloud/models.py:103 -#: xpack/plugins/cloud/serializers/task.py:155 +#: xpack/plugins/cloud/models.py:105 xpack/plugins/cloud/serializers/task.py:44 msgid "Sync IP type" msgstr "同步IP类型" -#: xpack/plugins/cloud/models.py:106 -#: xpack/plugins/cloud/serializers/task.py:173 +#: xpack/plugins/cloud/models.py:108 xpack/plugins/cloud/serializers/task.py:61 msgid "Always update" msgstr "总是更新" -#: xpack/plugins/cloud/models.py:112 +#: xpack/plugins/cloud/models.py:114 msgid "Date last sync" msgstr "最后同步日期" -#: xpack/plugins/cloud/models.py:115 xpack/plugins/cloud/models.py:313 -#: xpack/plugins/cloud/models.py:337 -msgid "Strategy" -msgstr "策略" - -#: xpack/plugins/cloud/models.py:120 xpack/plugins/cloud/models.py:197 +#: xpack/plugins/cloud/models.py:119 xpack/plugins/cloud/models.py:160 msgid "Sync instance task" msgstr "同步实例任务" -#: xpack/plugins/cloud/models.py:208 xpack/plugins/cloud/models.py:260 +#: xpack/plugins/cloud/models.py:171 xpack/plugins/cloud/models.py:219 msgid "Date sync" msgstr "同步日期" -#: xpack/plugins/cloud/models.py:212 -msgid "Sync instance snapshot" -msgstr "同步实例快照" - -#: xpack/plugins/cloud/models.py:216 +#: xpack/plugins/cloud/models.py:175 msgid "Sync instance task execution" msgstr "同步实例任务执行" -#: xpack/plugins/cloud/models.py:240 +#: xpack/plugins/cloud/models.py:199 msgid "Sync task" msgstr "同步任务" -#: xpack/plugins/cloud/models.py:244 +#: xpack/plugins/cloud/models.py:203 msgid "Sync instance task history" msgstr "同步实例任务历史" -#: xpack/plugins/cloud/models.py:247 +#: xpack/plugins/cloud/models.py:206 msgid "Instance" msgstr "实例" -#: xpack/plugins/cloud/models.py:264 +#: xpack/plugins/cloud/models.py:223 msgid "Sync instance detail" msgstr "同步实例详情" -#: xpack/plugins/cloud/models.py:281 -msgid "Task strategy" -msgstr "密码策略" - -#: xpack/plugins/cloud/models.py:285 -msgid "Exact" -msgstr "" - -#: xpack/plugins/cloud/models.py:286 -msgid "Not" -msgstr "否" - -#: xpack/plugins/cloud/models.py:287 -msgid "In" -msgstr "在..里面" - -#: xpack/plugins/cloud/models.py:288 -msgid "Contains" -msgstr "包含" - -#: xpack/plugins/cloud/models.py:289 -msgid "Startswith" -msgstr "以..开头" - -#: xpack/plugins/cloud/models.py:290 -msgid "Endswith" -msgstr "以..结尾" - -#: xpack/plugins/cloud/models.py:296" -msgid "Instance platform" -msgstr "实例平台" - -#: xpack/plugins/cloud/models.py:297 -msgid "Instance address" -msgstr "实例地址" - -#: xpack/plugins/cloud/models.py:304 -msgid "Rule attr" -msgstr "规则属性" - -#: xpack/plugins/cloud/models.py:308 -msgid "Rule match" -msgstr "规则匹配" - -#: xpack/plugins/cloud/models.py:310 -msgid "Rule value" -msgstr "规则值" - -#: xpack/plugins/cloud/models.py:317 -msgid "Strategy rule" -msgstr "策略规则" - -#: xpack/plugins/cloud/models.py:332 -msgid "Action attr" -msgstr "动作属性" - -#: xpack/plugins/cloud/models.py:334 -msgid "Action value" -msgstr "动作值" - -#: xpack/plugins/cloud/models.py:341 -msgid "Strategy action" -msgstr "策略动作" - #: xpack/plugins/cloud/providers/aws_international.py:18 msgid "China (Beijing)" msgstr "中国(北京)" @@ -7769,7 +7716,7 @@ msgid "CN East-Suzhou" msgstr "华东-苏州" #: xpack/plugins/cloud/providers/baiducloud.py:57 -#: xpack/plugins/cloud/providers/huaweicloud.py:49 +#: xpack/plugins/cloud/providers/huaweicloud.py:50 msgid "CN-Hong Kong" msgstr "中国-香港" @@ -7787,65 +7734,65 @@ msgid "CN East-Shanghai" msgstr "华东-上海" #: xpack/plugins/cloud/providers/baiducloud.py:61 -#: xpack/plugins/cloud/providers/huaweicloud.py:51 +#: xpack/plugins/cloud/providers/huaweicloud.py:49 msgid "AP-Singapore" msgstr "亚太-新加坡" +#: xpack/plugins/cloud/providers/huaweicloud.py:37 +msgid "AF-Johannesburg" +msgstr "非洲-约翰内斯堡" + +#: xpack/plugins/cloud/providers/huaweicloud.py:38 +msgid "CN North-Beijing4" +msgstr "华北-北京4" + #: xpack/plugins/cloud/providers/huaweicloud.py:39 msgid "CN North-Beijing1" msgstr "华北-北京1" #: xpack/plugins/cloud/providers/huaweicloud.py:40 -msgid "CN North-Beijing4" -msgstr "华北-北京4" - -#: xpack/plugins/cloud/providers/huaweicloud.py:41 -msgid "CN North-Ulanqab1" -msgstr "华北-乌兰察布一" - -#: xpack/plugins/cloud/providers/huaweicloud.py:43 -msgid "CN South-Shenzhen" -msgstr "华南-广州" - -#: xpack/plugins/cloud/providers/huaweicloud.py:44 -msgid "CN South-Guangzhou-InvitationOnly" -msgstr "华南-广州-友好用户环境" - -#: xpack/plugins/cloud/providers/huaweicloud.py:45 msgid "CN East-Shanghai2" msgstr "华东-上海2" -#: xpack/plugins/cloud/providers/huaweicloud.py:46 +#: xpack/plugins/cloud/providers/huaweicloud.py:41 msgid "CN East-Shanghai1" msgstr "华东-上海1" -#: xpack/plugins/cloud/providers/huaweicloud.py:48 -msgid "CN Southwest-Guiyang1" -msgstr "西南-贵阳1" - -#: xpack/plugins/cloud/providers/huaweicloud.py:50 -msgid "AP-Bangkok" -msgstr "亚太-曼谷" - -#: xpack/plugins/cloud/providers/huaweicloud.py:53 -msgid "AF-Johannesburg" -msgstr "非洲-约翰内斯堡" - -#: xpack/plugins/cloud/providers/huaweicloud.py:54 +#: xpack/plugins/cloud/providers/huaweicloud.py:43 msgid "LA-Mexico City1" msgstr "拉美-墨西哥城一" -#: xpack/plugins/cloud/providers/huaweicloud.py:55 +#: xpack/plugins/cloud/providers/huaweicloud.py:44 msgid "LA-Santiago" msgstr "拉美-圣地亚哥" -#: xpack/plugins/cloud/providers/huaweicloud.py:56 +#: xpack/plugins/cloud/providers/huaweicloud.py:45 msgid "LA-Sao Paulo1" msgstr "拉美-圣保罗一" -#: xpack/plugins/cloud/providers/huaweicloud.py:58 -msgid "TR-Istanbul" -msgstr "" +#: xpack/plugins/cloud/providers/huaweicloud.py:46 +msgid "EU-Paris" +msgstr "欧洲-巴黎" + +#: xpack/plugins/cloud/providers/huaweicloud.py:47 +msgid "CN Southwest-Guiyang1" +msgstr "西南-贵阳1" + +#: xpack/plugins/cloud/providers/huaweicloud.py:48 +msgid "AP-Bangkok" +msgstr "亚太-曼谷" + +#: xpack/plugins/cloud/providers/huaweicloud.py:52 +msgid "CN Northeast-Dalian" +msgstr "华北-大连" + +#: xpack/plugins/cloud/providers/huaweicloud.py:53 +msgid "CN North-Ulanqab1" +msgstr "华北-乌兰察布一" + +#: xpack/plugins/cloud/providers/huaweicloud.py:54 +msgid "CN South-Guangzhou-InvitationOnly" +msgstr "华南-广州-友好用户环境" #: xpack/plugins/cloud/providers/jdcloud.py:126 msgid "CN East-Suqian" @@ -7875,7 +7822,7 @@ msgstr "订阅 ID" #: xpack/plugins/cloud/serializers/account_attrs.py:103 #: xpack/plugins/cloud/serializers/account_attrs.py:119 #: xpack/plugins/cloud/serializers/account_attrs.py:149 -#: xpack/plugins/cloud/serializers/account_attrs.py:199 +#: xpack/plugins/cloud/serializers/account_attrs.py:202 msgid "API Endpoint" msgstr "API 端点" @@ -7940,11 +7887,11 @@ msgstr "测试端口" msgid "Test timeout" msgstr "测试超时时间" -#: xpack/plugins/cloud/serializers/account_attrs.py:209 +#: xpack/plugins/cloud/serializers/account_attrs.py:212 msgid "Project" msgstr "project" -#: xpack/plugins/cloud/serializers/task.py:139 +#: xpack/plugins/cloud/serializers/task.py:28 msgid "" "Only instances matching the IP range will be synced.
    If the instance " "contains multiple IP addresses, the first IP address that matches will be " @@ -7956,11 +7903,11 @@ msgstr "" "到的 IP 地址将被用作创建的资产的 IP。
    默认值 * 表示同步所有实例和随机匹配 " "IP 地址。
    例如: 192.168.1.0/24,10.1.1.1-10.1.1.20。" -#: xpack/plugins/cloud/serializers/task.py:145 +#: xpack/plugins/cloud/serializers/task.py:34 msgid "History count" msgstr "执行次数" -#: xpack/plugins/cloud/serializers/task.py:146 +#: xpack/plugins/cloud/serializers/task.py:35 msgid "Instance count" msgstr "实例个数" @@ -7972,6 +7919,10 @@ msgstr "执行同步实例任务" msgid "Period clean sync instance task execution" msgstr "定期清除同步实例任务执行记录" +#: xpack/plugins/cloud/utils.py:68 +msgid "Account unavailable" +msgstr "账号无效" + #: xpack/plugins/interface/api.py:52 msgid "Restore default successfully." msgstr "恢复默认成功!" @@ -8036,11 +7987,62 @@ msgstr "旗舰版" msgid "Community edition" msgstr "社区版" -#~ msgid "EU-Paris" -#~ msgstr "欧洲-巴黎" +#~ msgid "Edition" +#~ msgstr "版本" -#~ msgid "CN Northeast-Dalian" -#~ msgstr "华北-大连" +#~ msgid "Strategy" +#~ msgstr "策略" + +#~ msgid "Sync instance snapshot" +#~ msgstr "同步实例快照" + +#~ msgid "Task strategy" +#~ msgstr "密码策略" + +#~ msgid "Not" +#~ msgstr "否" + +#~ msgid "In" +#~ msgstr "在..里面" + +#~ msgid "Contains" +#~ msgstr "包含" + +#~ msgid "Startswith" +#~ msgstr "以..开头" + +#~ msgid "Endswith" +#~ msgstr "以..结尾" + +#~ msgid "Instance platform" +#~ msgstr "实例平台" + +#~ msgid "Instance address" +#~ msgstr "实例地址" + +#~ msgid "Rule attr" +#~ msgstr "规则属性" + +#~ msgid "Rule match" +#~ msgstr "规则匹配" + +#~ msgid "Rule value" +#~ msgstr "规则值" + +#~ msgid "Strategy rule" +#~ msgstr "策略规则" + +#~ msgid "Action attr" +#~ msgstr "动作属性" + +#~ msgid "Action value" +#~ msgstr "动作值" + +#~ msgid "Strategy action" +#~ msgstr "策略动作" + +#~ msgid "CN South-Shenzhen" +#~ msgstr "华南-广州" #~ msgid "Current only support login from AD/LDAP" #~ msgstr "当前仅支持 AD/LDAP 方式登录的用户" diff --git a/apps/ops/migrations/0026_auto_20230810_1039.py b/apps/ops/migrations/0026_auto_20230810_1039.py new file mode 100644 index 000000000..f9bd966a8 --- /dev/null +++ b/apps/ops/migrations/0026_auto_20230810_1039.py @@ -0,0 +1,39 @@ +# Generated by Django 4.1.10 on 2023-08-10 02:36 + +import common.db.encoder +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('ops', '0025_auto_20230413_1531'), + ] + + operations = [ + migrations.AlterField( + model_name='adhoc', + name='module', + field=models.CharField(choices=[('shell', 'Shell'), ('win_shell', 'Powershell'), ('python', 'Python'), ('mysql', 'MySQL'), ('postgresql', 'PostgreSQL'), ('sqlserver', 'SQLServer')], default='shell', max_length=128, verbose_name='Module'), + ), + migrations.AlterField( + model_name='historicaljob', + name='module', + field=models.CharField(choices=[('shell', 'Shell'), ('win_shell', 'Powershell'), ('python', 'Python'), ('mysql', 'MySQL'), ('postgresql', 'PostgreSQL'), ('sqlserver', 'SQLServer')], default='shell', max_length=128, null=True, verbose_name='Module'), + ), + migrations.AlterField( + model_name='job', + name='module', + field=models.CharField(choices=[('shell', 'Shell'), ('win_shell', 'Powershell'), ('python', 'Python'), ('mysql', 'MySQL'), ('postgresql', 'PostgreSQL'), ('sqlserver', 'SQLServer')], default='shell', max_length=128, null=True, verbose_name='Module'), + ), + migrations.AlterField( + model_name='jobexecution', + name='result', + field=models.JSONField(blank=True, encoder=common.db.encoder.ModelJSONFieldEncoder, null=True, verbose_name='Result'), + ), + migrations.AlterField( + model_name='jobexecution', + name='summary', + field=models.JSONField(default=dict, encoder=common.db.encoder.ModelJSONFieldEncoder, verbose_name='Summary'), + ), + ] diff --git a/apps/settings/serializers/security.py b/apps/settings/serializers/security.py index e2571415e..bb1e2207c 100644 --- a/apps/settings/serializers/security.py +++ b/apps/settings/serializers/security.py @@ -36,7 +36,7 @@ login_ip_limit_time_help_text = _( class SecurityAuthSerializer(serializers.Serializer): SECURITY_MFA_AUTH = serializers.ChoiceField( choices=( - [0, _('Disable')], + [0, _('Not enabled')], [1, _('All users')], [2, _('Only admin users')], ), diff --git a/apps/terminal/migrations/0066_auto_20230810_1118.py b/apps/terminal/migrations/0066_auto_20230810_1118.py new file mode 100644 index 000000000..8c17fa6cb --- /dev/null +++ b/apps/terminal/migrations/0066_auto_20230810_1118.py @@ -0,0 +1,27 @@ +# Generated by Django 4.1.10 on 2023-08-10 02:36 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('terminal', '0065_session_command_amount'), + ] + + operations = [ + migrations.RemoveField( + model_name='applet', + name='edition', + ), + migrations.AddField( + model_name='applet', + name='enterprise', + field=models.BooleanField(default=False, verbose_name='Enterprise'), + ), + migrations.AlterField( + model_name='task', + name='name', + field=models.CharField(choices=[('kill_session', 'Kill Session'), ('lock_session', 'Lock Session'), ('unlock_session', 'Unlock Session')], max_length=128, verbose_name='Name'), + ), + ] diff --git a/apps/terminal/models/applet/applet.py b/apps/terminal/models/applet/applet.py index ccd1a8e52..547b89065 100644 --- a/apps/terminal/models/applet/applet.py +++ b/apps/terminal/models/applet/applet.py @@ -33,8 +33,7 @@ class Applet(JMSBaseModel): display_name = models.CharField(max_length=128, verbose_name=_('Display name')) version = models.CharField(max_length=16, verbose_name=_('Version')) author = models.CharField(max_length=128, verbose_name=_('Author')) - edition = models.CharField(max_length=128, choices=Edition.choices, default=Edition.community, - verbose_name=_('Edition')) + enterprise = models.BooleanField(default=False, verbose_name=_('Enterprise')) type = models.CharField(max_length=16, verbose_name=_('Type'), default='general', choices=Type.choices) is_active = models.BooleanField(default=True, verbose_name=_('Is active')) builtin = models.BooleanField(default=False, verbose_name=_('Builtin')) diff --git a/apps/terminal/serializers/applet.py b/apps/terminal/serializers/applet.py index aa3623436..681ff232b 100644 --- a/apps/terminal/serializers/applet.py +++ b/apps/terminal/serializers/applet.py @@ -27,8 +27,6 @@ class AppletPublicationSerializer(serializers.ModelSerializer): class AppletSerializer(serializers.ModelSerializer): icon = serializers.ReadOnlyField(label=_("Icon")) type = LabeledChoiceField(choices=Applet.Type.choices, label=_("Type")) - edition = LabeledChoiceField(choices=Applet.Edition.choices, label=_("Edition"), required=False, - default=Applet.Edition.community) class Meta: model = Applet @@ -37,6 +35,6 @@ class AppletSerializer(serializers.ModelSerializer): 'icon', 'readme', 'date_created', 'date_updated', ] fields = fields_mini + [ - 'version', 'author', 'type', 'edition', + 'version', 'author', 'type', 'enterprise', 'can_concurrent', 'protocols', 'tags', 'comment', ] + read_only_fields From e0463420fa21febe21af671aaf8310ae21388bf0 Mon Sep 17 00:00:00 2001 From: ibuler Date: Thu, 10 Aug 2023 11:23:42 +0800 Subject: [PATCH 124/177] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=E9=BB=98?= =?UTF-8?q?=E8=AE=A4=E6=B7=BB=E5=8A=A0=20core=20=E5=88=B0=20allow=20hosts?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/jumpserver/settings/base.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/jumpserver/settings/base.py b/apps/jumpserver/settings/base.py index 7498b1a33..dabe34c7c 100644 --- a/apps/jumpserver/settings/base.py +++ b/apps/jumpserver/settings/base.py @@ -78,7 +78,7 @@ ALLOWED_DOMAINS = [host.strip() for host in ALLOWED_DOMAINS] ALLOWED_DOMAINS = [host.replace('http://', '').replace('https://', '') for host in ALLOWED_DOMAINS if host] ALLOWED_DOMAINS = [host.split('/')[0] for host in ALLOWED_DOMAINS if host] -DEBUG_HOSTS = ('127.0.0.1', 'localhost') +DEBUG_HOSTS = ('127.0.0.1', 'localhost', 'core') DEBUG_PORT = ['8080', '80', ] if DEBUG: DEBUG_PORT.extend(['4200', '9528']) @@ -88,7 +88,7 @@ ALLOWED_DOMAINS.extend(DEBUG_HOST_PORTS) ALLOWED_HOSTS = list(set(['.' + host.split(':')[0] for host in ALLOWED_DOMAINS])) print("ALLOWED_HOSTS: ", ) for host in ALLOWED_HOSTS: - print(' - ' + host) + print(' - ' + host.lstrip('.')) # https://docs.djangoproject.com/en/4.1/ref/settings/#std-setting-CSRF_TRUSTED_ORIGINS CSRF_TRUSTED_ORIGINS = [] @@ -103,9 +103,9 @@ for host_port in ALLOWED_DOMAINS: continue CSRF_TRUSTED_ORIGINS.append('{}://*.{}'.format(schema, origin)) -print("CSRF_TRUSTED_ORIGINS: ") -for origin in CSRF_TRUSTED_ORIGINS: - print(' - ' + origin) +# print("CSRF_TRUSTED_ORIGINS: ") +# for origin in CSRF_TRUSTED_ORIGINS: +# print(' - ' + origin) # Max post update field num DATA_UPLOAD_MAX_NUMBER_FIELDS = 10000 From 07530bc56bff2e425edde5662583f514e5324deb Mon Sep 17 00:00:00 2001 From: ibuler Date: Thu, 10 Aug 2023 11:39:51 +0800 Subject: [PATCH 125/177] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=20CORE=5FHOS?= =?UTF-8?q?T?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/jumpserver/settings/base.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/apps/jumpserver/settings/base.py b/apps/jumpserver/settings/base.py index dabe34c7c..dbe6a59a7 100644 --- a/apps/jumpserver/settings/base.py +++ b/apps/jumpserver/settings/base.py @@ -68,8 +68,11 @@ SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https') # LOG LEVEL LOG_LEVEL = CONFIG.LOG_LEVEL DOMAINS = CONFIG.DOMAINS or 'localhost' -if os.environ.get('SERVER_NAME'): - DOMAINS += ',{}'.format(os.environ.get('SERVER_NAME')) +for name in ['SERVER_NAME', 'CORE_HOST']: + env = os.environ.get(name) + if not env: + continue + DOMAINS += ',{}'.format(env) if CONFIG.SITE_URL: DOMAINS += ',{}'.format(CONFIG.SITE_URL) From a778a40b21097a878b7905fbcf8c512031d61d3b Mon Sep 17 00:00:00 2001 From: ibuler Date: Thu, 10 Aug 2023 14:41:43 +0800 Subject: [PATCH 126/177] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=20applet=20?= =?UTF-8?q?=E4=BC=81=E4=B8=9A=E7=89=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...remove_applet_enterprise_applet_edition.py | 22 +++++++++++++++++++ apps/terminal/models/applet/applet.py | 3 ++- apps/terminal/serializers/applet.py | 2 +- 3 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 apps/terminal/migrations/0067_remove_applet_enterprise_applet_edition.py diff --git a/apps/terminal/migrations/0067_remove_applet_enterprise_applet_edition.py b/apps/terminal/migrations/0067_remove_applet_enterprise_applet_edition.py new file mode 100644 index 000000000..3dd03408d --- /dev/null +++ b/apps/terminal/migrations/0067_remove_applet_enterprise_applet_edition.py @@ -0,0 +1,22 @@ +# Generated by Django 4.1.10 on 2023-08-10 06:35 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('terminal', '0066_auto_20230810_1118'), + ] + + operations = [ + migrations.RemoveField( + model_name='applet', + name='enterprise', + ), + migrations.AddField( + model_name='applet', + name='edition', + field=models.CharField(choices=[('community', 'Community'), ('enterprise', 'Enterprise')], default='community', max_length=128, verbose_name='Edition'), + ), + ] diff --git a/apps/terminal/models/applet/applet.py b/apps/terminal/models/applet/applet.py index 547b89065..ccd1a8e52 100644 --- a/apps/terminal/models/applet/applet.py +++ b/apps/terminal/models/applet/applet.py @@ -33,7 +33,8 @@ class Applet(JMSBaseModel): display_name = models.CharField(max_length=128, verbose_name=_('Display name')) version = models.CharField(max_length=16, verbose_name=_('Version')) author = models.CharField(max_length=128, verbose_name=_('Author')) - enterprise = models.BooleanField(default=False, verbose_name=_('Enterprise')) + edition = models.CharField(max_length=128, choices=Edition.choices, default=Edition.community, + verbose_name=_('Edition')) type = models.CharField(max_length=16, verbose_name=_('Type'), default='general', choices=Type.choices) is_active = models.BooleanField(default=True, verbose_name=_('Is active')) builtin = models.BooleanField(default=False, verbose_name=_('Builtin')) diff --git a/apps/terminal/serializers/applet.py b/apps/terminal/serializers/applet.py index 681ff232b..0b1737232 100644 --- a/apps/terminal/serializers/applet.py +++ b/apps/terminal/serializers/applet.py @@ -35,6 +35,6 @@ class AppletSerializer(serializers.ModelSerializer): 'icon', 'readme', 'date_created', 'date_updated', ] fields = fields_mini + [ - 'version', 'author', 'type', 'enterprise', + 'version', 'author', 'type', 'edition', 'can_concurrent', 'protocols', 'tags', 'comment', ] + read_only_fields From 71e69782b7e13cf4178fb25fc541ae4388fc3806 Mon Sep 17 00:00:00 2001 From: ibuler Date: Thu, 10 Aug 2023 15:11:52 +0800 Subject: [PATCH 127/177] =?UTF-8?q?perf:=20=E5=90=88=E5=B9=B6=20migrations?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../migrations/0064_auto_20230728_1001.py | 10 +++++++ .../migrations/0065_session_command_amount.py | 18 ------------- .../migrations/0066_auto_20230810_1118.py | 27 ------------------- ...remove_applet_enterprise_applet_edition.py | 22 --------------- 4 files changed, 10 insertions(+), 67 deletions(-) delete mode 100644 apps/terminal/migrations/0065_session_command_amount.py delete mode 100644 apps/terminal/migrations/0066_auto_20230810_1118.py delete mode 100644 apps/terminal/migrations/0067_remove_applet_enterprise_applet_edition.py diff --git a/apps/terminal/migrations/0064_auto_20230728_1001.py b/apps/terminal/migrations/0064_auto_20230728_1001.py index 264bcde38..900abb5ba 100644 --- a/apps/terminal/migrations/0064_auto_20230728_1001.py +++ b/apps/terminal/migrations/0064_auto_20230728_1001.py @@ -25,4 +25,14 @@ class Migration(migrations.Migration): name='origin', field=models.URLField(blank=True, null=True, verbose_name='Origin'), ), + migrations.AddField( + model_name='session', + name='cmd_amount', + field=models.IntegerField(default=-1, verbose_name='Command amount'), + ), + migrations.AlterField( + model_name='task', + name='name', + field=models.CharField(choices=[('kill_session', 'Kill Session'), ('lock_session', 'Lock Session'), ('unlock_session', 'Unlock Session')], max_length=128, verbose_name='Name'), + ), ] diff --git a/apps/terminal/migrations/0065_session_command_amount.py b/apps/terminal/migrations/0065_session_command_amount.py deleted file mode 100644 index 1733d7a19..000000000 --- a/apps/terminal/migrations/0065_session_command_amount.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 4.1.10 on 2023-07-31 10:46 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('terminal', '0064_auto_20230728_1001'), - ] - - operations = [ - migrations.AddField( - model_name='session', - name='cmd_amount', - field=models.IntegerField(default=-1, verbose_name='Command amount'), - ), - ] diff --git a/apps/terminal/migrations/0066_auto_20230810_1118.py b/apps/terminal/migrations/0066_auto_20230810_1118.py deleted file mode 100644 index 8c17fa6cb..000000000 --- a/apps/terminal/migrations/0066_auto_20230810_1118.py +++ /dev/null @@ -1,27 +0,0 @@ -# Generated by Django 4.1.10 on 2023-08-10 02:36 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('terminal', '0065_session_command_amount'), - ] - - operations = [ - migrations.RemoveField( - model_name='applet', - name='edition', - ), - migrations.AddField( - model_name='applet', - name='enterprise', - field=models.BooleanField(default=False, verbose_name='Enterprise'), - ), - migrations.AlterField( - model_name='task', - name='name', - field=models.CharField(choices=[('kill_session', 'Kill Session'), ('lock_session', 'Lock Session'), ('unlock_session', 'Unlock Session')], max_length=128, verbose_name='Name'), - ), - ] diff --git a/apps/terminal/migrations/0067_remove_applet_enterprise_applet_edition.py b/apps/terminal/migrations/0067_remove_applet_enterprise_applet_edition.py deleted file mode 100644 index 3dd03408d..000000000 --- a/apps/terminal/migrations/0067_remove_applet_enterprise_applet_edition.py +++ /dev/null @@ -1,22 +0,0 @@ -# Generated by Django 4.1.10 on 2023-08-10 06:35 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('terminal', '0066_auto_20230810_1118'), - ] - - operations = [ - migrations.RemoveField( - model_name='applet', - name='enterprise', - ), - migrations.AddField( - model_name='applet', - name='edition', - field=models.CharField(choices=[('community', 'Community'), ('enterprise', 'Enterprise')], default='community', max_length=128, verbose_name='Edition'), - ), - ] From 433324ec8cba58a2aabf7a57784017c3279e9ea3 Mon Sep 17 00:00:00 2001 From: ibuler Date: Thu, 10 Aug 2023 15:56:31 +0800 Subject: [PATCH 128/177] =?UTF-8?q?perf:=20=E4=BF=AE=E5=A4=8D=E8=B4=A6?= =?UTF-8?q?=E5=8F=B7=E6=9D=83=E9=99=90=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/perms/utils/account.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/perms/utils/account.py b/apps/perms/utils/account.py index 302552315..303e3ad22 100644 --- a/apps/perms/utils/account.py +++ b/apps/perms/utils/account.py @@ -62,7 +62,7 @@ class PermAccountUtil(AssetPermissionUtil): account = None _accounts = [] if alias == AliasAccount.USER and user.username in username_accounts_mapper: - account = username_accounts_mapper[user.username] + _accounts = username_accounts_mapper[user.username] elif alias in username_accounts_mapper: _accounts = username_accounts_mapper[alias] elif alias in ['@INPUT', '@ANON', '@USER']: From 7ea61c0f2281b402c18e49b40a3880440fb94c17 Mon Sep 17 00:00:00 2001 From: ibuler Date: Thu, 10 Aug 2023 17:30:04 +0800 Subject: [PATCH 129/177] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=E7=BF=BB?= =?UTF-8?q?=E8=AF=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/locale/ja/LC_MESSAGES/django.mo | 4 +- apps/locale/ja/LC_MESSAGES/django.po | 59 ++++++++++++++-------------- apps/locale/zh/LC_MESSAGES/django.mo | 4 +- apps/locale/zh/LC_MESSAGES/django.po | 59 ++++++++++++++-------------- apps/terminal/serializers/applet.py | 4 ++ 5 files changed, 68 insertions(+), 62 deletions(-) diff --git a/apps/locale/ja/LC_MESSAGES/django.mo b/apps/locale/ja/LC_MESSAGES/django.mo index b71df6d0d..b0b33e499 100644 --- a/apps/locale/ja/LC_MESSAGES/django.mo +++ b/apps/locale/ja/LC_MESSAGES/django.mo @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:50d8a03cc8991f92c9e649b4eb1685a9bc862671e013a11ba7683a1b7fcd0ae4 -size 152899 +oid sha256:7bc2e996c082d5f9348277e69cd70b7b9884dc416d9d83e075656a4d8b9bc141 +size 152939 diff --git a/apps/locale/ja/LC_MESSAGES/django.po b/apps/locale/ja/LC_MESSAGES/django.po index cb98e8c6e..4909e19e5 100644 --- a/apps/locale/ja/LC_MESSAGES/django.po +++ b/apps/locale/ja/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-08-10 11:06+0800\n" +"POT-Creation-Date: 2023-08-10 17:27+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -523,7 +523,7 @@ msgstr "特権アカウント" #: assets/models/automations/base.py:21 assets/models/cmd_filter.py:39 #: assets/models/label.py:22 #: authentication/serializers/connect_token_secret.py:114 -#: terminal/models/applet/applet.py:38 +#: terminal/models/applet/applet.py:39 #: terminal/models/component/endpoint.py:105 users/serializers/user.py:169 msgid "Is active" msgstr "アクティブです。" @@ -636,7 +636,7 @@ msgstr "カテゴリ" #: assets/serializers/platform.py:127 audits/serializers.py:49 #: authentication/serializers/connect_token_secret.py:123 ops/models/job.py:130 #: perms/serializers/user_permission.py:27 settings/serializers/vault.py:13 -#: terminal/models/applet/applet.py:37 terminal/models/component/storage.py:57 +#: terminal/models/applet/applet.py:38 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:226 #: terminal/serializers/storage.py:238 tickets/models/comment.py:26 @@ -761,8 +761,8 @@ msgstr "" #: assets/models/cmd_filter.py:40 assets/models/cmd_filter.py:88 #: assets/models/group.py:20 common/db/models.py:36 ops/models/adhoc.py:26 #: ops/models/job.py:138 ops/models/playbook.py:31 rbac/models/role.py:37 -#: settings/models.py:37 terminal/models/applet/applet.py:43 -#: terminal/models/applet/applet.py:283 terminal/models/applet/host.py:141 +#: settings/models.py:37 terminal/models/applet/applet.py:44 +#: terminal/models/applet/applet.py:284 terminal/models/applet/host.py:141 #: terminal/models/component/endpoint.py:24 #: terminal/models/component/endpoint.py:104 #: terminal/models/session/session.py:46 tickets/models/comment.py:32 @@ -1386,7 +1386,7 @@ msgstr "ユーザーと同じユーザー名" #: assets/models/_user.py:52 authentication/models/connection_token.py:41 #: authentication/serializers/connect_token_secret.py:111 -#: terminal/models/applet/applet.py:40 terminal/serializers/session.py:19 +#: terminal/models/applet/applet.py:41 terminal/serializers/session.py:19 #: terminal/serializers/session.py:42 terminal/serializers/storage.py:70 msgid "Protocol" msgstr "プロトコル" @@ -1530,7 +1530,7 @@ msgstr "アセットの自動化タスク" #: assets/models/automations/base.py:113 audits/models.py:199 #: audits/serializers.py:50 ops/models/base.py:49 ops/models/job.py:213 -#: terminal/models/applet/applet.py:282 terminal/models/applet/host.py:138 +#: terminal/models/applet/applet.py:283 terminal/models/applet/host.py:138 #: terminal/models/component/status.py:30 terminal/serializers/applet.py:18 #: terminal/serializers/applet_host.py:115 tickets/models/ticket/general.py:283 #: tickets/serializers/super_ticket.py:13 @@ -4062,7 +4062,7 @@ msgstr "デフォルト組織" msgid "SYSTEM" msgstr "システム組織" -#: orgs/models.py:83 rbac/models/role.py:36 terminal/models/applet/applet.py:39 +#: orgs/models.py:83 rbac/models/role.py:36 terminal/models/applet/applet.py:40 msgid "Builtin" msgstr "ビルトイン" @@ -4359,8 +4359,8 @@ msgstr "タスクセンター" msgid "My assets" msgstr "私の資産" -#: rbac/tree.py:56 terminal/models/applet/applet.py:50 -#: terminal/models/applet/applet.py:279 terminal/models/applet/host.py:29 +#: rbac/tree.py:56 terminal/models/applet/applet.py:51 +#: terminal/models/applet/applet.py:280 terminal/models/applet/host.py:29 #: terminal/serializers/applet.py:15 msgid "Applet" msgstr "リモートアプリケーション" @@ -5760,7 +5760,7 @@ msgstr "確認コードが送信されました" msgid "Home page" msgstr "ホームページ" -#: templates/resource_download.html:18 templates/resource_download.html:32 +#: templates/resource_download.html:18 templates/resource_download.html:33 msgid "Client" msgstr "クライアント" @@ -5773,15 +5773,15 @@ msgstr "" "るために使用されており、現在はRDP SSHクライアントのみをサポートしています。" "「Telnetは将来的にサポートする" -#: templates/resource_download.html:32 +#: templates/resource_download.html:33 msgid "Microsoft" msgstr "マイクロソフト" -#: templates/resource_download.html:32 +#: templates/resource_download.html:33 msgid "Official" msgstr "公式" -#: templates/resource_download.html:34 +#: templates/resource_download.html:35 msgid "" "macOS needs to download the client to connect RDP asset, which comes with " "Windows" @@ -5789,11 +5789,11 @@ msgstr "" "MacOSは、Windowsに付属のRDPアセットを接続するためにクライアントをダウンロード" "する必要があります" -#: templates/resource_download.html:43 +#: templates/resource_download.html:44 msgid "Windows Remote application publisher tools" msgstr "Windowsリモートアプリケーション発行者ツール" -#: templates/resource_download.html:44 +#: templates/resource_download.html:45 msgid "" "OpenSSH is a program used to connect remote applications in the Windows " "Remote Application Publisher" @@ -5801,7 +5801,7 @@ msgstr "" "OpenSSHはリモートアプリケーションをWindowsリモートアプリケーションで接続する" "プログラムです" -#: templates/resource_download.html:52 +#: templates/resource_download.html:53 msgid "Offline video player" msgstr "オフラインビデオプレーヤー" @@ -5984,7 +5984,7 @@ msgstr "ストレージが無効です" msgid "Community" msgstr "コミュニティ版" -#: terminal/models/applet/applet.py:30 terminal/models/applet/applet.py:36 +#: terminal/models/applet/applet.py:30 msgid "Enterprise" msgstr "エンタープライズ版" @@ -5992,35 +5992,39 @@ msgstr "エンタープライズ版" msgid "Author" msgstr "著者" -#: terminal/models/applet/applet.py:41 +#: terminal/models/applet/applet.py:37 terminal/serializers/applet.py:31 +msgid "Edition" +msgstr "バージョン" + +#: terminal/models/applet/applet.py:42 msgid "Can concurrent" msgstr "同時実行可能" -#: terminal/models/applet/applet.py:42 +#: terminal/models/applet/applet.py:43 msgid "Tags" msgstr "ラベル" -#: terminal/models/applet/applet.py:46 terminal/serializers/storage.py:159 +#: terminal/models/applet/applet.py:47 terminal/serializers/storage.py:159 msgid "Hosts" msgstr "ホスト" -#: terminal/models/applet/applet.py:91 +#: terminal/models/applet/applet.py:92 msgid "Applet pkg not valid, Missing file {}" msgstr "無効なアプレット パッケージ、ファイル {} がありません" -#: terminal/models/applet/applet.py:110 +#: terminal/models/applet/applet.py:111 msgid "Load platform.yml failed: {}" msgstr "platform.ymlのロードに失敗しました:{}" -#: terminal/models/applet/applet.py:113 +#: terminal/models/applet/applet.py:114 msgid "Only support custom platform" msgstr "カスタムプラットフォームのみをサポート" -#: terminal/models/applet/applet.py:118 +#: terminal/models/applet/applet.py:119 msgid "Missing type in platform.yml" msgstr "platform.ymlにタイプがありません" -#: terminal/models/applet/applet.py:281 terminal/models/applet/host.py:35 +#: terminal/models/applet/applet.py:282 terminal/models/applet/host.py:35 #: terminal/models/applet/host.py:136 msgid "Hosting" msgstr "ホスト マシン" @@ -8112,9 +8116,6 @@ msgstr "究極のエディション" msgid "Community edition" msgstr "コミュニティ版" -#~ msgid "Edition" -#~ msgstr "バージョン" - #~ msgid "Strategy" #~ msgstr "戦略" diff --git a/apps/locale/zh/LC_MESSAGES/django.mo b/apps/locale/zh/LC_MESSAGES/django.mo index fea8bac2a..eb66df73f 100644 --- a/apps/locale/zh/LC_MESSAGES/django.mo +++ b/apps/locale/zh/LC_MESSAGES/django.mo @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7ece6510d9392a16daca6d2729518ed6cf5df3a8c40c6e9e7881207df72a326b -size 125537 +oid sha256:d1a6a042b4813d67922799caf3ac81ce3f1e831aed1a771dc9a16dab147a0692 +size 125568 diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po index 87fc95037..b03c3a1ad 100644 --- a/apps/locale/zh/LC_MESSAGES/django.po +++ b/apps/locale/zh/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: JumpServer 0.3.3\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-08-10 11:06+0800\n" +"POT-Creation-Date: 2023-08-10 17:27+0800\n" "PO-Revision-Date: 2021-05-20 10:54+0800\n" "Last-Translator: ibuler \n" "Language-Team: JumpServer team\n" @@ -522,7 +522,7 @@ msgstr "特权账号" #: assets/models/automations/base.py:21 assets/models/cmd_filter.py:39 #: assets/models/label.py:22 #: authentication/serializers/connect_token_secret.py:114 -#: terminal/models/applet/applet.py:38 +#: terminal/models/applet/applet.py:39 #: terminal/models/component/endpoint.py:105 users/serializers/user.py:169 msgid "Is active" msgstr "激活" @@ -636,7 +636,7 @@ msgstr "类别" #: assets/serializers/platform.py:127 audits/serializers.py:49 #: authentication/serializers/connect_token_secret.py:123 ops/models/job.py:130 #: perms/serializers/user_permission.py:27 settings/serializers/vault.py:13 -#: terminal/models/applet/applet.py:37 terminal/models/component/storage.py:57 +#: terminal/models/applet/applet.py:38 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:226 #: terminal/serializers/storage.py:238 tickets/models/comment.py:26 @@ -761,8 +761,8 @@ msgstr "" #: assets/models/cmd_filter.py:40 assets/models/cmd_filter.py:88 #: assets/models/group.py:20 common/db/models.py:36 ops/models/adhoc.py:26 #: ops/models/job.py:138 ops/models/playbook.py:31 rbac/models/role.py:37 -#: settings/models.py:37 terminal/models/applet/applet.py:43 -#: terminal/models/applet/applet.py:283 terminal/models/applet/host.py:141 +#: settings/models.py:37 terminal/models/applet/applet.py:44 +#: terminal/models/applet/applet.py:284 terminal/models/applet/host.py:141 #: terminal/models/component/endpoint.py:24 #: terminal/models/component/endpoint.py:104 #: terminal/models/session/session.py:46 tickets/models/comment.py:32 @@ -1384,7 +1384,7 @@ msgstr "用户名与用户相同" #: assets/models/_user.py:52 authentication/models/connection_token.py:41 #: authentication/serializers/connect_token_secret.py:111 -#: terminal/models/applet/applet.py:40 terminal/serializers/session.py:19 +#: terminal/models/applet/applet.py:41 terminal/serializers/session.py:19 #: terminal/serializers/session.py:42 terminal/serializers/storage.py:70 msgid "Protocol" msgstr "协议" @@ -1528,7 +1528,7 @@ msgstr "资产自动化任务" #: assets/models/automations/base.py:113 audits/models.py:199 #: audits/serializers.py:50 ops/models/base.py:49 ops/models/job.py:213 -#: terminal/models/applet/applet.py:282 terminal/models/applet/host.py:138 +#: terminal/models/applet/applet.py:283 terminal/models/applet/host.py:138 #: terminal/models/component/status.py:30 terminal/serializers/applet.py:18 #: terminal/serializers/applet_host.py:115 tickets/models/ticket/general.py:283 #: tickets/serializers/super_ticket.py:13 @@ -4013,7 +4013,7 @@ msgstr "默认组织" msgid "SYSTEM" msgstr "系统组织" -#: orgs/models.py:83 rbac/models/role.py:36 terminal/models/applet/applet.py:39 +#: orgs/models.py:83 rbac/models/role.py:36 terminal/models/applet/applet.py:40 msgid "Builtin" msgstr "内置的" @@ -4309,8 +4309,8 @@ msgstr "任务中心" msgid "My assets" msgstr "我的资产" -#: rbac/tree.py:56 terminal/models/applet/applet.py:50 -#: terminal/models/applet/applet.py:279 terminal/models/applet/host.py:29 +#: rbac/tree.py:56 terminal/models/applet/applet.py:51 +#: terminal/models/applet/applet.py:280 terminal/models/applet/host.py:29 #: terminal/serializers/applet.py:15 msgid "Applet" msgstr "远程应用" @@ -5676,7 +5676,7 @@ msgstr "验证码已发送" msgid "Home page" msgstr "首页" -#: templates/resource_download.html:18 templates/resource_download.html:32 +#: templates/resource_download.html:18 templates/resource_download.html:33 msgid "Client" msgstr "客户端" @@ -5688,31 +5688,31 @@ msgstr "" "JumpServer 客户端,目前用来唤起 特定客户端程序 连接资产, 目前仅支持 RDP SSH " "客户端,Telnet 会在未来支持" -#: templates/resource_download.html:32 +#: templates/resource_download.html:33 msgid "Microsoft" msgstr "微软" -#: templates/resource_download.html:32 +#: templates/resource_download.html:33 msgid "Official" msgstr "官方" -#: templates/resource_download.html:34 +#: templates/resource_download.html:35 msgid "" "macOS needs to download the client to connect RDP asset, which comes with " "Windows" msgstr "macOS 需要下载客户端来连接 RDP 资产,Windows 系统默认安装了该程序" -#: templates/resource_download.html:43 +#: templates/resource_download.html:44 msgid "Windows Remote application publisher tools" msgstr "Windows 远程应用发布服务器工具" -#: templates/resource_download.html:44 +#: templates/resource_download.html:45 msgid "" "OpenSSH is a program used to connect remote applications in the Windows " "Remote Application Publisher" msgstr "OpenSSH 是在 windows 远程应用发布服务器中用来连接远程应用的程序" -#: templates/resource_download.html:52 +#: templates/resource_download.html:53 msgid "Offline video player" msgstr "离线录像播放器" @@ -5887,7 +5887,7 @@ msgstr "存储无效" msgid "Community" msgstr "社区版" -#: terminal/models/applet/applet.py:30 terminal/models/applet/applet.py:36 +#: terminal/models/applet/applet.py:30 msgid "Enterprise" msgstr "企业版" @@ -5895,35 +5895,39 @@ msgstr "企业版" msgid "Author" msgstr "作者" -#: terminal/models/applet/applet.py:41 +#: terminal/models/applet/applet.py:37 terminal/serializers/applet.py:31 +msgid "Edition" +msgstr "版本" + +#: terminal/models/applet/applet.py:42 msgid "Can concurrent" msgstr "可以并发" -#: terminal/models/applet/applet.py:42 +#: terminal/models/applet/applet.py:43 msgid "Tags" msgstr "标签" -#: terminal/models/applet/applet.py:46 terminal/serializers/storage.py:159 +#: terminal/models/applet/applet.py:47 terminal/serializers/storage.py:159 msgid "Hosts" msgstr "主机" -#: terminal/models/applet/applet.py:91 +#: terminal/models/applet/applet.py:92 msgid "Applet pkg not valid, Missing file {}" msgstr "Applet pkg 无效,缺少文件 {}" -#: terminal/models/applet/applet.py:110 +#: terminal/models/applet/applet.py:111 msgid "Load platform.yml failed: {}" msgstr "加载 platform.yml 失败: {}" -#: terminal/models/applet/applet.py:113 +#: terminal/models/applet/applet.py:114 msgid "Only support custom platform" msgstr "只支持自定义平台" -#: terminal/models/applet/applet.py:118 +#: terminal/models/applet/applet.py:119 msgid "Missing type in platform.yml" msgstr "在 platform.yml 中缺少类型" -#: terminal/models/applet/applet.py:281 terminal/models/applet/host.py:35 +#: terminal/models/applet/applet.py:282 terminal/models/applet/host.py:35 #: terminal/models/applet/host.py:136 msgid "Hosting" msgstr "宿主机" @@ -7987,9 +7991,6 @@ msgstr "旗舰版" msgid "Community edition" msgstr "社区版" -#~ msgid "Edition" -#~ msgstr "版本" - #~ msgid "Strategy" #~ msgstr "策略" diff --git a/apps/terminal/serializers/applet.py b/apps/terminal/serializers/applet.py index 0b1737232..fad8e9780 100644 --- a/apps/terminal/serializers/applet.py +++ b/apps/terminal/serializers/applet.py @@ -27,6 +27,10 @@ class AppletPublicationSerializer(serializers.ModelSerializer): class AppletSerializer(serializers.ModelSerializer): icon = serializers.ReadOnlyField(label=_("Icon")) type = LabeledChoiceField(choices=Applet.Type.choices, label=_("Type")) + edition = LabeledChoiceField( + choices=Applet.Edition.choices, label=_("Edition"), required=False, + default=Applet.Edition.community + ) class Meta: model = Applet From 3203c298e5ceef17494b37ff2ca2486671c8a4fa Mon Sep 17 00:00:00 2001 From: Bai Date: Thu, 10 Aug 2023 17:37:24 +0800 Subject: [PATCH 130/177] =?UTF-8?q?perf:=20=E5=8F=91=E5=B8=83=E6=9C=BA?= =?UTF-8?q?=E8=8E=B7=E5=8F=96=E8=B4=A6=E5=8F=B7API=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/terminal/api/applet/relation.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/apps/terminal/api/applet/relation.py b/apps/terminal/api/applet/relation.py index 8028ff1c8..30dfe88f4 100644 --- a/apps/terminal/api/applet/relation.py +++ b/apps/terminal/api/applet/relation.py @@ -8,7 +8,7 @@ from rest_framework.response import Response from common.api import JMSModelViewSet from common.permissions import IsServiceAccount -from common.utils import is_uuid +from common.utils import is_uuid, get_logger from orgs.utils import tmp_to_builtin_org from rbac.permissions import RBACPermission from terminal.models import AppletHost @@ -18,6 +18,8 @@ from terminal.serializers import ( AppletHostAppletReportSerializer, ) +logger = get_logger(__file__) + class HostMixin: request: Request @@ -36,6 +38,10 @@ class HostMixin: def self_host(self): try: + info = 'User {} has applet host {}'.format( + self.request.user, self.request.user.terminal.applet_host + ) + logger.info(info) return self.request.user.terminal.applet_host except AttributeError: raise self.permission_denied(self.request, 'User has no applet host') @@ -46,9 +52,11 @@ class HostMixin: @property def host(self): if self.kwargs.get('host'): - return self.pk_host() + host = self.pk_host() else: - return self.self_host() + host = self.self_host() + logger.info('Applet host: {}'.format(host)) + return host class AppletHostAccountsViewSet(HostMixin, JMSModelViewSet): From e9e5fbb4c247c26e1d6aeb048063071af2f12e10 Mon Sep 17 00:00:00 2001 From: ibuler Date: Thu, 10 Aug 2023 18:23:53 +0800 Subject: [PATCH 131/177] =?UTF-8?q?perf:=20=E8=B4=A6=E5=8F=B7=E7=94=9F?= =?UTF-8?q?=E6=88=90=E6=97=B6=EF=BC=8C=E6=8E=92=E9=99=A4=20[=20=E5=BC=80?= =?UTF-8?q?=E5=A4=B4=E7=9A=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/locale/ja/LC_MESSAGES/django.po | 22 +++++++++++-------- apps/locale/zh/LC_MESSAGES/django.po | 22 +++++++++++-------- apps/perms/api/user_group_permission.py | 8 +++---- apps/terminal/models/applet/host.py | 1 + apps/users/api/__init__.py | 4 ++-- .../api/{service_account.py => service.py} | 0 apps/users/api/user.py | 4 ++++ 7 files changed, 36 insertions(+), 25 deletions(-) rename apps/users/api/{service_account.py => service.py} (100%) diff --git a/apps/locale/ja/LC_MESSAGES/django.po b/apps/locale/ja/LC_MESSAGES/django.po index 4909e19e5..d6f806295 100644 --- a/apps/locale/ja/LC_MESSAGES/django.po +++ b/apps/locale/ja/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-08-10 17:27+0800\n" +"POT-Creation-Date: 2023-08-10 18:22+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -289,7 +289,7 @@ msgstr "アカウントバックアップ計画" #: assets/models/automations/base.py:115 audits/models.py:60 #: ops/models/base.py:55 ops/models/celery.py:63 ops/models/job.py:221 #: ops/templates/ops/celery_task_log.html:75 -#: perms/models/asset_permission.py:72 terminal/models/applet/host.py:139 +#: perms/models/asset_permission.py:72 terminal/models/applet/host.py:140 #: terminal/models/session/session.py:44 #: tickets/models/ticket/apply_application.py:30 #: tickets/models/ticket/apply_asset.py:19 @@ -418,7 +418,7 @@ msgstr "開始日" #: accounts/models/automations/change_secret.py:91 #: assets/models/automations/base.py:116 ops/models/base.py:56 #: ops/models/celery.py:64 ops/models/job.py:222 -#: terminal/models/applet/host.py:140 +#: terminal/models/applet/host.py:141 msgid "Date finished" msgstr "終了日" @@ -762,7 +762,7 @@ msgstr "" #: assets/models/group.py:20 common/db/models.py:36 ops/models/adhoc.py:26 #: ops/models/job.py:138 ops/models/playbook.py:31 rbac/models/role.py:37 #: settings/models.py:37 terminal/models/applet/applet.py:44 -#: terminal/models/applet/applet.py:284 terminal/models/applet/host.py:141 +#: terminal/models/applet/applet.py:284 terminal/models/applet/host.py:142 #: terminal/models/component/endpoint.py:24 #: terminal/models/component/endpoint.py:104 #: terminal/models/session/session.py:46 tickets/models/comment.py:32 @@ -1530,7 +1530,7 @@ msgstr "アセットの自動化タスク" #: assets/models/automations/base.py:113 audits/models.py:199 #: audits/serializers.py:50 ops/models/base.py:49 ops/models/job.py:213 -#: terminal/models/applet/applet.py:283 terminal/models/applet/host.py:138 +#: terminal/models/applet/applet.py:283 terminal/models/applet/host.py:139 #: terminal/models/component/status.py:30 terminal/serializers/applet.py:18 #: terminal/serializers/applet_host.py:115 tickets/models/ticket/general.py:283 #: tickets/serializers/super_ticket.py:13 @@ -2138,7 +2138,7 @@ msgstr "セッションログ" msgid "Login log" msgstr "ログインログ" -#: audits/const.py:43 terminal/models/applet/host.py:142 +#: audits/const.py:43 terminal/models/applet/host.py:143 #: terminal/models/component/task.py:22 msgid "Task" msgstr "タスク" @@ -6025,7 +6025,7 @@ msgid "Missing type in platform.yml" msgstr "platform.ymlにタイプがありません" #: terminal/models/applet/applet.py:282 terminal/models/applet/host.py:35 -#: terminal/models/applet/host.py:136 +#: terminal/models/applet/host.py:137 msgid "Hosting" msgstr "ホスト マシン" @@ -6053,7 +6053,7 @@ msgstr "初期化日" msgid "Date synced" msgstr "同期日" -#: terminal/models/applet/host.py:137 +#: terminal/models/applet/host.py:138 msgid "Initial" msgstr "初期化" @@ -6962,7 +6962,11 @@ msgstr "無効な承認アクション" msgid "This user is not authorized to approve this ticket" msgstr "このユーザーはこの作業指示を承認する権限がありません" -#: users/api/user.py:190 +#: users/api/user.py:141 +msgid "Can not invite self" +msgstr "自分自身を招待することはできません" + +#: users/api/user.py:194 msgid "Could not reset self otp, use profile reset instead" msgstr "自己otpをリセットできませんでした、代わりにプロファイルリセットを使用" diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po index b03c3a1ad..3c1119e4c 100644 --- a/apps/locale/zh/LC_MESSAGES/django.po +++ b/apps/locale/zh/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: JumpServer 0.3.3\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-08-10 17:27+0800\n" +"POT-Creation-Date: 2023-08-10 18:22+0800\n" "PO-Revision-Date: 2021-05-20 10:54+0800\n" "Last-Translator: ibuler \n" "Language-Team: JumpServer team\n" @@ -288,7 +288,7 @@ msgstr "账号备份计划" #: assets/models/automations/base.py:115 audits/models.py:60 #: ops/models/base.py:55 ops/models/celery.py:63 ops/models/job.py:221 #: ops/templates/ops/celery_task_log.html:75 -#: perms/models/asset_permission.py:72 terminal/models/applet/host.py:139 +#: perms/models/asset_permission.py:72 terminal/models/applet/host.py:140 #: terminal/models/session/session.py:44 #: tickets/models/ticket/apply_application.py:30 #: tickets/models/ticket/apply_asset.py:19 @@ -417,7 +417,7 @@ msgstr "开始日期" #: accounts/models/automations/change_secret.py:91 #: assets/models/automations/base.py:116 ops/models/base.py:56 #: ops/models/celery.py:64 ops/models/job.py:222 -#: terminal/models/applet/host.py:140 +#: terminal/models/applet/host.py:141 msgid "Date finished" msgstr "结束日期" @@ -762,7 +762,7 @@ msgstr "" #: assets/models/group.py:20 common/db/models.py:36 ops/models/adhoc.py:26 #: ops/models/job.py:138 ops/models/playbook.py:31 rbac/models/role.py:37 #: settings/models.py:37 terminal/models/applet/applet.py:44 -#: terminal/models/applet/applet.py:284 terminal/models/applet/host.py:141 +#: terminal/models/applet/applet.py:284 terminal/models/applet/host.py:142 #: terminal/models/component/endpoint.py:24 #: terminal/models/component/endpoint.py:104 #: terminal/models/session/session.py:46 tickets/models/comment.py:32 @@ -1528,7 +1528,7 @@ msgstr "资产自动化任务" #: assets/models/automations/base.py:113 audits/models.py:199 #: audits/serializers.py:50 ops/models/base.py:49 ops/models/job.py:213 -#: terminal/models/applet/applet.py:283 terminal/models/applet/host.py:138 +#: terminal/models/applet/applet.py:283 terminal/models/applet/host.py:139 #: terminal/models/component/status.py:30 terminal/serializers/applet.py:18 #: terminal/serializers/applet_host.py:115 tickets/models/ticket/general.py:283 #: tickets/serializers/super_ticket.py:13 @@ -2127,7 +2127,7 @@ msgstr "会话日志" msgid "Login log" msgstr "登录日志" -#: audits/const.py:43 terminal/models/applet/host.py:142 +#: audits/const.py:43 terminal/models/applet/host.py:143 #: terminal/models/component/task.py:22 msgid "Task" msgstr "任务" @@ -5928,7 +5928,7 @@ msgid "Missing type in platform.yml" msgstr "在 platform.yml 中缺少类型" #: terminal/models/applet/applet.py:282 terminal/models/applet/host.py:35 -#: terminal/models/applet/host.py:136 +#: terminal/models/applet/host.py:137 msgid "Hosting" msgstr "宿主机" @@ -5956,7 +5956,7 @@ msgstr "初始化日期" msgid "Date synced" msgstr "同步日期" -#: terminal/models/applet/host.py:137 +#: terminal/models/applet/host.py:138 msgid "Initial" msgstr "初始化" @@ -6853,7 +6853,11 @@ msgstr "无效的审批动作" msgid "This user is not authorized to approve this ticket" msgstr "此用户无权审批此工单" -#: users/api/user.py:190 +#: users/api/user.py:141 +msgid "Can not invite self" +msgstr "不能邀请自己" + +#: users/api/user.py:194 msgid "Could not reset self otp, use profile reset instead" msgstr "不能在该页面重置 MFA 多因子认证, 请去个人信息页面重置" diff --git a/apps/perms/api/user_group_permission.py b/apps/perms/api/user_group_permission.py index 850d1385b..dcc208e99 100644 --- a/apps/perms/api/user_group_permission.py +++ b/apps/perms/api/user_group_permission.py @@ -47,11 +47,9 @@ class UserGroupGrantedAssetsApi(ListAPIView): granted_q |= Q(granted_by_permissions__id__in=asset_perm_ids) - assets = Asset.objects.filter( - granted_q - ).distinct().only( - *self.only_fields - ) + assets = Asset.objects.filter(granted_q) \ + .only(*self.only_fields) \ + .distinct() return assets diff --git a/apps/terminal/models/applet/host.py b/apps/terminal/models/applet/host.py index a4945a890..23af7f5ac 100644 --- a/apps/terminal/models/applet/host.py +++ b/apps/terminal/models/applet/host.py @@ -125,6 +125,7 @@ class AppletHost(Host): from users.models import User usernames = User.objects \ .filter(is_active=True, is_service_account=False) \ + .exclude(username__startswith='[') \ .values_list('username', flat=True) account_usernames = self.accounts.all().values_list('username', flat=True) account_usernames = [username[3:] for username in account_usernames if username.startswith('js_')] diff --git a/apps/users/api/__init__.py b/apps/users/api/__init__.py index d5db61888..6231e874b 100644 --- a/apps/users/api/__init__.py +++ b/apps/users/api/__init__.py @@ -1,8 +1,8 @@ # -*- coding: utf-8 -*- # -from .user import * from .group import * from .profile import * -from .service_account import * from .relation import * +from .service import * +from .user import * diff --git a/apps/users/api/service_account.py b/apps/users/api/service.py similarity index 100% rename from apps/users/api/service_account.py rename to apps/users/api/service.py diff --git a/apps/users/api/user.py b/apps/users/api/user.py index e0bc288c8..524571025 100644 --- a/apps/users/api/user.py +++ b/apps/users/api/user.py @@ -136,6 +136,10 @@ class UserViewSet(CommonApiMixin, UserQuerysetMixin, SuggestionMixin, BulkModelV users = validated_data['users'] org_roles = validated_data['org_roles'] + has_self = any([str(u.id) == str(request.user.id) for u in users]) + if has_self and not request.user.is_superuser: + error = {"error": _("Can not invite self")} + return Response(error, status=400) for user in users: user.org_roles.set(org_roles) return Response(serializer.data, status=201) From a890a8d5356e26bc1cff85084c8d6d182ecdeea8 Mon Sep 17 00:00:00 2001 From: Bai Date: Fri, 11 Aug 2023 15:14:19 +0800 Subject: [PATCH 132/177] =?UTF-8?q?perf:=20=E5=8F=91=E5=B8=83=E6=9C=BA?= =?UTF-8?q?=E8=8E=B7=E5=8F=96=E8=B4=A6=E5=8F=B7API=E7=A7=BB=E9=99=A4?= =?UTF-8?q?=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/terminal/api/applet/relation.py | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/apps/terminal/api/applet/relation.py b/apps/terminal/api/applet/relation.py index 30dfe88f4..6435b6c0c 100644 --- a/apps/terminal/api/applet/relation.py +++ b/apps/terminal/api/applet/relation.py @@ -8,7 +8,7 @@ from rest_framework.response import Response from common.api import JMSModelViewSet from common.permissions import IsServiceAccount -from common.utils import is_uuid, get_logger +from common.utils import is_uuid from orgs.utils import tmp_to_builtin_org from rbac.permissions import RBACPermission from terminal.models import AppletHost @@ -18,8 +18,6 @@ from terminal.serializers import ( AppletHostAppletReportSerializer, ) -logger = get_logger(__file__) - class HostMixin: request: Request @@ -38,10 +36,6 @@ class HostMixin: def self_host(self): try: - info = 'User {} has applet host {}'.format( - self.request.user, self.request.user.terminal.applet_host - ) - logger.info(info) return self.request.user.terminal.applet_host except AttributeError: raise self.permission_denied(self.request, 'User has no applet host') @@ -55,7 +49,6 @@ class HostMixin: host = self.pk_host() else: host = self.self_host() - logger.info('Applet host: {}'.format(host)) return host From e2de7443981e012681b36781b8961a2c325b16ab Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Fri, 11 Aug 2023 16:01:05 +0800 Subject: [PATCH 133/177] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96vault=20?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=20(#11254)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: feng <1304903146@qq.com> --- apps/accounts/backends/__init__.py | 4 ++-- apps/settings/api/vault.py | 5 +++-- apps/settings/serializers/public.py | 1 + apps/settings/serializers/vault.py | 6 +++++- 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/apps/accounts/backends/__init__.py b/apps/accounts/backends/__init__.py index 9bfd63dfb..1b12e6be8 100644 --- a/apps/accounts/backends/__init__.py +++ b/apps/accounts/backends/__init__.py @@ -1,7 +1,7 @@ -import os -from django.utils.functional import LazyObject from importlib import import_module +from django.utils.functional import LazyObject + from common.utils import get_logger from ..const import VaultTypeChoices diff --git a/apps/settings/api/vault.py b/apps/settings/api/vault.py index 339b13ab3..7cbe4c39e 100644 --- a/apps/settings/api/vault.py +++ b/apps/settings/api/vault.py @@ -1,11 +1,11 @@ -from django.utils.translation import gettext_lazy as _ from django.conf import settings +from django.utils.translation import gettext_lazy as _ from rest_framework import status from rest_framework.generics import GenericAPIView from rest_framework.views import Response, APIView -from accounts.tasks.vault import sync_secret_to_vault from accounts.backends import get_vault_client +from accounts.tasks.vault import sync_secret_to_vault from settings.models import Setting from .. import serializers @@ -29,6 +29,7 @@ class VaultTestingAPI(GenericAPIView): def post(self, request): config = self.get_config(request) + config['VAULT_TYPE'] = settings.VAULT_TYPE try: client = get_vault_client(raise_exception=True, **config) ok, error = client.is_active() diff --git a/apps/settings/serializers/public.py b/apps/settings/serializers/public.py index 49ee3e1e1..7fb1308ae 100644 --- a/apps/settings/serializers/public.py +++ b/apps/settings/serializers/public.py @@ -53,6 +53,7 @@ class PrivateSettingSerializer(PublicSettingSerializer): TICKETS_ENABLED = serializers.BooleanField() CONNECTION_TOKEN_REUSABLE = serializers.BooleanField() CACHE_LOGIN_PASSWORD_ENABLED = serializers.BooleanField() + VAULT_TYPE = serializers.CharField() class ServerInfoSerializer(serializers.Serializer): diff --git a/apps/settings/serializers/vault.py b/apps/settings/serializers/vault.py index b8b94d5ca..e25c73e6c 100644 --- a/apps/settings/serializers/vault.py +++ b/apps/settings/serializers/vault.py @@ -16,8 +16,12 @@ class VaultSettingSerializer(serializers.Serializer): max_length=256, allow_blank=True, required=False, label=_('Host') ) VAULT_HCP_TOKEN = EncryptedField( - max_length=256, allow_blank=True, required=False, label=_('Token') + max_length=256, allow_blank=True, required=False, label=_('Token'), default='' ) VAULT_HCP_MOUNT_POINT = serializers.CharField( max_length=256, allow_blank=True, required=False, label=_('Mount Point') ) + + def validate(self, attrs): + attrs.pop('VAULT_TYPE', None) + return attrs From c3ea5300a383d75bdc920a71bab26d39a21b02c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Chuailei000=E2=80=9D?= <2280131253@qq.com> Date: Fri, 11 Aug 2023 17:49:25 +0800 Subject: [PATCH 134/177] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=E4=BB=BB?= =?UTF-8?q?=E5=8A=A1=E6=97=A5=E5=BF=97=E9=A1=B5=E9=9D=A2=E6=97=B6=E9=97=B4?= =?UTF-8?q?=E6=98=BE=E7=A4=BA=E5=85=BC=E5=AE=B9=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/ops/templates/ops/celery_task_log.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/ops/templates/ops/celery_task_log.html b/apps/ops/templates/ops/celery_task_log.html index 3dfc23886..a2a025391 100644 --- a/apps/ops/templates/ops/celery_task_log.html +++ b/apps/ops/templates/ops/celery_task_log.html @@ -135,7 +135,7 @@ method: "GET", flash_message: false, success(data) { - const dateStart = new Date(data.date_start).toLocaleString(); + const dateStart = data.date_start ? new Date(data.date_start).toLocaleString() : ''; $('.task-id').html(data.id); $('.task-type').html(data.task_name); $('.date-start').html(dateStart); From bd7c5f8e651301c3573bc51bcc96820c44cb0ee2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=90=B4=E5=B0=8F=E7=99=BD?= <296015668@qq.com> Date: Mon, 14 Aug 2023 10:57:40 +0800 Subject: [PATCH 135/177] =?UTF-8?q?revert:=20=E8=BF=98=E5=8E=9F=E6=9E=84?= =?UTF-8?q?=E5=BB=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 73 ++++++++------------------------------------------ Dockerfile-ee | 71 ++++++++++++++++++++++++++++++++++++++++++++++-- poetry.lock | 41 ++++------------------------ pyproject.toml | 15 ++--------- 4 files changed, 87 insertions(+), 113 deletions(-) diff --git a/Dockerfile b/Dockerfile index 42ef5566c..6742225f0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,14 @@ -FROM jumpserver/python:3.11-slim-buster as stage-build +FROM python:3.11-slim-bullseye as stage-build +ARG TARGETARCH + +ARG VERSION +ENV VERSION=$VERSION + +WORKDIR /opt/jumpserver +ADD . . +RUN cd utils && bash -ixeu build.sh + +FROM python:3.11-slim-bullseye ARG TARGETARCH ARG BUILD_DEPENDENCIES=" \ @@ -42,67 +52,6 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked,id=core \ && apt-get -y install --no-install-recommends ${BUILD_DEPENDENCIES} \ && apt-get -y install --no-install-recommends ${DEPENDENCIES} \ && apt-get -y install --no-install-recommends ${TOOLS} \ - && echo "no" | dpkg-reconfigure dash \ - && rm -rf /var/lib/apt/lists/* - -WORKDIR /opt -RUN set -ex \ - && cd /opt \ - && \ - if [ "${TARGETARCH}" == "loong64" ]; then \ - mkdir -p /opt/rust-install; \ - wget -O /opt/rust.tar.gz https://rust-lang.loongnix.cn/dist/2022-11-03/rust-1.65.0-loongarch64-unknown-linux-gnu.tar.xz; \ - tar -xf /opt/rust.tar.gz -C /opt/rust-install --strip-components=1; \ - cd /opt/rust-install && ./install.sh; \ - cd /opt; \ - rm -rf /opt/rust.tar.gz /opt/rust-install; \ - fi - -ARG VERSION -ENV VERSION=$VERSION - -WORKDIR /opt/jumpserver -ADD . . -RUN cd utils && bash -ixeu build.sh - -ARG PIP_MIRROR=https://pypi.tuna.tsinghua.edu.cn/simple -RUN --mount=type=cache,target=/root/.cache \ - set -ex \ - && pip install poetry -i ${PIP_MIRROR} \ - && poetry config virtualenvs.create false \ - && poetry install - -FROM jumpserver/python:3.11-slim-buster -ARG TARGETARCH - -ARG DEPENDENCIES=" \ - libxmlsec1-openssl" - -ARG TOOLS=" \ - ca-certificates \ - curl \ - default-libmysqlclient-dev \ - default-mysql-client \ - inetutils-ping \ - locales \ - openssh-client \ - procps \ - sshpass \ - telnet \ - unzip \ - vim \ - nmap \ - wget" - -ARG APT_MIRROR=http://mirrors.ustc.edu.cn - -RUN --mount=type=cache,target=/var/cache/apt,sharing=locked,id=core \ - sed -i "s@http://.*.debian.org@${APT_MIRROR}@g" /etc/apt/sources.list \ - && rm -f /etc/apt/apt.conf.d/docker-clean \ - && ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \ - && apt-get update \ - && apt-get -y install --no-install-recommends ${DEPENDENCIES} \ - && apt-get -y install --no-install-recommends ${TOOLS} \ && mkdir -p /root/.ssh/ \ && echo "Host *\n\tStrictHostKeyChecking no\n\tUserKnownHostsFile /dev/null\n\tCiphers +aes128-cbc\n\tKexAlgorithms +diffie-hellman-group1-sha1\n\tHostKeyAlgorithms +ssh-rsa" > /root/.ssh/config \ && echo "set mouse-=a" > ~/.vimrc \ diff --git a/Dockerfile-ee b/Dockerfile-ee index 9594e1579..8e1c5b1dc 100644 --- a/Dockerfile-ee +++ b/Dockerfile-ee @@ -1,11 +1,78 @@ ARG VERSION FROM registry.fit2cloud.com/jumpserver/xpack:${VERSION} as build-xpack -FROM jumpserver/core:${VERSION} +FROM python:3.11-slim-bullseye as stage-build ARG TARGETARCH -COPY --from=build-xpack /opt/xpack /opt/jumpserver/apps/xpack +ARG VERSION +ENV VERSION=$VERSION WORKDIR /opt/jumpserver +ADD . . +RUN cd utils && bash -ixeu build.sh + +FROM python:3.11-slim-bullseye +ARG TARGETARCH + +ARG BUILD_DEPENDENCIES=" \ + g++ \ + make \ + pkg-config" + +ARG DEPENDENCIES=" \ + freetds-dev \ + libpq-dev \ + libffi-dev \ + libjpeg-dev \ + libkrb5-dev \ + libldap2-dev \ + libsasl2-dev \ + libssl-dev \ + libxml2-dev \ + libxmlsec1-dev \ + libxmlsec1-openssl \ + freerdp2-dev \ + libaio-dev" + +ARG TOOLS=" \ + ca-certificates \ + curl \ + default-libmysqlclient-dev \ + default-mysql-client \ + git \ + git-lfs \ + unzip \ + xz-utils \ + wget" + +ARG APT_MIRROR=http://mirrors.ustc.edu.cn + +RUN --mount=type=cache,target=/var/cache/apt,sharing=locked,id=core \ + sed -i "s@http://.*.debian.org@${APT_MIRROR}@g" /etc/apt/sources.list \ + && rm -f /etc/apt/apt.conf.d/docker-clean \ + && ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \ + && apt-get update \ + && apt-get -y install --no-install-recommends ${BUILD_DEPENDENCIES} \ + && apt-get -y install --no-install-recommends ${DEPENDENCIES} \ + && apt-get -y install --no-install-recommends ${TOOLS} \ + && mkdir -p /root/.ssh/ \ + && echo "Host *\n\tStrictHostKeyChecking no\n\tUserKnownHostsFile /dev/null\n\tCiphers +aes128-cbc\n\tKexAlgorithms +diffie-hellman-group1-sha1\n\tHostKeyAlgorithms +ssh-rsa" > /root/.ssh/config \ + && echo "set mouse-=a" > ~/.vimrc \ + && echo "no" | dpkg-reconfigure dash \ + && echo "zh_CN.UTF-8" | dpkg-reconfigure locales \ + && sed -i "s@# export @export @g" ~/.bashrc \ + && sed -i "s@# alias @alias @g" ~/.bashrc \ + && rm -rf /var/lib/apt/lists/* + +COPY --from=stage-build /opt/jumpserver/release/jumpserver /opt/jumpserver +WORKDIR /opt/jumpserver + +ARG PIP_MIRROR=https://pypi.douban.com/simple +RUN --mount=type=cache,target=/root/.cache \ + set -ex \ + && echo > /opt/jumpserver/config.yml \ + && pip install poetry -i ${PIP_MIRROR} \ + && poetry config virtualenvs.create false \ + && poetry install --only=main RUN --mount=type=cache,target=/root/.cache \ set -ex \ diff --git a/poetry.lock b/poetry.lock index 39b36a989..6cbdae8f2 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2825,24 +2825,6 @@ type = "legacy" url = "https://pypi.tuna.tsinghua.edu.cn/simple" reference = "tsinghua" -[[package]] -name = "greenlet" -version = "2.0.2" -description = "Lightweight in-process concurrent programming" -optional = false -python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*" -files = [ - {file = "greenlet-2.0.2-cp311-cp311-linux_loongarch64.whl", hash = "sha256:65f6e0520d2cad7b0d5c7486e050ffe4d1e3a83b6a9f214e9bb51b56fb3ba163"}, -] - -[package.extras] -docs = ["Sphinx", "docutils (<0.18)"] -test = ["objgraph", "psutil"] - -[package.source] -type = "url" -url = "https://download.jumpserver.org/pypi/simple/greenlet/greenlet-2.0.2-cp311-cp311-linux_loongarch64.whl" - [[package]] name = "grpcio" version = "1.56.2" @@ -2905,23 +2887,6 @@ type = "legacy" url = "https://pypi.tuna.tsinghua.edu.cn/simple" reference = "tsinghua" -[[package]] -name = "grpcio" -version = "1.56.2" -description = "HTTP/2-based RPC framework" -optional = false -python-versions = ">=3.7" -files = [ - {file = "grpcio-1.56.2-cp311-cp311-linux_loongarch64.whl", hash = "sha256:c1625d6e03b33927cedbd79d13d6caa07173b67245f04373b814b3ae7dc050a7"}, -] - -[package.extras] -protobuf = ["grpcio-tools (>=1.56.2)"] - -[package.source] -type = "url" -url = "https://download.jumpserver.org/pypi/simple/grpcio/grpcio-1.56.2-cp311-cp311-linux_loongarch64.whl" - [[package]] name = "grpcio-status" version = "1.56.2" @@ -5351,9 +5316,11 @@ files = [ {file = "pymssql-2.2.8-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:049f2e3de919e8e02504780a21ebbf235e21ca8ed5c7538c5b6e705aa6c43d8c"}, {file = "pymssql-2.2.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0dd86d8e3e346e34f3f03d12e333747b53a1daa74374a727f4714d5b82ee0dd5"}, {file = "pymssql-2.2.8-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:508226a0df7cb6faeda9f8e84e85743690ca427d7b27af9a73d75fcf0c1eef6e"}, + {file = "pymssql-2.2.8-cp310-cp310-win_amd64.whl", hash = "sha256:47859887adeaf184766b5e0bc845dd23611f3808f9521552063bb36eabc10092"}, {file = "pymssql-2.2.8-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:d873e553374d5b1c57fe1c43bb75e3bcc2920678db1ef26f6bfed396c7d21b30"}, {file = "pymssql-2.2.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf31b8b76634c826a91f9999e15b7bfb0c051a0f53b319fd56481a67e5b903bb"}, {file = "pymssql-2.2.8-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:821945c2214fe666fd456c61e09a29a00e7719c9e136c801bffb3a254e9c579b"}, + {file = "pymssql-2.2.8-cp311-cp311-win_amd64.whl", hash = "sha256:cc85b609b4e60eac25fa38bbac1ff854fd2c2a276e0ca4a3614c6f97efb644bb"}, {file = "pymssql-2.2.8-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:ebe7f64d5278d807f14bea08951e02512bfbc6219fd4d4f15bb45ded885cf3d4"}, {file = "pymssql-2.2.8-cp36-cp36m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:253af3d39fc0235627966817262d5c4c94ad09dcbea59664748063470048c29c"}, {file = "pymssql-2.2.8-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c9d109df536dc5f7dd851a88d285a4c9cb12a9314b621625f4f5ab1197eb312"}, @@ -5369,11 +5336,13 @@ files = [ {file = "pymssql-2.2.8-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3906993300650844ec140aa58772c0f5f3e9e9d5709c061334fd1551acdcf066"}, {file = "pymssql-2.2.8-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:7309c7352e4a87c9995c3183ebfe0ff4135e955bb759109637673c61c9f0ca8d"}, {file = "pymssql-2.2.8-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:9b8d603cc1ec7ae585c5a409a1d45e8da067970c79dd550d45c238ae0aa0f79f"}, + {file = "pymssql-2.2.8-cp38-cp38-win_amd64.whl", hash = "sha256:293cb4d0339e221d877d6b19a1905082b658f0100a1e2ccc9dda10de58938901"}, {file = "pymssql-2.2.8-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:895041edd002a2e91d8a4faf0906b6fbfef29d9164bc6beb398421f5927fa40e"}, {file = "pymssql-2.2.8-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6b2d9c6d38a416c6f2db36ff1cd8e69f9a5387a46f9f4f612623192e0c9404b1"}, {file = "pymssql-2.2.8-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d63d6f25cf40fe6a03c49be2d4d337858362b8ab944d6684c268e4990807cf0c"}, {file = "pymssql-2.2.8-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:c83ad3ad20951f3a94894b354fa5fa9666dcd5ebb4a635dad507c7d1dd545833"}, {file = "pymssql-2.2.8-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:3933f7f082be74698eea835df51798dab9bc727d94d3d280bffc75ab9265f890"}, + {file = "pymssql-2.2.8-cp39-cp39-win_amd64.whl", hash = "sha256:de313375b90b0f554058992f35c4a4beb3f6ec2f5912d8cd6afb649f95b03a9f"}, {file = "pymssql-2.2.8.tar.gz", hash = "sha256:9baefbfbd07d0142756e2dfcaa804154361ac5806ab9381350aad4e780c3033e"}, ] @@ -7244,4 +7213,4 @@ reference = "tsinghua" [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "acdb324e0081968235e843be40803734f3ab814de44c90c4367fa0ef0801759d" +content-hash = "062b7b8ab32d3eeacc77b6b160764bc7083b599f32a653da3a1ccaa353041fc8" diff --git a/pyproject.toml b/pyproject.toml index 069fd91a4..3cc8c76b7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -103,11 +103,7 @@ django-proxy = "1.2.2" channels-redis = "4.1.0" python-daemon = "3.0.1" eventlet = "0.33.3" -# greenlet = "2.0.2" -greenlet = [ - { url = "https://download.jumpserver.org/pypi/simple/greenlet/greenlet-2.0.2-cp311-cp311-linux_loongarch64.whl", markers = "sys_platform == 'linux' and platform_machine == 'loongarch64'" }, - { version = "2.0.2", source = "tsinghua", markers = "platform_machine != 'loongarch64'" } -] +greenlet = "2.0.2" gunicorn = "21.2.0" celery = "5.3.1" flower = "2.0.0" @@ -142,13 +138,11 @@ pyhcl = "0.4.4" ipy = "1.1" netifaces = "^0.11.0" - [tool.poetry.group.dev.dependencies] daphne = "4.0.0" channels = "^4.0.0" channels-redis = "^4.1.0" - [tool.poetry.group.xpack.dependencies] qingcloud-sdk = "1.2.15" azure-mgmt-subscription = "3.1.1" @@ -156,11 +150,7 @@ azure-identity = "1.13.0" azure-mgmt-compute = "30.0.0" azure-mgmt-network = "23.1.0" google-cloud-compute = "1.13.0" -# grpcio = "1.56.2" -grpcio = [ - { url = "https://download.jumpserver.org/pypi/simple/grpcio/grpcio-1.56.2-cp311-cp311-linux_loongarch64.whl", markers = "sys_platform == 'linux' and platform_machine == 'loongarch64'" }, - { version = "1.56.2", source = "tsinghua", markers = "platform_machine != 'loongarch64'" } -] +grpcio = "1.56.2" alibabacloud-dysmsapi20170525 = "2.0.24" python-novaclient = "18.3.0" python-keystoneclient = "5.1.0" @@ -183,7 +173,6 @@ name = "tsinghua" url = "https://pypi.tuna.tsinghua.edu.cn/simple/" priority = "primary" - [[tool.poetry.source]] name = "PyPI" priority = "primary" From 237c71f92133e234bf02c85057cf366dd27abe25 Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Mon, 14 Aug 2023 10:57:59 +0800 Subject: [PATCH 136/177] =?UTF-8?q?perf:=20vault=20=E5=90=8C=E6=AD=A5?= =?UTF-8?q?=E6=97=A5=E5=BF=97=E4=BC=98=E5=8C=96=20(#11261)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: feng <1304903146@qq.com> --- apps/accounts/tasks/vault.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/accounts/tasks/vault.py b/apps/accounts/tasks/vault.py index a6c9ed6db..154f1f9d7 100644 --- a/apps/accounts/tasks/vault.py +++ b/apps/accounts/tasks/vault.py @@ -28,8 +28,9 @@ def sync_secret_to_vault(): failed = [] skipped = [] instances = model.objects.all() + verbose_name = model._meta.original_attrs['verbose_name'] for instance in instances: - instance_desc = f'[{instance}]' + instance_desc = f'[{verbose_name}-{instance.id}-{instance}]' if instance.secret_has_save_to_vault: print(f'\033[32m- 跳过同步: {instance_desc}, 原因: [已同步]') skipped.append(instance) From 339fe1b73be2110caed452e1f6cd024c7524ef59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=90=B4=E5=B0=8F=E7=99=BD?= <296015668@qq.com> Date: Mon, 14 Aug 2023 10:57:40 +0800 Subject: [PATCH 137/177] =?UTF-8?q?revert:=20=E8=BF=98=E5=8E=9F=E6=9E=84?= =?UTF-8?q?=E5=BB=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 98 +++++++++----------------------------------------- Dockerfile-ee | 72 +++++++++++++++++++++++++++++++++++-- poetry.lock | 41 +++------------------ pyproject.toml | 15 ++------ 4 files changed, 94 insertions(+), 132 deletions(-) diff --git a/Dockerfile b/Dockerfile index 42ef5566c..fc1bcf3e2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,14 @@ -FROM jumpserver/python:3.11-slim-buster as stage-build +FROM python:3.11-slim-bullseye as stage-build +ARG TARGETARCH + +ARG VERSION +ENV VERSION=$VERSION + +WORKDIR /opt/jumpserver +ADD . . +RUN cd utils && bash -ixeu build.sh + +FROM python:3.11-slim-bullseye ARG TARGETARCH ARG BUILD_DEPENDENCIES=" \ @@ -26,10 +36,11 @@ ARG TOOLS=" \ curl \ default-libmysqlclient-dev \ default-mysql-client \ - git \ - git-lfs \ - unzip \ - xz-utils \ + locales \ + openssh-client \ + sshpass \ + telnet \ + vim \ wget" ARG APT_MIRROR=http://mirrors.ustc.edu.cn @@ -42,67 +53,6 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked,id=core \ && apt-get -y install --no-install-recommends ${BUILD_DEPENDENCIES} \ && apt-get -y install --no-install-recommends ${DEPENDENCIES} \ && apt-get -y install --no-install-recommends ${TOOLS} \ - && echo "no" | dpkg-reconfigure dash \ - && rm -rf /var/lib/apt/lists/* - -WORKDIR /opt -RUN set -ex \ - && cd /opt \ - && \ - if [ "${TARGETARCH}" == "loong64" ]; then \ - mkdir -p /opt/rust-install; \ - wget -O /opt/rust.tar.gz https://rust-lang.loongnix.cn/dist/2022-11-03/rust-1.65.0-loongarch64-unknown-linux-gnu.tar.xz; \ - tar -xf /opt/rust.tar.gz -C /opt/rust-install --strip-components=1; \ - cd /opt/rust-install && ./install.sh; \ - cd /opt; \ - rm -rf /opt/rust.tar.gz /opt/rust-install; \ - fi - -ARG VERSION -ENV VERSION=$VERSION - -WORKDIR /opt/jumpserver -ADD . . -RUN cd utils && bash -ixeu build.sh - -ARG PIP_MIRROR=https://pypi.tuna.tsinghua.edu.cn/simple -RUN --mount=type=cache,target=/root/.cache \ - set -ex \ - && pip install poetry -i ${PIP_MIRROR} \ - && poetry config virtualenvs.create false \ - && poetry install - -FROM jumpserver/python:3.11-slim-buster -ARG TARGETARCH - -ARG DEPENDENCIES=" \ - libxmlsec1-openssl" - -ARG TOOLS=" \ - ca-certificates \ - curl \ - default-libmysqlclient-dev \ - default-mysql-client \ - inetutils-ping \ - locales \ - openssh-client \ - procps \ - sshpass \ - telnet \ - unzip \ - vim \ - nmap \ - wget" - -ARG APT_MIRROR=http://mirrors.ustc.edu.cn - -RUN --mount=type=cache,target=/var/cache/apt,sharing=locked,id=core \ - sed -i "s@http://.*.debian.org@${APT_MIRROR}@g" /etc/apt/sources.list \ - && rm -f /etc/apt/apt.conf.d/docker-clean \ - && ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \ - && apt-get update \ - && apt-get -y install --no-install-recommends ${DEPENDENCIES} \ - && apt-get -y install --no-install-recommends ${TOOLS} \ && mkdir -p /root/.ssh/ \ && echo "Host *\n\tStrictHostKeyChecking no\n\tUserKnownHostsFile /dev/null\n\tCiphers +aes128-cbc\n\tKexAlgorithms +diffie-hellman-group1-sha1\n\tHostKeyAlgorithms +ssh-rsa" > /root/.ssh/config \ && echo "set mouse-=a" > ~/.vimrc \ @@ -112,24 +62,10 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked,id=core \ && sed -i "s@# alias @alias @g" ~/.bashrc \ && rm -rf /var/lib/apt/lists/* -ARG DOWNLOAD_URL=https://download.jumpserver.org - -RUN set -ex \ - && \ - if [ "${TARGETARCH}" == "amd64" ] || [ "${TARGETARCH}" == "arm64" ]; then \ - mkdir -p /opt/oracle; \ - cd /opt/oracle; \ - wget ${DOWNLOAD_URL}/public/instantclient-basiclite-linux.${TARGETARCH}-19.10.0.0.0.zip; \ - unzip instantclient-basiclite-linux.${TARGETARCH}-19.10.0.0.0.zip; \ - echo "/opt/oracle/instantclient_19_10" > /etc/ld.so.conf.d/oracle-instantclient.conf; \ - ldconfig; \ - rm -f instantclient-basiclite-linux.${TARGETARCH}-19.10.0.0.0.zip; \ - fi - COPY --from=stage-build /opt/jumpserver/release/jumpserver /opt/jumpserver WORKDIR /opt/jumpserver -ARG PIP_MIRROR=https://pypi.douban.com/simple +ARG PIP_MIRROR=https://pypi.tuna.tsinghua.edu.cn/simple RUN --mount=type=cache,target=/root/.cache \ set -ex \ && echo > /opt/jumpserver/config.yml \ diff --git a/Dockerfile-ee b/Dockerfile-ee index 9594e1579..4b875cd17 100644 --- a/Dockerfile-ee +++ b/Dockerfile-ee @@ -1,11 +1,79 @@ ARG VERSION FROM registry.fit2cloud.com/jumpserver/xpack:${VERSION} as build-xpack -FROM jumpserver/core:${VERSION} +FROM python:3.11-slim-bullseye as stage-build ARG TARGETARCH -COPY --from=build-xpack /opt/xpack /opt/jumpserver/apps/xpack +ARG VERSION +ENV VERSION=$VERSION WORKDIR /opt/jumpserver +ADD . . +RUN cd utils && bash -ixeu build.sh + +FROM python:3.11-slim-bullseye +ARG TARGETARCH + +ARG BUILD_DEPENDENCIES=" \ + g++ \ + make \ + pkg-config" + +ARG DEPENDENCIES=" \ + freetds-dev \ + libpq-dev \ + libffi-dev \ + libjpeg-dev \ + libkrb5-dev \ + libldap2-dev \ + libsasl2-dev \ + libssl-dev \ + libxml2-dev \ + libxmlsec1-dev \ + libxmlsec1-openssl \ + freerdp2-dev \ + libaio-dev" + +ARG TOOLS=" \ + ca-certificates \ + curl \ + default-libmysqlclient-dev \ + default-mysql-client \ + locales \ + openssh-client \ + sshpass \ + telnet \ + vim \ + wget" + +ARG APT_MIRROR=http://mirrors.ustc.edu.cn + +RUN --mount=type=cache,target=/var/cache/apt,sharing=locked,id=core \ + sed -i "s@http://.*.debian.org@${APT_MIRROR}@g" /etc/apt/sources.list \ + && rm -f /etc/apt/apt.conf.d/docker-clean \ + && ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \ + && apt-get update \ + && apt-get -y install --no-install-recommends ${BUILD_DEPENDENCIES} \ + && apt-get -y install --no-install-recommends ${DEPENDENCIES} \ + && apt-get -y install --no-install-recommends ${TOOLS} \ + && mkdir -p /root/.ssh/ \ + && echo "Host *\n\tStrictHostKeyChecking no\n\tUserKnownHostsFile /dev/null\n\tCiphers +aes128-cbc\n\tKexAlgorithms +diffie-hellman-group1-sha1\n\tHostKeyAlgorithms +ssh-rsa" > /root/.ssh/config \ + && echo "set mouse-=a" > ~/.vimrc \ + && echo "no" | dpkg-reconfigure dash \ + && echo "zh_CN.UTF-8" | dpkg-reconfigure locales \ + && sed -i "s@# export @export @g" ~/.bashrc \ + && sed -i "s@# alias @alias @g" ~/.bashrc \ + && rm -rf /var/lib/apt/lists/* + +COPY --from=stage-build /opt/jumpserver/release/jumpserver /opt/jumpserver +WORKDIR /opt/jumpserver + +ARG PIP_MIRROR=https://pypi.douban.com/simple +RUN --mount=type=cache,target=/root/.cache \ + set -ex \ + && echo > /opt/jumpserver/config.yml \ + && pip install poetry -i ${PIP_MIRROR} \ + && poetry config virtualenvs.create false \ + && poetry install --only=main RUN --mount=type=cache,target=/root/.cache \ set -ex \ diff --git a/poetry.lock b/poetry.lock index 39b36a989..6cbdae8f2 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2825,24 +2825,6 @@ type = "legacy" url = "https://pypi.tuna.tsinghua.edu.cn/simple" reference = "tsinghua" -[[package]] -name = "greenlet" -version = "2.0.2" -description = "Lightweight in-process concurrent programming" -optional = false -python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*" -files = [ - {file = "greenlet-2.0.2-cp311-cp311-linux_loongarch64.whl", hash = "sha256:65f6e0520d2cad7b0d5c7486e050ffe4d1e3a83b6a9f214e9bb51b56fb3ba163"}, -] - -[package.extras] -docs = ["Sphinx", "docutils (<0.18)"] -test = ["objgraph", "psutil"] - -[package.source] -type = "url" -url = "https://download.jumpserver.org/pypi/simple/greenlet/greenlet-2.0.2-cp311-cp311-linux_loongarch64.whl" - [[package]] name = "grpcio" version = "1.56.2" @@ -2905,23 +2887,6 @@ type = "legacy" url = "https://pypi.tuna.tsinghua.edu.cn/simple" reference = "tsinghua" -[[package]] -name = "grpcio" -version = "1.56.2" -description = "HTTP/2-based RPC framework" -optional = false -python-versions = ">=3.7" -files = [ - {file = "grpcio-1.56.2-cp311-cp311-linux_loongarch64.whl", hash = "sha256:c1625d6e03b33927cedbd79d13d6caa07173b67245f04373b814b3ae7dc050a7"}, -] - -[package.extras] -protobuf = ["grpcio-tools (>=1.56.2)"] - -[package.source] -type = "url" -url = "https://download.jumpserver.org/pypi/simple/grpcio/grpcio-1.56.2-cp311-cp311-linux_loongarch64.whl" - [[package]] name = "grpcio-status" version = "1.56.2" @@ -5351,9 +5316,11 @@ files = [ {file = "pymssql-2.2.8-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:049f2e3de919e8e02504780a21ebbf235e21ca8ed5c7538c5b6e705aa6c43d8c"}, {file = "pymssql-2.2.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0dd86d8e3e346e34f3f03d12e333747b53a1daa74374a727f4714d5b82ee0dd5"}, {file = "pymssql-2.2.8-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:508226a0df7cb6faeda9f8e84e85743690ca427d7b27af9a73d75fcf0c1eef6e"}, + {file = "pymssql-2.2.8-cp310-cp310-win_amd64.whl", hash = "sha256:47859887adeaf184766b5e0bc845dd23611f3808f9521552063bb36eabc10092"}, {file = "pymssql-2.2.8-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:d873e553374d5b1c57fe1c43bb75e3bcc2920678db1ef26f6bfed396c7d21b30"}, {file = "pymssql-2.2.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf31b8b76634c826a91f9999e15b7bfb0c051a0f53b319fd56481a67e5b903bb"}, {file = "pymssql-2.2.8-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:821945c2214fe666fd456c61e09a29a00e7719c9e136c801bffb3a254e9c579b"}, + {file = "pymssql-2.2.8-cp311-cp311-win_amd64.whl", hash = "sha256:cc85b609b4e60eac25fa38bbac1ff854fd2c2a276e0ca4a3614c6f97efb644bb"}, {file = "pymssql-2.2.8-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:ebe7f64d5278d807f14bea08951e02512bfbc6219fd4d4f15bb45ded885cf3d4"}, {file = "pymssql-2.2.8-cp36-cp36m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:253af3d39fc0235627966817262d5c4c94ad09dcbea59664748063470048c29c"}, {file = "pymssql-2.2.8-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c9d109df536dc5f7dd851a88d285a4c9cb12a9314b621625f4f5ab1197eb312"}, @@ -5369,11 +5336,13 @@ files = [ {file = "pymssql-2.2.8-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3906993300650844ec140aa58772c0f5f3e9e9d5709c061334fd1551acdcf066"}, {file = "pymssql-2.2.8-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:7309c7352e4a87c9995c3183ebfe0ff4135e955bb759109637673c61c9f0ca8d"}, {file = "pymssql-2.2.8-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:9b8d603cc1ec7ae585c5a409a1d45e8da067970c79dd550d45c238ae0aa0f79f"}, + {file = "pymssql-2.2.8-cp38-cp38-win_amd64.whl", hash = "sha256:293cb4d0339e221d877d6b19a1905082b658f0100a1e2ccc9dda10de58938901"}, {file = "pymssql-2.2.8-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:895041edd002a2e91d8a4faf0906b6fbfef29d9164bc6beb398421f5927fa40e"}, {file = "pymssql-2.2.8-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6b2d9c6d38a416c6f2db36ff1cd8e69f9a5387a46f9f4f612623192e0c9404b1"}, {file = "pymssql-2.2.8-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d63d6f25cf40fe6a03c49be2d4d337858362b8ab944d6684c268e4990807cf0c"}, {file = "pymssql-2.2.8-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:c83ad3ad20951f3a94894b354fa5fa9666dcd5ebb4a635dad507c7d1dd545833"}, {file = "pymssql-2.2.8-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:3933f7f082be74698eea835df51798dab9bc727d94d3d280bffc75ab9265f890"}, + {file = "pymssql-2.2.8-cp39-cp39-win_amd64.whl", hash = "sha256:de313375b90b0f554058992f35c4a4beb3f6ec2f5912d8cd6afb649f95b03a9f"}, {file = "pymssql-2.2.8.tar.gz", hash = "sha256:9baefbfbd07d0142756e2dfcaa804154361ac5806ab9381350aad4e780c3033e"}, ] @@ -7244,4 +7213,4 @@ reference = "tsinghua" [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "acdb324e0081968235e843be40803734f3ab814de44c90c4367fa0ef0801759d" +content-hash = "062b7b8ab32d3eeacc77b6b160764bc7083b599f32a653da3a1ccaa353041fc8" diff --git a/pyproject.toml b/pyproject.toml index 069fd91a4..3cc8c76b7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -103,11 +103,7 @@ django-proxy = "1.2.2" channels-redis = "4.1.0" python-daemon = "3.0.1" eventlet = "0.33.3" -# greenlet = "2.0.2" -greenlet = [ - { url = "https://download.jumpserver.org/pypi/simple/greenlet/greenlet-2.0.2-cp311-cp311-linux_loongarch64.whl", markers = "sys_platform == 'linux' and platform_machine == 'loongarch64'" }, - { version = "2.0.2", source = "tsinghua", markers = "platform_machine != 'loongarch64'" } -] +greenlet = "2.0.2" gunicorn = "21.2.0" celery = "5.3.1" flower = "2.0.0" @@ -142,13 +138,11 @@ pyhcl = "0.4.4" ipy = "1.1" netifaces = "^0.11.0" - [tool.poetry.group.dev.dependencies] daphne = "4.0.0" channels = "^4.0.0" channels-redis = "^4.1.0" - [tool.poetry.group.xpack.dependencies] qingcloud-sdk = "1.2.15" azure-mgmt-subscription = "3.1.1" @@ -156,11 +150,7 @@ azure-identity = "1.13.0" azure-mgmt-compute = "30.0.0" azure-mgmt-network = "23.1.0" google-cloud-compute = "1.13.0" -# grpcio = "1.56.2" -grpcio = [ - { url = "https://download.jumpserver.org/pypi/simple/grpcio/grpcio-1.56.2-cp311-cp311-linux_loongarch64.whl", markers = "sys_platform == 'linux' and platform_machine == 'loongarch64'" }, - { version = "1.56.2", source = "tsinghua", markers = "platform_machine != 'loongarch64'" } -] +grpcio = "1.56.2" alibabacloud-dysmsapi20170525 = "2.0.24" python-novaclient = "18.3.0" python-keystoneclient = "5.1.0" @@ -183,7 +173,6 @@ name = "tsinghua" url = "https://pypi.tuna.tsinghua.edu.cn/simple/" priority = "primary" - [[tool.poetry.source]] name = "PyPI" priority = "primary" From db4f05afbe9475793b9c26395994627f98c7faa9 Mon Sep 17 00:00:00 2001 From: jiangweidong Date: Mon, 14 Aug 2023 11:07:28 +0800 Subject: [PATCH 138/177] =?UTF-8?q?fix:=20=E8=A7=A3=E5=86=B3=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B=E6=A0=91=E5=B1=95=E5=BC=80=E5=85=A8=E9=83=A8=E6=97=B6?= =?UTF-8?q?=EF=BC=8C=E6=A0=B9=E8=8A=82=E7=82=B9=E6=97=A0=E9=99=90=E9=80=92?= =?UTF-8?q?=E5=BD=92=E5=B1=95=E5=BC=80=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/assets/const/types.py | 6 +++--- apps/perms/api/user_permission/tree/node_with_asset.py | 4 +++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/apps/assets/const/types.py b/apps/assets/const/types.py index afa0f6d05..8654002b9 100644 --- a/apps/assets/const/types.py +++ b/apps/assets/const/types.py @@ -224,7 +224,7 @@ class AllTypes(ChoicesMixin): return dict(id='ROOT', name=_('All types'), title=_('All types'), open=True, isParent=True) @classmethod - def get_tree_nodes(cls, resource_platforms, include_asset=False): + def get_tree_nodes(cls, resource_platforms, include_asset=False, get_root=True): from ..models import Platform platform_count = defaultdict(int) for platform_id in resource_platforms: @@ -239,10 +239,10 @@ class AllTypes(ChoicesMixin): category_type_mapper[p.category] += platform_count[p.id] tp_platforms[p.category + '_' + p.type].append(p) - nodes = [cls.get_root_nodes()] + nodes = [cls.get_root_nodes()] if get_root else [] for category, type_cls in cls.category_types(): # Category 格式化 - meta = {'type': 'category', 'category': category.value} + meta = {'type': 'category', 'category': category.value, '_type': category.value} category_node = cls.choice_to_node(category, 'ROOT', meta=meta) category_count = category_type_mapper.get(category, 0) category_node['name'] += f'({category_count})' diff --git a/apps/perms/api/user_permission/tree/node_with_asset.py b/apps/perms/api/user_permission/tree/node_with_asset.py index 72080247a..d67eda467 100644 --- a/apps/perms/api/user_permission/tree/node_with_asset.py +++ b/apps/perms/api/user_permission/tree/node_with_asset.py @@ -177,8 +177,10 @@ class UserPermedNodeChildrenWithAssetsAsCategoryTreeApi( return [] pid = f'ROOT_{str(assets[0].category).upper()}_{tp}' return self.serialize_assets(assets, pid=pid) + params = self.request.query_params + get_root = not list(filter(lambda x: params.get(x), ('type', 'n'))) resource_platforms = assets.order_by('id').values_list('platform_id', flat=True) - node_all = AllTypes.get_tree_nodes(resource_platforms) + node_all = AllTypes.get_tree_nodes(resource_platforms, get_root=get_root) pattern = re.compile(r'\(0\)?') nodes = [] for node in node_all: From d2f7396689da56ef5062686bebf37c624127ea24 Mon Sep 17 00:00:00 2001 From: Bai Date: Mon, 14 Aug 2023 11:20:58 +0800 Subject: [PATCH 139/177] perf: jms-storage==0.0.51 --- poetry.lock | 48 ++++++++++++++---------------------------------- pyproject.toml | 2 +- 2 files changed, 15 insertions(+), 35 deletions(-) diff --git a/poetry.lock b/poetry.lock index 39b36a989..f771d3ca6 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2259,44 +2259,24 @@ url = "https://pypi.tuna.tsinghua.edu.cn/simple" reference = "tsinghua" [[package]] -name = "elastic-transport" -version = "8.4.0" -description = "Transport classes and utilities shared among Python Elastic client libraries" +name = "elasticsearch" +version = "7.8.0" +description = "Python client for Elasticsearch" optional = false -python-versions = ">=3.6" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, <4" files = [ - {file = "elastic-transport-8.4.0.tar.gz", hash = "sha256:b9ad708ceb7fcdbc6b30a96f886609a109f042c0b9d9f2e44403b3133ba7ff10"}, - {file = "elastic_transport-8.4.0-py3-none-any.whl", hash = "sha256:19db271ab79c9f70f8c43f8f5b5111408781a6176b54ab2e54d713b6d9ceb815"}, + {file = "elasticsearch-7.8.0-py2.py3-none-any.whl", hash = "sha256:6fb566dd23b91b5871ce12212888674b4cf33374e92b71b1080916c931e44dcb"}, + {file = "elasticsearch-7.8.0.tar.gz", hash = "sha256:e637d8cf4e27e279b5ff8ca8edc0c086f4b5df4bf2b48e2f950b7833aca3a792"}, ] [package.dependencies] certifi = "*" -urllib3 = ">=1.26.2,<2" +urllib3 = ">=1.21.1" [package.extras] -develop = ["aiohttp", "mock", "pytest", "pytest-asyncio", "pytest-cov", "pytest-httpserver", "pytest-mock", "requests", "trustme"] - -[package.source] -type = "legacy" -url = "https://pypi.tuna.tsinghua.edu.cn/simple" -reference = "tsinghua" - -[[package]] -name = "elasticsearch" -version = "8.8.2" -description = "Python client for Elasticsearch" -optional = false -python-versions = ">=3.6, <4" -files = [ - {file = "elasticsearch-8.8.2-py3-none-any.whl", hash = "sha256:bffd6ce4faaacf90e6f617241773b3da8fb94e2e83554f5508e2fab92ca79643"}, - {file = "elasticsearch-8.8.2.tar.gz", hash = "sha256:bed8cf8fcc6c3be7c254b579de4c29afab021f373c832246f912d37aef3c6bd5"}, -] - -[package.dependencies] -elastic-transport = ">=8,<9" - -[package.extras] -async = ["aiohttp (>=3,<4)"] +async = ["aiohttp (>=3,<4)", "yarl"] +develop = ["black", "coverage", "jinja2", "mock", "pytest", "pytest-cov", "pyyaml", "requests (>=2.0.0,<3.0.0)", "sphinx (<1.7)", "sphinx-rtd-theme"] +docs = ["sphinx (<1.7)", "sphinx-rtd-theme"] requests = ["requests (>=2.4.0,<3.0.0)"] [package.source] @@ -3378,12 +3358,12 @@ reference = "tsinghua" [[package]] name = "jms-storage" -version = "0.0.50" +version = "0.0.51" description = "Jumpserver storage python sdk tools" optional = false python-versions = "*" files = [ - {file = "jms-storage-0.0.50.tar.gz", hash = "sha256:f757180e145a9eb3390b8b32663a5feebcb1e720a6f2c36cc16f726ac047f28b"}, + {file = "jms-storage-0.0.51.tar.gz", hash = "sha256:47a50ac4d952a21693b0e2f926f42fa0d02bc1fa8e507a8284059743b2b81911"}, ] [package.dependencies] @@ -3395,7 +3375,7 @@ certifi = "2023.7.22" chardet = "5.1.0" crcmod = "1.7" docutils = "0.20.1" -elasticsearch = "8.8.2" +elasticsearch = "7.8.0" esdk-obs-python = "3.21.4" idna = "3.4" oss2 = "2.18.1" @@ -7244,4 +7224,4 @@ reference = "tsinghua" [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "acdb324e0081968235e843be40803734f3ab814de44c90c4367fa0ef0801759d" +content-hash = "9bb582f0c306346ea364334a31c1b10b21e6beb5e3448b85cc397c744db6d2a9" diff --git a/pyproject.toml b/pyproject.toml index 069fd91a4..06d981f79 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -47,7 +47,7 @@ pynacl = "1.5.0" python-dateutil = "2.8.2" pyyaml = "6.0.1" requests = "2.31.0" -jms-storage = "0.0.50" +jms-storage = "0.0.51" simplejson = "3.19.1" six = "1.16.0" sshtunnel = "0.4.0" From bd642a0281e5524541a74941bc816da9fd50bef1 Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Mon, 14 Aug 2023 14:47:51 +0800 Subject: [PATCH 140/177] =?UTF-8?q?perf:=20=E7=BF=BB=E8=AF=91=20(#11266)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: feng <1304903146@qq.com> --- .../models/automations/change_secret.py | 2 +- apps/locale/ja/LC_MESSAGES/django.mo | 4 +- apps/locale/ja/LC_MESSAGES/django.po | 367 +++++++++--------- apps/locale/zh/LC_MESSAGES/django.mo | 4 +- apps/locale/zh/LC_MESSAGES/django.po | 335 +++++++++------- 5 files changed, 383 insertions(+), 329 deletions(-) diff --git a/apps/accounts/models/automations/change_secret.py b/apps/accounts/models/automations/change_secret.py index a2a1d42a2..0efeff049 100644 --- a/apps/accounts/models/automations/change_secret.py +++ b/apps/accounts/models/automations/change_secret.py @@ -86,7 +86,7 @@ class ChangeSecretRecord(JMSBaseModel): asset = models.ForeignKey('assets.Asset', on_delete=models.CASCADE, null=True) account = models.ForeignKey('accounts.Account', on_delete=models.CASCADE, null=True) old_secret = fields.EncryptTextField(blank=True, null=True, verbose_name=_('Old secret')) - new_secret = fields.EncryptTextField(blank=True, null=True, verbose_name=_('Secret')) + new_secret = fields.EncryptTextField(blank=True, null=True, verbose_name=_('New secret')) date_started = models.DateTimeField(blank=True, null=True, verbose_name=_('Date started')) date_finished = models.DateTimeField(blank=True, null=True, verbose_name=_('Date finished')) status = models.CharField(max_length=16, default='pending') diff --git a/apps/locale/ja/LC_MESSAGES/django.mo b/apps/locale/ja/LC_MESSAGES/django.mo index b0b33e499..30c700477 100644 --- a/apps/locale/ja/LC_MESSAGES/django.mo +++ b/apps/locale/ja/LC_MESSAGES/django.mo @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7bc2e996c082d5f9348277e69cd70b7b9884dc416d9d83e075656a4d8b9bc141 -size 152939 +oid sha256:293fbcdc14165ff1db355cef5c896f5f7b45fe7b22402d5735307bd6fcb8529f +size 154292 diff --git a/apps/locale/ja/LC_MESSAGES/django.po b/apps/locale/ja/LC_MESSAGES/django.po index d6f806295..169db0677 100644 --- a/apps/locale/ja/LC_MESSAGES/django.po +++ b/apps/locale/ja/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-08-10 18:22+0800\n" +"POT-Creation-Date: 2023-08-14 14:42+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -213,7 +213,7 @@ msgstr "HashiCorp Vault" #: terminal/serializers/session.py:26 #: terminal/templates/terminal/_msg_command_warning.html:4 #: terminal/templates/terminal/_msg_session_sharing.html:4 -#: tickets/models/ticket/apply_asset.py:16 xpack/plugins/cloud/models.py:212 +#: tickets/models/ticket/apply_asset.py:16 xpack/plugins/cloud/models.py:253 msgid "Asset" msgstr "資産" @@ -248,7 +248,7 @@ msgstr "ソース ID" #: terminal/backends/command/models.py:18 terminal/models/session/session.py:33 #: terminal/templates/terminal/_msg_command_warning.html:8 #: terminal/templates/terminal/_msg_session_sharing.html:8 -#: tickets/models/ticket/command_confirm.py:13 xpack/plugins/cloud/models.py:85 +#: tickets/models/ticket/command_confirm.py:13 xpack/plugins/cloud/models.py:89 msgid "Account" msgstr "アカウント" @@ -315,7 +315,7 @@ msgid "Trigger mode" msgstr "トリガーモード" #: accounts/models/automations/backup_account.py:105 audits/models.py:194 -#: terminal/models/session/sharing.py:121 xpack/plugins/cloud/models.py:168 +#: terminal/models/session/sharing.py:121 xpack/plugins/cloud/models.py:205 msgid "Reason" msgstr "理由" @@ -376,7 +376,6 @@ msgid "Secret type" msgstr "鍵の種類" #: accounts/models/automations/change_secret.py:20 -#: accounts/models/automations/change_secret.py:89 #: accounts/models/mixins/vault.py:48 accounts/serializers/account/base.py:19 #: authentication/models/temp_token.py:10 #: authentication/templates/authentication/_access_key_modal.html:31 @@ -409,7 +408,11 @@ msgstr "自動暗号化" #: accounts/models/automations/change_secret.py:88 msgid "Old secret" -msgstr "以前のパスワード" +msgstr "オリジナルキー" + +#: accounts/models/automations/change_secret.py:89 +msgid "New secret" +msgstr "新しい鍵" #: accounts/models/automations/change_secret.py:90 msgid "Date started" @@ -511,7 +514,8 @@ msgstr "アカウントの確認" #: terminal/models/component/storage.py:26 terminal/models/component/task.py:13 #: terminal/models/component/terminal.py:84 users/forms/profile.py:33 #: users/models/group.py:13 users/models/user.py:787 -#: xpack/plugins/cloud/models.py:28 +#: xpack/plugins/cloud/models.py:32 xpack/plugins/cloud/models.py:273 +#: xpack/plugins/cloud/serializers/task.py:68 msgid "Name" msgstr "名前" @@ -528,7 +532,7 @@ msgstr "特権アカウント" msgid "Is active" msgstr "アクティブです。" -#: accounts/models/template.py:19 +#: accounts/models/template.py:19 xpack/plugins/cloud/models.py:325 msgid "Account template" msgstr "アカウント テンプレート" @@ -767,7 +771,7 @@ msgstr "" #: terminal/models/component/endpoint.py:104 #: terminal/models/session/session.py:46 tickets/models/comment.py:32 #: tickets/models/ticket/general.py:297 users/models/user.py:826 -#: xpack/plugins/cloud/models.py:35 xpack/plugins/cloud/models.py:111 +#: xpack/plugins/cloud/models.py:39 xpack/plugins/cloud/models.py:109 msgid "Comment" msgstr "コメント" @@ -888,11 +892,13 @@ msgstr "警告" #: acls/models/base.py:37 assets/models/_user.py:51 #: assets/models/cmd_filter.py:76 terminal/models/component/endpoint.py:97 +#: xpack/plugins/cloud/models.py:275 msgid "Priority" msgstr "優先順位" #: acls/models/base.py:38 assets/models/_user.py:51 #: assets/models/cmd_filter.py:76 terminal/models/component/endpoint.py:98 +#: xpack/plugins/cloud/models.py:276 msgid "1-100, the lower the value will be match first" msgstr "1-100、低い値は最初に一致します" @@ -929,6 +935,7 @@ msgid "Command" msgstr "コマンド" #: acls/models/command_acl.py:17 assets/models/cmd_filter.py:59 +#: xpack/plugins/cloud/models.py:291 msgid "Regex" msgstr "正規情報" @@ -1025,7 +1032,7 @@ msgid "None of the reviewers belong to Organization `{}`" msgstr "いずれのレビューアも組織 '{}' に属していません" #: acls/serializers/rules/rules.py:20 -#: xpack/plugins/cloud/serializers/task.py:22 +#: xpack/plugins/cloud/serializers/task.py:133 msgid "IP address invalid: `{}`" msgstr "IPアドレスが無効: '{}'" @@ -1053,7 +1060,7 @@ msgstr "期間" msgid "Applications" msgstr "アプリケーション" -#: applications/models.py:16 xpack/plugins/cloud/models.py:33 +#: applications/models.py:16 xpack/plugins/cloud/models.py:37 #: xpack/plugins/cloud/serializers/account.py:63 msgid "Attrs" msgstr "ツールバーの" @@ -1451,14 +1458,13 @@ msgstr "アドレス" #: assets/models/asset/common.py:151 assets/models/platform.py:119 #: authentication/serializers/connect_token_secret.py:115 -#: perms/serializers/user_permission.py:24 -#: xpack/plugins/cloud/serializers/account_attrs.py:196 +#: perms/serializers/user_permission.py:24 xpack/plugins/cloud/models.py:321 msgid "Platform" msgstr "プラットフォーム" #: assets/models/asset/common.py:153 assets/models/domain.py:21 #: authentication/serializers/connect_token_secret.py:133 -#: perms/serializers/user_permission.py:29 +#: perms/serializers/user_permission.py:29 xpack/plugins/cloud/models.py:323 msgid "Domain" msgstr "ドメイン" @@ -1534,8 +1540,8 @@ msgstr "アセットの自動化タスク" #: terminal/models/component/status.py:30 terminal/serializers/applet.py:18 #: terminal/serializers/applet_host.py:115 tickets/models/ticket/general.py:283 #: tickets/serializers/super_ticket.py:13 -#: tickets/serializers/ticket/ticket.py:20 xpack/plugins/cloud/models.py:164 -#: xpack/plugins/cloud/models.py:216 +#: tickets/serializers/ticket/ticket.py:20 xpack/plugins/cloud/models.py:201 +#: xpack/plugins/cloud/models.py:257 msgid "Status" msgstr "ステータス" @@ -1599,7 +1605,7 @@ msgstr "資産グループ" #: assets/models/group.py:31 assets/models/platform.py:19 #: assets/serializers/platform.py:113 -#: xpack/plugins/cloud/providers/nutanix.py:32 +#: xpack/plugins/cloud/providers/nutanix.py:30 msgid "Default" msgstr "デフォルト" @@ -1649,7 +1655,7 @@ msgid "Parent key" msgstr "親キー" #: assets/models/node.py:558 perms/serializers/permission.py:35 -#: tickets/models/ticket/apply_asset.py:14 xpack/plugins/cloud/models.py:96 +#: tickets/models/ticket/apply_asset.py:14 xpack/plugins/cloud/models.py:322 msgid "Node" msgstr "ノード" @@ -1790,7 +1796,8 @@ msgstr "" #: assets/serializers/asset/common.py:124 assets/serializers/platform.py:129 #: authentication/serializers/connect_token_secret.py:29 #: authentication/serializers/connect_token_secret.py:72 -#: perms/serializers/user_permission.py:25 xpack/plugins/cloud/models.py:99 +#: perms/serializers/user_permission.py:25 xpack/plugins/cloud/models.py:324 +#: xpack/plugins/cloud/serializers/task.py:31 msgid "Protocols" msgstr "プロトコル" @@ -3739,22 +3746,16 @@ msgid "Python" msgstr "Python" #: ops/const.py:52 -#, fuzzy -#| msgid "MySQL port" msgid "MySQL" -msgstr "MySQL ポート" +msgstr "MySQL" #: ops/const.py:53 -#, fuzzy -#| msgid "PostgreSQL port" msgid "PostgreSQL" -msgstr "PostgreSQL ポート" +msgstr "PostgreSQL" #: ops/const.py:54 -#, fuzzy -#| msgid "Server url" msgid "SQLServer" -msgstr "サービス側アドレス" +msgstr "SQLServer" #: ops/const.py:60 msgid "Timeout" @@ -3821,7 +3822,7 @@ msgid "Date last run" msgstr "最終実行日" #: ops/models/base.py:51 ops/models/job.py:217 -#: xpack/plugins/cloud/models.py:162 +#: xpack/plugins/cloud/models.py:199 msgid "Result" msgstr "結果" @@ -4382,7 +4383,7 @@ msgid "View permission tree" msgstr "権限ツリーの表示" #: settings/api/dingtalk.py:31 settings/api/feishu.py:36 -#: settings/api/sms.py:155 settings/api/vault.py:39 settings/api/wecom.py:37 +#: settings/api/sms.py:155 settings/api/vault.py:40 settings/api/wecom.py:37 msgid "Test success" msgstr "テストの成功" @@ -5166,10 +5167,8 @@ msgstr "" "はできません。" #: settings/serializers/security.py:39 -#, fuzzy -#| msgid "MFA not enabled" msgid "Not enabled" -msgstr "MFAが有効化されていません" +msgstr "有効化されていません" #: settings/serializers/security.py:40 msgid "All users" @@ -5880,22 +5879,16 @@ msgid "Risk level" msgstr "リスクレベル" #: terminal/connect_methods.py:29 -#, fuzzy -#| msgid "Client" msgid "SSH Client" -msgstr "クライアント" +msgstr "SSH クライアント" #: terminal/connect_methods.py:30 -#, fuzzy -#| msgid "SSH key" msgid "SSH Guide" -msgstr "SSH キー" +msgstr "SSH ガイド人" #: terminal/connect_methods.py:31 -#, fuzzy -#| msgid "Client" msgid "SFTP Client" -msgstr "クライアント" +msgstr "SFTP クライアント" #: terminal/connect_methods.py:33 msgid "DB Guide" @@ -5906,10 +5899,8 @@ msgid "DB Client" msgstr "データベース クライアント" #: terminal/connect_methods.py:36 -#, fuzzy -#| msgid "Remote Address" msgid "Remote Desktop" -msgstr "リモートアドレス" +msgstr "リモートデスクトップ" #: terminal/const.py:12 msgid "Review & Reject" @@ -6516,7 +6507,7 @@ msgstr "アクセスキー" msgid "Access key secret" msgstr "アクセスキーシークレット" -#: terminal/serializers/storage.py:67 xpack/plugins/cloud/models.py:209 +#: terminal/serializers/storage.py:67 xpack/plugins/cloud/models.py:250 msgid "Region" msgstr "リージョン" @@ -7078,7 +7069,7 @@ msgid "Not a valid ssh public key" msgstr "有効なssh公開鍵ではありません" #: users/forms/profile.py:173 users/models/user.py:820 -#: xpack/plugins/cloud/serializers/account_attrs.py:206 +#: xpack/plugins/cloud/serializers/account_attrs.py:203 msgid "Public key" msgstr "公開キー" @@ -7107,7 +7098,7 @@ msgid "OTP secret key" msgstr "OTP 秘密" #: users/models/user.py:817 -#: xpack/plugins/cloud/serializers/account_attrs.py:209 +#: xpack/plugins/cloud/serializers/account_attrs.py:206 msgid "Private key" msgstr "ssh秘密鍵" @@ -7546,11 +7537,11 @@ msgstr "パスワードの成功をリセットし、ログインページに戻 msgid "XPACK" msgstr "XPack" -#: xpack/plugins/cloud/api.py:38 +#: xpack/plugins/cloud/api.py:56 msgid "Test connection successful" msgstr "テスト接続成功" -#: xpack/plugins/cloud/api.py:40 +#: xpack/plugins/cloud/api.py:58 msgid "Test connection failed: {}" msgstr "テスト接続に失敗しました: {}" @@ -7638,7 +7629,7 @@ msgstr "プライベートIP" msgid "Public IP" msgstr "パブリックIP" -#: xpack/plugins/cloud/const.py:38 +#: xpack/plugins/cloud/const.py:38 xpack/plugins/cloud/models.py:295 msgid "Instance name" msgstr "インスタンス名" @@ -7666,78 +7657,158 @@ msgstr "同期済み" msgid "Released" msgstr "リリース済み" +#: xpack/plugins/cloud/manager.py:53 +msgid "Account unavailable" +msgstr "利用できないアカウント" + #: xpack/plugins/cloud/meta.py:9 msgid "Cloud center" msgstr "クラウドセンター" -#: xpack/plugins/cloud/models.py:30 +#: xpack/plugins/cloud/models.py:34 msgid "Provider" msgstr "プロバイダー" -#: xpack/plugins/cloud/models.py:34 +#: xpack/plugins/cloud/models.py:38 msgid "Validity" msgstr "有効性" -#: xpack/plugins/cloud/models.py:39 +#: xpack/plugins/cloud/models.py:43 msgid "Cloud account" msgstr "クラウドアカウント" -#: xpack/plugins/cloud/models.py:41 +#: xpack/plugins/cloud/models.py:45 msgid "Test cloud account" msgstr "クラウドアカウントのテスト" -#: xpack/plugins/cloud/models.py:88 xpack/plugins/cloud/serializers/task.py:36 +#: xpack/plugins/cloud/models.py:92 xpack/plugins/cloud/serializers/task.py:147 msgid "Regions" msgstr "リージョン" -#: xpack/plugins/cloud/models.py:91 +#: xpack/plugins/cloud/models.py:95 msgid "Hostname strategy" msgstr "ホスト名戦略" -#: xpack/plugins/cloud/models.py:102 xpack/plugins/cloud/serializers/task.py:39 +#: xpack/plugins/cloud/models.py:100 +#: xpack/plugins/cloud/serializers/task.py:150 msgid "IP network segment group" msgstr "IPネットワークセグメントグループ" -#: xpack/plugins/cloud/models.py:105 xpack/plugins/cloud/serializers/task.py:44 +#: xpack/plugins/cloud/models.py:103 +#: xpack/plugins/cloud/serializers/task.py:155 msgid "Sync IP type" msgstr "同期IPタイプ" -#: xpack/plugins/cloud/models.py:108 xpack/plugins/cloud/serializers/task.py:61 +#: xpack/plugins/cloud/models.py:106 +#: xpack/plugins/cloud/serializers/task.py:173 msgid "Always update" msgstr "常に更新" -#: xpack/plugins/cloud/models.py:114 +#: xpack/plugins/cloud/models.py:112 msgid "Date last sync" msgstr "最終同期日" -#: xpack/plugins/cloud/models.py:119 xpack/plugins/cloud/models.py:160 +#: xpack/plugins/cloud/models.py:115 xpack/plugins/cloud/models.py:313 +#: xpack/plugins/cloud/models.py:337 +msgid "Strategy" +msgstr "戦略" + +#: xpack/plugins/cloud/models.py:120 xpack/plugins/cloud/models.py:197 msgid "Sync instance task" msgstr "インスタンスの同期タスク" -#: xpack/plugins/cloud/models.py:171 xpack/plugins/cloud/models.py:219 +#: xpack/plugins/cloud/models.py:208 xpack/plugins/cloud/models.py:260 msgid "Date sync" msgstr "日付の同期" -#: xpack/plugins/cloud/models.py:175 +#: xpack/plugins/cloud/models.py:212 +msgid "Sync instance snapshot" +msgstr "インスタンススナップショットの同期" + +#: xpack/plugins/cloud/models.py:216 msgid "Sync instance task execution" msgstr "インスタンスタスクの同期実行" -#: xpack/plugins/cloud/models.py:199 +#: xpack/plugins/cloud/models.py:240 msgid "Sync task" msgstr "同期タスク" -#: xpack/plugins/cloud/models.py:203 +#: xpack/plugins/cloud/models.py:244 msgid "Sync instance task history" msgstr "インスタンスタスク履歴の同期" -#: xpack/plugins/cloud/models.py:206 +#: xpack/plugins/cloud/models.py:247 msgid "Instance" msgstr "インスタンス" -#: xpack/plugins/cloud/models.py:223 +#: xpack/plugins/cloud/models.py:264 msgid "Sync instance detail" msgstr "同期インスタンスの詳細" +#: xpack/plugins/cloud/models.py:281 +msgid "Task strategy" +msgstr "タスク戦略" + +#: xpack/plugins/cloud/models.py:285 +msgid "Exact" +msgstr "" + +#: xpack/plugins/cloud/models.py:286 +msgid "Not" +msgstr "否" + +#: xpack/plugins/cloud/models.py:287 +msgid "In" +msgstr "イン" + +#: xpack/plugins/cloud/models.py:288 +msgid "Contains" +msgstr "含む" + +#: xpack/plugins/cloud/models.py:289 +msgid "Startswith" +msgstr "始まる" + +#: xpack/plugins/cloud/models.py:290 +msgid "Endswith" +msgstr "終わる" + +#: xpack/plugins/cloud/models.py:296 +msgid "Instance platform" +msgstr "インスタンス名" + +#: xpack/plugins/cloud/models.py:297 +msgid "Instance address" +msgstr "インスタンスアドレス" + +#: xpack/plugins/cloud/models.py:304 +msgid "Rule attr" +msgstr "ルール属性" + +#: xpack/plugins/cloud/models.py:308 +msgid "Rule match" +msgstr "ルール一致" + +#: xpack/plugins/cloud/models.py:310 +msgid "Rule value" +msgstr "ルール値" + +#: xpack/plugins/cloud/models.py:317 +msgid "Strategy rule" +msgstr "戦略ルール" + +#: xpack/plugins/cloud/models.py:332 +msgid "Action attr" +msgstr "アクション属性" + +#: xpack/plugins/cloud/models.py:334 +msgid "Action value" +msgstr "アクション値" + +#: xpack/plugins/cloud/models.py:341 +msgid "Strategy action" +msgstr "戦略アクション" + #: xpack/plugins/cloud/providers/aws_international.py:18 msgid "China (Beijing)" msgstr "中国 (北京)" @@ -7846,7 +7917,7 @@ msgid "CN East-Suzhou" msgstr "華東-蘇州" #: xpack/plugins/cloud/providers/baiducloud.py:57 -#: xpack/plugins/cloud/providers/huaweicloud.py:50 +#: xpack/plugins/cloud/providers/huaweicloud.py:49 msgid "CN-Hong Kong" msgstr "中国-香港" @@ -7864,66 +7935,66 @@ msgid "CN East-Shanghai" msgstr "華東-上海" #: xpack/plugins/cloud/providers/baiducloud.py:61 -#: xpack/plugins/cloud/providers/huaweicloud.py:49 +#: xpack/plugins/cloud/providers/huaweicloud.py:51 msgid "AP-Singapore" msgstr "アジア太平洋-シンガポール" -#: xpack/plugins/cloud/providers/huaweicloud.py:37 -msgid "AF-Johannesburg" -msgstr "アフリカ-ヨハネスブルク" - -#: xpack/plugins/cloud/providers/huaweicloud.py:38 -msgid "CN North-Beijing4" -msgstr "華北-北京4" - #: xpack/plugins/cloud/providers/huaweicloud.py:39 msgid "CN North-Beijing1" msgstr "華北-北京1" #: xpack/plugins/cloud/providers/huaweicloud.py:40 -msgid "CN East-Shanghai2" -msgstr "華東-上海2" +msgid "CN North-Beijing4" +msgstr "華北-北京4" #: xpack/plugins/cloud/providers/huaweicloud.py:41 -msgid "CN East-Shanghai1" -msgstr "華東-上海1" - -#: xpack/plugins/cloud/providers/huaweicloud.py:43 -msgid "LA-Mexico City1" -msgstr "LA-メキシコCity1" - -#: xpack/plugins/cloud/providers/huaweicloud.py:44 -msgid "LA-Santiago" -msgstr "ラテンアメリカ-サンディエゴ" - -#: xpack/plugins/cloud/providers/huaweicloud.py:45 -msgid "LA-Sao Paulo1" -msgstr "ラミー・サンパウロ1" - -#: xpack/plugins/cloud/providers/huaweicloud.py:46 -msgid "EU-Paris" -msgstr "ヨーロッパ-パリ" - -#: xpack/plugins/cloud/providers/huaweicloud.py:47 -msgid "CN Southwest-Guiyang1" -msgstr "南西-貴陽1" - -#: xpack/plugins/cloud/providers/huaweicloud.py:48 -msgid "AP-Bangkok" -msgstr "アジア太平洋-バンコク" - -#: xpack/plugins/cloud/providers/huaweicloud.py:52 -msgid "CN Northeast-Dalian" -msgstr "华北-大连" - -#: xpack/plugins/cloud/providers/huaweicloud.py:53 msgid "CN North-Ulanqab1" msgstr "華北-ウランチャブ一" -#: xpack/plugins/cloud/providers/huaweicloud.py:54 +#: xpack/plugins/cloud/providers/huaweicloud.py:43 +msgid "CN South-Shenzhen" +msgstr "華南-広州" + +#: xpack/plugins/cloud/providers/huaweicloud.py:44 msgid "CN South-Guangzhou-InvitationOnly" msgstr "華南-広州-友好ユーザー環境" +#: xpack/plugins/cloud/providers/huaweicloud.py:45 +msgid "CN East-Shanghai2" +msgstr "華東-上海2" + +#: xpack/plugins/cloud/providers/huaweicloud.py:46 +msgid "CN East-Shanghai1" +msgstr "華東-上海1" + +#: xpack/plugins/cloud/providers/huaweicloud.py:48 +msgid "CN Southwest-Guiyang1" +msgstr "南西-貴陽1" + +#: xpack/plugins/cloud/providers/huaweicloud.py:50 +msgid "AP-Bangkok" +msgstr "アジア太平洋-バンコク" + +#: xpack/plugins/cloud/providers/huaweicloud.py:53 +msgid "AF-Johannesburg" +msgstr "アフリカ-ヨハネスブルク" + +#: xpack/plugins/cloud/providers/huaweicloud.py:54 +msgid "LA-Mexico City1" +msgstr "LA-メキシコCity1" + +#: xpack/plugins/cloud/providers/huaweicloud.py:55 +msgid "LA-Santiago" +msgstr "ラテンアメリカ-サンディエゴ" + +#: xpack/plugins/cloud/providers/huaweicloud.py:56 +msgid "LA-Sao Paulo1" +msgstr "ラミー・サンパウロ1" + +#: xpack/plugins/cloud/providers/huaweicloud.py:58 +msgid "TR-Istanbul" +msgstr "" + #: xpack/plugins/cloud/providers/jdcloud.py:126 msgid "CN East-Suqian" msgstr "華東-宿遷" @@ -7952,7 +8023,7 @@ msgstr "サブスクリプションID" #: xpack/plugins/cloud/serializers/account_attrs.py:103 #: xpack/plugins/cloud/serializers/account_attrs.py:119 #: xpack/plugins/cloud/serializers/account_attrs.py:149 -#: xpack/plugins/cloud/serializers/account_attrs.py:202 +#: xpack/plugins/cloud/serializers/account_attrs.py:199 msgid "API Endpoint" msgstr "APIエンドポイント" @@ -8018,11 +8089,11 @@ msgstr "テストポート" msgid "Test timeout" msgstr "テストタイムアウト" -#: xpack/plugins/cloud/serializers/account_attrs.py:212 +#: xpack/plugins/cloud/serializers/account_attrs.py:209 msgid "Project" msgstr "project" -#: xpack/plugins/cloud/serializers/task.py:28 +#: xpack/plugins/cloud/serializers/task.py:139 msgid "" "Only instances matching the IP range will be synced.
    If the instance " "contains multiple IP addresses, the first IP address that matches will be " @@ -8036,11 +8107,11 @@ msgstr "" "ドレスをランダムに一致させることを意味します。
    例: " "192.168.1.0/24,10.1.1.1-10.1.1.20。" -#: xpack/plugins/cloud/serializers/task.py:34 +#: xpack/plugins/cloud/serializers/task.py:145 msgid "History count" msgstr "実行回数" -#: xpack/plugins/cloud/serializers/task.py:35 +#: xpack/plugins/cloud/serializers/task.py:146 msgid "Instance count" msgstr "インスタンス数" @@ -8052,10 +8123,6 @@ msgstr "同期インスタンス タスクを実行する" msgid "Period clean sync instance task execution" msgstr "同期インスタンス タスクの実行記録を定期的にクリアする" -#: xpack/plugins/cloud/utils.py:68 -msgid "Account unavailable" -msgstr "利用できないアカウント" - #: xpack/plugins/interface/api.py:52 msgid "Restore default successfully." msgstr "デフォルトの復元に成功しました。" @@ -8120,59 +8187,11 @@ msgstr "究極のエディション" msgid "Community edition" msgstr "コミュニティ版" -#~ msgid "Strategy" -#~ msgstr "戦略" +#~ msgid "EU-Paris" +#~ msgstr "ヨーロッパ-パリ" -#~ msgid "Sync instance snapshot" -#~ msgstr "インスタンススナップショットの同期" - -#~ msgid "Task strategy" -#~ msgstr "タスク戦略" - -#~ msgid "Not" -#~ msgstr "否" - -#~ msgid "In" -#~ msgstr "イン" - -#~ msgid "Contains" -#~ msgstr "含む" - -#~ msgid "Startswith" -#~ msgstr "始まる" - -#~ msgid "Endswith" -#~ msgstr "終わる" - -#~ msgid "Instance platform" -#~ msgstr "インスタンス名" - -#~ msgid "Instance address" -#~ msgstr "インスタンスアドレス" - -#~ msgid "Rule attr" -#~ msgstr "ルール属性" - -#~ msgid "Rule match" -#~ msgstr "ルール一致" - -#~ msgid "Rule value" -#~ msgstr "ルール値" - -#~ msgid "Strategy rule" -#~ msgstr "戦略ルール" - -#~ msgid "Action attr" -#~ msgstr "アクション属性" - -#~ msgid "Action value" -#~ msgstr "アクション値" - -#~ msgid "Strategy action" -#~ msgstr "戦略アクション" - -#~ msgid "CN South-Shenzhen" -#~ msgstr "華南-広州" +#~ msgid "CN Northeast-Dalian" +#~ msgstr "华北-大连" #~ msgid "Current only support login from AD/LDAP" #~ msgstr "現在、AD/LDAPからのログインのみサポートしています" diff --git a/apps/locale/zh/LC_MESSAGES/django.mo b/apps/locale/zh/LC_MESSAGES/django.mo index eb66df73f..6c53bdf64 100644 --- a/apps/locale/zh/LC_MESSAGES/django.mo +++ b/apps/locale/zh/LC_MESSAGES/django.mo @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d1a6a042b4813d67922799caf3ac81ce3f1e831aed1a771dc9a16dab147a0692 -size 125568 +oid sha256:6edfda171c544a964c46157c91142bef031c69971ca837cd933b60b1fdb925ba +size 126380 diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po index 3c1119e4c..d459400d9 100644 --- a/apps/locale/zh/LC_MESSAGES/django.po +++ b/apps/locale/zh/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: JumpServer 0.3.3\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-08-10 18:22+0800\n" +"POT-Creation-Date: 2023-08-14 14:39+0800\n" "PO-Revision-Date: 2021-05-20 10:54+0800\n" "Last-Translator: ibuler \n" "Language-Team: JumpServer team\n" @@ -212,7 +212,7 @@ msgstr "HashiCorp Vault" #: terminal/serializers/session.py:26 #: terminal/templates/terminal/_msg_command_warning.html:4 #: terminal/templates/terminal/_msg_session_sharing.html:4 -#: tickets/models/ticket/apply_asset.py:16 xpack/plugins/cloud/models.py:212 +#: tickets/models/ticket/apply_asset.py:16 xpack/plugins/cloud/models.py:253 msgid "Asset" msgstr "资产" @@ -247,7 +247,7 @@ msgstr "来源 ID" #: terminal/backends/command/models.py:18 terminal/models/session/session.py:33 #: terminal/templates/terminal/_msg_command_warning.html:8 #: terminal/templates/terminal/_msg_session_sharing.html:8 -#: tickets/models/ticket/command_confirm.py:13 xpack/plugins/cloud/models.py:85 +#: tickets/models/ticket/command_confirm.py:13 xpack/plugins/cloud/models.py:89 msgid "Account" msgstr "账号" @@ -314,7 +314,7 @@ msgid "Trigger mode" msgstr "触发模式" #: accounts/models/automations/backup_account.py:105 audits/models.py:194 -#: terminal/models/session/sharing.py:121 xpack/plugins/cloud/models.py:168 +#: terminal/models/session/sharing.py:121 xpack/plugins/cloud/models.py:205 msgid "Reason" msgstr "原因" @@ -375,7 +375,6 @@ msgid "Secret type" msgstr "密文类型" #: accounts/models/automations/change_secret.py:20 -#: accounts/models/automations/change_secret.py:89 #: accounts/models/mixins/vault.py:48 accounts/serializers/account/base.py:19 #: authentication/models/temp_token.py:10 #: authentication/templates/authentication/_access_key_modal.html:31 @@ -408,7 +407,11 @@ msgstr "自动化改密" #: accounts/models/automations/change_secret.py:88 msgid "Old secret" -msgstr "原密码" +msgstr "原密钥" + +#: accounts/models/automations/change_secret.py:89 +msgid "New secret" +msgstr "新密钥" #: accounts/models/automations/change_secret.py:90 msgid "Date started" @@ -510,7 +513,8 @@ msgstr "账号验证" #: terminal/models/component/storage.py:26 terminal/models/component/task.py:13 #: terminal/models/component/terminal.py:84 users/forms/profile.py:33 #: users/models/group.py:13 users/models/user.py:787 -#: xpack/plugins/cloud/models.py:28 +#: xpack/plugins/cloud/models.py:32 xpack/plugins/cloud/models.py:273 +#: xpack/plugins/cloud/serializers/task.py:68 msgid "Name" msgstr "名称" @@ -527,7 +531,7 @@ msgstr "特权账号" msgid "Is active" msgstr "激活" -#: accounts/models/template.py:19 +#: accounts/models/template.py:19 xpack/plugins/cloud/models.py:325 msgid "Account template" msgstr "账号模版" @@ -767,7 +771,7 @@ msgstr "" #: terminal/models/component/endpoint.py:104 #: terminal/models/session/session.py:46 tickets/models/comment.py:32 #: tickets/models/ticket/general.py:297 users/models/user.py:826 -#: xpack/plugins/cloud/models.py:35 xpack/plugins/cloud/models.py:111 +#: xpack/plugins/cloud/models.py:39 xpack/plugins/cloud/models.py:109 msgid "Comment" msgstr "备注" @@ -888,11 +892,13 @@ msgstr "告警" #: acls/models/base.py:37 assets/models/_user.py:51 #: assets/models/cmd_filter.py:76 terminal/models/component/endpoint.py:97 +#: xpack/plugins/cloud/models.py:275 msgid "Priority" msgstr "优先级" #: acls/models/base.py:38 assets/models/_user.py:51 #: assets/models/cmd_filter.py:76 terminal/models/component/endpoint.py:98 +#: xpack/plugins/cloud/models.py:276 msgid "1-100, the lower the value will be match first" msgstr "优先级可选范围为 1-100 (数值越小越优先)" @@ -929,6 +935,7 @@ msgid "Command" msgstr "命令" #: acls/models/command_acl.py:17 assets/models/cmd_filter.py:59 +#: xpack/plugins/cloud/models.py:291 msgid "Regex" msgstr "正则表达式" @@ -1024,7 +1031,7 @@ msgid "None of the reviewers belong to Organization `{}`" msgstr "所有复核人都不属于组织 `{}`" #: acls/serializers/rules/rules.py:20 -#: xpack/plugins/cloud/serializers/task.py:22 +#: xpack/plugins/cloud/serializers/task.py:133 msgid "IP address invalid: `{}`" msgstr "IP 地址无效: `{}`" @@ -1052,7 +1059,7 @@ msgstr "时段" msgid "Applications" msgstr "应用管理" -#: applications/models.py:16 xpack/plugins/cloud/models.py:33 +#: applications/models.py:16 xpack/plugins/cloud/models.py:37 #: xpack/plugins/cloud/serializers/account.py:63 msgid "Attrs" msgstr "属性" @@ -1449,14 +1456,13 @@ msgstr "地址" #: assets/models/asset/common.py:151 assets/models/platform.py:119 #: authentication/serializers/connect_token_secret.py:115 -#: perms/serializers/user_permission.py:24 -#: xpack/plugins/cloud/serializers/account_attrs.py:196 +#: perms/serializers/user_permission.py:24 xpack/plugins/cloud/models.py:321 msgid "Platform" msgstr "系统平台" #: assets/models/asset/common.py:153 assets/models/domain.py:21 #: authentication/serializers/connect_token_secret.py:133 -#: perms/serializers/user_permission.py:29 +#: perms/serializers/user_permission.py:29 xpack/plugins/cloud/models.py:323 msgid "Domain" msgstr "网域" @@ -1532,8 +1538,8 @@ msgstr "资产自动化任务" #: terminal/models/component/status.py:30 terminal/serializers/applet.py:18 #: terminal/serializers/applet_host.py:115 tickets/models/ticket/general.py:283 #: tickets/serializers/super_ticket.py:13 -#: tickets/serializers/ticket/ticket.py:20 xpack/plugins/cloud/models.py:164 -#: xpack/plugins/cloud/models.py:216 +#: tickets/serializers/ticket/ticket.py:20 xpack/plugins/cloud/models.py:201 +#: xpack/plugins/cloud/models.py:257 msgid "Status" msgstr "状态" @@ -1597,7 +1603,7 @@ msgstr "资产组" #: assets/models/group.py:31 assets/models/platform.py:19 #: assets/serializers/platform.py:113 -#: xpack/plugins/cloud/providers/nutanix.py:32 +#: xpack/plugins/cloud/providers/nutanix.py:30 msgid "Default" msgstr "默认" @@ -1647,7 +1653,7 @@ msgid "Parent key" msgstr "ssh私钥" #: assets/models/node.py:558 perms/serializers/permission.py:35 -#: tickets/models/ticket/apply_asset.py:14 xpack/plugins/cloud/models.py:96 +#: tickets/models/ticket/apply_asset.py:14 xpack/plugins/cloud/models.py:322 msgid "Node" msgstr "节点" @@ -1786,7 +1792,8 @@ msgstr "资产中批量更新平台,不符合平台类型跳过的资产" #: assets/serializers/asset/common.py:124 assets/serializers/platform.py:129 #: authentication/serializers/connect_token_secret.py:29 #: authentication/serializers/connect_token_secret.py:72 -#: perms/serializers/user_permission.py:25 xpack/plugins/cloud/models.py:99 +#: perms/serializers/user_permission.py:25 xpack/plugins/cloud/models.py:324 +#: xpack/plugins/cloud/serializers/task.py:31 msgid "Protocols" msgstr "协议组" @@ -3773,7 +3780,7 @@ msgid "Date last run" msgstr "最后运行日期" #: ops/models/base.py:51 ops/models/job.py:217 -#: xpack/plugins/cloud/models.py:162 +#: xpack/plugins/cloud/models.py:199 msgid "Result" msgstr "结果" @@ -4332,7 +4339,7 @@ msgid "View permission tree" msgstr "查看授权树" #: settings/api/dingtalk.py:31 settings/api/feishu.py:36 -#: settings/api/sms.py:155 settings/api/vault.py:39 settings/api/wecom.py:37 +#: settings/api/sms.py:155 settings/api/vault.py:40 settings/api/wecom.py:37 msgid "Test success" msgstr "测试成功" @@ -6413,7 +6420,7 @@ msgstr "Access key ID(AK)" msgid "Access key secret" msgstr "Access key secret(SK)" -#: terminal/serializers/storage.py:67 xpack/plugins/cloud/models.py:209 +#: terminal/serializers/storage.py:67 xpack/plugins/cloud/models.py:250 msgid "Region" msgstr "地域" @@ -6969,7 +6976,7 @@ msgid "Not a valid ssh public key" msgstr "SSH密钥不合法" #: users/forms/profile.py:173 users/models/user.py:820 -#: xpack/plugins/cloud/serializers/account_attrs.py:206 +#: xpack/plugins/cloud/serializers/account_attrs.py:203 msgid "Public key" msgstr "SSH公钥" @@ -6998,7 +7005,7 @@ msgid "OTP secret key" msgstr "OTP 密钥" #: users/models/user.py:817 -#: xpack/plugins/cloud/serializers/account_attrs.py:209 +#: xpack/plugins/cloud/serializers/account_attrs.py:206 msgid "Private key" msgstr "ssh私钥" @@ -7424,11 +7431,11 @@ msgstr "重置密码成功,返回到登录页面" msgid "XPACK" msgstr "XPack" -#: xpack/plugins/cloud/api.py:38 +#: xpack/plugins/cloud/api.py:56 msgid "Test connection successful" msgstr "测试成功" -#: xpack/plugins/cloud/api.py:40 +#: xpack/plugins/cloud/api.py:58 msgid "Test connection failed: {}" msgstr "测试连接失败:{}" @@ -7516,7 +7523,7 @@ msgstr "私有IP" msgid "Public IP" msgstr "公网IP" -#: xpack/plugins/cloud/const.py:38 +#: xpack/plugins/cloud/const.py:38 xpack/plugins/cloud/models.py:295 msgid "Instance name" msgstr "实例名称" @@ -7544,78 +7551,158 @@ msgstr "已同步" msgid "Released" msgstr "已释放" +#: xpack/plugins/cloud/manager.py:53 +msgid "Account unavailable" +msgstr "账号无效" + #: xpack/plugins/cloud/meta.py:9 msgid "Cloud center" msgstr "云管中心" -#: xpack/plugins/cloud/models.py:30 +#: xpack/plugins/cloud/models.py:34 msgid "Provider" msgstr "云服务商" -#: xpack/plugins/cloud/models.py:34 +#: xpack/plugins/cloud/models.py:38 msgid "Validity" msgstr "有效" -#: xpack/plugins/cloud/models.py:39 +#: xpack/plugins/cloud/models.py:43 msgid "Cloud account" msgstr "云账号" -#: xpack/plugins/cloud/models.py:41 +#: xpack/plugins/cloud/models.py:45 msgid "Test cloud account" msgstr "测试云账号" -#: xpack/plugins/cloud/models.py:88 xpack/plugins/cloud/serializers/task.py:36 +#: xpack/plugins/cloud/models.py:92 xpack/plugins/cloud/serializers/task.py:147 msgid "Regions" msgstr "地域" -#: xpack/plugins/cloud/models.py:91 +#: xpack/plugins/cloud/models.py:95 msgid "Hostname strategy" msgstr "主机名策略" -#: xpack/plugins/cloud/models.py:102 xpack/plugins/cloud/serializers/task.py:39 +#: xpack/plugins/cloud/models.py:100 +#: xpack/plugins/cloud/serializers/task.py:150 msgid "IP network segment group" msgstr "IP网段组" -#: xpack/plugins/cloud/models.py:105 xpack/plugins/cloud/serializers/task.py:44 +#: xpack/plugins/cloud/models.py:103 +#: xpack/plugins/cloud/serializers/task.py:155 msgid "Sync IP type" msgstr "同步IP类型" -#: xpack/plugins/cloud/models.py:108 xpack/plugins/cloud/serializers/task.py:61 +#: xpack/plugins/cloud/models.py:106 +#: xpack/plugins/cloud/serializers/task.py:173 msgid "Always update" msgstr "总是更新" -#: xpack/plugins/cloud/models.py:114 +#: xpack/plugins/cloud/models.py:112 msgid "Date last sync" msgstr "最后同步日期" -#: xpack/plugins/cloud/models.py:119 xpack/plugins/cloud/models.py:160 +#: xpack/plugins/cloud/models.py:115 xpack/plugins/cloud/models.py:313 +#: xpack/plugins/cloud/models.py:337 +msgid "Strategy" +msgstr "策略" + +#: xpack/plugins/cloud/models.py:120 xpack/plugins/cloud/models.py:197 msgid "Sync instance task" msgstr "同步实例任务" -#: xpack/plugins/cloud/models.py:171 xpack/plugins/cloud/models.py:219 +#: xpack/plugins/cloud/models.py:208 xpack/plugins/cloud/models.py:260 msgid "Date sync" msgstr "同步日期" -#: xpack/plugins/cloud/models.py:175 +#: xpack/plugins/cloud/models.py:212 +msgid "Sync instance snapshot" +msgstr "同步实例快照" + +#: xpack/plugins/cloud/models.py:216 msgid "Sync instance task execution" msgstr "同步实例任务执行" -#: xpack/plugins/cloud/models.py:199 +#: xpack/plugins/cloud/models.py:240 msgid "Sync task" msgstr "同步任务" -#: xpack/plugins/cloud/models.py:203 +#: xpack/plugins/cloud/models.py:244 msgid "Sync instance task history" msgstr "同步实例任务历史" -#: xpack/plugins/cloud/models.py:206 +#: xpack/plugins/cloud/models.py:247 msgid "Instance" msgstr "实例" -#: xpack/plugins/cloud/models.py:223 +#: xpack/plugins/cloud/models.py:264 msgid "Sync instance detail" msgstr "同步实例详情" +#: xpack/plugins/cloud/models.py:281 +msgid "Task strategy" +msgstr "密码策略" + +#: xpack/plugins/cloud/models.py:285 +msgid "Exact" +msgstr "" + +#: xpack/plugins/cloud/models.py:286 +msgid "Not" +msgstr "否" + +#: xpack/plugins/cloud/models.py:287 +msgid "In" +msgstr "在..里面" + +#: xpack/plugins/cloud/models.py:288 +msgid "Contains" +msgstr "包含" + +#: xpack/plugins/cloud/models.py:289 +msgid "Startswith" +msgstr "以..开头" + +#: xpack/plugins/cloud/models.py:290 +msgid "Endswith" +msgstr "以..结尾" + +#: xpack/plugins/cloud/models.py:296 +msgid "Instance platform" +msgstr "实例平台" + +#: xpack/plugins/cloud/models.py:297 +msgid "Instance address" +msgstr "实例地址" + +#: xpack/plugins/cloud/models.py:304 +msgid "Rule attr" +msgstr "规则属性" + +#: xpack/plugins/cloud/models.py:308 +msgid "Rule match" +msgstr "规则匹配" + +#: xpack/plugins/cloud/models.py:310 +msgid "Rule value" +msgstr "规则值" + +#: xpack/plugins/cloud/models.py:317 +msgid "Strategy rule" +msgstr "策略规则" + +#: xpack/plugins/cloud/models.py:332 +msgid "Action attr" +msgstr "动作属性" + +#: xpack/plugins/cloud/models.py:334 +msgid "Action value" +msgstr "动作值" + +#: xpack/plugins/cloud/models.py:341 +msgid "Strategy action" +msgstr "策略动作" + #: xpack/plugins/cloud/providers/aws_international.py:18 msgid "China (Beijing)" msgstr "中国(北京)" @@ -7724,7 +7811,7 @@ msgid "CN East-Suzhou" msgstr "华东-苏州" #: xpack/plugins/cloud/providers/baiducloud.py:57 -#: xpack/plugins/cloud/providers/huaweicloud.py:50 +#: xpack/plugins/cloud/providers/huaweicloud.py:49 msgid "CN-Hong Kong" msgstr "中国-香港" @@ -7742,66 +7829,66 @@ msgid "CN East-Shanghai" msgstr "华东-上海" #: xpack/plugins/cloud/providers/baiducloud.py:61 -#: xpack/plugins/cloud/providers/huaweicloud.py:49 +#: xpack/plugins/cloud/providers/huaweicloud.py:51 msgid "AP-Singapore" msgstr "亚太-新加坡" -#: xpack/plugins/cloud/providers/huaweicloud.py:37 -msgid "AF-Johannesburg" -msgstr "非洲-约翰内斯堡" - -#: xpack/plugins/cloud/providers/huaweicloud.py:38 -msgid "CN North-Beijing4" -msgstr "华北-北京4" - #: xpack/plugins/cloud/providers/huaweicloud.py:39 msgid "CN North-Beijing1" msgstr "华北-北京1" #: xpack/plugins/cloud/providers/huaweicloud.py:40 -msgid "CN East-Shanghai2" -msgstr "华东-上海2" +msgid "CN North-Beijing4" +msgstr "华北-北京4" #: xpack/plugins/cloud/providers/huaweicloud.py:41 -msgid "CN East-Shanghai1" -msgstr "华东-上海1" - -#: xpack/plugins/cloud/providers/huaweicloud.py:43 -msgid "LA-Mexico City1" -msgstr "拉美-墨西哥城一" - -#: xpack/plugins/cloud/providers/huaweicloud.py:44 -msgid "LA-Santiago" -msgstr "拉美-圣地亚哥" - -#: xpack/plugins/cloud/providers/huaweicloud.py:45 -msgid "LA-Sao Paulo1" -msgstr "拉美-圣保罗一" - -#: xpack/plugins/cloud/providers/huaweicloud.py:46 -msgid "EU-Paris" -msgstr "欧洲-巴黎" - -#: xpack/plugins/cloud/providers/huaweicloud.py:47 -msgid "CN Southwest-Guiyang1" -msgstr "西南-贵阳1" - -#: xpack/plugins/cloud/providers/huaweicloud.py:48 -msgid "AP-Bangkok" -msgstr "亚太-曼谷" - -#: xpack/plugins/cloud/providers/huaweicloud.py:52 -msgid "CN Northeast-Dalian" -msgstr "华北-大连" - -#: xpack/plugins/cloud/providers/huaweicloud.py:53 msgid "CN North-Ulanqab1" msgstr "华北-乌兰察布一" -#: xpack/plugins/cloud/providers/huaweicloud.py:54 +#: xpack/plugins/cloud/providers/huaweicloud.py:43 +msgid "CN South-Shenzhen" +msgstr "华南-广州" + +#: xpack/plugins/cloud/providers/huaweicloud.py:44 msgid "CN South-Guangzhou-InvitationOnly" msgstr "华南-广州-友好用户环境" +#: xpack/plugins/cloud/providers/huaweicloud.py:45 +msgid "CN East-Shanghai2" +msgstr "华东-上海2" + +#: xpack/plugins/cloud/providers/huaweicloud.py:46 +msgid "CN East-Shanghai1" +msgstr "华东-上海1" + +#: xpack/plugins/cloud/providers/huaweicloud.py:48 +msgid "CN Southwest-Guiyang1" +msgstr "西南-贵阳1" + +#: xpack/plugins/cloud/providers/huaweicloud.py:50 +msgid "AP-Bangkok" +msgstr "亚太-曼谷" + +#: xpack/plugins/cloud/providers/huaweicloud.py:53 +msgid "AF-Johannesburg" +msgstr "非洲-约翰内斯堡" + +#: xpack/plugins/cloud/providers/huaweicloud.py:54 +msgid "LA-Mexico City1" +msgstr "拉美-墨西哥城一" + +#: xpack/plugins/cloud/providers/huaweicloud.py:55 +msgid "LA-Santiago" +msgstr "拉美-圣地亚哥" + +#: xpack/plugins/cloud/providers/huaweicloud.py:56 +msgid "LA-Sao Paulo1" +msgstr "拉美-圣保罗一" + +#: xpack/plugins/cloud/providers/huaweicloud.py:58 +msgid "TR-Istanbul" +msgstr "" + #: xpack/plugins/cloud/providers/jdcloud.py:126 msgid "CN East-Suqian" msgstr "华东-宿迁" @@ -7830,7 +7917,7 @@ msgstr "订阅 ID" #: xpack/plugins/cloud/serializers/account_attrs.py:103 #: xpack/plugins/cloud/serializers/account_attrs.py:119 #: xpack/plugins/cloud/serializers/account_attrs.py:149 -#: xpack/plugins/cloud/serializers/account_attrs.py:202 +#: xpack/plugins/cloud/serializers/account_attrs.py:199 msgid "API Endpoint" msgstr "API 端点" @@ -7895,11 +7982,11 @@ msgstr "测试端口" msgid "Test timeout" msgstr "测试超时时间" -#: xpack/plugins/cloud/serializers/account_attrs.py:212 +#: xpack/plugins/cloud/serializers/account_attrs.py:209 msgid "Project" msgstr "project" -#: xpack/plugins/cloud/serializers/task.py:28 +#: xpack/plugins/cloud/serializers/task.py:139 msgid "" "Only instances matching the IP range will be synced.
    If the instance " "contains multiple IP addresses, the first IP address that matches will be " @@ -7911,11 +7998,11 @@ msgstr "" "到的 IP 地址将被用作创建的资产的 IP。
    默认值 * 表示同步所有实例和随机匹配 " "IP 地址。
    例如: 192.168.1.0/24,10.1.1.1-10.1.1.20。" -#: xpack/plugins/cloud/serializers/task.py:34 +#: xpack/plugins/cloud/serializers/task.py:145 msgid "History count" msgstr "执行次数" -#: xpack/plugins/cloud/serializers/task.py:35 +#: xpack/plugins/cloud/serializers/task.py:146 msgid "Instance count" msgstr "实例个数" @@ -7927,10 +8014,6 @@ msgstr "执行同步实例任务" msgid "Period clean sync instance task execution" msgstr "定期清除同步实例任务执行记录" -#: xpack/plugins/cloud/utils.py:68 -msgid "Account unavailable" -msgstr "账号无效" - #: xpack/plugins/interface/api.py:52 msgid "Restore default successfully." msgstr "恢复默认成功!" @@ -7995,59 +8078,11 @@ msgstr "旗舰版" msgid "Community edition" msgstr "社区版" -#~ msgid "Strategy" -#~ msgstr "策略" +#~ msgid "EU-Paris" +#~ msgstr "欧洲-巴黎" -#~ msgid "Sync instance snapshot" -#~ msgstr "同步实例快照" - -#~ msgid "Task strategy" -#~ msgstr "密码策略" - -#~ msgid "Not" -#~ msgstr "否" - -#~ msgid "In" -#~ msgstr "在..里面" - -#~ msgid "Contains" -#~ msgstr "包含" - -#~ msgid "Startswith" -#~ msgstr "以..开头" - -#~ msgid "Endswith" -#~ msgstr "以..结尾" - -#~ msgid "Instance platform" -#~ msgstr "实例平台" - -#~ msgid "Instance address" -#~ msgstr "实例地址" - -#~ msgid "Rule attr" -#~ msgstr "规则属性" - -#~ msgid "Rule match" -#~ msgstr "规则匹配" - -#~ msgid "Rule value" -#~ msgstr "规则值" - -#~ msgid "Strategy rule" -#~ msgstr "策略规则" - -#~ msgid "Action attr" -#~ msgstr "动作属性" - -#~ msgid "Action value" -#~ msgstr "动作值" - -#~ msgid "Strategy action" -#~ msgstr "策略动作" - -#~ msgid "CN South-Shenzhen" -#~ msgstr "华南-广州" +#~ msgid "CN Northeast-Dalian" +#~ msgstr "华北-大连" #~ msgid "Current only support login from AD/LDAP" #~ msgstr "当前仅支持 AD/LDAP 方式登录的用户" From da521809769edd6320f43db8f0b0da63381007d2 Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Mon, 14 Aug 2023 16:37:56 +0800 Subject: [PATCH 141/177] =?UTF-8?q?perf:=20=E7=BB=84=E7=BB=87=E8=A7=92?= =?UTF-8?q?=E8=89=B2=E6=B7=BB=E5=8A=A0connectiontoken=E6=9D=83=E9=99=90=20?= =?UTF-8?q?(#11268)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: feng <1304903146@qq.com> --- apps/rbac/const.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/rbac/const.py b/apps/rbac/const.py index c484b747f..20f469611 100644 --- a/apps/rbac/const.py +++ b/apps/rbac/const.py @@ -144,7 +144,9 @@ only_system_permissions = ( ('terminal', 'task', '*', '*'), ('terminal', 'endpoint', '*', '*'), ('terminal', 'endpointrule', '*', '*'), - ('authentication', '*', '*', '*'), + ('authentication', 'accesskey', '*', '*'), + ('authentication', 'superconnectiontoken', '*', '*'), + ('authentication', 'temptoken', '*', '*'), ('tickets', '*', '*', '*'), ('orgs', 'organization', 'view', 'rootorg'), ('terminal', 'applet', '*', '*'), From 98b4f51cbb0fd2cd5c35c86d6f6bad98296e4b3b Mon Sep 17 00:00:00 2001 From: jiangweidong Date: Mon, 14 Aug 2023 17:05:26 +0800 Subject: [PATCH 142/177] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E4=BA=91?= =?UTF-8?q?=E5=90=8C=E6=AD=A5=E7=AD=96=E7=95=A5=E6=9D=83=E9=99=90=E4=BD=8D?= =?UTF-8?q?=E7=BD=AE=E6=98=BE=E7=A4=BA=E4=B8=8D=E6=AD=A3=E5=B8=B8=E9=97=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/rbac/tree.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/apps/rbac/tree.py b/apps/rbac/tree.py index a586208b6..5bbedbbf0 100644 --- a/apps/rbac/tree.py +++ b/apps/rbac/tree.py @@ -70,6 +70,9 @@ special_pid_mapper = { 'xpack.syncinstancedetail': 'cloud_import', 'xpack.syncinstancetask': 'cloud_import', 'xpack.syncinstancetaskexecution': 'cloud_import', + 'xpack.strategy': 'cloud_import', + 'xpack.strategyaction': 'cloud_import', + 'xpack.strategyrule': 'cloud_import', 'terminal.applet': 'remote_application', 'terminal.applethost': 'remote_application', 'accounts.accountbackupautomation': "backup_account_node", From ef0c2f41ace0df13bd2316387e57730f7b510915 Mon Sep 17 00:00:00 2001 From: jiangweidong Date: Mon, 14 Aug 2023 17:36:27 +0800 Subject: [PATCH 143/177] =?UTF-8?q?perf:=20=E7=BF=BB=E8=AF=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/locale/ja/LC_MESSAGES/django.po | 2 +- apps/locale/zh/LC_MESSAGES/django.po | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/locale/ja/LC_MESSAGES/django.po b/apps/locale/ja/LC_MESSAGES/django.po index 169db0677..1755a5caf 100644 --- a/apps/locale/ja/LC_MESSAGES/django.po +++ b/apps/locale/ja/LC_MESSAGES/django.po @@ -7747,7 +7747,7 @@ msgstr "同期インスタンスの詳細" #: xpack/plugins/cloud/models.py:281 msgid "Task strategy" -msgstr "タスク戦略" +msgstr "ミッション戦略です" #: xpack/plugins/cloud/models.py:285 msgid "Exact" diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po index d459400d9..0da2ecaa3 100644 --- a/apps/locale/zh/LC_MESSAGES/django.po +++ b/apps/locale/zh/LC_MESSAGES/django.po @@ -7641,7 +7641,7 @@ msgstr "同步实例详情" #: xpack/plugins/cloud/models.py:281 msgid "Task strategy" -msgstr "密码策略" +msgstr "任务策略" #: xpack/plugins/cloud/models.py:285 msgid "Exact" From 4899f6bb69cffc43383a10bf4e77d0b0509a70b8 Mon Sep 17 00:00:00 2001 From: Eric Date: Mon, 14 Aug 2023 15:46:46 +0800 Subject: [PATCH 144/177] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E5=8F=91?= =?UTF-8?q?=E5=B8=83=E6=9C=BA=E7=BD=91=E5=85=B3=E9=80=89=E6=8B=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/authentication/models/connection_token.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/authentication/models/connection_token.py b/apps/authentication/models/connection_token.py index 29f0c28f1..6ea5474c4 100644 --- a/apps/authentication/models/connection_token.py +++ b/apps/authentication/models/connection_token.py @@ -191,7 +191,7 @@ class ConnectionToken(JMSOrgBaseModel): raise JMSException({'error': 'No host account available'}) host, account, lock_key, ttl = bulk_get(host_account, ('host', 'account', 'lock_key', 'ttl')) - gateway = host.gateway.select_gateway() if host.domain else None + gateway = host.domain.select_gateway() if host.domain else None data = { 'id': account.id, From efe57b3ebeb5594f9a7067be8fef5247e3e2f5ff Mon Sep 17 00:00:00 2001 From: Eric Date: Mon, 14 Aug 2023 17:18:13 +0800 Subject: [PATCH 145/177] =?UTF-8?q?perf:=20=E4=BF=AE=E5=A4=8D=E6=89=8B?= =?UTF-8?q?=E5=8A=A8=E7=99=BB=E9=99=86=E8=B4=A6=E5=8F=B7=E5=AF=86=E7=A0=81?= =?UTF-8?q?=E6=97=A0=E6=B3=95=E8=B5=8B=E5=80=BC=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/accounts/models/mixins/vault.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/apps/accounts/models/mixins/vault.py b/apps/accounts/models/mixins/vault.py index e517516a9..b16927b62 100644 --- a/apps/accounts/models/mixins/vault.py +++ b/apps/accounts/models/mixins/vault.py @@ -52,17 +52,18 @@ class VaultModelMixin(models.Model): abstract = True # 缓存 secret 值, lazy-property 不能用 - __secret = False + __secret = None @property def secret(self): - if self.__secret is False: - from accounts.backends import vault_client - secret = vault_client.get(self) - if not secret and not self.secret_has_save_to_vault: - # vault_client 获取不到, 并且 secret 没有保存到 vault, 就从 self._secret 获取 - secret = self._secret - self.__secret = secret + if self.__secret: + return self.__secret + from accounts.backends import vault_client + secret = vault_client.get(self) + if not secret and not self.secret_has_save_to_vault: + # vault_client 获取不到, 并且 secret 没有保存到 vault, 就从 self._secret 获取 + secret = self._secret + self.__secret = secret return self.__secret @secret.setter @@ -72,6 +73,7 @@ class VaultModelMixin(models.Model): 先保存到 db, 再保存到 vault 同时删除本地 db _secret 值 """ self._secret = value + self.__secret = value _secret_save_to_vault_mark = '# Secret-has-been-saved-to-vault #' From c11ba16e4e3219bc394892ae97c6794ae2218851 Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Mon, 14 Aug 2023 18:37:28 +0800 Subject: [PATCH 146/177] =?UTF-8?q?perf:=20oidc=20=E6=9B=BF=E6=8D=A2?= =?UTF-8?q?=E5=8E=9F=E6=9C=89=E7=9A=84is=5Fajax=E6=96=B9=E6=B3=95=EF=BC=8C?= =?UTF-8?q?=E4=BC=98=E5=8C=96accountbackupexecution=20=E8=BF=81=E7=A7=BB?= =?UTF-8?q?=E6=96=87=E4=BB=B6=20(#11274)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: feng <1304903146@qq.com> --- .../0013_account_backup_recipients.py | 32 +++++++++++++++---- .../backends/oidc/middleware.py | 16 ++++++---- 2 files changed, 35 insertions(+), 13 deletions(-) diff --git a/apps/accounts/migrations/0013_account_backup_recipients.py b/apps/accounts/migrations/0013_account_backup_recipients.py index ac9956b76..6fe03e349 100644 --- a/apps/accounts/migrations/0013_account_backup_recipients.py +++ b/apps/accounts/migrations/0013_account_backup_recipients.py @@ -1,8 +1,9 @@ # Generated by Django 4.1.10 on 2023-08-03 08:28 - from django.conf import settings from django.db import migrations, models +import common.db.encoder + def migrate_recipients(apps, schema_editor): account_backup_model = apps.get_model('accounts', 'AccountBackupAutomation') @@ -13,13 +14,22 @@ def migrate_recipients(apps, schema_editor): continue account_backup.recipients_part_one.set(recipients) - execution_bojs = [] + objs = [] for execution in execution_model.objects.all(): snapshot = execution.snapshot recipients = snapshot.pop('recipients', {}) snapshot.update({'recipients_part_one': recipients, 'recipients_part_two': {}}) - execution_bojs.append(execution) - execution_model.objects.bulk_update(execution_bojs, ['snapshot']) + objs.append(execution) + execution_model.objects.bulk_update(objs, ['snapshot']) + + +def migrate_snapshot(apps, schema_editor): + model = apps.get_model('accounts', 'AccountBackupExecution') + objs = [] + for execution in model.objects.all(): + execution.snapshot = execution.plan_snapshot + objs.append(execution) + model.objects.bulk_update(objs, ['snapshot']) class Migration(migrations.Migration): @@ -45,12 +55,20 @@ class Migration(migrations.Migration): to=settings.AUTH_USER_MODEL, verbose_name='Recipient part two' ), ), - migrations.RenameField( + migrations.AddField( model_name='accountbackupexecution', - old_name='plan_snapshot', - new_name='snapshot', + name='snapshot', + field=models.JSONField( + default=dict, encoder=common.db.encoder.ModelJSONFieldEncoder, + null=True, blank=True, verbose_name='Account backup snapshot' + ), ), + migrations.RunPython(migrate_snapshot), migrations.RunPython(migrate_recipients), + migrations.RemoveField( + model_name='accountbackupexecution', + name='plan_snapshot', + ), migrations.RemoveField( model_name='accountbackupautomation', name='recipients', diff --git a/apps/authentication/backends/oidc/middleware.py b/apps/authentication/backends/oidc/middleware.py index c2ad33637..4481951e4 100644 --- a/apps/authentication/backends/oidc/middleware.py +++ b/apps/authentication/backends/oidc/middleware.py @@ -1,15 +1,14 @@ import time + import requests import requests.exceptions - -from django.core.exceptions import MiddlewareNotUsed from django.conf import settings from django.contrib import auth +from django.core.exceptions import MiddlewareNotUsed + from common.utils import get_logger - -from .utils import validate_and_return_id_token from .decorator import ssl_verification - +from .utils import validate_and_return_id_token logger = get_logger(__file__) @@ -25,11 +24,16 @@ class OIDCRefreshIDTokenMiddleware: def __call__(self, request): # Refreshes tokens only in the applicable cases. - if request.method == 'GET' and not request.is_ajax() and request.user.is_authenticated and settings.AUTH_OPENID: + if request.method == 'GET' and not self.is_ajax(request) and \ + request.user.is_authenticated and settings.AUTH_OPENID: self.refresh_token(request) response = self.get_response(request) return response + @staticmethod + def is_ajax(request): + return request.META.get('HTTP_X_REQUESTED_WITH') == 'XMLHttpRequest' + @ssl_verification def refresh_token(self, request): """ Refreshes the token of the current user. """ From a6e49b730b524af224577cd69d61fa944566f4e4 Mon Sep 17 00:00:00 2001 From: Bai Date: Mon, 14 Aug 2023 18:29:03 +0800 Subject: [PATCH 147/177] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E5=BF=98?= =?UTF-8?q?=E8=AE=B0=E5=AF=86=E7=A0=81=E4=B8=8D=E5=8C=85=E5=90=AB=E5=B7=A6?= =?UTF-8?q?=E4=BE=A7=20+=20=E5=AD=97=E7=AC=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/authentication/api/password.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/apps/authentication/api/password.py b/apps/authentication/api/password.py index f1b245a46..86801bc6c 100644 --- a/apps/authentication/api/password.py +++ b/apps/authentication/api/password.py @@ -52,7 +52,11 @@ class UserResetPasswordSendCodeApi(CreateAPIView): other_args = {} target = serializer.validated_data[form_type] - query_key = 'phone' if form_type == 'sms' else form_type + if form_type == 'sms': + query_key = 'phone' + target = target.lstrip('+') + else: + query_key = form_type user, err = self.is_valid_user(username=username, **{query_key: target}) if not user: return Response({'error': err}, status=400) From 8e0c04c84cbcb4bd4ffa962fed01f008b4a1d9db Mon Sep 17 00:00:00 2001 From: ibuler Date: Mon, 14 Aug 2023 19:40:21 +0800 Subject: [PATCH 148/177] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=E8=AE=BE?= =?UTF-8?q?=E7=BD=AE=E5=B8=83=E5=B1=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/locale/ja/LC_MESSAGES/django.mo | 4 +- apps/locale/ja/LC_MESSAGES/django.po | 115 ++++++++----- apps/locale/zh/LC_MESSAGES/django.mo | 4 +- apps/locale/zh/LC_MESSAGES/django.po | 234 +++++++++++++------------- apps/settings/serializers/basic.py | 2 +- apps/settings/serializers/email.py | 4 + apps/settings/serializers/other.py | 13 -- apps/settings/serializers/security.py | 26 ++- 8 files changed, 220 insertions(+), 182 deletions(-) diff --git a/apps/locale/ja/LC_MESSAGES/django.mo b/apps/locale/ja/LC_MESSAGES/django.mo index b0b33e499..2c4a07054 100644 --- a/apps/locale/ja/LC_MESSAGES/django.mo +++ b/apps/locale/ja/LC_MESSAGES/django.mo @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7bc2e996c082d5f9348277e69cd70b7b9884dc416d9d83e075656a4d8b9bc141 -size 152939 +oid sha256:762fb91213e28a5545cb4706bd0cd6097965b3bb4a234fa89d945428f36bab5d +size 152159 diff --git a/apps/locale/ja/LC_MESSAGES/django.po b/apps/locale/ja/LC_MESSAGES/django.po index d6f806295..3578823b7 100644 --- a/apps/locale/ja/LC_MESSAGES/django.po +++ b/apps/locale/ja/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-08-10 18:22+0800\n" +"POT-Creation-Date: 2023-08-14 16:56+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -1239,7 +1239,7 @@ msgstr "コンソールセッションに接続" msgid "Any" msgstr "任意" -#: assets/const/protocol.py:66 settings/serializers/security.py:153 +#: assets/const/protocol.py:66 settings/serializers/security.py:160 msgid "Security" msgstr "セキュリティ" @@ -4382,7 +4382,7 @@ msgid "View permission tree" msgstr "権限ツリーの表示" #: settings/api/dingtalk.py:31 settings/api/feishu.py:36 -#: settings/api/sms.py:155 settings/api/vault.py:39 settings/api/wecom.py:37 +#: settings/api/sms.py:155 settings/api/vault.py:40 settings/api/wecom.py:37 msgid "Test success" msgstr "テストの成功" @@ -4898,8 +4898,10 @@ msgid "Site url" msgstr "サイトURL" #: settings/serializers/basic.py:31 -msgid "eg: http://dev.jumpserver.org:8080" -msgstr "例えば: http://dev.jumpserver.org:8080" +msgid "" +"Email links or other system callbacks are used to access it, eg: http://dev." +"jumpserver.org:8080" +msgstr "" #: settings/serializers/basic.py:34 msgid "User guide url" @@ -5158,6 +5160,10 @@ msgid "Must contain special" msgstr "特別な" #: settings/serializers/security.py:31 +#, fuzzy +#| msgid "" +#| "If the user has failed to log in for a limited number of times, no login " +#| "is allowed during this time interval." msgid "" "If the user has failed to log in for a limited number of times, no login is " "allowed during this time interval." @@ -5269,11 +5275,11 @@ msgstr "" "ローカル認証方法を除く他の認証方法のユーザーはログインでき、ユーザーが自動的" "に作成されます (ユーザーが存在しない場合)。" -#: settings/serializers/security.py:105 +#: settings/serializers/security.py:108 msgid "Only from source login" msgstr "ソースログインからのみ" -#: settings/serializers/security.py:107 +#: settings/serializers/security.py:110 msgid "" "If it is enabled, the user will only authenticate to the source when logging " "in; if it is disabled, the user will authenticate all the enabled " @@ -5284,28 +5290,38 @@ msgstr "" "な場合、ユーザーはログイン時に、いずれかの認証方法が成功する限り、有効なすべ" "ての認証方法を特定の順序で認証します。 、直接ログインできます" -#: settings/serializers/security.py:111 -msgid "MFA verify TTL (secend)" +#: settings/serializers/security.py:118 +#, fuzzy +#| msgid "MFA verify TTL (secend)" +msgid "MFA verify TTL" msgstr "MFAはTTLを確認します(秒)" -#: settings/serializers/security.py:113 +#: settings/serializers/security.py:120 +#, fuzzy +#| msgid "" +#| "The verification MFA takes effect only when you view the account password" msgid "" -"The verification MFA takes effect only when you view the account password" +"Unit: second, The verification MFA takes effect only when you view the " +"account password" msgstr "検証MFAはアカウントのパスワードを表示したときにのみ有効になります。" -#: settings/serializers/security.py:118 -msgid "Verify code TTL" +#: settings/serializers/security.py:125 +#, fuzzy +#| msgid "Verify code TTL" +msgid "Verify code TTL (second)" msgstr "認証コード有効時間" -#: settings/serializers/security.py:119 -msgid "Unit: second, reset password and send SMS code expiration time" +#: settings/serializers/security.py:126 +#, fuzzy +#| msgid "Unit: second, reset password and send SMS code expiration time" +msgid "Reset password and send SMS code expiration time" msgstr "パスワードをリセットしてSMSコードの有効期限を送信します" -#: settings/serializers/security.py:123 +#: settings/serializers/security.py:130 msgid "Enable Login dynamic code" msgstr "ログイン動的コードの有効化" -#: settings/serializers/security.py:124 +#: settings/serializers/security.py:131 msgid "" "The password and additional code are sent to a third party authentication " "system for verification" @@ -5313,28 +5329,28 @@ msgstr "" "パスワードと追加コードは、検証のためにサードパーティの認証システムに送信され" "ます" -#: settings/serializers/security.py:129 +#: settings/serializers/security.py:136 msgid "MFA in login page" msgstr "ログインページのMFA" -#: settings/serializers/security.py:130 +#: settings/serializers/security.py:137 msgid "Eu security regulations(GDPR) require MFA to be on the login page" msgstr "" "Euセキュリティ規制 (GDPR) では、MFAがログインページにある必要があります" -#: settings/serializers/security.py:133 +#: settings/serializers/security.py:140 msgid "Enable Login captcha" msgstr "ログインcaptchaの有効化" -#: settings/serializers/security.py:134 +#: settings/serializers/security.py:141 msgid "Enable captcha to prevent robot authentication" msgstr "Captchaを有効にしてロボット認証を防止する" -#: settings/serializers/security.py:156 +#: settings/serializers/security.py:163 msgid "Enable terminal register" msgstr "ターミナルレジスタの有効化" -#: settings/serializers/security.py:158 +#: settings/serializers/security.py:165 msgid "" "Allow terminal register, after all terminal setup, you should disable this " "for security" @@ -5342,86 +5358,94 @@ msgstr "" "ターミナルレジスタを許可し、すべてのターミナルセットアップの後、セキュリティ" "のためにこれを無効にする必要があります" -#: settings/serializers/security.py:162 +#: settings/serializers/security.py:169 msgid "Enable watermark" msgstr "透かしの有効化" -#: settings/serializers/security.py:163 +#: settings/serializers/security.py:170 msgid "Enabled, the web session and replay contains watermark information" msgstr "Webセッションとリプレイには透かし情報が含まれています。" -#: settings/serializers/security.py:167 +#: settings/serializers/security.py:174 msgid "Connection max idle time (minute)" msgstr "接続最大アイドル時間(分)" -#: settings/serializers/security.py:168 +#: settings/serializers/security.py:175 msgid "If idle time more than it, disconnect connection." msgstr "この設定以上の操作がない場合、接続は切断されます" -#: settings/serializers/security.py:172 +#: settings/serializers/security.py:179 msgid "Session max connection time (hour)" msgstr "セッション最大接続時間(時間)" -#: settings/serializers/security.py:173 +#: settings/serializers/security.py:180 msgid "If session connection time more than it, disconnect connection." msgstr "セッション接続時間がこれを超えると、接続が切断されます" -#: settings/serializers/security.py:176 +#: settings/serializers/security.py:183 msgid "Remember manual auth" msgstr "手動入力パスワードの保存" -#: settings/serializers/security.py:179 +#: settings/serializers/security.py:186 msgid "Insecure command alert" msgstr "安全でないコマンドアラート" -#: settings/serializers/security.py:182 +#: settings/serializers/security.py:189 msgid "Email recipient" msgstr "メール受信者" -#: settings/serializers/security.py:183 +#: settings/serializers/security.py:190 msgid "Multiple user using , split" msgstr "複数のユーザーを使用して、分割" -#: settings/serializers/security.py:186 +#: settings/serializers/security.py:193 msgid "Operation center" msgstr "職業センター" -#: settings/serializers/security.py:187 +#: settings/serializers/security.py:194 msgid "Allow user run batch command or not using ansible" msgstr "ユーザー実行バッチコマンドを許可するか、ansibleを使用しない" -#: settings/serializers/security.py:191 +#: settings/serializers/security.py:198 msgid "Operation center command blacklist" msgstr "オペレーション センター コマンド ブラックリスト" -#: settings/serializers/security.py:192 +#: settings/serializers/security.py:199 msgid "Commands that are not allowed execute." msgstr "実行が許可されていないコマンド" -#: settings/serializers/security.py:195 +#: settings/serializers/security.py:202 msgid "Session share" msgstr "セッション共有" -#: settings/serializers/security.py:196 +#: settings/serializers/security.py:203 msgid "Enabled, Allows user active session to be shared with other users" msgstr "" "ユーザーのアクティブなセッションを他のユーザーと共有できるようにします。" -#: settings/serializers/security.py:200 +#: settings/serializers/security.py:207 +#, fuzzy +#| msgid "Unused user timeout (day)" msgid "Unused user timeout (day)" -msgstr "" +msgstr "未使用のユーザータイムアウト(日)" -#: settings/serializers/security.py:201 +#: settings/serializers/security.py:208 +#, fuzzy +#| msgid "" +#| "Detect infrequent users daily and disable them if they exceed the " +#| "predetermined time limit." msgid "" "Detect infrequent users daily and disable them if they exceed the " "predetermined time limit." msgstr "" +"毎日、頻度の低いユーザーを検出し、予め決められた時間制限を超えた場合は無効に" +"します。" -#: settings/serializers/security.py:204 +#: settings/serializers/security.py:211 msgid "Remote Login Protection" msgstr "リモートログイン保護" -#: settings/serializers/security.py:206 +#: settings/serializers/security.py:213 msgid "" "The system determines whether the login IP address belongs to a common login " "city. If the account is logged in from a common login city, the system sends " @@ -8120,6 +8144,9 @@ msgstr "究極のエディション" msgid "Community edition" msgstr "コミュニティ版" +#~ msgid "eg: http://dev.jumpserver.org:8080" +#~ msgstr "例えば: http://dev.jumpserver.org:8080" + #~ msgid "Strategy" #~ msgstr "戦略" diff --git a/apps/locale/zh/LC_MESSAGES/django.mo b/apps/locale/zh/LC_MESSAGES/django.mo index eb66df73f..22a8b4239 100644 --- a/apps/locale/zh/LC_MESSAGES/django.mo +++ b/apps/locale/zh/LC_MESSAGES/django.mo @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d1a6a042b4813d67922799caf3ac81ce3f1e831aed1a771dc9a16dab147a0692 -size 125568 +oid sha256:3656dfce61012412c97720e60c1134f39d0f5c1faed26bff88ca795ebce31f81 +size 125596 diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po index 3c1119e4c..d6630142c 100644 --- a/apps/locale/zh/LC_MESSAGES/django.po +++ b/apps/locale/zh/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: JumpServer 0.3.3\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-08-10 18:22+0800\n" +"POT-Creation-Date: 2023-08-14 16:56+0800\n" "PO-Revision-Date: 2021-05-20 10:54+0800\n" "Last-Translator: ibuler \n" "Language-Team: JumpServer team\n" @@ -1005,7 +1005,7 @@ msgid "" "support)" msgstr "" "* 表示匹配所有。例如: 192.168.10.1, 192.168.1.0/24, 10.1.1.1-10.1.1.20, 2001:" -"db8:2de::e13, 2001:db8:1a:1110::/64 (支持网域)" +"db8:2de::e13, 2001:db8:1a:1110::/64 (支持网域)" #: acls/serializers/base.py:41 assets/serializers/asset/host.py:19 msgid "IP/Host" @@ -1236,7 +1236,7 @@ msgstr "连接到控制台会话" msgid "Any" msgstr "任意" -#: assets/const/protocol.py:66 settings/serializers/security.py:153 +#: assets/const/protocol.py:66 settings/serializers/security.py:160 msgid "Security" msgstr "安全" @@ -2507,20 +2507,20 @@ msgid "" "You can also try {times_try} times (The account will be temporarily locked " "for {block_time} minutes)" msgstr "" -"您输入的用户名或密码不正确,请重新输入。 您还可以尝试 {times_try} 次(账号将" -"被临时 锁定 {block_time} 分钟)" +"您输入的用户名或密码不正确,请重新输入。 您还可以尝试 {times_try} 次 (账号将" +"被临时 锁定 {block_time} 分钟)" #: authentication/errors/const.py:47 authentication/errors/const.py:55 msgid "" "The account has been locked (please contact admin to unlock it or try again " "after {} minutes)" -msgstr "账号已被锁定(请联系管理员解锁或{}分钟后重试)" +msgstr "账号已被锁定 (请联系管理员解锁或{}分钟后重试)" #: authentication/errors/const.py:51 msgid "" "The address has been locked (please contact admin to unlock it or try again " "after {} minutes)" -msgstr "IP 已被锁定(请联系管理员解锁或 {} 分钟后重试)" +msgstr "IP 已被锁定 (请联系管理员解锁或 {} 分钟后重试)" #: authentication/errors/const.py:59 #, python-brace-format @@ -2528,7 +2528,7 @@ msgid "" "{error}, You can also try {times_try} times (The account will be temporarily " "locked for {block_time} minutes)" msgstr "" -"{error},您还可以尝试 {times_try} 次(账号将被临时锁定 {block_time} 分钟)" +"{error},您还可以尝试 {times_try} 次 (账号将被临时锁定 {block_time} 分钟)" #: authentication/errors/const.py:63 msgid "MFA required" @@ -2699,7 +2699,7 @@ msgstr "清空手机号码禁用" #: authentication/middleware.py:93 settings/utils/ldap.py:661 msgid "Authentication failed (before login check failed): {}" -msgstr "认证失败(登录前检查失败): {}" +msgstr "认证失败 (登录前检查失败): {}" #: authentication/mixins.py:91 msgid "" @@ -3816,7 +3816,7 @@ msgstr "运行目录" #: ops/models/job.py:126 msgid "Timeout (Seconds)" -msgstr "超时时间(秒)" +msgstr "超时时间 (秒)" #: ops/models/job.py:133 msgid "Use Parameter Define" @@ -4332,7 +4332,7 @@ msgid "View permission tree" msgstr "查看授权树" #: settings/api/dingtalk.py:31 settings/api/feishu.py:36 -#: settings/api/sms.py:155 settings/api/vault.py:39 settings/api/wecom.py:37 +#: settings/api/sms.py:155 settings/api/vault.py:40 settings/api/wecom.py:37 msgid "Test success" msgstr "测试成功" @@ -4843,11 +4843,13 @@ msgstr "更多信息 URL" #: settings/serializers/basic.py:30 msgid "Site url" -msgstr "当前站点URL" +msgstr "当前站点 URL" #: settings/serializers/basic.py:31 -msgid "eg: http://dev.jumpserver.org:8080" -msgstr "如: http://dev.jumpserver.org:8080" +msgid "" +"Email links or other system callbacks are used to access it, eg: http://dev." +"jumpserver.org:8080" +msgstr "" #: settings/serializers/basic.py:34 msgid "User guide url" @@ -4891,38 +4893,38 @@ msgstr "定時清掃" #: settings/serializers/cleaning.py:12 msgid "Login log keep days (day)" -msgstr "登录日志(天)" +msgstr "登录日志 (天)" #: settings/serializers/cleaning.py:16 msgid "Task log keep days (day)" -msgstr "任务日志(天)" +msgstr "任务日志 (天)" #: settings/serializers/cleaning.py:20 msgid "Operate log keep days (day)" -msgstr "操作日志(天)" +msgstr "操作日志 (天)" #: settings/serializers/cleaning.py:24 msgid "FTP log keep days (day)" -msgstr "上传下载(天)" +msgstr "上传下载 (天)" #: settings/serializers/cleaning.py:28 msgid "Cloud sync record keep days (day)" -msgstr "云同步记录(天)" +msgstr "云同步记录 (天)" #: settings/serializers/cleaning.py:31 msgid "Session keep duration (day)" -msgstr "会话日志(天)" +msgstr "会话日志 (天)" #: settings/serializers/cleaning.py:33 msgid "" "Session, record, command will be delete if more than duration, only in " "database, OSS will not be affected." msgstr "" -"会话、录像,命令记录超过该时长将会被清除(影响数据库存储,OSS 等不受影响)" +"会话、录像,命令记录超过该时长将会被清除 (影响数据库存储,OSS 等不受影响)" #: settings/serializers/cleaning.py:37 msgid "Activity log keep days (day)" -msgstr "活动记录(天)" +msgstr "活动记录 (天)" #: settings/serializers/email.py:21 msgid "SMTP host" @@ -5101,7 +5103,7 @@ msgstr "必须包含特殊字符" msgid "" "If the user has failed to log in for a limited number of times, no login is " "allowed during this time interval." -msgstr "当用户登录失败次数达到限制后,那么在此时间间隔内禁止登录" +msgstr "当用户登录失败次数达到限制后,那么在此间隔内禁止登录" #: settings/serializers/security.py:39 msgid "Not enabled" @@ -5121,7 +5123,7 @@ msgstr "全局启用 MFA 认证" #: settings/serializers/security.py:47 msgid "Third-party login users perform MFA authentication" -msgstr "第三方登录用户进行MFA认证" +msgstr "第三方认证开启 MFA" #: settings/serializers/security.py:48 msgid "The third-party login modes include OIDC, CAS, and SAML2" @@ -5133,7 +5135,7 @@ msgstr "限制用户登录失败次数" #: settings/serializers/security.py:56 msgid "Block user login interval (minute)" -msgstr "禁止用户登录时间间隔(分)" +msgstr "禁止用户登录间隔 (分)" #: settings/serializers/security.py:61 msgid "Limit the number of IP login failures" @@ -5141,7 +5143,7 @@ msgstr "限制 IP 登录失败次数" #: settings/serializers/security.py:65 msgid "Block IP login interval (minute)" -msgstr "禁止 IP 登录时间间隔(分)" +msgstr "禁止 IP 登录间隔 (分)" #: settings/serializers/security.py:69 msgid "Login IP White List" @@ -5153,7 +5155,7 @@ msgstr "IP 登录黑名单" #: settings/serializers/security.py:80 msgid "User password expiration (day)" -msgstr "用户密码过期时间(天)" +msgstr "用户密码过期时间 (天)" #: settings/serializers/security.py:82 msgid "" @@ -5162,7 +5164,7 @@ msgid "" "sent to the user by system within 5 days (daily) before the password expires" msgstr "" "如果用户在此期间没有更新密码,用户密码将过期失效; 密码过期提醒邮件将在密码过" -"期前5天内由系统(每天)自动发送给用户" +"期前5天内由系统 (每天)自动发送给用户" #: settings/serializers/security.py:89 msgid "Number of repeated historical passwords" @@ -5196,13 +5198,13 @@ msgid "" "exist)" msgstr "" "如果开启,不存在的用户将不被允许登录;如果关闭,除本地认证方式外,其他认证方" -"式的用户都允许登录并自动创建用户(如果用户不存在)" +"式的用户都允许登录并自动创建用户 (如果用户不存在)" -#: settings/serializers/security.py:105 +#: settings/serializers/security.py:108 msgid "Only from source login" msgstr "仅从用户来源登录" -#: settings/serializers/security.py:107 +#: settings/serializers/security.py:110 msgid "" "If it is enabled, the user will only authenticate to the source when logging " "in; if it is disabled, the user will authenticate all the enabled " @@ -5212,28 +5214,29 @@ msgstr "" "如果开启,用户登录时仅会向来源端进行认证;如果关闭,用户登录时会按照一定的顺" "序对所有已开启的认证方式进行顺序认证,只要有一个认证成功就可以直接登录" -#: settings/serializers/security.py:111 -msgid "MFA verify TTL (secend)" -msgstr "MFA 校验有效期(秒)" - -#: settings/serializers/security.py:113 -msgid "" -"The verification MFA takes effect only when you view the account password" -msgstr "目前仅在查看账号密码校验 MFA 时生效" - #: settings/serializers/security.py:118 -msgid "Verify code TTL" -msgstr "验证码有效时间" +msgid "MFA verify TTL" +msgstr "MFA 校验有效期" -#: settings/serializers/security.py:119 -msgid "Unit: second, reset password and send SMS code expiration time" +#: settings/serializers/security.py:120 +msgid "" +"Unit: second, The verification MFA takes effect only when you view the " +"account password" +msgstr "单位:秒,目前仅在查看账号密码校验 MFA 时生效" + +#: settings/serializers/security.py:125 +msgid "Verify code TTL (second)" +msgstr "验证码有效时间 (分)" + +#: settings/serializers/security.py:126 +msgid "Reset password and send SMS code expiration time" msgstr "重置密码的验证码及发送短信的验证码过期时间" -#: settings/serializers/security.py:123 +#: settings/serializers/security.py:130 msgid "Enable Login dynamic code" msgstr "启用登录附加码" -#: settings/serializers/security.py:124 +#: settings/serializers/security.py:131 msgid "" "The password and additional code are sent to a third party authentication " "system for verification" @@ -5241,111 +5244,111 @@ msgstr "" "密码和附加码一并发送给第三方认证系统进行校验, 如:有的第三方认证系统,需要 密" "码+6位数字 完成认证" -#: settings/serializers/security.py:129 +#: settings/serializers/security.py:136 msgid "MFA in login page" msgstr "MFA 在登录页面输入" -#: settings/serializers/security.py:130 +#: settings/serializers/security.py:137 msgid "Eu security regulations(GDPR) require MFA to be on the login page" msgstr "欧盟数据安全法规(GDPR) 要求 MFA 在登录页面,来确保系统登录安全" -#: settings/serializers/security.py:133 +#: settings/serializers/security.py:140 msgid "Enable Login captcha" msgstr "启用登录验证码" -#: settings/serializers/security.py:134 +#: settings/serializers/security.py:141 msgid "Enable captcha to prevent robot authentication" msgstr "开启验证码,防止机器人登录" -#: settings/serializers/security.py:156 +#: settings/serializers/security.py:163 msgid "Enable terminal register" msgstr "终端注册" -#: settings/serializers/security.py:158 +#: settings/serializers/security.py:165 msgid "" "Allow terminal register, after all terminal setup, you should disable this " "for security" msgstr "是否允许终端注册,当所有终端启动后,为了安全应该关闭" -#: settings/serializers/security.py:162 +#: settings/serializers/security.py:169 msgid "Enable watermark" msgstr "开启水印" -#: settings/serializers/security.py:163 +#: settings/serializers/security.py:170 msgid "Enabled, the web session and replay contains watermark information" msgstr "启用后,Web 会话和录像将包含水印信息" -#: settings/serializers/security.py:167 +#: settings/serializers/security.py:174 msgid "Connection max idle time (minute)" -msgstr "连接最大空闲时间(分)" +msgstr "连接最大空闲时间 (分)" -#: settings/serializers/security.py:168 +#: settings/serializers/security.py:175 msgid "If idle time more than it, disconnect connection." msgstr "提示:如果超过该配置没有操作,连接会被断开" -#: settings/serializers/security.py:172 +#: settings/serializers/security.py:179 msgid "Session max connection time (hour)" -msgstr "会话连接最大时间(时)" +msgstr "会话连接最大时间 (时)" -#: settings/serializers/security.py:173 +#: settings/serializers/security.py:180 msgid "If session connection time more than it, disconnect connection." msgstr "提示:如果会话连接超过该配置,连接会被断开" -#: settings/serializers/security.py:176 +#: settings/serializers/security.py:183 msgid "Remember manual auth" msgstr "保存手动输入密码" -#: settings/serializers/security.py:179 +#: settings/serializers/security.py:186 msgid "Insecure command alert" msgstr "危险命令告警" -#: settings/serializers/security.py:182 +#: settings/serializers/security.py:189 msgid "Email recipient" msgstr "邮件收件人" -#: settings/serializers/security.py:183 +#: settings/serializers/security.py:190 msgid "Multiple user using , split" msgstr "多个用户,使用 , 分割" -#: settings/serializers/security.py:186 +#: settings/serializers/security.py:193 msgid "Operation center" msgstr "作业中心" -#: settings/serializers/security.py:187 +#: settings/serializers/security.py:194 msgid "Allow user run batch command or not using ansible" msgstr "是否允许用户使用 ansible 执行批量命令" -#: settings/serializers/security.py:191 +#: settings/serializers/security.py:198 msgid "Operation center command blacklist" msgstr "作业中心命令黑名单" -#: settings/serializers/security.py:192 +#: settings/serializers/security.py:199 msgid "Commands that are not allowed execute." msgstr "不允许执行的命令" -#: settings/serializers/security.py:195 +#: settings/serializers/security.py:202 msgid "Session share" msgstr "会话分享" -#: settings/serializers/security.py:196 +#: settings/serializers/security.py:203 msgid "Enabled, Allows user active session to be shared with other users" msgstr "开启后允许用户分享已连接的资产会话给他人,协同工作" -#: settings/serializers/security.py:200 +#: settings/serializers/security.py:207 msgid "Unused user timeout (day)" -msgstr "" +msgstr "不活跃用户自动禁用 (天)" -#: settings/serializers/security.py:201 +#: settings/serializers/security.py:208 msgid "" "Detect infrequent users daily and disable them if they exceed the " "predetermined time limit." -msgstr "" +msgstr "每天检测一次,超过预设时间的用户自动禁用" -#: settings/serializers/security.py:204 +#: settings/serializers/security.py:211 msgid "Remote Login Protection" -msgstr "异地登录保护" +msgstr "异地登录通知" -#: settings/serializers/security.py:206 +#: settings/serializers/security.py:213 msgid "" "The system determines whether the login IP address belongs to a common login " "city. If the account is logged in from a common login city, the system sends " @@ -5479,27 +5482,27 @@ msgstr "LDAP认证没有启用" #: settings/utils/ldap.py:613 msgid "Error (Invalid LDAP server): {}" -msgstr "错误 (不合法的LDAP服务器地址): {}" +msgstr "错误 (不合法的LDAP服务器地址): {}" #: settings/utils/ldap.py:615 msgid "Error (Invalid Bind DN): {}" -msgstr "错误(不合法的绑定DN): {}" +msgstr "错误 (不合法的绑定DN): {}" #: settings/utils/ldap.py:617 msgid "Error (Invalid LDAP User attr map): {}" -msgstr "错误(不合法的LDAP属性映射): {}" +msgstr "错误 (不合法的LDAP属性映射): {}" #: settings/utils/ldap.py:619 msgid "Error (Invalid User OU or User search filter): {}" -msgstr "错误(不合法的用户OU或用户过滤器): {}" +msgstr "错误 (不合法的用户OU或用户过滤器): {}" #: settings/utils/ldap.py:621 msgid "Error (Not enabled LDAP authentication): {}" -msgstr "错误(没有启用LDAP认证): {}" +msgstr "错误 (没有启用LDAP认证): {}" #: settings/utils/ldap.py:623 msgid "Error (Unknown): {}" -msgstr "错误(未知): {}" +msgstr "错误 (未知): {}" #: settings/utils/ldap.py:626 msgid "Succeed: Match {} s user" @@ -5507,7 +5510,7 @@ msgstr "成功匹配 {} 个用户" #: settings/utils/ldap.py:659 msgid "Authentication failed (configuration incorrect): {}" -msgstr "认证失败(配置错误): {}" +msgstr "认证失败 (配置错误): {}" #: settings/utils/ldap.py:663 msgid "Authentication failed (username or password incorrect): {}" @@ -6349,8 +6352,8 @@ msgid "" "access address of the current browser will be used (the default endpoint " "does not allow modification of the host)" msgstr "" -"连接资产时访问的主机地址,如果为空则使用当前浏览器的访问地址(默认端点不允许" -"修改主机)" +"连接资产时访问的主机地址,如果为空则使用当前浏览器的访问地址 (默认端点不允许" +"修改主机)" #: terminal/serializers/endpoint.py:64 msgid "" @@ -6899,8 +6902,8 @@ msgid "" "in. you can also directly bind in \"personal information -> quick " "modification -> change MFA Settings\"!" msgstr "" -"启用之后您将会在下次登录时进入多因子认证绑定流程;您也可以在(个人信息->快速" -"修改->设置 MFA 多因子认证)中直接绑定!" +"启用之后您将会在下次登录时进入多因子认证绑定流程;您也可以在 (个人信息->快速" +"修改->设置 MFA 多因子认证)中直接绑定!" #: users/forms/profile.py:61 msgid "* Enable MFA to make the account more secure." @@ -6912,8 +6915,8 @@ msgid "" "and key sensitive information properly. (for example: setting complex " "password, enabling MFA)" msgstr "" -"为了保护您和公司的安全,请妥善保管您的账号、密码和密钥等重要敏感信息;(如:" -"设置复杂密码,并启用 MFA 多因子认证)" +"为了保护您和公司的安全,请妥善保管您的账号、密码和密钥等重要敏感信息; (如:" +"设置复杂密码,并启用 MFA 多因子认证)" #: users/forms/profile.py:77 msgid "Finish" @@ -7341,7 +7344,7 @@ msgstr "iPhone手机下载" msgid "" "After installation, click the next step to enter the binding page (if " "installed, go to the next step directly)." -msgstr "安装完成后点击下一步进入绑定页面(如已安装,直接进入下一步)" +msgstr "安装完成后点击下一步进入绑定页面 (如已安装,直接进入下一步)" #: users/templates/users/user_password_verify.html:8 #: users/templates/users/user_password_verify.html:9 @@ -7618,95 +7621,95 @@ msgstr "同步实例详情" #: xpack/plugins/cloud/providers/aws_international.py:18 msgid "China (Beijing)" -msgstr "中国(北京)" +msgstr "中国 (北京)" #: xpack/plugins/cloud/providers/aws_international.py:19 msgid "China (Ningxia)" -msgstr "中国(宁夏)" +msgstr "中国 (宁夏)" #: xpack/plugins/cloud/providers/aws_international.py:22 msgid "US East (Ohio)" -msgstr "美国东部(俄亥俄州)" +msgstr "美国东部 (俄亥俄州)" #: xpack/plugins/cloud/providers/aws_international.py:23 msgid "US East (N. Virginia)" -msgstr "美国东部(弗吉尼亚北部)" +msgstr "美国东部 (弗吉尼亚北部)" #: xpack/plugins/cloud/providers/aws_international.py:24 msgid "US West (N. California)" -msgstr "美国西部(加利福尼亚北部)" +msgstr "美国西部 (加利福尼亚北部)" #: xpack/plugins/cloud/providers/aws_international.py:25 msgid "US West (Oregon)" -msgstr "美国西部(俄勒冈)" +msgstr "美国西部 (俄勒冈)" #: xpack/plugins/cloud/providers/aws_international.py:26 msgid "Africa (Cape Town)" -msgstr "非洲(开普敦)" +msgstr "非洲 (开普敦)" #: xpack/plugins/cloud/providers/aws_international.py:27 msgid "Asia Pacific (Hong Kong)" -msgstr "亚太地区(香港)" +msgstr "亚太地区 (香港)" #: xpack/plugins/cloud/providers/aws_international.py:28 msgid "Asia Pacific (Mumbai)" -msgstr "亚太地区(孟买)" +msgstr "亚太地区 (孟买)" #: xpack/plugins/cloud/providers/aws_international.py:29 msgid "Asia Pacific (Osaka-Local)" -msgstr "亚太区域(大阪当地)" +msgstr "亚太区域 (大阪当地)" #: xpack/plugins/cloud/providers/aws_international.py:30 msgid "Asia Pacific (Seoul)" -msgstr "亚太区域(首尔)" +msgstr "亚太区域 (首尔)" #: xpack/plugins/cloud/providers/aws_international.py:31 msgid "Asia Pacific (Singapore)" -msgstr "亚太区域(新加坡)" +msgstr "亚太区域 (新加坡)" #: xpack/plugins/cloud/providers/aws_international.py:32 msgid "Asia Pacific (Sydney)" -msgstr "亚太区域(悉尼)" +msgstr "亚太区域 (悉尼)" #: xpack/plugins/cloud/providers/aws_international.py:33 msgid "Asia Pacific (Tokyo)" -msgstr "亚太区域(东京)" +msgstr "亚太区域 (东京)" #: xpack/plugins/cloud/providers/aws_international.py:34 msgid "Canada (Central)" -msgstr "加拿大(中部)" +msgstr "加拿大 (中部)" #: xpack/plugins/cloud/providers/aws_international.py:35 msgid "Europe (Frankfurt)" -msgstr "欧洲(法兰克福)" +msgstr "欧洲 (法兰克福)" #: xpack/plugins/cloud/providers/aws_international.py:36 msgid "Europe (Ireland)" -msgstr "欧洲(爱尔兰)" +msgstr "欧洲 (爱尔兰)" #: xpack/plugins/cloud/providers/aws_international.py:37 msgid "Europe (London)" -msgstr "欧洲(伦敦)" +msgstr "欧洲 (伦敦)" #: xpack/plugins/cloud/providers/aws_international.py:38 msgid "Europe (Milan)" -msgstr "欧洲(米兰)" +msgstr "欧洲 (米兰)" #: xpack/plugins/cloud/providers/aws_international.py:39 msgid "Europe (Paris)" -msgstr "欧洲(巴黎)" +msgstr "欧洲 (巴黎)" #: xpack/plugins/cloud/providers/aws_international.py:40 msgid "Europe (Stockholm)" -msgstr "欧洲(斯德哥尔摩)" +msgstr "欧洲 (斯德哥尔摩)" #: xpack/plugins/cloud/providers/aws_international.py:41 msgid "Middle East (Bahrain)" -msgstr "中东(巴林)" +msgstr "中东 (巴林)" #: xpack/plugins/cloud/providers/aws_international.py:42 msgid "South America (São Paulo)" -msgstr "南美洲(圣保罗)" +msgstr "南美洲 (圣保罗)" #: xpack/plugins/cloud/providers/baiducloud.py:54 #: xpack/plugins/cloud/providers/jdcloud.py:125 @@ -7995,6 +7998,9 @@ msgstr "旗舰版" msgid "Community edition" msgstr "社区版" +#~ msgid "eg: http://dev.jumpserver.org:8080" +#~ msgstr "如: http://dev.jumpserver.org:8080" + #~ msgid "Strategy" #~ msgstr "策略" diff --git a/apps/settings/serializers/basic.py b/apps/settings/serializers/basic.py index 91a81d45b..1201ee7cb 100644 --- a/apps/settings/serializers/basic.py +++ b/apps/settings/serializers/basic.py @@ -28,7 +28,7 @@ class BasicSettingSerializer(serializers.Serializer): SITE_URL = serializers.URLField( required=True, label=_("Site url"), - help_text=_('eg: http://dev.jumpserver.org:8080') + help_text=_('Email links or other system callbacks are used to access it, eg: http://dev.jumpserver.org:8080') ) USER_GUIDE_URL = serializers.URLField( required=False, allow_blank=True, allow_null=True, label=_("User guide url"), diff --git a/apps/settings/serializers/email.py b/apps/settings/serializers/email.py index ce4568b62..db8f7545e 100644 --- a/apps/settings/serializers/email.py +++ b/apps/settings/serializers/email.py @@ -44,6 +44,10 @@ class EmailSettingSerializer(serializers.Serializer): EMAIL_SUBJECT_PREFIX = serializers.CharField( max_length=1024, required=True, label=_('Subject prefix') ) + 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') + ) class EmailContentSettingSerializer(serializers.Serializer): diff --git a/apps/settings/serializers/other.py b/apps/settings/serializers/other.py index 7cf447ef0..1bdfc9465 100644 --- a/apps/settings/serializers/other.py +++ b/apps/settings/serializers/other.py @@ -5,19 +5,6 @@ from rest_framework import serializers class OtherSettingSerializer(serializers.Serializer): PREFIX_TITLE = _('More...') - 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') - ) - - OTP_ISSUER_NAME = serializers.CharField( - required=False, max_length=16, label=_('OTP issuer name'), - ) - OTP_VALID_WINDOW = serializers.IntegerField( - min_value=1, max_value=10, - label=_("OTP valid window") - ) - PERM_SINGLE_ASSET_TO_UNGROUP_NODE = serializers.BooleanField( required=False, label=_("Perm ungroup node"), help_text=_("Perm single to ungroup node") diff --git a/apps/settings/serializers/security.py b/apps/settings/serializers/security.py index bb1e2207c..c64791ca9 100644 --- a/apps/settings/serializers/security.py +++ b/apps/settings/serializers/security.py @@ -99,24 +99,31 @@ class SecurityAuthSerializer(serializers.Serializer): ONLY_ALLOW_EXIST_USER_AUTH = serializers.BooleanField( required=False, default=False, label=_("Only exist user login"), help_text=_( - "If enabled, non-existent users will not be allowed to log in; if disabled, users of other authentication methods except local authentication methods are allowed to log in and automatically create users (if the user does not exist)") + "If enabled, non-existent users will not be allowed to log in; if disabled, " + "users of other authentication methods except local authentication methods are allowed " + "to log in and automatically create users (if the user does not exist)" + ) ) ONLY_ALLOW_AUTH_FROM_SOURCE = serializers.BooleanField( required=False, default=False, label=_("Only from source login"), help_text=_( - "If it is enabled, the user will only authenticate to the source when logging in; if it is disabled, the user will authenticate all the enabled authentication methods in a certain order when logging in, and as long as one of the authentication methods is successful, they can log in directly") + "If it is enabled, the user will only authenticate to the source when logging in; " + "if it is disabled, the user will authenticate all the enabled authentication methods " + "in a certain order when logging in, and as long as one of the authentication methods is successful, " + "they can log in directly" + ) ) SECURITY_MFA_VERIFY_TTL = serializers.IntegerField( min_value=5, max_value=60 * 60 * 10, - label=_("MFA verify TTL (secend)"), + label=_("MFA verify TTL"), help_text=_( - "The verification MFA takes effect only when you view the account password" + "Unit: second, The verification MFA takes effect only when you view the account password" ) ) VERIFY_CODE_TTL = serializers.IntegerField( min_value=5, max_value=60 * 60 * 10, - label=_("Verify code TTL"), - help_text=_("Unit: second, reset password and send SMS code expiration time") + label=_("Verify code TTL (second)"), + help_text=_("Reset password and send SMS code expiration time") ) SECURITY_LOGIN_CHALLENGE_ENABLED = serializers.BooleanField( required=False, default=False, @@ -207,3 +214,10 @@ class SecuritySettingSerializer(SecurityPasswordRuleSerializer, SecurityAuthSeri 'If the account is logged in from a common login city, the system sends a remote login reminder' ) ) + OTP_ISSUER_NAME = serializers.CharField( + required=False, max_length=16, label=_('OTP issuer name'), + ) + OTP_VALID_WINDOW = serializers.IntegerField( + min_value=1, max_value=10, + label=_("OTP valid window") + ) From 1f8428ac1c01e15cc6f4ff564fd426452a56d782 Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Mon, 14 Aug 2023 22:32:53 +0800 Subject: [PATCH 149/177] =?UTF-8?q?perf:=20=20vault=20=E5=90=8C=E6=AD=A5?= =?UTF-8?q?=E9=80=9F=E5=BA=A6=E9=97=AE=E9=A2=98=20(#11277)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: feng <1304903146@qq.com> --- apps/accounts/backends/base.py | 2 +- apps/accounts/backends/hcp/main.py | 10 ++++- apps/accounts/tasks/vault.py | 70 +++++++++++++++++------------- 3 files changed, 50 insertions(+), 32 deletions(-) diff --git a/apps/accounts/backends/base.py b/apps/accounts/backends/base.py index 12547a7cb..0af8e0167 100644 --- a/apps/accounts/backends/base.py +++ b/apps/accounts/backends/base.py @@ -43,7 +43,7 @@ class BaseVault(ABC): 'name', 'username', 'secret_type', 'connectivity', 'su_from', 'privileged' ]) - metadata = {field: str(value) for field, value in metadata.items()} + metadata = {k: str(v)[:500] for k, v in metadata.items() if v} return self._save_metadata(instance, metadata) # -------- abstractmethod -------- # diff --git a/apps/accounts/backends/hcp/main.py b/apps/accounts/backends/hcp/main.py index 9fb752c1b..53491e975 100644 --- a/apps/accounts/backends/hcp/main.py +++ b/apps/accounts/backends/hcp/main.py @@ -1,9 +1,12 @@ +from common.db.utils import get_logger from .entries import build_entry from .service import VaultKVClient from ..base import BaseVault __all__ = ['Vault'] +logger = get_logger(__name__) + class Vault(BaseVault): def __init__(self, *args, **kwargs): @@ -43,5 +46,8 @@ class Vault(BaseVault): instance.mark_secret_save_to_vault() def _save_metadata(self, instance, metadata): - entry = build_entry(instance) - self.client.update_metadata(path=entry.full_path, metadata=metadata) + try: + entry = build_entry(instance) + self.client.update_metadata(path=entry.full_path, metadata=metadata) + except Exception as e: + logger.error(f'save metadata error: {e}') diff --git a/apps/accounts/tasks/vault.py b/apps/accounts/tasks/vault.py index 154f1f9d7..5ada959d1 100644 --- a/apps/accounts/tasks/vault.py +++ b/apps/accounts/tasks/vault.py @@ -1,4 +1,5 @@ import datetime +from concurrent.futures import ThreadPoolExecutor, as_completed from celery import shared_task from django.utils.translation import gettext_lazy as _ @@ -12,6 +13,22 @@ from ..const import VaultTypeChoices logger = get_logger(__name__) +def sync_instance(instance): + instance_desc = f'[{instance._meta.verbose_name}-{instance.id}-{instance}]' + if instance.secret_has_save_to_vault: + msg = f'\033[32m- 跳过同步: {instance_desc}, 原因: [已同步]' + return "skipped", msg + + try: + vault_client.create(instance) + except Exception as e: + msg = f'\033[31m- 同步失败: {instance_desc}, 原因: [{e}]' + return "failed", msg + else: + msg = f'\033[32m- 同步成功: {instance_desc}' + return "succeeded", msg + + @shared_task(verbose_name=_('Sync secret to vault')) def sync_secret_to_vault(): if vault_client.is_type(VaultTypeChoices.local): @@ -19,39 +36,34 @@ def sync_secret_to_vault(): print('\033[35m>>> 当前 Vault 类型为本地数据库, 不需要同步') return + failed, skipped, succeeded = 0, 0, 0 + to_sync_models = [Account, AccountTemplate, Account.history.model] print('\033[33m>>> 开始同步密钥数据到 Vault ({})'.format(datetime.datetime.now())) with tmp_to_root_org(): - to_sync_models = [Account, AccountTemplate, Account.history.model] + instances = [] for model in to_sync_models: - print(f'\033[33m>>> 开始同步: {model.__module__}') - succeeded = [] - failed = [] - skipped = [] - instances = model.objects.all() - verbose_name = model._meta.original_attrs['verbose_name'] - for instance in instances: - instance_desc = f'[{verbose_name}-{instance.id}-{instance}]' - if instance.secret_has_save_to_vault: - print(f'\033[32m- 跳过同步: {instance_desc}, 原因: [已同步]') - skipped.append(instance) - continue - try: - vault_client.create(instance) - except Exception as e: - failed.append(instance) - print(f'\033[31m- 同步失败: {instance_desc}, 原因: [{e}]') - else: - succeeded.append(instance) - print(f'\033[32m- 同步成功: {instance_desc}') + instances += list(model.objects.all()) - total = len(succeeded) + len(failed) + len(skipped) - print( - f'\033[33m>>> 同步完成: {model.__module__}, ' - f'共计: {total}, ' - f'成功: {len(succeeded)}, ' - f'失败: {len(failed)}, ' - f'跳过: {len(skipped)}' - ) + with ThreadPoolExecutor(max_workers=10) as executor: + tasks = [executor.submit(sync_instance, instance) for instance in instances] + for future in as_completed(tasks): + status, msg = future.result() + print(msg) + if status == "succeeded": + succeeded += 1 + elif status == "failed": + failed += 1 + elif status == "skipped": + skipped += 1 + + total = succeeded + failed + skipped + print( + f'\033[33m>>> 同步完成: {model.__module__}, ' + f'共计: {total}, ' + f'成功: {succeeded}, ' + f'失败: {failed}, ' + f'跳过: {skipped}' + ) print('\033[33m>>> 全部同步完成 ({})'.format(datetime.datetime.now())) print('\033[0m') From 7ba261c4f0a9e6a8f36b924ebb72b580d588d0a4 Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Tue, 15 Aug 2023 10:32:03 +0800 Subject: [PATCH 150/177] =?UTF-8?q?perf:=20vault=20=E5=90=8C=E6=AD=A5?= =?UTF-8?q?=E6=97=A5=E5=BF=97=20(#11278)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: feng <1304903146@qq.com> --- apps/accounts/tasks/vault.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/accounts/tasks/vault.py b/apps/accounts/tasks/vault.py index 5ada959d1..90e78cebf 100644 --- a/apps/accounts/tasks/vault.py +++ b/apps/accounts/tasks/vault.py @@ -1,5 +1,5 @@ -import datetime from concurrent.futures import ThreadPoolExecutor, as_completed +from datetime import datetime from celery import shared_task from django.utils.translation import gettext_lazy as _ @@ -38,7 +38,7 @@ def sync_secret_to_vault(): failed, skipped, succeeded = 0, 0, 0 to_sync_models = [Account, AccountTemplate, Account.history.model] - print('\033[33m>>> 开始同步密钥数据到 Vault ({})'.format(datetime.datetime.now())) + print(f'\033[33m>>> 开始同步密钥数据到 Vault ({datetime.now().strftime("%Y-%m-%d %H:%M:%S")})') with tmp_to_root_org(): instances = [] for model in to_sync_models: @@ -65,5 +65,5 @@ def sync_secret_to_vault(): f'失败: {failed}, ' f'跳过: {skipped}' ) - print('\033[33m>>> 全部同步完成 ({})'.format(datetime.datetime.now())) + print(f'\033[33m>>> 全部同步完成 ({datetime.now().strftime("%Y-%m-%d %H:%M:%S")})') print('\033[0m') From 873e6d1ab939b2ff49c28b3963f5dac48c67ee57 Mon Sep 17 00:00:00 2001 From: BoringCat Date: Tue, 15 Aug 2023 10:31:22 +0800 Subject: [PATCH 151/177] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E9=A3=9E=E4=B9=A6mar?= =?UTF-8?q?kdown=E4=BF=A1=E6=81=AF=E6=B8=B2=E6=9F=93=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/common/sdk/im/feishu/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/common/sdk/im/feishu/__init__.py b/apps/common/sdk/im/feishu/__init__.py index 087a2fb88..67d3f2538 100644 --- a/apps/common/sdk/im/feishu/__init__.py +++ b/apps/common/sdk/im/feishu/__init__.py @@ -117,8 +117,8 @@ class FeiShu(RequestMixin): } body = { - 'msg_type': 'text', - 'content': json.dumps({'text': msg}) + 'msg_type': 'interactive', + 'content': json.dumps({'elements':[{'tag':'markdown','content': msg}]}) } invalid_users = [] From 7707101379f9e3ca54c832989bdb6644e48ab9cf Mon Sep 17 00:00:00 2001 From: Bai Date: Tue, 15 Aug 2023 11:02:57 +0800 Subject: [PATCH 152/177] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=E9=A3=9E?= =?UTF-8?q?=E4=B9=A6=E4=BF=A1=E6=81=AF=E9=80=9A=E7=9F=A5=E6=96=87=E6=A1=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/common/sdk/im/feishu/__init__.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/apps/common/sdk/im/feishu/__init__.py b/apps/common/sdk/im/feishu/__init__.py index 67d3f2538..99194e5c1 100644 --- a/apps/common/sdk/im/feishu/__init__.py +++ b/apps/common/sdk/im/feishu/__init__.py @@ -116,9 +116,13 @@ class FeiShu(RequestMixin): 'receive_id_type': 'user_id' } + """ + https://open.feishu.cn/document/common-capabilities/message-card/message-cards-content + /using-markdown-tags + """ body = { 'msg_type': 'interactive', - 'content': json.dumps({'elements':[{'tag':'markdown','content': msg}]}) + 'content': json.dumps({'elements': [{'tag': 'markdown', 'content': msg}]}) } invalid_users = [] From c4528612d5624e69c7c307dad889aa2557e2e1bf Mon Sep 17 00:00:00 2001 From: ibuler Date: Tue, 15 Aug 2023 13:45:44 +0800 Subject: [PATCH 153/177] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=E5=AE=8C?= =?UTF-8?q?=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/settings/api/settings.py | 8 + apps/settings/api/sms.py | 12 +- apps/settings/serializers/__init__.py | 6 +- apps/settings/serializers/basic.py | 32 +--- apps/settings/serializers/feature.py | 80 +++++++++ .../settings/serializers/{email.py => msg.py} | 10 +- apps/settings/serializers/other.py | 20 +-- apps/settings/serializers/security.py | 158 +++++++++--------- apps/settings/serializers/settings.py | 2 +- apps/settings/serializers/sms.py | 7 - apps/settings/serializers/terminal.py | 6 + apps/settings/serializers/vault.py | 27 --- 12 files changed, 203 insertions(+), 165 deletions(-) create mode 100644 apps/settings/serializers/feature.py rename apps/settings/serializers/{email.py => msg.py} (90%) delete mode 100644 apps/settings/serializers/sms.py delete mode 100644 apps/settings/serializers/vault.py diff --git a/apps/settings/api/settings.py b/apps/settings/api/settings.py index ab7be6e9b..31a25784c 100644 --- a/apps/settings/api/settings.py +++ b/apps/settings/api/settings.py @@ -28,6 +28,11 @@ class SettingsApi(generics.RetrieveUpdateAPIView): 'basic': serializers.BasicSettingSerializer, 'terminal': serializers.TerminalSettingSerializer, 'security': serializers.SecuritySettingSerializer, + 'security_auth': serializers.SecurityAuthSerializer, + 'security_basic': serializers.SecurityBasicSerializer, + 'security_session': serializers.SecuritySessionSerializer, + 'security_password': serializers.SecurityPasswordRuleSerializer, + 'security_login_limit': serializers.SecurityLoginLimitSerializer, 'ldap': serializers.LDAPSettingSerializer, 'email': serializers.EmailSettingSerializer, 'email_content': serializers.EmailContentSettingSerializer, @@ -51,6 +56,9 @@ class SettingsApi(generics.RetrieveUpdateAPIView): 'cmpp2': serializers.CMPP2SMSSettingSerializer, 'custom': serializers.CustomSMSSettingSerializer, 'vault': serializers.VaultSettingSerializer, + 'announcement': serializers.AnnouncementSettingSerializer, + 'ticket': serializers.TicketSettingSerializer, + } rbac_category_permissions = { diff --git a/apps/settings/api/sms.py b/apps/settings/api/sms.py index 01fca4436..ec767828d 100644 --- a/apps/settings/api/sms.py +++ b/apps/settings/api/sms.py @@ -1,18 +1,16 @@ import importlib - from collections import OrderedDict +from django.utils.translation import gettext_lazy as _ +from rest_framework import status +from rest_framework.exceptions import APIException from rest_framework.generics import ListAPIView, GenericAPIView from rest_framework.response import Response -from rest_framework.exceptions import APIException -from rest_framework import status -from django.utils.translation import gettext_lazy as _ -from common.sdk.sms import BACKENDS from common.exceptions import JMSException -from settings.serializers.sms import SMSBackendSerializer +from common.sdk.sms import BACKENDS from settings.models import Setting - +from settings.serializers import SMSBackendSerializer from .. import serializers diff --git a/apps/settings/serializers/__init__.py b/apps/settings/serializers/__init__.py index 7abfb74e3..fe94eb1da 100644 --- a/apps/settings/serializers/__init__.py +++ b/apps/settings/serializers/__init__.py @@ -4,11 +4,11 @@ from .auth import * from .basic import * from .cleaning import * -from .email import * +from .feature import * +from .msg import * +from .msg import * from .other import * from .public import * from .security import * from .settings import * from .terminal import * -from .vault import * - diff --git a/apps/settings/serializers/basic.py b/apps/settings/serializers/basic.py index 1201ee7cb..83c2b65ee 100644 --- a/apps/settings/serializers/basic.py +++ b/apps/settings/serializers/basic.py @@ -1,28 +1,7 @@ -import uuid - from django.utils.translation import gettext_lazy as _ from rest_framework import serializers -class AnnouncementSerializer(serializers.Serializer): - ID = serializers.CharField(required=False, allow_blank=True, allow_null=True) - SUBJECT = serializers.CharField(required=True, max_length=1024, label=_("Subject")) - CONTENT = serializers.CharField(label=_("Content")) - LINK = serializers.URLField( - required=False, allow_null=True, allow_blank=True, - label=_("More url"), default='', - ) - - def to_representation(self, instance): - defaults = {'ID': '', 'SUBJECT': '', 'CONTENT': '', 'LINK': '', 'ENABLED': False} - data = {**defaults, **instance} - return super().to_representation(data) - - def to_internal_value(self, data): - data['ID'] = str(uuid.uuid4()) - return super().to_internal_value(data) - - class BasicSettingSerializer(serializers.Serializer): PREFIX_TITLE = _('Basic') @@ -43,9 +22,14 @@ class BasicSettingSerializer(serializers.Serializer): required=False, max_length=1024, allow_blank=True, allow_null=True, label=_("Global organization name"), help_text=_('The name of global organization to display') ) - ANNOUNCEMENT_ENABLED = serializers.BooleanField(label=_('Enable announcement'), default=True) - ANNOUNCEMENT = AnnouncementSerializer(label=_("Announcement")) - TICKETS_ENABLED = serializers.BooleanField(required=False, default=True, label=_("Enable tickets")) + HELP_DOCUMENT_URL = serializers.URLField( + required=False, allow_blank=True, allow_null=True, label=_("Help Docs URL"), + help_text=_('default: http://docs.jumpserver.org') + ) + HELP_SUPPORT_URL = serializers.URLField( + required=False, allow_blank=True, allow_null=True, label=_("Help Support URL"), + help_text=_('default: http://www.jumpserver.org/support/') + ) @staticmethod def validate_SITE_URL(s): diff --git a/apps/settings/serializers/feature.py b/apps/settings/serializers/feature.py new file mode 100644 index 000000000..8d8f40c4e --- /dev/null +++ b/apps/settings/serializers/feature.py @@ -0,0 +1,80 @@ +import uuid + +from django.utils.translation import gettext_lazy as _ +from rest_framework import serializers + +from accounts.const import VaultTypeChoices +from common.serializers.fields import EncryptedField + +__all__ = [ + 'AnnouncementSettingSerializer', + 'VaultSettingSerializer', 'TicketSettingSerializer' +] + + +class AnnouncementSerializer(serializers.Serializer): + ID = serializers.CharField(required=False, allow_blank=True, allow_null=True) + SUBJECT = serializers.CharField(required=True, max_length=1024, label=_("Subject")) + CONTENT = serializers.CharField(label=_("Content")) + LINK = serializers.URLField( + required=False, allow_null=True, allow_blank=True, + label=_("More url"), default='', + ) + + def to_representation(self, instance): + defaults = {'ID': '', 'SUBJECT': '', 'CONTENT': '', 'LINK': '', 'ENABLED': False} + data = {**defaults, **instance} + return super().to_representation(data) + + def to_internal_value(self, data): + data['ID'] = str(uuid.uuid4()) + return super().to_internal_value(data) + + +class AnnouncementSettingSerializer(serializers.Serializer): + ANNOUNCEMENT_ENABLED = serializers.BooleanField(label=_('Enable announcement'), default=True) + ANNOUNCEMENT = AnnouncementSerializer(label=_("Announcement")) + + +class VaultSettingSerializer(serializers.Serializer): + VAULT_TYPE = serializers.ChoiceField( + default=VaultTypeChoices.local, choices=VaultTypeChoices.choices, + required=False, label=_('Type') + ) + VAULT_HCP_HOST = serializers.CharField( + max_length=256, allow_blank=True, required=False, label=_('Host') + ) + VAULT_HCP_TOKEN = EncryptedField( + max_length=256, allow_blank=True, required=False, label=_('Token'), default='' + ) + VAULT_HCP_MOUNT_POINT = serializers.CharField( + max_length=256, allow_blank=True, required=False, label=_('Mount Point') + ) + + def validate(self, attrs): + attrs.pop('VAULT_TYPE', None) + return attrs + + +class TicketSettingSerializer(serializers.Serializer): + TICKETS_ENABLED = serializers.BooleanField(required=False, default=True, label=_("Enable tickets")) + TICKET_AUTHORIZE_DEFAULT_TIME = serializers.IntegerField( + min_value=1, max_value=999999, required=False, + label=_("Ticket authorize default time") + ) + TICKET_AUTHORIZE_DEFAULT_TIME_UNIT = serializers.ChoiceField( + choices=[('day', _("day")), ('hour', _("hour"))], + label=_("Ticket authorize default time unit"), required=False, + ) + + +class OpsSettingSerializer(serializers.Serializer): + SECURITY_COMMAND_EXECUTION = serializers.BooleanField( + required=False, label=_('Operation center'), + help_text=_('Allow user run batch command or not using ansible') + ) + SECURITY_COMMAND_BLACKLIST = serializers.ListField( + child=serializers.CharField(max_length=1024, ), + label=_('Operation center command blacklist'), + help_text=_("Commands that are not allowed execute.") + ) diff --git a/apps/settings/serializers/email.py b/apps/settings/serializers/msg.py similarity index 90% rename from apps/settings/serializers/email.py rename to apps/settings/serializers/msg.py index db8f7545e..07e8e7205 100644 --- a/apps/settings/serializers/email.py +++ b/apps/settings/serializers/msg.py @@ -6,7 +6,10 @@ from rest_framework import serializers from common.serializers.fields import EncryptedField -__all__ = ['MailTestSerializer', 'EmailSettingSerializer', 'EmailContentSettingSerializer'] +__all__ = [ + 'MailTestSerializer', 'EmailSettingSerializer', + 'EmailContentSettingSerializer', 'SMSBackendSerializer', +] class MailTestSerializer(serializers.Serializer): @@ -73,3 +76,8 @@ class EmailContentSettingSerializer(serializers.Serializer): max_length=512, allow_blank=True, required=False, label=_('Signature'), help_text=_('Tips: Email signature (eg:jumpserver)') ) + + +class SMSBackendSerializer(serializers.Serializer): + name = serializers.CharField(max_length=256, required=True, label=_('Name')) + label = serializers.CharField(max_length=256, required=True, label=_('Label')) diff --git a/apps/settings/serializers/other.py b/apps/settings/serializers/other.py index 1bdfc9465..5b9ee654c 100644 --- a/apps/settings/serializers/other.py +++ b/apps/settings/serializers/other.py @@ -1,6 +1,8 @@ from django.utils.translation import gettext_lazy as _ from rest_framework import serializers +__all__ = ['OtherSettingSerializer'] + class OtherSettingSerializer(serializers.Serializer): PREFIX_TITLE = _('More...') @@ -10,24 +12,6 @@ class OtherSettingSerializer(serializers.Serializer): help_text=_("Perm single to ungroup node") ) - TICKET_AUTHORIZE_DEFAULT_TIME = serializers.IntegerField( - min_value=1, max_value=999999, required=False, - label=_("Ticket authorize default time") - ) - TICKET_AUTHORIZE_DEFAULT_TIME_UNIT = serializers.ChoiceField( - choices=[('day', _("day")), ('hour', _("hour"))], - label=_("Ticket authorize default time unit"), required=False, - ) - HELP_DOCUMENT_URL = serializers.URLField( - required=False, allow_blank=True, allow_null=True, label=_("Help Docs URL"), - help_text=_('default: http://docs.jumpserver.org') - ) - - HELP_SUPPORT_URL = serializers.URLField( - required=False, allow_blank=True, allow_null=True, label=_("Help Support URL"), - help_text=_('default: http://www.jumpserver.org/support/') - ) - # 准备废弃 # PERIOD_TASK_ENABLED = serializers.BooleanField( # required=False, label=_("Enable period task") diff --git a/apps/settings/serializers/security.py b/apps/settings/serializers/security.py index c64791ca9..a5c27f1a1 100644 --- a/apps/settings/serializers/security.py +++ b/apps/settings/serializers/security.py @@ -3,8 +3,31 @@ from rest_framework import serializers from acls.serializers.rules import ip_group_help_text, ip_group_child_validator +__all__ = [ + 'SecurityPasswordRuleSerializer', 'SecuritySessionSerializer', + 'SecurityAuthSerializer', 'SecuritySettingSerializer', + 'SecurityLoginLimitSerializer', 'SecurityBasicSerializer', +] + class SecurityPasswordRuleSerializer(serializers.Serializer): + SECURITY_PASSWORD_EXPIRATION_TIME = serializers.IntegerField( + min_value=1, max_value=99999, required=True, + label=_('User password expiration (day)'), + help_text=_( + 'If the user does not update the password during the time, ' + 'the user password will expire failure;The password expiration reminder mail will be ' + 'automatic sent to the user by system within 5 days (daily) before the password expires' + ) + ) + OLD_PASSWORD_HISTORY_LIMIT_COUNT = serializers.IntegerField( + min_value=0, max_value=99999, required=True, + label=_('Number of repeated historical passwords'), + help_text=_( + 'Tip: When the user resets the password, it cannot be ' + 'the previous n historical passwords of the user' + ) + ) SECURITY_PASSWORD_MIN_LENGTH = serializers.IntegerField( min_value=6, max_value=30, required=True, label=_('Password minimum length') @@ -33,20 +56,7 @@ login_ip_limit_time_help_text = _( ) -class SecurityAuthSerializer(serializers.Serializer): - SECURITY_MFA_AUTH = serializers.ChoiceField( - choices=( - [0, _('Not enabled')], - [1, _('All users')], - [2, _('Only admin users')], - ), - required=False, label=_("Global MFA auth") - ) - SECURITY_MFA_AUTH_ENABLED_FOR_THIRD_PARTY = serializers.BooleanField( - required=False, default=True, - label=_('Third-party login users perform MFA authentication'), - help_text=_('The third-party login modes include OIDC, CAS, and SAML2'), - ) +class SecurityLoginLimitSerializer(serializers.Serializer): SECURITY_LOGIN_LIMIT_COUNT = serializers.IntegerField( min_value=3, max_value=99999, label=_('Limit the number of user login failures') @@ -56,6 +66,7 @@ class SecurityAuthSerializer(serializers.Serializer): label=_('Block user login interval (minute)'), help_text=login_ip_limit_time_help_text ) + SECURITY_LOGIN_IP_LIMIT_COUNT = serializers.IntegerField( min_value=3, max_value=99999, label=_('Limit the number of IP login failures') @@ -75,23 +86,6 @@ class SecurityAuthSerializer(serializers.Serializer): child=serializers.CharField(max_length=1024, validators=[ip_group_child_validator]), help_text=ip_group_help_text ) - SECURITY_PASSWORD_EXPIRATION_TIME = serializers.IntegerField( - min_value=1, max_value=99999, required=True, - label=_('User password expiration (day)'), - help_text=_( - 'If the user does not update the password during the time, ' - 'the user password will expire failure;The password expiration reminder mail will be ' - 'automatic sent to the user by system within 5 days (daily) before the password expires' - ) - ) - OLD_PASSWORD_HISTORY_LIMIT_COUNT = serializers.IntegerField( - min_value=0, max_value=99999, required=True, - label=_('Number of repeated historical passwords'), - help_text=_( - 'Tip: When the user resets the password, it cannot be ' - 'the previous n historical passwords of the user' - ) - ) USER_LOGIN_SINGLE_MACHINE_ENABLED = serializers.BooleanField( required=False, default=False, label=_("Only single device login"), help_text=_("After the user logs in on the new device, other logged-in devices will automatically log out") @@ -113,6 +107,29 @@ class SecurityAuthSerializer(serializers.Serializer): "they can log in directly" ) ) + + +class SecurityAuthSerializer(serializers.Serializer): + SECURITY_MFA_AUTH = serializers.ChoiceField( + choices=( + [0, _('Not enabled')], + [1, _('All users')], + [2, _('Only admin users')], + ), + required=False, label=_("Global MFA auth") + ) + SECURITY_MFA_AUTH_ENABLED_FOR_THIRD_PARTY = serializers.BooleanField( + required=False, default=True, + label=_('Third-party login users perform MFA authentication'), + help_text=_('The third-party login modes include OIDC, CAS, and SAML2'), + ) + OTP_ISSUER_NAME = serializers.CharField( + required=False, max_length=16, label=_('OTP issuer name'), + ) + OTP_VALID_WINDOW = serializers.IntegerField( + min_value=1, max_value=10, + label=_("OTP valid window") + ) SECURITY_MFA_VERIFY_TTL = serializers.IntegerField( min_value=5, max_value=60 * 60 * 10, label=_("MFA verify TTL"), @@ -120,6 +137,11 @@ class SecurityAuthSerializer(serializers.Serializer): "Unit: second, The verification MFA takes effect only when you view the account password" ) ) + SECURITY_MFA_IN_LOGIN_PAGE = serializers.BooleanField( + required=False, default=False, + label=_("MFA in login page"), + help_text=_("Eu security regulations(GDPR) require MFA to be on the login page") + ) VERIFY_CODE_TTL = serializers.IntegerField( min_value=5, max_value=60 * 60 * 10, label=_("Verify code TTL (second)"), @@ -131,15 +153,22 @@ class SecurityAuthSerializer(serializers.Serializer): help_text=_("The password and additional code are sent to a third party " "authentication system for verification") ) - SECURITY_MFA_IN_LOGIN_PAGE = serializers.BooleanField( - required=False, default=False, - label=_("MFA in login page"), - help_text=_("Eu security regulations(GDPR) require MFA to be on the login page") - ) SECURITY_LOGIN_CAPTCHA_ENABLED = serializers.BooleanField( required=False, default=False, label=_("Enable Login captcha"), help_text=_("Enable captcha to prevent robot authentication") ) + SECURITY_CHECK_DIFFERENT_CITY_LOGIN = serializers.BooleanField( + required=False, label=_('Remote Login Protection'), + help_text=_( + 'The system determines whether the login IP address belongs to a common login city. ' + 'If the account is logged in from a common login city, the system sends a remote login reminder' + ) + ) + SECURITY_UNCOMMON_USERS_TTL = serializers.IntegerField( + min_value=30, max_value=99999, required=False, + label=_('Unused user timeout (day)'), + help_text=_("Detect infrequent users daily and disable them if they exceed the predetermined time limit.") + ) def validate(self, attrs): if attrs.get('SECURITY_MFA_AUTH') != 1: @@ -156,15 +185,7 @@ class SecurityAuthSerializer(serializers.Serializer): return data -class SecuritySettingSerializer(SecurityPasswordRuleSerializer, SecurityAuthSerializer): - PREFIX_TITLE = _('Security') - - SECURITY_SERVICE_ACCOUNT_REGISTRATION = serializers.BooleanField( - required=True, label=_('Enable terminal register'), - help_text=_( - "Allow terminal register, after all terminal setup, you should disable this for security" - ) - ) +class SecuritySessionSerializer(serializers.Serializer): SECURITY_WATERMARK_ENABLED = serializers.BooleanField( required=True, label=_('Enable watermark'), help_text=_('Enabled, the web session and replay contains watermark information') @@ -182,6 +203,13 @@ class SecuritySettingSerializer(SecurityPasswordRuleSerializer, SecurityAuthSeri SECURITY_LUNA_REMEMBER_AUTH = serializers.BooleanField( label=_("Remember manual auth") ) + SECURITY_SESSION_SHARE = serializers.BooleanField( + required=True, label=_('Session share'), + help_text=_("Enabled, Allows user active session to be shared with other users") + ) + + +class SecurityBasicSerializer(serializers.Serializer): SECURITY_INSECURE_COMMAND = serializers.BooleanField( required=False, label=_('Insecure command alert') ) @@ -189,35 +217,11 @@ class SecuritySettingSerializer(SecurityPasswordRuleSerializer, SecurityAuthSeri max_length=8192, required=False, allow_blank=True, label=_('Email recipient'), help_text=_('Multiple user using , split') ) - SECURITY_COMMAND_EXECUTION = serializers.BooleanField( - required=False, label=_('Operation center'), - help_text=_('Allow user run batch command or not using ansible') - ) - SECURITY_COMMAND_BLACKLIST = serializers.ListField( - child=serializers.CharField(max_length=1024, ), - label=_('Operation center command blacklist'), - help_text=_("Commands that are not allowed execute.") - ) - SECURITY_SESSION_SHARE = serializers.BooleanField( - required=True, label=_('Session share'), - help_text=_("Enabled, Allows user active session to be shared with other users") - ) - SECURITY_UNCOMMON_USERS_TTL = serializers.IntegerField( - min_value=30, max_value=99999, required=False, - label=_('Unused user timeout (day)'), - help_text=_("Detect infrequent users daily and disable them if they exceed the predetermined time limit.") - ) - SECURITY_CHECK_DIFFERENT_CITY_LOGIN = serializers.BooleanField( - required=False, label=_('Remote Login Protection'), - help_text=_( - 'The system determines whether the login IP address belongs to a common login city. ' - 'If the account is logged in from a common login city, the system sends a remote login reminder' - ) - ) - OTP_ISSUER_NAME = serializers.CharField( - required=False, max_length=16, label=_('OTP issuer name'), - ) - OTP_VALID_WINDOW = serializers.IntegerField( - min_value=1, max_value=10, - label=_("OTP valid window") - ) + + +class SecuritySettingSerializer( + SecurityPasswordRuleSerializer, SecurityAuthSerializer, + SecuritySessionSerializer, SecurityBasicSerializer, + SecurityLoginLimitSerializer, +): + PREFIX_TITLE = _('Security') diff --git a/apps/settings/serializers/settings.py b/apps/settings/serializers/settings.py index c0ff911a7..a0e022f77 100644 --- a/apps/settings/serializers/settings.py +++ b/apps/settings/serializers/settings.py @@ -14,7 +14,7 @@ from .auth import ( ) from .basic import BasicSettingSerializer from .cleaning import CleaningSerializer -from .email import EmailSettingSerializer, EmailContentSettingSerializer +from .msg import EmailSettingSerializer, EmailContentSettingSerializer from .other import OtherSettingSerializer from .security import SecuritySettingSerializer from .terminal import TerminalSettingSerializer diff --git a/apps/settings/serializers/sms.py b/apps/settings/serializers/sms.py deleted file mode 100644 index ec78993a6..000000000 --- a/apps/settings/serializers/sms.py +++ /dev/null @@ -1,7 +0,0 @@ -from django.utils.translation import gettext_lazy as _ -from rest_framework import serializers - - -class SMSBackendSerializer(serializers.Serializer): - name = serializers.CharField(max_length=256, required=True, label=_('Name')) - label = serializers.CharField(max_length=256, required=True, label=_('Label')) diff --git a/apps/settings/serializers/terminal.py b/apps/settings/serializers/terminal.py index ea1412cd1..17782a2e0 100644 --- a/apps/settings/serializers/terminal.py +++ b/apps/settings/serializers/terminal.py @@ -18,6 +18,12 @@ class TerminalSettingSerializer(serializers.Serializer): ('25', '25'), ('50', '50'), ) + SECURITY_SERVICE_ACCOUNT_REGISTRATION = serializers.BooleanField( + required=True, label=_('Enable terminal register'), + help_text=_( + "Allow terminal register, after all terminal setup, you should disable this for security" + ) + ) TERMINAL_PASSWORD_AUTH = serializers.BooleanField(required=False, label=_('Password auth')) TERMINAL_PUBLIC_KEY_AUTH = serializers.BooleanField( required=False, label=_('Public key auth'), diff --git a/apps/settings/serializers/vault.py b/apps/settings/serializers/vault.py deleted file mode 100644 index e25c73e6c..000000000 --- a/apps/settings/serializers/vault.py +++ /dev/null @@ -1,27 +0,0 @@ -from django.utils.translation import gettext_lazy as _ -from rest_framework import serializers - -from accounts.const import VaultTypeChoices -from common.serializers.fields import EncryptedField - -__all__ = ['VaultSettingSerializer'] - - -class VaultSettingSerializer(serializers.Serializer): - VAULT_TYPE = serializers.ChoiceField( - default=VaultTypeChoices.local, choices=VaultTypeChoices.choices, - required=False, label=_('Type') - ) - VAULT_HCP_HOST = serializers.CharField( - max_length=256, allow_blank=True, required=False, label=_('Host') - ) - VAULT_HCP_TOKEN = EncryptedField( - max_length=256, allow_blank=True, required=False, label=_('Token'), default='' - ) - VAULT_HCP_MOUNT_POINT = serializers.CharField( - max_length=256, allow_blank=True, required=False, label=_('Mount Point') - ) - - def validate(self, attrs): - attrs.pop('VAULT_TYPE', None) - return attrs From 663ccbca6febd91449043d67a405fc3806082991 Mon Sep 17 00:00:00 2001 From: ibuler Date: Tue, 15 Aug 2023 13:49:56 +0800 Subject: [PATCH 154/177] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=E7=BF=BB?= =?UTF-8?q?=E8=AF=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/locale/zh/LC_MESSAGES/django.po | 4 ++-- apps/terminal/models/applet/host.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po index d6630142c..39125c86a 100644 --- a/apps/locale/zh/LC_MESSAGES/django.po +++ b/apps/locale/zh/LC_MESSAGES/django.po @@ -5262,13 +5262,13 @@ msgstr "开启验证码,防止机器人登录" #: settings/serializers/security.py:163 msgid "Enable terminal register" -msgstr "终端注册" +msgstr "组件注册" #: settings/serializers/security.py:165 msgid "" "Allow terminal register, after all terminal setup, you should disable this " "for security" -msgstr "是否允许终端注册,当所有终端启动后,为了安全应该关闭" +msgstr "是否允许组件注册,当所有终端启动后,为了安全应该关闭" #: settings/serializers/security.py:169 msgid "Enable watermark" diff --git a/apps/terminal/models/applet/host.py b/apps/terminal/models/applet/host.py index 23af7f5ac..d7f5a9a6a 100644 --- a/apps/terminal/models/applet/host.py +++ b/apps/terminal/models/applet/host.py @@ -147,7 +147,7 @@ class AppletHostDeployment(JMSBaseModel): def start(self, **kwargs): # 重新初始化部署,applet host 关联的终端需要删除 - # 否则 tinker 会因终端注册名称相同,造成冲突,执行任务失败 + # 否则 tinker 会因组件注册名称相同,造成冲突,执行任务失败 if self.host.terminal: terminal = self.host.terminal self.host.terminal = None From 12744a08af5b9594681c5c25bb5f721273321110 Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Tue, 15 Aug 2023 15:09:25 +0800 Subject: [PATCH 155/177] =?UTF-8?q?perf:=20vault=20=E6=97=A5=E5=BF=97=20(#?= =?UTF-8?q?11282)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: feng <1304903146@qq.com> --- apps/accounts/backends/hcp/service.py | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/accounts/backends/hcp/service.py b/apps/accounts/backends/hcp/service.py index 179f98edb..b2fd4ae42 100644 --- a/apps/accounts/backends/hcp/service.py +++ b/apps/accounts/backends/hcp/service.py @@ -59,7 +59,6 @@ class VaultKVClient(object): mount_point=self.mount_point ) except exceptions.InvalidPath as e: - logger.error('Get secret error: {}'.format(e)) return {} data = response.get('data', {}) return data From 9e6221443ec7e2fba92be49090dcc9099f98534c Mon Sep 17 00:00:00 2001 From: ibuler Date: Tue, 15 Aug 2023 16:58:41 +0800 Subject: [PATCH 156/177] =?UTF-8?q?perf:=20=E5=86=8D=E6=AC=A1=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=20setting?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/settings/api/settings.py | 3 +-- apps/settings/serializers/auth/base.py | 4 +++- apps/settings/serializers/auth/sso.py | 3 +++ apps/settings/serializers/basic.py | 5 ----- apps/settings/serializers/feature.py | 10 +++++++++- apps/settings/serializers/settings.py | 3 +-- 6 files changed, 17 insertions(+), 11 deletions(-) diff --git a/apps/settings/api/settings.py b/apps/settings/api/settings.py index 31a25784c..bb55dc453 100644 --- a/apps/settings/api/settings.py +++ b/apps/settings/api/settings.py @@ -44,7 +44,6 @@ class SettingsApi(generics.RetrieveUpdateAPIView): 'keycloak': serializers.KeycloakSettingSerializer, 'radius': serializers.RadiusSettingSerializer, 'cas': serializers.CASSettingSerializer, - 'sso': serializers.SSOSettingSerializer, 'saml2': serializers.SAML2SettingSerializer, 'oauth2': serializers.OAuth2SettingSerializer, 'clean': serializers.CleaningSerializer, @@ -58,7 +57,7 @@ class SettingsApi(generics.RetrieveUpdateAPIView): 'vault': serializers.VaultSettingSerializer, 'announcement': serializers.AnnouncementSettingSerializer, 'ticket': serializers.TicketSettingSerializer, - + 'ops': serializers.OpsSettingSerializer, } rbac_category_permissions = { diff --git a/apps/settings/serializers/auth/base.py b/apps/settings/serializers/auth/base.py index ffc6acf1d..16cf535b4 100644 --- a/apps/settings/serializers/auth/base.py +++ b/apps/settings/serializers/auth/base.py @@ -9,14 +9,16 @@ __all__ = [ class AuthSettingSerializer(serializers.Serializer): PREFIX_TITLE = _('Authentication') + AUTH_LDAP = serializers.BooleanField(required=False, label=_('LDAP Auth')) AUTH_CAS = serializers.BooleanField(required=False, label=_('CAS Auth')) AUTH_OPENID = serializers.BooleanField(required=False, label=_('OPENID Auth')) + AUTH_SAML2 = serializers.BooleanField(default=False, label=_("SAML2 Auth")) + AUTH_OAUTH2 = serializers.BooleanField(default=False, label=_("OAuth2 Auth")) AUTH_RADIUS = serializers.BooleanField(required=False, label=_('RADIUS Auth')) AUTH_DINGTALK = serializers.BooleanField(default=False, label=_('DingTalk Auth')) AUTH_FEISHU = serializers.BooleanField(default=False, label=_('FeiShu Auth')) AUTH_WECOM = serializers.BooleanField(default=False, label=_('WeCom Auth')) AUTH_SSO = serializers.BooleanField(default=False, label=_("SSO Auth")) - AUTH_SAML2 = serializers.BooleanField(default=False, label=_("SAML2 Auth")) FORGOT_PASSWORD_URL = serializers.CharField( required=False, allow_blank=True, max_length=1024, label=_("Forgot password url") diff --git a/apps/settings/serializers/auth/sso.py b/apps/settings/serializers/auth/sso.py index 74549c72f..fe43357d6 100644 --- a/apps/settings/serializers/auth/sso.py +++ b/apps/settings/serializers/auth/sso.py @@ -7,6 +7,9 @@ __all__ = [ class SSOSettingSerializer(serializers.Serializer): + """ + 不对外开放了,只能通过配置文件修改,比较这个稍微有点危险 + """ PREFIX_TITLE = _('SSO') AUTH_SSO = serializers.BooleanField( diff --git a/apps/settings/serializers/basic.py b/apps/settings/serializers/basic.py index 83c2b65ee..baa5edb68 100644 --- a/apps/settings/serializers/basic.py +++ b/apps/settings/serializers/basic.py @@ -13,11 +13,6 @@ class BasicSettingSerializer(serializers.Serializer): required=False, allow_blank=True, allow_null=True, label=_("User guide url"), help_text=_('User first login update profile done redirect to it') ) - FORGOT_PASSWORD_URL = serializers.URLField( - required=False, allow_blank=True, allow_null=True, label=_("Forgot password url"), - help_text=_('The forgot password url on login page, If you use ' - 'ldap or cas external authentication, you can set it') - ) GLOBAL_ORG_DISPLAY_NAME = serializers.CharField( required=False, max_length=1024, allow_blank=True, allow_null=True, label=_("Global organization name"), help_text=_('The name of global organization to display') diff --git a/apps/settings/serializers/feature.py b/apps/settings/serializers/feature.py index 8d8f40c4e..d9d6d7ec5 100644 --- a/apps/settings/serializers/feature.py +++ b/apps/settings/serializers/feature.py @@ -7,7 +7,7 @@ from accounts.const import VaultTypeChoices from common.serializers.fields import EncryptedField __all__ = [ - 'AnnouncementSettingSerializer', + 'AnnouncementSettingSerializer', 'OpsSettingSerializer', 'VaultSettingSerializer', 'TicketSettingSerializer' ] @@ -32,11 +32,15 @@ class AnnouncementSerializer(serializers.Serializer): class AnnouncementSettingSerializer(serializers.Serializer): + PREFIX_TITLE = _('Announcement') + ANNOUNCEMENT_ENABLED = serializers.BooleanField(label=_('Enable announcement'), default=True) ANNOUNCEMENT = AnnouncementSerializer(label=_("Announcement")) class VaultSettingSerializer(serializers.Serializer): + PREFIX_TITLE = _('Vault') + VAULT_TYPE = serializers.ChoiceField( default=VaultTypeChoices.local, choices=VaultTypeChoices.choices, required=False, label=_('Type') @@ -57,6 +61,8 @@ class VaultSettingSerializer(serializers.Serializer): class TicketSettingSerializer(serializers.Serializer): + PREFIX_TITLE = _('Ticket') + TICKETS_ENABLED = serializers.BooleanField(required=False, default=True, label=_("Enable tickets")) TICKET_AUTHORIZE_DEFAULT_TIME = serializers.IntegerField( min_value=1, max_value=999999, required=False, @@ -69,6 +75,8 @@ class TicketSettingSerializer(serializers.Serializer): class OpsSettingSerializer(serializers.Serializer): + PREFIX_TITLE = _('Feature') + SECURITY_COMMAND_EXECUTION = serializers.BooleanField( required=False, label=_('Operation center'), help_text=_('Allow user run batch command or not using ansible') diff --git a/apps/settings/serializers/settings.py b/apps/settings/serializers/settings.py index a0e022f77..2d38ed74a 100644 --- a/apps/settings/serializers/settings.py +++ b/apps/settings/serializers/settings.py @@ -9,7 +9,7 @@ from .auth import ( CASSettingSerializer, RadiusSettingSerializer, FeiShuSettingSerializer, WeComSettingSerializer, DingTalkSettingSerializer, AlibabaSMSSettingSerializer, TencentSMSSettingSerializer, CMPP2SMSSettingSerializer, AuthSettingSerializer, - SAML2SettingSerializer, OAuth2SettingSerializer, SSOSettingSerializer, + SAML2SettingSerializer, OAuth2SettingSerializer, CustomSMSSettingSerializer, ) from .basic import BasicSettingSerializer @@ -42,7 +42,6 @@ class SettingsSerializer( KeycloakSettingSerializer, CASSettingSerializer, RadiusSettingSerializer, - SSOSettingSerializer, CleaningSerializer, AlibabaSMSSettingSerializer, TencentSMSSettingSerializer, From 362c2a95090878012e9ea435a3101a7d1b6f572c Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Tue, 15 Aug 2023 18:24:01 +0800 Subject: [PATCH 157/177] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=E7=BF=BB?= =?UTF-8?q?=E8=AF=91=20=E8=B4=A6=E5=8F=B7=E6=A8=A1=E7=89=88=E6=89=B9?= =?UTF-8?q?=E9=87=8F=E6=B7=BB=E5=8A=A0=20config=E9=85=8D=E7=BD=AE=E6=96=87?= =?UTF-8?q?=E4=BB=B6=20(#11286)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: feng <1304903146@qq.com> --- apps/accounts/serializers/account/account.py | 2 + apps/locale/ja/LC_MESSAGES/django.mo | 4 +- apps/locale/ja/LC_MESSAGES/django.po | 795 +++++++++---------- apps/locale/zh/LC_MESSAGES/django.mo | 4 +- apps/locale/zh/LC_MESSAGES/django.po | 760 ++++++++---------- config_example.yml | 3 + 6 files changed, 711 insertions(+), 857 deletions(-) diff --git a/apps/accounts/serializers/account/account.py b/apps/accounts/serializers/account/account.py index 9a4f1536b..e3ec5923c 100644 --- a/apps/accounts/serializers/account/account.py +++ b/apps/accounts/serializers/account/account.py @@ -95,6 +95,8 @@ class AccountCreateUpdateSerializerMixin(serializers.Serializer): field.name for field in template._meta.fields if field.name not in ignore_fields ] + field_names = [name if name != '_secret' else 'secret' for name in field_names] + attrs = {} for name in field_names: value = getattr(template, name, None) diff --git a/apps/locale/ja/LC_MESSAGES/django.mo b/apps/locale/ja/LC_MESSAGES/django.mo index 2c4a07054..2e46fa34c 100644 --- a/apps/locale/ja/LC_MESSAGES/django.mo +++ b/apps/locale/ja/LC_MESSAGES/django.mo @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:762fb91213e28a5545cb4706bd0cd6097965b3bb4a234fa89d945428f36bab5d -size 152159 +oid sha256:810d46e14e09a2309a8d898bc391f33082bfc5c164dec246bd95cea8436e33ee +size 154540 diff --git a/apps/locale/ja/LC_MESSAGES/django.po b/apps/locale/ja/LC_MESSAGES/django.po index 316a1c628..98f9f02bb 100644 --- a/apps/locale/ja/LC_MESSAGES/django.po +++ b/apps/locale/ja/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-08-10 18:22+0800\n" +"POT-Creation-Date: 2023-08-15 16:45+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -45,7 +45,7 @@ msgid "Access key" msgstr "アクセスキー" #: accounts/const/account.py:9 assets/models/_user.py:48 -#: authentication/models/sso_token.py:14 settings/serializers/vault.py:19 +#: authentication/models/sso_token.py:14 settings/serializers/feature.py:48 msgid "Token" msgstr "トークン" @@ -87,7 +87,7 @@ msgstr "テンプレート" msgid "Skip" msgstr "スキップ" -#: accounts/const/account.py:32 audits/const.py:24 rbac/tree.py:230 +#: accounts/const/account.py:32 audits/const.py:24 rbac/tree.py:233 #: templates/_csv_import_export.html:18 templates/_csv_update_modal.html:6 msgid "Update" msgstr "更新" @@ -198,8 +198,8 @@ msgstr "HashiCorp Vault" #: accounts/models/account.py:48 #: accounts/models/automations/gather_account.py:16 -#: accounts/serializers/account/account.py:200 -#: accounts/serializers/account/account.py:245 +#: accounts/serializers/account/account.py:202 +#: accounts/serializers/account/account.py:247 #: accounts/serializers/account/gathered_account.py:10 #: accounts/serializers/automations/change_secret.py:112 #: accounts/serializers/automations/change_secret.py:132 @@ -218,8 +218,8 @@ msgid "Asset" msgstr "資産" #: accounts/models/account.py:52 accounts/models/template.py:15 -#: accounts/serializers/account/account.py:207 -#: accounts/serializers/account/account.py:255 +#: accounts/serializers/account/account.py:209 +#: accounts/serializers/account/account.py:257 #: accounts/serializers/account/template.py:16 #: authentication/serializers/connect_token_secret.py:49 msgid "Su from" @@ -230,7 +230,7 @@ msgstr "から切り替え" msgid "Version" msgstr "バージョン" -#: accounts/models/account.py:56 accounts/serializers/account/account.py:202 +#: accounts/models/account.py:56 accounts/serializers/account/account.py:204 #: users/models/user.py:838 msgid "Source" msgstr "ソース" @@ -367,7 +367,7 @@ msgid "Can add push account execution" msgstr "プッシュ アカウントの作成の実行" #: accounts/models/automations/change_secret.py:18 accounts/models/base.py:36 -#: accounts/serializers/account/account.py:427 +#: accounts/serializers/account/account.py:429 #: accounts/serializers/account/base.py:16 #: accounts/serializers/automations/change_secret.py:46 #: authentication/serializers/connect_token_secret.py:41 @@ -426,7 +426,7 @@ msgid "Date finished" msgstr "終了日" #: accounts/models/automations/change_secret.py:93 -#: accounts/serializers/account/account.py:247 assets/const/automation.py:8 +#: accounts/serializers/account/account.py:249 assets/const/automation.py:8 #: authentication/views/base.py:26 authentication/views/base.py:27 #: authentication/views/base.py:28 common/const/choices.py:20 msgid "Error" @@ -508,7 +508,7 @@ msgstr "アカウントの確認" #: ops/models/adhoc.py:20 ops/models/celery.py:15 ops/models/celery.py:57 #: ops/models/job.py:119 ops/models/playbook.py:28 ops/serializers/job.py:20 #: orgs/models.py:82 perms/models/asset_permission.py:56 rbac/models/role.py:29 -#: settings/models.py:32 settings/serializers/sms.py:6 +#: settings/models.py:32 settings/serializers/msg.py:82 #: terminal/models/applet/applet.py:32 terminal/models/component/endpoint.py:12 #: terminal/models/component/endpoint.py:94 #: terminal/models/component/storage.py:26 terminal/models/component/task.py:13 @@ -622,7 +622,7 @@ msgstr "今すぐプッシュ" msgid "Exist policy" msgstr "アカウントの存在ポリシー" -#: accounts/serializers/account/account.py:180 applications/models.py:11 +#: accounts/serializers/account/account.py:182 applications/models.py:11 #: assets/models/label.py:21 assets/models/platform.py:89 #: assets/serializers/asset/common.py:121 assets/serializers/cagegory.py:8 #: assets/serializers/platform.py:128 assets/serializers/platform.py:224 @@ -631,7 +631,7 @@ msgstr "アカウントの存在ポリシー" msgid "Category" msgstr "カテゴリ" -#: accounts/serializers/account/account.py:181 +#: accounts/serializers/account/account.py:183 #: accounts/serializers/automations/base.py:54 acls/models/command_acl.py:24 #: acls/serializers/command_acl.py:18 applications/models.py:14 #: assets/models/_user.py:50 assets/models/automations/base.py:20 @@ -639,7 +639,7 @@ msgstr "カテゴリ" #: assets/serializers/asset/common.py:122 assets/serializers/platform.py:112 #: assets/serializers/platform.py:127 audits/serializers.py:49 #: authentication/serializers/connect_token_secret.py:123 ops/models/job.py:130 -#: perms/serializers/user_permission.py:27 settings/serializers/vault.py:13 +#: perms/serializers/user_permission.py:27 settings/serializers/feature.py:42 #: terminal/models/applet/applet.py:38 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:226 @@ -650,26 +650,26 @@ msgstr "カテゴリ" msgid "Type" msgstr "タイプ" -#: accounts/serializers/account/account.py:196 +#: accounts/serializers/account/account.py:198 msgid "Asset not found" msgstr "資産が存在しません" -#: accounts/serializers/account/account.py:236 +#: accounts/serializers/account/account.py:238 msgid "Has secret" msgstr "エスクローされたパスワード" -#: accounts/serializers/account/account.py:246 ops/models/celery.py:60 +#: accounts/serializers/account/account.py:248 ops/models/celery.py:60 #: tickets/models/comment.py:13 tickets/models/ticket/general.py:45 #: tickets/models/ticket/general.py:279 tickets/serializers/super_ticket.py:14 #: tickets/serializers/ticket/ticket.py:21 msgid "State" msgstr "状態" -#: accounts/serializers/account/account.py:248 +#: accounts/serializers/account/account.py:250 msgid "Changed" msgstr "編集済み" -#: accounts/serializers/account/account.py:258 +#: accounts/serializers/account/account.py:260 #: accounts/serializers/automations/base.py:22 acls/models/base.py:97 #: assets/models/automations/base.py:19 #: assets/serializers/automations/base.py:20 ops/models/base.py:17 @@ -678,27 +678,27 @@ msgstr "編集済み" msgid "Assets" msgstr "資産" -#: accounts/serializers/account/account.py:313 +#: accounts/serializers/account/account.py:315 msgid "Account already exists" msgstr "アカウントはすでに存在しています" -#: accounts/serializers/account/account.py:363 +#: accounts/serializers/account/account.py:365 #, python-format msgid "Asset does not support this secret type: %s" msgstr "アセットはアカウント タイプをサポートしていません: %s" -#: accounts/serializers/account/account.py:395 +#: accounts/serializers/account/account.py:397 msgid "Account has exist" msgstr "アカウントはすでに存在しています" -#: accounts/serializers/account/account.py:428 +#: accounts/serializers/account/account.py:430 #: authentication/serializers/connect_token_secret.py:156 #: authentication/templates/authentication/_access_key_modal.html:30 #: perms/models/perm_node.py:21 users/serializers/group.py:31 msgid "ID" msgstr "ID" -#: accounts/serializers/account/account.py:435 acls/serializers/base.py:116 +#: accounts/serializers/account/account.py:437 acls/serializers/base.py:116 #: assets/models/cmd_filter.py:24 assets/models/label.py:16 audits/models.py:49 #: audits/models.py:85 audits/models.py:163 #: authentication/models/connection_token.py:32 @@ -717,7 +717,7 @@ msgstr "ID" msgid "User" msgstr "ユーザー" -#: accounts/serializers/account/account.py:436 +#: accounts/serializers/account/account.py:438 #: authentication/templates/authentication/_access_key_modal.html:33 #: terminal/notifications.py:158 terminal/notifications.py:207 msgid "Date" @@ -841,7 +841,7 @@ msgstr "資産の口座番号を収集する" msgid "Push accounts to assets" msgstr "アカウントをアセットにプッシュ:" -#: accounts/tasks/vault.py:15 +#: accounts/tasks/vault.py:32 msgid "Sync secret to vault" msgstr "秘密をVaultに同期する" @@ -940,7 +940,7 @@ msgid "Regex" msgstr "正規情報" #: acls/models/command_acl.py:26 assets/models/cmd_filter.py:79 -#: settings/serializers/basic.py:10 xpack/plugins/license/models.py:30 +#: settings/serializers/feature.py:18 xpack/plugins/license/models.py:30 msgid "Content" msgstr "コンテンツ" @@ -1158,7 +1158,7 @@ msgstr "資産情報の収集" msgid "Disabled" msgstr "無効" -#: assets/const/base.py:34 settings/serializers/basic.py:27 +#: assets/const/base.py:34 settings/serializers/basic.py:6 msgid "Basic" msgstr "基本" @@ -1169,7 +1169,7 @@ msgstr "脚本" #: assets/const/category.py:10 assets/models/asset/host.py:8 #: settings/serializers/auth/radius.py:16 settings/serializers/auth/sms.py:67 -#: settings/serializers/vault.py:16 terminal/models/component/endpoint.py:13 +#: settings/serializers/feature.py:45 terminal/models/component/endpoint.py:13 #: terminal/serializers/applet.py:17 #: xpack/plugins/cloud/serializers/account_attrs.py:72 msgid "Host" @@ -1246,7 +1246,7 @@ msgstr "コンソールセッションに接続" msgid "Any" msgstr "任意" -#: assets/const/protocol.py:66 settings/serializers/security.py:160 +#: assets/const/protocol.py:66 settings/serializers/security.py:227 msgid "Security" msgstr "セキュリティ" @@ -1283,7 +1283,7 @@ msgid "We will consider login success when we see this prompt" msgstr "このプロンプトが表示されたらログイン成功とみなします" #: assets/const/protocol.py:112 assets/models/asset/database.py:10 -#: settings/serializers/email.py:37 +#: settings/serializers/msg.py:40 msgid "Use SSL" msgstr "SSLの使用" @@ -1630,7 +1630,7 @@ msgstr "値" #: assets/serializers/platform.py:111 #: authentication/serializers/connect_token_secret.py:121 #: common/serializers/common.py:85 perms/serializers/user_permission.py:28 -#: settings/serializers/sms.py:7 +#: settings/serializers/msg.py:83 msgid "Label" msgstr "ラベル" @@ -2077,7 +2077,7 @@ msgstr "Rmdir" #: audits/const.py:14 audits/const.py:25 #: authentication/templates/authentication/_access_key_modal.html:65 -#: perms/const.py:17 rbac/tree.py:231 +#: perms/const.py:17 rbac/tree.py:234 msgid "Delete" msgstr "削除" @@ -2101,7 +2101,7 @@ msgstr "ダウンロード" msgid "Rename dir" msgstr "マップディレクトリ" -#: audits/const.py:23 rbac/tree.py:229 +#: audits/const.py:23 rbac/tree.py:232 #: terminal/templates/terminal/_msg_command_warning.html:18 #: terminal/templates/terminal/_msg_session_sharing.html:10 msgid "View" @@ -2109,7 +2109,7 @@ msgstr "表示" #: audits/const.py:26 #: authentication/templates/authentication/_access_key_modal.html:22 -#: rbac/tree.py:228 +#: rbac/tree.py:231 msgid "Create" msgstr "作成" @@ -2393,7 +2393,7 @@ msgstr "" "ユーザーは {}からです。対応するシステムにアクセスしてパスワードを変更してくだ" "さい。" -#: authentication/api/password.py:60 +#: authentication/api/password.py:64 #: authentication/templates/authentication/login.html:305 #: users/templates/users/forgot_password.html:27 #: users/templates/users/forgot_password.html:28 @@ -2895,8 +2895,8 @@ msgstr "期限切れです" #: authentication/serializers/password_mfa.py:16 #: authentication/serializers/password_mfa.py:24 -#: notifications/backends/__init__.py:10 settings/serializers/email.py:19 -#: settings/serializers/email.py:50 users/forms/profile.py:102 +#: notifications/backends/__init__.py:10 settings/serializers/msg.py:22 +#: settings/serializers/msg.py:57 users/forms/profile.py:102 #: users/forms/profile.py:109 users/models/user.py:789 #: users/templates/users/forgot_password.html:117 #: users/views/profile/reset.py:73 @@ -4034,7 +4034,7 @@ msgstr "" msgid "The organization have resource ({}) cannot be deleted" msgstr "組織のリソース ({}) は削除できません" -#: orgs/apps.py:7 rbac/tree.py:119 +#: orgs/apps.py:7 rbac/tree.py:122 msgid "App organizations" msgstr "アプリ組織" @@ -4366,24 +4366,24 @@ msgstr "私の資産" msgid "Applet" msgstr "リモートアプリケーション" -#: rbac/tree.py:120 +#: rbac/tree.py:123 msgid "Ticket comment" msgstr "チケットコメント" -#: rbac/tree.py:121 tickets/models/ticket/general.py:307 +#: rbac/tree.py:124 tickets/models/ticket/general.py:307 msgid "Ticket" msgstr "チケット" -#: rbac/tree.py:122 +#: rbac/tree.py:125 msgid "Common setting" msgstr "共通設定" -#: rbac/tree.py:123 +#: rbac/tree.py:126 msgid "View permission tree" msgstr "権限ツリーの表示" #: settings/api/dingtalk.py:31 settings/api/feishu.py:36 -#: settings/api/sms.py:155 settings/api/vault.py:40 settings/api/wecom.py:37 +#: settings/api/sms.py:153 settings/api/vault.py:40 settings/api/wecom.py:37 msgid "Test success" msgstr "テストの成功" @@ -4411,11 +4411,11 @@ msgstr "Ldapユーザーを取得するにはNone" msgid "Imported {} users successfully (Organization: {})" msgstr "{} 人のユーザーを正常にインポートしました (組織: {})" -#: settings/api/sms.py:137 +#: settings/api/sms.py:135 msgid "Invalid SMS platform" msgstr "無効なショートメッセージプラットフォーム" -#: settings/api/sms.py:143 +#: settings/api/sms.py:141 msgid "test_phone is required" msgstr "携帯番号をテストこのフィールドは必須です" @@ -4503,7 +4503,7 @@ msgstr "SSO Token 認証" msgid "SAML2 Auth" msgstr "SAML2 認証" -#: settings/serializers/auth/base.py:22 settings/serializers/basic.py:38 +#: settings/serializers/auth/base.py:22 settings/serializers/basic.py:17 msgid "Forgot password url" msgstr "パスワードのURLを忘れた" @@ -4794,7 +4794,7 @@ msgstr "SMSプロバイダ / プロトコル" #: settings/serializers/auth/sms.py:23 settings/serializers/auth/sms.py:45 #: settings/serializers/auth/sms.py:53 settings/serializers/auth/sms.py:62 -#: settings/serializers/auth/sms.py:73 settings/serializers/email.py:69 +#: settings/serializers/auth/sms.py:73 settings/serializers/msg.py:76 msgid "Signature" msgstr "署名" @@ -4887,32 +4887,24 @@ msgid "Enable WeCom Auth" msgstr "企業微信認証の有効化" #: settings/serializers/basic.py:9 -msgid "Subject" -msgstr "件名" - -#: settings/serializers/basic.py:13 -msgid "More url" -msgstr "もっとURL" - -#: settings/serializers/basic.py:30 msgid "Site url" msgstr "サイトURL" -#: settings/serializers/basic.py:31 +#: settings/serializers/basic.py:10 msgid "" "Email links or other system callbacks are used to access it, eg: http://dev." "jumpserver.org:8080" msgstr "" -#: settings/serializers/basic.py:34 +#: settings/serializers/basic.py:13 msgid "User guide url" msgstr "ユーザーガイドurl" -#: settings/serializers/basic.py:35 +#: settings/serializers/basic.py:14 msgid "User first login update profile done redirect to it" msgstr "ユーザーの最初のログイン更新プロファイルがリダイレクトされました" -#: settings/serializers/basic.py:39 +#: settings/serializers/basic.py:18 msgid "" "The forgot password url on login page, If you use ldap or cas external " "authentication, you can set it" @@ -4920,25 +4912,29 @@ msgstr "" "ログインページでパスワードのURLを忘れてしまいました。ldapまたはcasの外部認証" "を使用している場合は、設定できます。" -#: settings/serializers/basic.py:43 +#: settings/serializers/basic.py:22 msgid "Global organization name" msgstr "グローバル組織名" -#: settings/serializers/basic.py:44 +#: settings/serializers/basic.py:23 msgid "The name of global organization to display" msgstr "表示するグローバル組織の名前" -#: settings/serializers/basic.py:46 -msgid "Enable announcement" -msgstr "アナウンスの有効化" +#: settings/serializers/basic.py:26 +msgid "Help Docs URL" +msgstr "ドキュメントリンク" -#: settings/serializers/basic.py:47 -msgid "Announcement" -msgstr "発表" +#: settings/serializers/basic.py:27 +msgid "default: http://docs.jumpserver.org" +msgstr "デフォルト: http://docs.jumpserver.org" -#: settings/serializers/basic.py:48 -msgid "Enable tickets" -msgstr "チケットを有効にする" +#: settings/serializers/basic.py:30 +msgid "Help Support URL" +msgstr "サポートリンク" + +#: settings/serializers/basic.py:31 +msgid "default: http://www.jumpserver.org/support/" +msgstr "デフォルト: http://www.jumpserver.org/support/" #: settings/serializers/cleaning.py:8 msgid "Period clean" @@ -4980,65 +4976,130 @@ msgstr "" msgid "Activity log keep days (day)" msgstr "活動ログは日数を保持します(天)" -#: settings/serializers/email.py:21 +#: settings/serializers/feature.py:17 +msgid "Subject" +msgstr "件名" + +#: settings/serializers/feature.py:21 +msgid "More url" +msgstr "もっとURL" + +#: settings/serializers/feature.py:35 +msgid "Enable announcement" +msgstr "アナウンスの有効化" + +#: settings/serializers/feature.py:36 +msgid "Announcement" +msgstr "発表" + +#: settings/serializers/feature.py:51 +msgid "Mount Point" +msgstr "" + +#: settings/serializers/feature.py:60 +msgid "Enable tickets" +msgstr "チケットを有効にする" + +#: settings/serializers/feature.py:63 +msgid "Ticket authorize default time" +msgstr "デフォルト製造オーダ承認時間" + +#: settings/serializers/feature.py:66 +msgid "day" +msgstr "日" + +#: settings/serializers/feature.py:66 +msgid "hour" +msgstr "時" + +#: settings/serializers/feature.py:67 +msgid "Ticket authorize default time unit" +msgstr "デフォルト製造オーダ承認時間単位" + +#: settings/serializers/feature.py:73 +msgid "Operation center" +msgstr "職業センター" + +#: settings/serializers/feature.py:74 +msgid "Allow user run batch command or not using ansible" +msgstr "ユーザー実行バッチコマンドを許可するか、ansibleを使用しない" + +#: settings/serializers/feature.py:78 +msgid "Operation center command blacklist" +msgstr "オペレーション センター コマンド ブラックリスト" + +#: settings/serializers/feature.py:79 +msgid "Commands that are not allowed execute." +msgstr "実行が許可されていないコマンド" + +#: settings/serializers/msg.py:24 msgid "SMTP host" msgstr "SMTPホスト" -#: settings/serializers/email.py:22 +#: settings/serializers/msg.py:25 msgid "SMTP port" msgstr "SMTPポート" -#: settings/serializers/email.py:23 +#: settings/serializers/msg.py:26 msgid "SMTP account" msgstr "SMTPアカウント" -#: settings/serializers/email.py:25 +#: settings/serializers/msg.py:28 msgid "SMTP password" msgstr "SMTPパスワード" -#: settings/serializers/email.py:26 +#: settings/serializers/msg.py:29 msgid "Tips: Some provider use token except password" msgstr "ヒント: 一部のプロバイダーはパスワード以外のトークンを使用します" -#: settings/serializers/email.py:29 +#: settings/serializers/msg.py:32 msgid "Send user" msgstr "ユーザーを送信" -#: settings/serializers/email.py:30 +#: settings/serializers/msg.py:33 msgid "Tips: Send mail account, default SMTP account as the send account" msgstr "" "ヒント: 送信メールアカウント、送信アカウントとしてのデフォルトのSMTPアカウン" "ト" -#: settings/serializers/email.py:33 +#: settings/serializers/msg.py:36 msgid "Test recipient" msgstr "テスト受信者" -#: settings/serializers/email.py:34 +#: settings/serializers/msg.py:37 msgid "Tips: Used only as a test mail recipient" msgstr "ヒント: テストメールの受信者としてのみ使用" -#: settings/serializers/email.py:38 +#: settings/serializers/msg.py:41 msgid "If SMTP port is 465, may be select" msgstr "SMTPポートが465の場合は、" -#: settings/serializers/email.py:41 +#: settings/serializers/msg.py:44 msgid "Use TLS" msgstr "TLSの使用" -#: settings/serializers/email.py:42 +#: settings/serializers/msg.py:45 msgid "If SMTP port is 587, may be select" msgstr "SMTPポートが587の場合は、" -#: settings/serializers/email.py:45 +#: settings/serializers/msg.py:48 msgid "Subject prefix" msgstr "件名プレフィックス" -#: settings/serializers/email.py:54 +#: settings/serializers/msg.py:51 +msgid "Email suffix" +msgstr "メールのサフィックス" + +#: settings/serializers/msg.py:52 +msgid "" +"This is used by default if no email is returned during SSO authentication" +msgstr "これは、SSO認証中にメールが返されない場合にデフォルトで使用されます。" + +#: settings/serializers/msg.py:61 msgid "Create user email subject" msgstr "ユーザーメール件名の作成" -#: settings/serializers/email.py:55 +#: settings/serializers/msg.py:62 msgid "" "Tips: When creating a user, send the subject of the email (eg:Create account " "successfully)" @@ -5046,20 +5107,20 @@ msgstr "" "ヒント: ユーザーを作成するときに、メールの件名を送信します (例: アカウントを" "正常に作成)" -#: settings/serializers/email.py:59 +#: settings/serializers/msg.py:66 msgid "Create user honorific" msgstr "ユーザー敬語の作成" -#: settings/serializers/email.py:60 +#: settings/serializers/msg.py:67 msgid "Tips: When creating a user, send the honorific of the email (eg:Hello)" msgstr "" "ヒント: ユーザーを作成するときは、メールの敬語を送信します (例: こんにちは)" -#: settings/serializers/email.py:64 +#: settings/serializers/msg.py:71 msgid "Create user email content" msgstr "ユーザーのメールコンテンツを作成する" -#: settings/serializers/email.py:66 +#: settings/serializers/msg.py:73 #, python-brace-format msgid "" "Tips: When creating a user, send the content of the email, support " @@ -5068,163 +5129,30 @@ msgstr "" "ヒント:ユーザーの作成時にパスワード設定メールの内容を送信し、{username}{name}" "{email}ラベルをサポートします。" -#: settings/serializers/email.py:70 +#: settings/serializers/msg.py:77 msgid "Tips: Email signature (eg:jumpserver)" msgstr "ヒント: メール署名 (例: jumpserver)" -#: settings/serializers/other.py:6 +#: settings/serializers/other.py:8 msgid "More..." msgstr "詳細..." -#: settings/serializers/other.py:9 -msgid "Email suffix" -msgstr "メールのサフィックス" - -#: settings/serializers/other.py:10 -msgid "" -"This is used by default if no email is returned during SSO authentication" -msgstr "これは、SSO認証中にメールが返されない場合にデフォルトで使用されます。" - -#: settings/serializers/other.py:14 -msgid "OTP issuer name" -msgstr "OTP発行者名" - -#: settings/serializers/other.py:18 -msgid "OTP valid window" -msgstr "OTP有効なウィンドウ" - -#: settings/serializers/other.py:22 +#: settings/serializers/other.py:11 msgid "Perm ungroup node" msgstr "グループ化されていないノードを表示" -#: settings/serializers/other.py:23 +#: settings/serializers/other.py:12 msgid "Perm single to ungroup node" msgstr "" "グループ化されていないノードに個別に許可された資産を配置し、資産が存在する" "ノードが表示されないようにしますが、そのノードが許可されていないという質問に" "質問" -#: settings/serializers/other.py:28 -msgid "Ticket authorize default time" -msgstr "デフォルト製造オーダ承認時間" - -#: settings/serializers/other.py:31 -msgid "day" -msgstr "日" - -#: settings/serializers/other.py:31 -msgid "hour" -msgstr "時" - -#: settings/serializers/other.py:32 -msgid "Ticket authorize default time unit" -msgstr "デフォルト製造オーダ承認時間単位" - -#: settings/serializers/other.py:35 -msgid "Help Docs URL" -msgstr "ドキュメントリンク" - -#: settings/serializers/other.py:36 -msgid "default: http://docs.jumpserver.org" -msgstr "デフォルト: http://docs.jumpserver.org" - -#: settings/serializers/other.py:40 -msgid "Help Support URL" -msgstr "サポートリンク" - -#: settings/serializers/other.py:41 -msgid "default: http://www.jumpserver.org/support/" -msgstr "デフォルト: http://www.jumpserver.org/support/" - -#: settings/serializers/security.py:10 -msgid "Password minimum length" -msgstr "パスワードの最小長" - -#: settings/serializers/security.py:14 -msgid "Admin user password minimum length" -msgstr "管理者ユーザーパスワードの最小長" - -#: settings/serializers/security.py:17 -msgid "Must contain capital" -msgstr "資本を含める必要があります" - -#: settings/serializers/security.py:20 -msgid "Must contain lowercase" -msgstr "小文字を含める必要があります。" - -#: settings/serializers/security.py:23 -msgid "Must contain numeric" -msgstr "数値を含める必要があります" - -#: settings/serializers/security.py:26 -msgid "Must contain special" -msgstr "特別な" - -#: settings/serializers/security.py:31 -#, fuzzy -#| msgid "" -#| "If the user has failed to log in for a limited number of times, no login " -#| "is allowed during this time interval." -msgid "" -"If the user has failed to log in for a limited number of times, no login is " -"allowed during this time interval." -msgstr "" -"ユーザーが限られた回数だけログインできなかった場合、この時間間隔ではログイン" -"はできません。" - -#: settings/serializers/security.py:39 -msgid "Not enabled" -msgstr "有効化されていません" - -#: settings/serializers/security.py:40 -msgid "All users" -msgstr "すべてのユーザー" - -#: settings/serializers/security.py:41 -msgid "Only admin users" -msgstr "管理者のみ" - -#: settings/serializers/security.py:43 -msgid "Global MFA auth" -msgstr "グローバル有効化MFA認証" - -#: settings/serializers/security.py:47 -msgid "Third-party login users perform MFA authentication" -msgstr "サードパーティのログインユーザーがMFA認証を実行" - -#: settings/serializers/security.py:48 -msgid "The third-party login modes include OIDC, CAS, and SAML2" -msgstr "サードパーティのログインモードには、OIDC、CAS、SAML2" - -#: settings/serializers/security.py:52 -msgid "Limit the number of user login failures" -msgstr "ユーザーログインの失敗数を制限する" - -#: settings/serializers/security.py:56 -msgid "Block user login interval (minute)" -msgstr "ユーザーのログイン間隔をブロックする(分)" - -#: settings/serializers/security.py:61 -msgid "Limit the number of IP login failures" -msgstr "IPログイン失敗の数を制限する" - -#: settings/serializers/security.py:65 -msgid "Block IP login interval (minute)" -msgstr "IPログイン間隔をブロックする(分)" - -#: settings/serializers/security.py:69 -msgid "Login IP White List" -msgstr "ログインIPホワイトリスト" - -#: settings/serializers/security.py:74 -msgid "Login IP Black List" -msgstr "ログインIPブラックリスト" - -#: settings/serializers/security.py:80 +#: settings/serializers/security.py:16 msgid "User password expiration (day)" msgstr "ユーザーパスワードの有効期限(天)" -#: settings/serializers/security.py:82 +#: settings/serializers/security.py:18 msgid "" "If the user does not update the password during the time, the user password " "will expire failure;The password expiration reminder mail will be automatic " @@ -5235,11 +5163,11 @@ msgstr "" "ドの有効期限が切れるリマインダーメールがシステムからユーザーに自動的に送信さ" "れます。" -#: settings/serializers/security.py:89 +#: settings/serializers/security.py:25 msgid "Number of repeated historical passwords" msgstr "繰り返された履歴パスワードの数" -#: settings/serializers/security.py:91 +#: settings/serializers/security.py:27 msgid "" "Tip: When the user resets the password, it cannot be the previous n " "historical passwords of the user" @@ -5247,11 +5175,67 @@ msgstr "" "ヒント: ユーザーがパスワードをリセットすると、ユーザーの前のnの履歴パスワード" "にすることはできません" -#: settings/serializers/security.py:96 +#: settings/serializers/security.py:33 +msgid "Password minimum length" +msgstr "パスワードの最小長" + +#: settings/serializers/security.py:37 +msgid "Admin user password minimum length" +msgstr "管理者ユーザーパスワードの最小長" + +#: settings/serializers/security.py:40 +msgid "Must contain capital" +msgstr "資本を含める必要があります" + +#: settings/serializers/security.py:43 +msgid "Must contain lowercase" +msgstr "小文字を含める必要があります。" + +#: settings/serializers/security.py:46 +msgid "Must contain numeric" +msgstr "数値を含める必要があります" + +#: settings/serializers/security.py:49 +msgid "Must contain special" +msgstr "特別な" + +#: settings/serializers/security.py:54 +msgid "" +"If the user has failed to log in for a limited number of times, no login is " +"allowed during this time interval." +msgstr "" +"ユーザーが限られた回数だけログインできなかった場合、この時間間隔ではログイン" +"はできません。" + +#: settings/serializers/security.py:62 +msgid "Limit the number of user login failures" +msgstr "ユーザーログインの失敗数を制限する" + +#: settings/serializers/security.py:66 +msgid "Block user login interval (minute)" +msgstr "ユーザーのログイン間隔をブロックする(分)" + +#: settings/serializers/security.py:72 +msgid "Limit the number of IP login failures" +msgstr "IPログイン失敗の数を制限する" + +#: settings/serializers/security.py:76 +msgid "Block IP login interval (minute)" +msgstr "IPログイン間隔をブロックする(分)" + +#: settings/serializers/security.py:80 +msgid "Login IP White List" +msgstr "ログインIPホワイトリスト" + +#: settings/serializers/security.py:85 +msgid "Login IP Black List" +msgstr "ログインIPブラックリスト" + +#: settings/serializers/security.py:90 msgid "Only single device login" msgstr "単一デバイスログインのみ" -#: settings/serializers/security.py:97 +#: settings/serializers/security.py:91 msgid "" "After the user logs in on the new device, other logged-in devices will " "automatically log out" @@ -5259,11 +5243,11 @@ msgstr "" "ユーザーが新しいデバイスにログインすると、ログインしている他のデバイスは自動" "的にログアウトします。" -#: settings/serializers/security.py:100 +#: settings/serializers/security.py:94 msgid "Only exist user login" msgstr "ユーザーログインのみ存在" -#: settings/serializers/security.py:102 +#: settings/serializers/security.py:96 msgid "" "If enabled, non-existent users will not be allowed to log in; if disabled, " "users of other authentication methods except local authentication methods " @@ -5274,11 +5258,11 @@ msgstr "" "ローカル認証方法を除く他の認証方法のユーザーはログインでき、ユーザーが自動的" "に作成されます (ユーザーが存在しない場合)。" -#: settings/serializers/security.py:108 +#: settings/serializers/security.py:102 msgid "Only from source login" msgstr "ソースログインからのみ" -#: settings/serializers/security.py:110 +#: settings/serializers/security.py:104 msgid "" "If it is enabled, the user will only authenticate to the source when logging " "in; if it is disabled, the user will authenticate all the enabled " @@ -5289,38 +5273,70 @@ msgstr "" "な場合、ユーザーはログイン時に、いずれかの認証方法が成功する限り、有効なすべ" "ての認証方法を特定の順序で認証します。 、直接ログインできます" -#: settings/serializers/security.py:118 -#, fuzzy -#| msgid "MFA verify TTL (secend)" +#: settings/serializers/security.py:115 +msgid "Not enabled" +msgstr "有効化されていません" + +#: settings/serializers/security.py:116 +msgid "All users" +msgstr "すべてのユーザー" + +#: settings/serializers/security.py:117 +msgid "Only admin users" +msgstr "管理者のみ" + +#: settings/serializers/security.py:119 +msgid "Global MFA auth" +msgstr "グローバル有効化MFA認証" + +#: settings/serializers/security.py:123 +msgid "Third-party login users perform MFA authentication" +msgstr "サードパーティのログインユーザーがMFA認証を実行" + +#: settings/serializers/security.py:124 +msgid "The third-party login modes include OIDC, CAS, and SAML2" +msgstr "サードパーティのログインモードには、OIDC、CAS、SAML2" + +#: settings/serializers/security.py:127 +msgid "OTP issuer name" +msgstr "OTP発行者名" + +#: settings/serializers/security.py:131 +msgid "OTP valid window" +msgstr "OTP有効なウィンドウ" + +#: settings/serializers/security.py:135 msgid "MFA verify TTL" msgstr "MFAはTTLを確認します(秒)" -#: settings/serializers/security.py:120 -#, fuzzy -#| msgid "" -#| "The verification MFA takes effect only when you view the account password" +#: settings/serializers/security.py:137 msgid "" "Unit: second, The verification MFA takes effect only when you view the " "account password" msgstr "検証MFAはアカウントのパスワードを表示したときにのみ有効になります。" -#: settings/serializers/security.py:125 -#, fuzzy -#| msgid "Verify code TTL" +#: settings/serializers/security.py:142 +msgid "MFA in login page" +msgstr "ログインページのMFA" + +#: settings/serializers/security.py:143 +msgid "Eu security regulations(GDPR) require MFA to be on the login page" +msgstr "" +"Euセキュリティ規制 (GDPR) では、MFAがログインページにある必要があります" + +#: settings/serializers/security.py:147 msgid "Verify code TTL (second)" msgstr "認証コード有効時間" -#: settings/serializers/security.py:126 -#, fuzzy -#| msgid "Unit: second, reset password and send SMS code expiration time" +#: settings/serializers/security.py:148 msgid "Reset password and send SMS code expiration time" msgstr "パスワードをリセットしてSMSコードの有効期限を送信します" -#: settings/serializers/security.py:130 +#: settings/serializers/security.py:152 msgid "Enable Login dynamic code" msgstr "ログイン動的コードの有効化" -#: settings/serializers/security.py:131 +#: settings/serializers/security.py:153 msgid "" "The password and additional code are sent to a third party authentication " "system for verification" @@ -5328,123 +5344,19 @@ msgstr "" "パスワードと追加コードは、検証のためにサードパーティの認証システムに送信され" "ます" -#: settings/serializers/security.py:136 -msgid "MFA in login page" -msgstr "ログインページのMFA" - -#: settings/serializers/security.py:137 -msgid "Eu security regulations(GDPR) require MFA to be on the login page" -msgstr "" -"Euセキュリティ規制 (GDPR) では、MFAがログインページにある必要があります" - -#: settings/serializers/security.py:140 +#: settings/serializers/security.py:157 msgid "Enable Login captcha" msgstr "ログインcaptchaの有効化" -#: settings/serializers/security.py:141 +#: settings/serializers/security.py:158 msgid "Enable captcha to prevent robot authentication" msgstr "Captchaを有効にしてロボット認証を防止する" -#: settings/serializers/security.py:163 -msgid "Enable terminal register" -msgstr "ターミナルレジスタの有効化" - -#: settings/serializers/security.py:165 -msgid "" -"Allow terminal register, after all terminal setup, you should disable this " -"for security" -msgstr "" -"ターミナルレジスタを許可し、すべてのターミナルセットアップの後、セキュリティ" -"のためにこれを無効にする必要があります" - -#: settings/serializers/security.py:169 -msgid "Enable watermark" -msgstr "透かしの有効化" - -#: settings/serializers/security.py:170 -msgid "Enabled, the web session and replay contains watermark information" -msgstr "Webセッションとリプレイには透かし情報が含まれています。" - -#: settings/serializers/security.py:174 -msgid "Connection max idle time (minute)" -msgstr "接続最大アイドル時間(分)" - -#: settings/serializers/security.py:175 -msgid "If idle time more than it, disconnect connection." -msgstr "この設定以上の操作がない場合、接続は切断されます" - -#: settings/serializers/security.py:179 -msgid "Session max connection time (hour)" -msgstr "セッション最大接続時間(時間)" - -#: settings/serializers/security.py:180 -msgid "If session connection time more than it, disconnect connection." -msgstr "セッション接続時間がこれを超えると、接続が切断されます" - -#: settings/serializers/security.py:183 -msgid "Remember manual auth" -msgstr "手動入力パスワードの保存" - -#: settings/serializers/security.py:186 -msgid "Insecure command alert" -msgstr "安全でないコマンドアラート" - -#: settings/serializers/security.py:189 -msgid "Email recipient" -msgstr "メール受信者" - -#: settings/serializers/security.py:190 -msgid "Multiple user using , split" -msgstr "複数のユーザーを使用して、分割" - -#: settings/serializers/security.py:193 -msgid "Operation center" -msgstr "職業センター" - -#: settings/serializers/security.py:194 -msgid "Allow user run batch command or not using ansible" -msgstr "ユーザー実行バッチコマンドを許可するか、ansibleを使用しない" - -#: settings/serializers/security.py:198 -msgid "Operation center command blacklist" -msgstr "オペレーション センター コマンド ブラックリスト" - -#: settings/serializers/security.py:199 -msgid "Commands that are not allowed execute." -msgstr "実行が許可されていないコマンド" - -#: settings/serializers/security.py:202 -msgid "Session share" -msgstr "セッション共有" - -#: settings/serializers/security.py:203 -msgid "Enabled, Allows user active session to be shared with other users" -msgstr "" -"ユーザーのアクティブなセッションを他のユーザーと共有できるようにします。" - -#: settings/serializers/security.py:207 -#, fuzzy -#| msgid "Unused user timeout (day)" -msgid "Unused user timeout (day)" -msgstr "未使用のユーザータイムアウト(日)" - -#: settings/serializers/security.py:208 -#, fuzzy -#| msgid "" -#| "Detect infrequent users daily and disable them if they exceed the " -#| "predetermined time limit." -msgid "" -"Detect infrequent users daily and disable them if they exceed the " -"predetermined time limit." -msgstr "" -"毎日、頻度の低いユーザーを検出し、予め決められた時間制限を超えた場合は無効に" -"します。" - -#: settings/serializers/security.py:211 +#: settings/serializers/security.py:161 msgid "Remote Login Protection" msgstr "リモートログイン保護" -#: settings/serializers/security.py:213 +#: settings/serializers/security.py:163 msgid "" "The system determines whether the login IP address belongs to a common login " "city. If the account is logged in from a common login city, the system sends " @@ -5454,6 +5366,67 @@ msgstr "" "します。アカウントが共通のログイン都市からログインしている場合、システムはリ" "モートログインリマインダーを送信します" +#: settings/serializers/security.py:169 +msgid "Unused user timeout (day)" +msgstr "未使用のユーザータイムアウト(日)" + +#: settings/serializers/security.py:170 +msgid "" +"Detect infrequent users daily and disable them if they exceed the " +"predetermined time limit." +msgstr "" +"毎日、頻度の低いユーザーを検出し、予め決められた時間制限を超えた場合は無効に" +"します。" + +#: settings/serializers/security.py:190 +msgid "Enable watermark" +msgstr "透かしの有効化" + +#: settings/serializers/security.py:191 +msgid "Enabled, the web session and replay contains watermark information" +msgstr "Webセッションとリプレイには透かし情報が含まれています。" + +#: settings/serializers/security.py:195 +msgid "Connection max idle time (minute)" +msgstr "接続最大アイドル時間(分)" + +#: settings/serializers/security.py:196 +msgid "If idle time more than it, disconnect connection." +msgstr "この設定以上の操作がない場合、接続は切断されます" + +#: settings/serializers/security.py:200 +msgid "Session max connection time (hour)" +msgstr "セッション最大接続時間(時間)" + +#: settings/serializers/security.py:201 +msgid "If session connection time more than it, disconnect connection." +msgstr "セッション接続時間がこれを超えると、接続が切断されます" + +#: settings/serializers/security.py:204 +msgid "Remember manual auth" +msgstr "手動入力パスワードの保存" + +#: settings/serializers/security.py:207 +msgid "Session share" +msgstr "セッション共有" + +#: settings/serializers/security.py:208 +msgid "Enabled, Allows user active session to be shared with other users" +msgstr "" +"ユーザーのアクティブなセッションを他のユーザーと共有できるようにします。" + +#: settings/serializers/security.py:214 +msgid "Insecure command alert" +msgstr "安全でないコマンドアラート" + +#: settings/serializers/security.py:217 +msgid "Email recipient" +msgstr "メール受信者" + +#: settings/serializers/security.py:218 +msgid "Multiple user using , split" +msgstr "複数のユーザーを使用して、分割" + #: settings/serializers/settings.py:70 #, python-format msgid "[%s] %s" @@ -5467,15 +5440,27 @@ msgstr "ホスト名" msgid "Auto" msgstr "自動" -#: settings/serializers/terminal.py:21 +#: settings/serializers/terminal.py:22 +msgid "Enable terminal register" +msgstr "ターミナルレジスタの有効化" + +#: settings/serializers/terminal.py:24 +msgid "" +"Allow terminal register, after all terminal setup, you should disable this " +"for security" +msgstr "" +"ターミナルレジスタを許可し、すべてのターミナルセットアップの後、セキュリティ" +"のためにこれを無効にする必要があります" + +#: settings/serializers/terminal.py:27 msgid "Password auth" msgstr "パスワード認証" -#: settings/serializers/terminal.py:23 +#: settings/serializers/terminal.py:29 msgid "Public key auth" msgstr "鍵認証" -#: settings/serializers/terminal.py:24 +#: settings/serializers/terminal.py:30 msgid "" "Tips: If use other auth method, like AD/LDAP, you should disable this to " "avoid being able to log in after deleting" @@ -5483,41 +5468,37 @@ msgstr "" "ヒント: AD/LDAPなどの他の認証方法を使用する場合は、サードパーティ製システムの" "削除後にこの項目を無効にする必要があります, ログインも可能" -#: settings/serializers/terminal.py:28 +#: settings/serializers/terminal.py:34 msgid "List sort by" msgstr "リストの並べ替え" -#: settings/serializers/terminal.py:31 +#: settings/serializers/terminal.py:37 msgid "List page size" msgstr "ページサイズを一覧表示" -#: settings/serializers/terminal.py:33 +#: settings/serializers/terminal.py:39 msgid "Enable database proxy" msgstr "属性マップの有効化" -#: settings/serializers/terminal.py:34 +#: settings/serializers/terminal.py:40 msgid "Enable Razor" msgstr "Razor の有効化" -#: settings/serializers/terminal.py:35 +#: settings/serializers/terminal.py:41 msgid "Enable SSH Client" msgstr "SSH Clientの有効化" -#: settings/serializers/terminal.py:46 +#: settings/serializers/terminal.py:52 msgid "Default graphics resolution" msgstr "デフォルトのグラフィック解像度" -#: settings/serializers/terminal.py:47 +#: settings/serializers/terminal.py:53 msgid "" "Tip: Default resolution to use when connecting graphical assets in Luna pages" msgstr "" "ヒント: Luna ページでグラフィック アセットを接続するときに使用するデフォルト" "の解像度" -#: settings/serializers/vault.py:22 -msgid "Mount Point" -msgstr "" - #: settings/tasks/ldap.py:24 msgid "Periodic import ldap user" msgstr "LDAP ユーザーを定期的にインポートする" @@ -8210,69 +8191,3 @@ msgstr "究極のエディション" #: xpack/plugins/license/models.py:86 msgid "Community edition" msgstr "コミュニティ版" - -#~ msgid "Strategy" -#~ msgstr "戦略" - -#~ msgid "Sync instance snapshot" -#~ msgstr "インスタンススナップショットの同期" - -#~ msgid "Task strategy" -#~ msgstr "タスク戦略" - -#~ msgid "Not" -#~ msgstr "否" - -#~ msgid "In" -#~ msgstr "イン" - -#~ msgid "Contains" -#~ msgstr "含む" - -#~ msgid "Startswith" -#~ msgstr "始まる" - -#~ msgid "Endswith" -#~ msgstr "終わる" - -#~ msgid "Instance platform" -#~ msgstr "インスタンス名" - -#~ msgid "Instance address" -#~ msgstr "インスタンスアドレス" - -#~ msgid "Rule attr" -#~ msgstr "ルール属性" - -#~ msgid "Rule match" -#~ msgstr "ルール一致" - -#~ msgid "Rule value" -#~ msgstr "ルール値" - -#~ msgid "Strategy rule" -#~ msgstr "戦略ルール" - -#~ msgid "Action attr" -#~ msgstr "アクション属性" - -#~ msgid "Action value" -#~ msgstr "アクション値" - -#~ msgid "CN Northeast-Dalian" -#~ msgstr "华北-大连" - -#~ msgid "Current only support login from AD/LDAP" -#~ msgstr "現在、AD/LDAPからのログインのみサポートしています" - -#~ msgid "SFTP enabled" -#~ msgstr "SFTP が有効" - -#~ msgid "Item" -#~ msgstr "アイテム" - -#~ msgid "Url" -#~ msgstr "リンク" - -#~ msgid "Danger command alert" -#~ msgstr "危険コマンドアラート" diff --git a/apps/locale/zh/LC_MESSAGES/django.mo b/apps/locale/zh/LC_MESSAGES/django.mo index 22a8b4239..16bde8040 100644 --- a/apps/locale/zh/LC_MESSAGES/django.mo +++ b/apps/locale/zh/LC_MESSAGES/django.mo @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3656dfce61012412c97720e60c1134f39d0f5c1faed26bff88ca795ebce31f81 -size 125596 +oid sha256:da4f312ed86d27fa8b6bde8da3bc70b0f32fe40811ee855f9fe81d89a68a646f +size 126402 diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po index 53b6b9c83..17302daba 100644 --- a/apps/locale/zh/LC_MESSAGES/django.po +++ b/apps/locale/zh/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: JumpServer 0.3.3\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-08-10 18:22+0800\n" +"POT-Creation-Date: 2023-08-15 16:44+0800\n" "PO-Revision-Date: 2021-05-20 10:54+0800\n" "Last-Translator: ibuler \n" "Language-Team: JumpServer team\n" @@ -44,7 +44,7 @@ msgid "Access key" msgstr "Access key" #: accounts/const/account.py:9 assets/models/_user.py:48 -#: authentication/models/sso_token.py:14 settings/serializers/vault.py:19 +#: authentication/models/sso_token.py:14 settings/serializers/feature.py:48 msgid "Token" msgstr "Token" @@ -86,7 +86,7 @@ msgstr "模板" msgid "Skip" msgstr "跳过" -#: accounts/const/account.py:32 audits/const.py:24 rbac/tree.py:230 +#: accounts/const/account.py:32 audits/const.py:24 rbac/tree.py:233 #: templates/_csv_import_export.html:18 templates/_csv_update_modal.html:6 msgid "Update" msgstr "更新" @@ -197,8 +197,8 @@ msgstr "HashiCorp Vault" #: accounts/models/account.py:48 #: accounts/models/automations/gather_account.py:16 -#: accounts/serializers/account/account.py:200 -#: accounts/serializers/account/account.py:245 +#: accounts/serializers/account/account.py:202 +#: accounts/serializers/account/account.py:247 #: accounts/serializers/account/gathered_account.py:10 #: accounts/serializers/automations/change_secret.py:112 #: accounts/serializers/automations/change_secret.py:132 @@ -217,8 +217,8 @@ msgid "Asset" msgstr "资产" #: accounts/models/account.py:52 accounts/models/template.py:15 -#: accounts/serializers/account/account.py:207 -#: accounts/serializers/account/account.py:255 +#: accounts/serializers/account/account.py:209 +#: accounts/serializers/account/account.py:257 #: accounts/serializers/account/template.py:16 #: authentication/serializers/connect_token_secret.py:49 msgid "Su from" @@ -229,7 +229,7 @@ msgstr "切换自" msgid "Version" msgstr "版本" -#: accounts/models/account.py:56 accounts/serializers/account/account.py:202 +#: accounts/models/account.py:56 accounts/serializers/account/account.py:204 #: users/models/user.py:838 msgid "Source" msgstr "来源" @@ -366,7 +366,7 @@ msgid "Can add push account execution" msgstr "创建推送账号执行" #: accounts/models/automations/change_secret.py:18 accounts/models/base.py:36 -#: accounts/serializers/account/account.py:427 +#: accounts/serializers/account/account.py:429 #: accounts/serializers/account/base.py:16 #: accounts/serializers/automations/change_secret.py:46 #: authentication/serializers/connect_token_secret.py:41 @@ -425,7 +425,7 @@ msgid "Date finished" msgstr "结束日期" #: accounts/models/automations/change_secret.py:93 -#: accounts/serializers/account/account.py:247 assets/const/automation.py:8 +#: accounts/serializers/account/account.py:249 assets/const/automation.py:8 #: authentication/views/base.py:26 authentication/views/base.py:27 #: authentication/views/base.py:28 common/const/choices.py:20 msgid "Error" @@ -507,7 +507,7 @@ msgstr "账号验证" #: ops/models/adhoc.py:20 ops/models/celery.py:15 ops/models/celery.py:57 #: ops/models/job.py:119 ops/models/playbook.py:28 ops/serializers/job.py:20 #: orgs/models.py:82 perms/models/asset_permission.py:56 rbac/models/role.py:29 -#: settings/models.py:32 settings/serializers/sms.py:6 +#: settings/models.py:32 settings/serializers/msg.py:82 #: terminal/models/applet/applet.py:32 terminal/models/component/endpoint.py:12 #: terminal/models/component/endpoint.py:94 #: terminal/models/component/storage.py:26 terminal/models/component/task.py:13 @@ -622,7 +622,7 @@ msgstr "立即推送" msgid "Exist policy" msgstr "账号存在策略" -#: accounts/serializers/account/account.py:180 applications/models.py:11 +#: accounts/serializers/account/account.py:182 applications/models.py:11 #: assets/models/label.py:21 assets/models/platform.py:89 #: assets/serializers/asset/common.py:121 assets/serializers/cagegory.py:8 #: assets/serializers/platform.py:128 assets/serializers/platform.py:224 @@ -631,7 +631,7 @@ msgstr "账号存在策略" msgid "Category" msgstr "类别" -#: accounts/serializers/account/account.py:181 +#: accounts/serializers/account/account.py:183 #: accounts/serializers/automations/base.py:54 acls/models/command_acl.py:24 #: acls/serializers/command_acl.py:18 applications/models.py:14 #: assets/models/_user.py:50 assets/models/automations/base.py:20 @@ -639,7 +639,7 @@ msgstr "类别" #: assets/serializers/asset/common.py:122 assets/serializers/platform.py:112 #: assets/serializers/platform.py:127 audits/serializers.py:49 #: authentication/serializers/connect_token_secret.py:123 ops/models/job.py:130 -#: perms/serializers/user_permission.py:27 settings/serializers/vault.py:13 +#: perms/serializers/user_permission.py:27 settings/serializers/feature.py:42 #: terminal/models/applet/applet.py:38 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:226 @@ -650,26 +650,26 @@ msgstr "类别" msgid "Type" msgstr "类型" -#: accounts/serializers/account/account.py:196 +#: accounts/serializers/account/account.py:198 msgid "Asset not found" msgstr "资产不存在" -#: accounts/serializers/account/account.py:236 +#: accounts/serializers/account/account.py:238 msgid "Has secret" msgstr "已托管密码" -#: accounts/serializers/account/account.py:246 ops/models/celery.py:60 +#: accounts/serializers/account/account.py:248 ops/models/celery.py:60 #: tickets/models/comment.py:13 tickets/models/ticket/general.py:45 #: tickets/models/ticket/general.py:279 tickets/serializers/super_ticket.py:14 #: tickets/serializers/ticket/ticket.py:21 msgid "State" msgstr "状态" -#: accounts/serializers/account/account.py:248 +#: accounts/serializers/account/account.py:250 msgid "Changed" msgstr "已修改" -#: accounts/serializers/account/account.py:258 +#: accounts/serializers/account/account.py:260 #: accounts/serializers/automations/base.py:22 acls/models/base.py:97 #: assets/models/automations/base.py:19 #: assets/serializers/automations/base.py:20 ops/models/base.py:17 @@ -678,27 +678,27 @@ msgstr "已修改" msgid "Assets" msgstr "资产" -#: accounts/serializers/account/account.py:313 +#: accounts/serializers/account/account.py:315 msgid "Account already exists" msgstr "账号已存在" -#: accounts/serializers/account/account.py:363 +#: accounts/serializers/account/account.py:365 #, python-format msgid "Asset does not support this secret type: %s" msgstr "资产不支持账号类型: %s" -#: accounts/serializers/account/account.py:395 +#: accounts/serializers/account/account.py:397 msgid "Account has exist" msgstr "账号已存在" -#: accounts/serializers/account/account.py:428 +#: accounts/serializers/account/account.py:430 #: authentication/serializers/connect_token_secret.py:156 #: authentication/templates/authentication/_access_key_modal.html:30 #: perms/models/perm_node.py:21 users/serializers/group.py:31 msgid "ID" msgstr "ID" -#: accounts/serializers/account/account.py:435 acls/serializers/base.py:116 +#: accounts/serializers/account/account.py:437 acls/serializers/base.py:116 #: assets/models/cmd_filter.py:24 assets/models/label.py:16 audits/models.py:49 #: audits/models.py:85 audits/models.py:163 #: authentication/models/connection_token.py:32 @@ -717,7 +717,7 @@ msgstr "ID" msgid "User" msgstr "用户" -#: accounts/serializers/account/account.py:436 +#: accounts/serializers/account/account.py:438 #: authentication/templates/authentication/_access_key_modal.html:33 #: terminal/notifications.py:158 terminal/notifications.py:207 msgid "Date" @@ -841,7 +841,7 @@ msgstr "收集资产上的账号" msgid "Push accounts to assets" msgstr "推送账号到资产" -#: accounts/tasks/vault.py:15 +#: accounts/tasks/vault.py:32 msgid "Sync secret to vault" msgstr "同步密文到 vault" @@ -940,7 +940,7 @@ msgid "Regex" msgstr "正则表达式" #: acls/models/command_acl.py:26 assets/models/cmd_filter.py:79 -#: settings/serializers/basic.py:10 xpack/plugins/license/models.py:30 +#: settings/serializers/feature.py:18 xpack/plugins/license/models.py:30 msgid "Content" msgstr "内容" @@ -1155,7 +1155,7 @@ msgstr "收集资产信息" msgid "Disabled" msgstr "禁用" -#: assets/const/base.py:34 settings/serializers/basic.py:27 +#: assets/const/base.py:34 settings/serializers/basic.py:6 msgid "Basic" msgstr "基本" @@ -1166,7 +1166,7 @@ msgstr "脚本" #: assets/const/category.py:10 assets/models/asset/host.py:8 #: settings/serializers/auth/radius.py:16 settings/serializers/auth/sms.py:67 -#: settings/serializers/vault.py:16 terminal/models/component/endpoint.py:13 +#: settings/serializers/feature.py:45 terminal/models/component/endpoint.py:13 #: terminal/serializers/applet.py:17 #: xpack/plugins/cloud/serializers/account_attrs.py:72 msgid "Host" @@ -1243,7 +1243,7 @@ msgstr "连接到控制台会话" msgid "Any" msgstr "任意" -#: assets/const/protocol.py:66 settings/serializers/security.py:160 +#: assets/const/protocol.py:66 settings/serializers/security.py:227 msgid "Security" msgstr "安全" @@ -1280,7 +1280,7 @@ msgid "We will consider login success when we see this prompt" msgstr "当我们看到这个提示时,我们将认为登录成功" #: assets/const/protocol.py:112 assets/models/asset/database.py:10 -#: settings/serializers/email.py:37 +#: settings/serializers/msg.py:40 msgid "Use SSL" msgstr "使用 SSL" @@ -1628,7 +1628,7 @@ msgstr "值" #: assets/serializers/platform.py:111 #: authentication/serializers/connect_token_secret.py:121 #: common/serializers/common.py:85 perms/serializers/user_permission.py:28 -#: settings/serializers/sms.py:7 +#: settings/serializers/msg.py:83 msgid "Label" msgstr "标签" @@ -2066,7 +2066,7 @@ msgstr "删除目录" #: audits/const.py:14 audits/const.py:25 #: authentication/templates/authentication/_access_key_modal.html:65 -#: perms/const.py:17 rbac/tree.py:231 +#: perms/const.py:17 rbac/tree.py:234 msgid "Delete" msgstr "删除" @@ -2090,7 +2090,7 @@ msgstr "下载" msgid "Rename dir" msgstr "映射目录" -#: audits/const.py:23 rbac/tree.py:229 +#: audits/const.py:23 rbac/tree.py:232 #: terminal/templates/terminal/_msg_command_warning.html:18 #: terminal/templates/terminal/_msg_session_sharing.html:10 msgid "View" @@ -2098,7 +2098,7 @@ msgstr "查看" #: audits/const.py:26 #: authentication/templates/authentication/_access_key_modal.html:22 -#: rbac/tree.py:228 +#: rbac/tree.py:231 msgid "Create" msgstr "创建" @@ -2378,7 +2378,7 @@ msgid "" "password" msgstr "用户来自 {} 请去相应系统修改密码" -#: authentication/api/password.py:60 +#: authentication/api/password.py:64 #: authentication/templates/authentication/login.html:305 #: users/templates/users/forgot_password.html:27 #: users/templates/users/forgot_password.html:28 @@ -2868,8 +2868,8 @@ msgstr "已过期" #: authentication/serializers/password_mfa.py:16 #: authentication/serializers/password_mfa.py:24 -#: notifications/backends/__init__.py:10 settings/serializers/email.py:19 -#: settings/serializers/email.py:50 users/forms/profile.py:102 +#: notifications/backends/__init__.py:10 settings/serializers/msg.py:22 +#: settings/serializers/msg.py:57 users/forms/profile.py:102 #: users/forms/profile.py:109 users/models/user.py:789 #: users/templates/users/forgot_password.html:117 #: users/views/profile/reset.py:73 @@ -3991,7 +3991,7 @@ msgstr "LDAP 同步设置组织为当前组织,请切换其他组织后再进 msgid "The organization have resource ({}) cannot be deleted" msgstr "组织存在资源 ({}) 不能被删除" -#: orgs/apps.py:7 rbac/tree.py:119 +#: orgs/apps.py:7 rbac/tree.py:122 msgid "App organizations" msgstr "组织管理" @@ -4322,24 +4322,24 @@ msgstr "我的资产" msgid "Applet" msgstr "远程应用" -#: rbac/tree.py:120 +#: rbac/tree.py:123 msgid "Ticket comment" msgstr "工单评论" -#: rbac/tree.py:121 tickets/models/ticket/general.py:307 +#: rbac/tree.py:124 tickets/models/ticket/general.py:307 msgid "Ticket" msgstr "工单管理" -#: rbac/tree.py:122 +#: rbac/tree.py:125 msgid "Common setting" msgstr "一般设置" -#: rbac/tree.py:123 +#: rbac/tree.py:126 msgid "View permission tree" msgstr "查看授权树" #: settings/api/dingtalk.py:31 settings/api/feishu.py:36 -#: settings/api/sms.py:155 settings/api/vault.py:40 settings/api/wecom.py:37 +#: settings/api/sms.py:153 settings/api/vault.py:40 settings/api/wecom.py:37 msgid "Test success" msgstr "测试成功" @@ -4367,11 +4367,11 @@ msgstr "获取 LDAP 用户为 None" msgid "Imported {} users successfully (Organization: {})" msgstr "成功导入 {} 个用户 ( 组织: {} )" -#: settings/api/sms.py:137 +#: settings/api/sms.py:135 msgid "Invalid SMS platform" msgstr "无效的短信平台" -#: settings/api/sms.py:143 +#: settings/api/sms.py:141 msgid "test_phone is required" msgstr "测试手机号 该字段是必填项。" @@ -4459,7 +4459,7 @@ msgstr "SSO 令牌认证" msgid "SAML2 Auth" msgstr "SAML2 认证" -#: settings/serializers/auth/base.py:22 settings/serializers/basic.py:38 +#: settings/serializers/auth/base.py:22 settings/serializers/basic.py:17 msgid "Forgot password url" msgstr "忘记密码 URL" @@ -4750,7 +4750,7 @@ msgstr "短信服务商 / 协议" #: settings/serializers/auth/sms.py:23 settings/serializers/auth/sms.py:45 #: settings/serializers/auth/sms.py:53 settings/serializers/auth/sms.py:62 -#: settings/serializers/auth/sms.py:73 settings/serializers/email.py:69 +#: settings/serializers/auth/sms.py:73 settings/serializers/msg.py:76 msgid "Signature" msgstr "签名" @@ -4841,32 +4841,24 @@ msgid "Enable WeCom Auth" msgstr "启用企业微信认证" #: settings/serializers/basic.py:9 -msgid "Subject" -msgstr "主题" - -#: settings/serializers/basic.py:13 -msgid "More url" -msgstr "更多信息 URL" - -#: settings/serializers/basic.py:30 msgid "Site url" msgstr "当前站点 URL" -#: settings/serializers/basic.py:31 +#: settings/serializers/basic.py:10 msgid "" "Email links or other system callbacks are used to access it, eg: http://dev." "jumpserver.org:8080" msgstr "" -#: settings/serializers/basic.py:34 +#: settings/serializers/basic.py:13 msgid "User guide url" msgstr "用户向导URL" -#: settings/serializers/basic.py:35 +#: settings/serializers/basic.py:14 msgid "User first login update profile done redirect to it" msgstr "用户第一次登录,修改profile后重定向到地址, 可以是 wiki 或 其他说明文档" -#: settings/serializers/basic.py:39 +#: settings/serializers/basic.py:18 msgid "" "The forgot password url on login page, If you use ldap or cas external " "authentication, you can set it" @@ -4874,25 +4866,29 @@ msgstr "" "登录页面忘记密码URL, 如果使用了 LDAP, OPENID 等外部认证系统,可以自定义用户重" "置密码访问的地址" -#: settings/serializers/basic.py:43 +#: settings/serializers/basic.py:22 msgid "Global organization name" msgstr "全局组织名" -#: settings/serializers/basic.py:44 +#: settings/serializers/basic.py:23 msgid "The name of global organization to display" msgstr "全局组织的显示名称,默认为 全局组织" -#: settings/serializers/basic.py:46 -msgid "Enable announcement" -msgstr "启用公告" +#: settings/serializers/basic.py:26 +msgid "Help Docs URL" +msgstr "文档链接" -#: settings/serializers/basic.py:47 -msgid "Announcement" -msgstr "公告" +#: settings/serializers/basic.py:27 +msgid "default: http://docs.jumpserver.org" +msgstr "默认: http://dev.jumpserver.org:8080" -#: settings/serializers/basic.py:48 -msgid "Enable tickets" -msgstr "启用工单" +#: settings/serializers/basic.py:30 +msgid "Help Support URL" +msgstr "支持链接" + +#: settings/serializers/basic.py:31 +msgid "default: http://www.jumpserver.org/support/" +msgstr "默认: http://www.jumpserver.org/support/" #: settings/serializers/cleaning.py:8 msgid "Period clean" @@ -4933,81 +4929,146 @@ msgstr "" msgid "Activity log keep days (day)" msgstr "活动记录 (天)" -#: settings/serializers/email.py:21 +#: settings/serializers/feature.py:17 +msgid "Subject" +msgstr "主题" + +#: settings/serializers/feature.py:21 +msgid "More url" +msgstr "更多信息 URL" + +#: settings/serializers/feature.py:35 +msgid "Enable announcement" +msgstr "启用公告" + +#: settings/serializers/feature.py:36 +msgid "Announcement" +msgstr "公告" + +#: settings/serializers/feature.py:51 +msgid "Mount Point" +msgstr "" + +#: settings/serializers/feature.py:60 +msgid "Enable tickets" +msgstr "启用工单" + +#: settings/serializers/feature.py:63 +msgid "Ticket authorize default time" +msgstr "默认工单授权时间" + +#: settings/serializers/feature.py:66 +msgid "day" +msgstr "天" + +#: settings/serializers/feature.py:66 +msgid "hour" +msgstr "时" + +#: settings/serializers/feature.py:67 +msgid "Ticket authorize default time unit" +msgstr "默认工单授权时间单位" + +#: settings/serializers/feature.py:73 +msgid "Operation center" +msgstr "作业中心" + +#: settings/serializers/feature.py:74 +msgid "Allow user run batch command or not using ansible" +msgstr "是否允许用户使用 ansible 执行批量命令" + +#: settings/serializers/feature.py:78 +msgid "Operation center command blacklist" +msgstr "作业中心命令黑名单" + +#: settings/serializers/feature.py:79 +msgid "Commands that are not allowed execute." +msgstr "不允许执行的命令" + +#: settings/serializers/msg.py:24 msgid "SMTP host" msgstr "SMTP 主机" -#: settings/serializers/email.py:22 +#: settings/serializers/msg.py:25 msgid "SMTP port" msgstr "SMTP 端口" -#: settings/serializers/email.py:23 +#: settings/serializers/msg.py:26 msgid "SMTP account" msgstr "SMTP 账号" -#: settings/serializers/email.py:25 +#: settings/serializers/msg.py:28 msgid "SMTP password" msgstr "SMTP 密码" -#: settings/serializers/email.py:26 +#: settings/serializers/msg.py:29 msgid "Tips: Some provider use token except password" msgstr "提示:一些邮件提供商需要输入的是授权码" -#: settings/serializers/email.py:29 +#: settings/serializers/msg.py:32 msgid "Send user" msgstr "发件人" -#: settings/serializers/email.py:30 +#: settings/serializers/msg.py:33 msgid "Tips: Send mail account, default SMTP account as the send account" msgstr "提示:发送邮件账号,默认使用 SMTP 账号作为发送账号" -#: settings/serializers/email.py:33 +#: settings/serializers/msg.py:36 msgid "Test recipient" msgstr "测试收件人" -#: settings/serializers/email.py:34 +#: settings/serializers/msg.py:37 msgid "Tips: Used only as a test mail recipient" msgstr "提示:仅用来作为测试邮件收件人" -#: settings/serializers/email.py:38 +#: settings/serializers/msg.py:41 msgid "If SMTP port is 465, may be select" msgstr "如果SMTP端口是465,通常需要启用 SSL" -#: settings/serializers/email.py:41 +#: settings/serializers/msg.py:44 msgid "Use TLS" msgstr "使用 TLS" -#: settings/serializers/email.py:42 +#: settings/serializers/msg.py:45 msgid "If SMTP port is 587, may be select" msgstr "如果SMTP端口是587,通常需要启用 TLS" -#: settings/serializers/email.py:45 +#: settings/serializers/msg.py:48 msgid "Subject prefix" msgstr "主题前缀" -#: settings/serializers/email.py:54 +#: settings/serializers/msg.py:51 +msgid "Email suffix" +msgstr "邮件后缀" + +#: settings/serializers/msg.py:52 +msgid "" +"This is used by default if no email is returned during SSO authentication" +msgstr "SSO认证时,如果没有返回邮件地址,将使用该后缀" + +#: settings/serializers/msg.py:61 msgid "Create user email subject" msgstr "邮件主题" -#: settings/serializers/email.py:55 +#: settings/serializers/msg.py:62 msgid "" "Tips: When creating a user, send the subject of the email (eg:Create account " "successfully)" msgstr "提示: 创建用户时,发送设置密码邮件的主题 (例如: 创建用户成功)" -#: settings/serializers/email.py:59 +#: settings/serializers/msg.py:66 msgid "Create user honorific" msgstr "邮件问候语" -#: settings/serializers/email.py:60 +#: settings/serializers/msg.py:67 msgid "Tips: When creating a user, send the honorific of the email (eg:Hello)" msgstr "提示: 创建用户时,发送设置密码邮件的敬语 (例如: 你好)" -#: settings/serializers/email.py:64 +#: settings/serializers/msg.py:71 msgid "Create user email content" msgstr "邮件的内容" -#: settings/serializers/email.py:66 +#: settings/serializers/msg.py:73 #, python-brace-format msgid "" "Tips: When creating a user, send the content of the email, support " @@ -5015,156 +5076,29 @@ msgid "" msgstr "" "提示: 创建用户时,发送设置密码邮件的内容, 支持 {username} {name} {email} 标签" -#: settings/serializers/email.py:70 +#: settings/serializers/msg.py:77 msgid "Tips: Email signature (eg:jumpserver)" msgstr "邮件署名 (如:jumpserver)" -#: settings/serializers/other.py:6 +#: settings/serializers/other.py:8 msgid "More..." msgstr "更多..." -#: settings/serializers/other.py:9 -msgid "Email suffix" -msgstr "邮件后缀" - -#: settings/serializers/other.py:10 -msgid "" -"This is used by default if no email is returned during SSO authentication" -msgstr "SSO认证时,如果没有返回邮件地址,将使用该后缀" - -#: settings/serializers/other.py:14 -msgid "OTP issuer name" -msgstr "OTP 扫描后的名称" - -#: settings/serializers/other.py:18 -msgid "OTP valid window" -msgstr "OTP 延迟有效次数" - -#: settings/serializers/other.py:22 +#: settings/serializers/other.py:11 msgid "Perm ungroup node" msgstr "显示未分组节点" -#: settings/serializers/other.py:23 +#: settings/serializers/other.py:12 msgid "Perm single to ungroup node" msgstr "" "放置单独授权的资产到未分组节点, 避免能看到资产所在节点,但该节点未被授权的问" "题" -#: settings/serializers/other.py:28 -msgid "Ticket authorize default time" -msgstr "默认工单授权时间" - -#: settings/serializers/other.py:31 -msgid "day" -msgstr "天" - -#: settings/serializers/other.py:31 -msgid "hour" -msgstr "时" - -#: settings/serializers/other.py:32 -msgid "Ticket authorize default time unit" -msgstr "默认工单授权时间单位" - -#: settings/serializers/other.py:35 -msgid "Help Docs URL" -msgstr "文档链接" - -#: settings/serializers/other.py:36 -msgid "default: http://docs.jumpserver.org" -msgstr "默认: http://dev.jumpserver.org:8080" - -#: settings/serializers/other.py:40 -msgid "Help Support URL" -msgstr "支持链接" - -#: settings/serializers/other.py:41 -msgid "default: http://www.jumpserver.org/support/" -msgstr "默认: http://www.jumpserver.org/support/" - -#: settings/serializers/security.py:10 -msgid "Password minimum length" -msgstr "密码最小长度" - -#: settings/serializers/security.py:14 -msgid "Admin user password minimum length" -msgstr "管理员密码最小长度" - -#: settings/serializers/security.py:17 -msgid "Must contain capital" -msgstr "必须包含大写字符" - -#: settings/serializers/security.py:20 -msgid "Must contain lowercase" -msgstr "必须包含小写字符" - -#: settings/serializers/security.py:23 -msgid "Must contain numeric" -msgstr "必须包含数字" - -#: settings/serializers/security.py:26 -msgid "Must contain special" -msgstr "必须包含特殊字符" - -#: settings/serializers/security.py:31 -msgid "" -"If the user has failed to log in for a limited number of times, no login is " -"allowed during this time interval." -msgstr "当用户登录失败次数达到限制后,那么在此间隔内禁止登录" - -#: settings/serializers/security.py:39 -msgid "Not enabled" -msgstr "未启用" - -#: settings/serializers/security.py:40 -msgid "All users" -msgstr "所有用户" - -#: settings/serializers/security.py:41 -msgid "Only admin users" -msgstr "仅管理员" - -#: settings/serializers/security.py:43 -msgid "Global MFA auth" -msgstr "全局启用 MFA 认证" - -#: settings/serializers/security.py:47 -msgid "Third-party login users perform MFA authentication" -msgstr "第三方认证开启 MFA" - -#: settings/serializers/security.py:48 -msgid "The third-party login modes include OIDC, CAS, and SAML2" -msgstr "第三方登录方式包括: OIDC、CAS、SAML2" - -#: settings/serializers/security.py:52 -msgid "Limit the number of user login failures" -msgstr "限制用户登录失败次数" - -#: settings/serializers/security.py:56 -msgid "Block user login interval (minute)" -msgstr "禁止用户登录间隔 (分)" - -#: settings/serializers/security.py:61 -msgid "Limit the number of IP login failures" -msgstr "限制 IP 登录失败次数" - -#: settings/serializers/security.py:65 -msgid "Block IP login interval (minute)" -msgstr "禁止 IP 登录间隔 (分)" - -#: settings/serializers/security.py:69 -msgid "Login IP White List" -msgstr "IP 登录白名单" - -#: settings/serializers/security.py:74 -msgid "Login IP Black List" -msgstr "IP 登录黑名单" - -#: settings/serializers/security.py:80 +#: settings/serializers/security.py:16 msgid "User password expiration (day)" msgstr "用户密码过期时间 (天)" -#: settings/serializers/security.py:82 +#: settings/serializers/security.py:18 msgid "" "If the user does not update the password during the time, the user password " "will expire failure;The password expiration reminder mail will be automatic " @@ -5173,31 +5107,85 @@ msgstr "" "如果用户在此期间没有更新密码,用户密码将过期失效; 密码过期提醒邮件将在密码过" "期前5天内由系统 (每天)自动发送给用户" -#: settings/serializers/security.py:89 +#: settings/serializers/security.py:25 msgid "Number of repeated historical passwords" msgstr "不能设置近几次密码" -#: settings/serializers/security.py:91 +#: settings/serializers/security.py:27 msgid "" "Tip: When the user resets the password, it cannot be the previous n " "historical passwords of the user" msgstr "提示:用户重置密码时,不能为该用户前几次使用过的密码" -#: settings/serializers/security.py:96 +#: settings/serializers/security.py:33 +msgid "Password minimum length" +msgstr "密码最小长度" + +#: settings/serializers/security.py:37 +msgid "Admin user password minimum length" +msgstr "管理员密码最小长度" + +#: settings/serializers/security.py:40 +msgid "Must contain capital" +msgstr "必须包含大写字符" + +#: settings/serializers/security.py:43 +msgid "Must contain lowercase" +msgstr "必须包含小写字符" + +#: settings/serializers/security.py:46 +msgid "Must contain numeric" +msgstr "必须包含数字" + +#: settings/serializers/security.py:49 +msgid "Must contain special" +msgstr "必须包含特殊字符" + +#: settings/serializers/security.py:54 +msgid "" +"If the user has failed to log in for a limited number of times, no login is " +"allowed during this time interval." +msgstr "当用户登录失败次数达到限制后,那么在此间隔内禁止登录" + +#: settings/serializers/security.py:62 +msgid "Limit the number of user login failures" +msgstr "限制用户登录失败次数" + +#: settings/serializers/security.py:66 +msgid "Block user login interval (minute)" +msgstr "禁止用户登录间隔 (分)" + +#: settings/serializers/security.py:72 +msgid "Limit the number of IP login failures" +msgstr "限制 IP 登录失败次数" + +#: settings/serializers/security.py:76 +msgid "Block IP login interval (minute)" +msgstr "禁止 IP 登录间隔 (分)" + +#: settings/serializers/security.py:80 +msgid "Login IP White List" +msgstr "IP 登录白名单" + +#: settings/serializers/security.py:85 +msgid "Login IP Black List" +msgstr "IP 登录黑名单" + +#: settings/serializers/security.py:90 msgid "Only single device login" msgstr "仅一台设备登录" -#: settings/serializers/security.py:97 +#: settings/serializers/security.py:91 msgid "" "After the user logs in on the new device, other logged-in devices will " "automatically log out" msgstr "用户在新设备登录后,其他已登录的设备会自动退出" -#: settings/serializers/security.py:100 +#: settings/serializers/security.py:94 msgid "Only exist user login" msgstr "仅已存在用户登录" -#: settings/serializers/security.py:102 +#: settings/serializers/security.py:96 msgid "" "If enabled, non-existent users will not be allowed to log in; if disabled, " "users of other authentication methods except local authentication methods " @@ -5207,11 +5195,11 @@ msgstr "" "如果开启,不存在的用户将不被允许登录;如果关闭,除本地认证方式外,其他认证方" "式的用户都允许登录并自动创建用户 (如果用户不存在)" -#: settings/serializers/security.py:108 +#: settings/serializers/security.py:102 msgid "Only from source login" msgstr "仅从用户来源登录" -#: settings/serializers/security.py:110 +#: settings/serializers/security.py:104 msgid "" "If it is enabled, the user will only authenticate to the source when logging " "in; if it is disabled, the user will authenticate all the enabled " @@ -5221,29 +5209,69 @@ msgstr "" "如果开启,用户登录时仅会向来源端进行认证;如果关闭,用户登录时会按照一定的顺" "序对所有已开启的认证方式进行顺序认证,只要有一个认证成功就可以直接登录" -#: settings/serializers/security.py:118 +#: settings/serializers/security.py:115 +msgid "Not enabled" +msgstr "未启用" + +#: settings/serializers/security.py:116 +msgid "All users" +msgstr "所有用户" + +#: settings/serializers/security.py:117 +msgid "Only admin users" +msgstr "仅管理员" + +#: settings/serializers/security.py:119 +msgid "Global MFA auth" +msgstr "全局启用 MFA 认证" + +#: settings/serializers/security.py:123 +msgid "Third-party login users perform MFA authentication" +msgstr "第三方认证开启 MFA" + +#: settings/serializers/security.py:124 +msgid "The third-party login modes include OIDC, CAS, and SAML2" +msgstr "第三方登录方式包括: OIDC、CAS、SAML2" + +#: settings/serializers/security.py:127 +msgid "OTP issuer name" +msgstr "OTP 扫描后的名称" + +#: settings/serializers/security.py:131 +msgid "OTP valid window" +msgstr "OTP 延迟有效次数" + +#: settings/serializers/security.py:135 msgid "MFA verify TTL" msgstr "MFA 校验有效期" -#: settings/serializers/security.py:120 +#: settings/serializers/security.py:137 msgid "" "Unit: second, The verification MFA takes effect only when you view the " "account password" msgstr "单位:秒,目前仅在查看账号密码校验 MFA 时生效" -#: settings/serializers/security.py:125 +#: settings/serializers/security.py:142 +msgid "MFA in login page" +msgstr "MFA 在登录页面输入" + +#: settings/serializers/security.py:143 +msgid "Eu security regulations(GDPR) require MFA to be on the login page" +msgstr "欧盟数据安全法规(GDPR) 要求 MFA 在登录页面,来确保系统登录安全" + +#: settings/serializers/security.py:147 msgid "Verify code TTL (second)" msgstr "验证码有效时间 (分)" -#: settings/serializers/security.py:126 +#: settings/serializers/security.py:148 msgid "Reset password and send SMS code expiration time" msgstr "重置密码的验证码及发送短信的验证码过期时间" -#: settings/serializers/security.py:130 +#: settings/serializers/security.py:152 msgid "Enable Login dynamic code" msgstr "启用登录附加码" -#: settings/serializers/security.py:131 +#: settings/serializers/security.py:153 msgid "" "The password and additional code are sent to a third party authentication " "system for verification" @@ -5251,111 +5279,19 @@ msgstr "" "密码和附加码一并发送给第三方认证系统进行校验, 如:有的第三方认证系统,需要 密" "码+6位数字 完成认证" -#: settings/serializers/security.py:136 -msgid "MFA in login page" -msgstr "MFA 在登录页面输入" - -#: settings/serializers/security.py:137 -msgid "Eu security regulations(GDPR) require MFA to be on the login page" -msgstr "欧盟数据安全法规(GDPR) 要求 MFA 在登录页面,来确保系统登录安全" - -#: settings/serializers/security.py:140 +#: settings/serializers/security.py:157 msgid "Enable Login captcha" msgstr "启用登录验证码" -#: settings/serializers/security.py:141 +#: settings/serializers/security.py:158 msgid "Enable captcha to prevent robot authentication" msgstr "开启验证码,防止机器人登录" -#: settings/serializers/security.py:163 -msgid "Enable terminal register" -msgstr "组件注册" - -#: settings/serializers/security.py:165 -msgid "" -"Allow terminal register, after all terminal setup, you should disable this " -"for security" -msgstr "是否允许组件注册,当所有终端启动后,为了安全应该关闭" - -#: settings/serializers/security.py:169 -msgid "Enable watermark" -msgstr "开启水印" - -#: settings/serializers/security.py:170 -msgid "Enabled, the web session and replay contains watermark information" -msgstr "启用后,Web 会话和录像将包含水印信息" - -#: settings/serializers/security.py:174 -msgid "Connection max idle time (minute)" -msgstr "连接最大空闲时间 (分)" - -#: settings/serializers/security.py:175 -msgid "If idle time more than it, disconnect connection." -msgstr "提示:如果超过该配置没有操作,连接会被断开" - -#: settings/serializers/security.py:179 -msgid "Session max connection time (hour)" -msgstr "会话连接最大时间 (时)" - -#: settings/serializers/security.py:180 -msgid "If session connection time more than it, disconnect connection." -msgstr "提示:如果会话连接超过该配置,连接会被断开" - -#: settings/serializers/security.py:183 -msgid "Remember manual auth" -msgstr "保存手动输入密码" - -#: settings/serializers/security.py:186 -msgid "Insecure command alert" -msgstr "危险命令告警" - -#: settings/serializers/security.py:189 -msgid "Email recipient" -msgstr "邮件收件人" - -#: settings/serializers/security.py:190 -msgid "Multiple user using , split" -msgstr "多个用户,使用 , 分割" - -#: settings/serializers/security.py:193 -msgid "Operation center" -msgstr "作业中心" - -#: settings/serializers/security.py:194 -msgid "Allow user run batch command or not using ansible" -msgstr "是否允许用户使用 ansible 执行批量命令" - -#: settings/serializers/security.py:198 -msgid "Operation center command blacklist" -msgstr "作业中心命令黑名单" - -#: settings/serializers/security.py:199 -msgid "Commands that are not allowed execute." -msgstr "不允许执行的命令" - -#: settings/serializers/security.py:202 -msgid "Session share" -msgstr "会话分享" - -#: settings/serializers/security.py:203 -msgid "Enabled, Allows user active session to be shared with other users" -msgstr "开启后允许用户分享已连接的资产会话给他人,协同工作" - -#: settings/serializers/security.py:207 -msgid "Unused user timeout (day)" -msgstr "不活跃用户自动禁用 (天)" - -#: settings/serializers/security.py:208 -msgid "" -"Detect infrequent users daily and disable them if they exceed the " -"predetermined time limit." -msgstr "每天检测一次,超过预设时间的用户自动禁用" - -#: settings/serializers/security.py:211 +#: settings/serializers/security.py:161 msgid "Remote Login Protection" msgstr "异地登录通知" -#: settings/serializers/security.py:213 +#: settings/serializers/security.py:163 msgid "" "The system determines whether the login IP address belongs to a common login " "city. If the account is logged in from a common login city, the system sends " @@ -5364,6 +5300,64 @@ msgstr "" "根据登录 IP 是否所属常用登录城市进行判断,若账号在非常用城市登录,会发送异地" "登录提醒" +#: settings/serializers/security.py:169 +msgid "Unused user timeout (day)" +msgstr "不活跃用户自动禁用 (天)" + +#: settings/serializers/security.py:170 +msgid "" +"Detect infrequent users daily and disable them if they exceed the " +"predetermined time limit." +msgstr "每天检测一次,超过预设时间的用户自动禁用" + +#: settings/serializers/security.py:190 +msgid "Enable watermark" +msgstr "开启水印" + +#: settings/serializers/security.py:191 +msgid "Enabled, the web session and replay contains watermark information" +msgstr "启用后,Web 会话和录像将包含水印信息" + +#: settings/serializers/security.py:195 +msgid "Connection max idle time (minute)" +msgstr "连接最大空闲时间 (分)" + +#: settings/serializers/security.py:196 +msgid "If idle time more than it, disconnect connection." +msgstr "提示:如果超过该配置没有操作,连接会被断开" + +#: settings/serializers/security.py:200 +msgid "Session max connection time (hour)" +msgstr "会话连接最大时间 (时)" + +#: settings/serializers/security.py:201 +msgid "If session connection time more than it, disconnect connection." +msgstr "提示:如果会话连接超过该配置,连接会被断开" + +#: settings/serializers/security.py:204 +msgid "Remember manual auth" +msgstr "保存手动输入密码" + +#: settings/serializers/security.py:207 +msgid "Session share" +msgstr "会话分享" + +#: settings/serializers/security.py:208 +msgid "Enabled, Allows user active session to be shared with other users" +msgstr "开启后允许用户分享已连接的资产会话给他人,协同工作" + +#: settings/serializers/security.py:214 +msgid "Insecure command alert" +msgstr "危险命令告警" + +#: settings/serializers/security.py:217 +msgid "Email recipient" +msgstr "邮件收件人" + +#: settings/serializers/security.py:218 +msgid "Multiple user using , split" +msgstr "多个用户,使用 , 分割" + #: settings/serializers/settings.py:70 #, python-format msgid "[%s] %s" @@ -5377,15 +5371,25 @@ msgstr "主机名" msgid "Auto" msgstr "自动" -#: settings/serializers/terminal.py:21 +#: settings/serializers/terminal.py:22 +msgid "Enable terminal register" +msgstr "组件注册" + +#: settings/serializers/terminal.py:24 +msgid "" +"Allow terminal register, after all terminal setup, you should disable this " +"for security" +msgstr "是否允许组件注册,当所有终端启动后,为了安全应该关闭" + +#: settings/serializers/terminal.py:27 msgid "Password auth" msgstr "密码认证" -#: settings/serializers/terminal.py:23 +#: settings/serializers/terminal.py:29 msgid "Public key auth" msgstr "密钥认证" -#: settings/serializers/terminal.py:24 +#: settings/serializers/terminal.py:30 msgid "" "Tips: If use other auth method, like AD/LDAP, you should disable this to " "avoid being able to log in after deleting" @@ -5393,39 +5397,35 @@ msgstr "" "提示:如果你使用其它认证方式,如 AD/LDAP,你应该禁用此项,以避免第三方系统删" "除后,还可以登录" -#: settings/serializers/terminal.py:28 +#: settings/serializers/terminal.py:34 msgid "List sort by" msgstr "资产列表排序" -#: settings/serializers/terminal.py:31 +#: settings/serializers/terminal.py:37 msgid "List page size" msgstr "资产列表每页数量" -#: settings/serializers/terminal.py:33 +#: settings/serializers/terminal.py:39 msgid "Enable database proxy" msgstr "启用数据库组件" -#: settings/serializers/terminal.py:34 +#: settings/serializers/terminal.py:40 msgid "Enable Razor" msgstr "启用 Razor 服务" -#: settings/serializers/terminal.py:35 +#: settings/serializers/terminal.py:41 msgid "Enable SSH Client" msgstr "启用 SSH Client" -#: settings/serializers/terminal.py:46 +#: settings/serializers/terminal.py:52 msgid "Default graphics resolution" msgstr "默认图形化分辨率" -#: settings/serializers/terminal.py:47 +#: settings/serializers/terminal.py:53 msgid "" "Tip: Default resolution to use when connecting graphical assets in Luna pages" msgstr "提示:在Luna 页面中连接图形化资产时默认使用的分辨率" -#: settings/serializers/vault.py:22 -msgid "Mount Point" -msgstr "" - #: settings/tasks/ldap.py:24 msgid "Periodic import ldap user" msgstr "周期导入 LDAP 用户" @@ -8080,69 +8080,3 @@ msgstr "旗舰版" #: xpack/plugins/license/models.py:86 msgid "Community edition" msgstr "社区版" - -#~ msgid "Strategy" -#~ msgstr "策略" - -#~ msgid "Sync instance snapshot" -#~ msgstr "同步实例快照" - -#~ msgid "Task strategy" -#~ msgstr "密码策略" - -#~ msgid "Not" -#~ msgstr "否" - -#~ msgid "In" -#~ msgstr "在..里面" - -#~ msgid "Contains" -#~ msgstr "包含" - -#~ msgid "Startswith" -#~ msgstr "以..开头" - -#~ msgid "Endswith" -#~ msgstr "以..结尾" - -#~ msgid "Instance platform" -#~ msgstr "实例平台" - -#~ msgid "Instance address" -#~ msgstr "实例地址" - -#~ msgid "Rule attr" -#~ msgstr "规则属性" - -#~ msgid "Rule match" -#~ msgstr "规则匹配" - -#~ msgid "Rule value" -#~ msgstr "规则值" - -#~ msgid "Strategy rule" -#~ msgstr "策略规则" - -#~ msgid "Action attr" -#~ msgstr "动作属性" - -#~ msgid "Action value" -#~ msgstr "动作值" - -#~ msgid "CN Northeast-Dalian" -#~ msgstr "华北-大连" - -#~ msgid "Current only support login from AD/LDAP" -#~ msgstr "当前仅支持 AD/LDAP 方式登录的用户" - -#~ msgid "SFTP enabled" -#~ msgstr "SFTP 已启用" - -#~ msgid "Item" -#~ msgstr "项目" - -#~ msgid "Url" -#~ msgstr "链接" - -#~ msgid "Danger command alert" -#~ msgstr "危险命令告警" diff --git a/config_example.yml b/config_example.yml index a21edb01b..bab9b35f5 100644 --- a/config_example.yml +++ b/config_example.yml @@ -96,3 +96,6 @@ REDIS_PORT: 6379 # 仅允许已存在的用户登录,不允许第三方认证后,自动创建用户 # ONLY_ALLOW_EXIST_USER_AUTH: False +# 当前存储的类型,默认 local,新增类型 hcp 为远端 vault 存储 +# VAULT_TYPE: local + From fc595bc4e469b89f6af06384faa89eeed3e8ed95 Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Tue, 15 Aug 2023 18:50:48 +0800 Subject: [PATCH 158/177] =?UTF-8?q?perf:=20=E5=90=AF=E5=8A=A8=20ssh=20?= =?UTF-8?q?=E9=9A=A7=E9=81=93=E9=94=99=E8=AF=AF=E5=A4=84=E7=90=86=E4=BC=98?= =?UTF-8?q?=E5=8C=96=20(#11287)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: feng <1304903146@qq.com> --- apps/assets/automations/base/manager.py | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/apps/assets/automations/base/manager.py b/apps/assets/automations/base/manager.py index 2107e6e56..4d35c9121 100644 --- a/apps/assets/automations/base/manager.py +++ b/apps/assets/automations/base/manager.py @@ -9,7 +9,7 @@ import yaml from django.conf import settings from django.utils import timezone from django.utils.translation import gettext as _ -from sshtunnel import SSHTunnelForwarder, BaseSSHTunnelForwarderError +from sshtunnel import SSHTunnelForwarder from assets.automations.methods import platform_automation_methods from common.utils import get_logger, lazyproperty, is_openssh_format_key, ssh_pubkey_gen @@ -265,19 +265,18 @@ class BasePlaybookManager: jms_asset, jms_gateway = host.get('jms_asset'), host.get('gateway') if not jms_gateway: continue - - server = SSHTunnelForwarder( - (jms_gateway['address'], jms_gateway['port']), - ssh_username=jms_gateway['username'], - ssh_password=jms_gateway['secret'], - ssh_pkey=jms_gateway['private_key_path'], - remote_bind_address=(jms_asset['address'], jms_asset['port']) - ) try: + server = SSHTunnelForwarder( + (jms_gateway['address'], jms_gateway['port']), + ssh_username=jms_gateway['username'], + ssh_password=jms_gateway['secret'], + ssh_pkey=jms_gateway['private_key_path'], + remote_bind_address=(jms_asset['address'], jms_asset['port']) + ) server.start() - except BaseSSHTunnelForwarderError: + except Exception as e: err_msg = 'Gateway is not active: %s' % jms_asset.get('name', '') - print('\033[31m %s \033[0m\n' % err_msg) + print(f'\033[31m {err_msg} 原因: {e} \033[0m\n') not_valid.append(k) else: host['ansible_host'] = jms_asset['address'] = '127.0.0.1' From dfde9258c7f7d9d102455e9730811b99c5d7e04b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=90=B4=E5=B0=8F=E7=99=BD?= <296015668@qq.com> Date: Wed, 16 Aug 2023 11:05:58 +0800 Subject: [PATCH 159/177] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=E6=9E=84?= =?UTF-8?q?=E5=BB=BA=E4=BC=81=E4=B8=9A=E7=89=88=E6=9C=AC=E9=95=9C=E5=83=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile-ee | 78 ++------------------------------------------------- 1 file changed, 3 insertions(+), 75 deletions(-) diff --git a/Dockerfile-ee b/Dockerfile-ee index d4b2391e6..b485f1ecc 100644 --- a/Dockerfile-ee +++ b/Dockerfile-ee @@ -1,81 +1,9 @@ ARG VERSION FROM registry.fit2cloud.com/jumpserver/xpack:${VERSION} as build-xpack -FROM python:3.11-slim-bullseye as stage-build -ARG TARGETARCH +FROM jumpserver/core:${VERSION} -ARG VERSION -ENV VERSION=$VERSION - -WORKDIR /opt/jumpserver -ADD . . -RUN cd utils && bash -ixeu build.sh - -FROM python:3.11-slim-bullseye -ARG TARGETARCH - -ARG BUILD_DEPENDENCIES=" \ - g++ \ - make \ - pkg-config" - -ARG DEPENDENCIES=" \ - freetds-dev \ - libpq-dev \ - libffi-dev \ - libjpeg-dev \ - libkrb5-dev \ - libldap2-dev \ - libsasl2-dev \ - libssl-dev \ - libxml2-dev \ - libxmlsec1-dev \ - libxmlsec1-openssl \ - freerdp2-dev \ - libaio-dev" - -ARG TOOLS=" \ - ca-certificates \ - curl \ - default-libmysqlclient-dev \ - default-mysql-client \ - locales \ - nmap \ - openssh-client \ - sshpass \ - telnet \ - vim \ - wget" - -ARG APT_MIRROR=http://mirrors.ustc.edu.cn - -RUN --mount=type=cache,target=/var/cache/apt,sharing=locked,id=core \ - sed -i "s@http://.*.debian.org@${APT_MIRROR}@g" /etc/apt/sources.list \ - && rm -f /etc/apt/apt.conf.d/docker-clean \ - && ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \ - && apt-get update \ - && apt-get -y install --no-install-recommends ${BUILD_DEPENDENCIES} \ - && apt-get -y install --no-install-recommends ${DEPENDENCIES} \ - && apt-get -y install --no-install-recommends ${TOOLS} \ - && mkdir -p /root/.ssh/ \ - && echo "Host *\n\tStrictHostKeyChecking no\n\tUserKnownHostsFile /dev/null\n\tCiphers +aes128-cbc\n\tKexAlgorithms +diffie-hellman-group1-sha1\n\tHostKeyAlgorithms +ssh-rsa" > /root/.ssh/config \ - && echo "set mouse-=a" > ~/.vimrc \ - && echo "no" | dpkg-reconfigure dash \ - && echo "zh_CN.UTF-8" | dpkg-reconfigure locales \ - && sed -i "s@# export @export @g" ~/.bashrc \ - && sed -i "s@# alias @alias @g" ~/.bashrc \ - && rm -rf /var/lib/apt/lists/* - -COPY --from=stage-build /opt/jumpserver/release/jumpserver /opt/jumpserver -WORKDIR /opt/jumpserver - -ARG PIP_MIRROR=https://pypi.douban.com/simple -RUN --mount=type=cache,target=/root/.cache \ - set -ex \ - && echo > /opt/jumpserver/config.yml \ - && pip install poetry -i ${PIP_MIRROR} \ - && poetry config virtualenvs.create false \ - && poetry install --only=main +COPY --from=build-xpack /opt/xpack /opt/jumpserver/apps/xpack RUN --mount=type=cache,target=/root/.cache \ set -ex \ - && poetry install --only=xpack + && poetry install --only=xpack \ No newline at end of file From ceee2e1633a6c33798b7d7d83f161e7953d843c1 Mon Sep 17 00:00:00 2001 From: ibuler Date: Wed, 16 Aug 2023 11:42:36 +0800 Subject: [PATCH 160/177] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=20k8s=20icon?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/assets/utils/k8s.py | 2 +- apps/perms/api/user_permission/tree/node_with_asset.py | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/apps/assets/utils/k8s.py b/apps/assets/utils/k8s.py index 35fe4fd18..dbfd20ecf 100644 --- a/apps/assets/utils/k8s.py +++ b/apps/assets/utils/k8s.py @@ -105,7 +105,7 @@ class KubernetesTree: i = str(self.asset.id) name = str(self.asset) node = self.create_tree_node( - i, i, name, 'asset', is_open=True, + i, i, name, 'asset', icon='k8s', is_open=True, ) return node diff --git a/apps/perms/api/user_permission/tree/node_with_asset.py b/apps/perms/api/user_permission/tree/node_with_asset.py index d67eda467..1b4ee5d73 100644 --- a/apps/perms/api/user_permission/tree/node_with_asset.py +++ b/apps/perms/api/user_permission/tree/node_with_asset.py @@ -228,9 +228,8 @@ class UserGrantedK8sAsTreeApi(SelfOrPKUserMixin, ListAPIView): util = PermAccountUtil() accounts = util.get_permed_accounts_for_user(self.user, token.asset) account_name = token.account - if account_name in [ - AliasAccount.INPUT, AliasAccount.USER - ]: + + if account_name in [AliasAccount.INPUT, AliasAccount.USER]: return token.input_secret else: accounts = filter(lambda x: x.name == account_name, accounts) From df1aa73723ba0e7780fe9ee3bb10c5672adec339 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=90=B4=E5=B0=8F=E7=99=BD?= <296015668@qq.com> Date: Wed, 16 Aug 2023 13:11:48 +0800 Subject: [PATCH 161/177] perf: python-oracledb Thin Mode --- apps/ops/ansible/modules_utils/oracle_common.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/ops/ansible/modules_utils/oracle_common.py b/apps/ops/ansible/modules_utils/oracle_common.py index 8036a8c1e..a89543bc1 100644 --- a/apps/ops/ansible/modules_utils/oracle_common.py +++ b/apps/ops/ansible/modules_utils/oracle_common.py @@ -56,7 +56,7 @@ class OracleClient(object): def cursor(self): if self._cursor is None: try: - oracledb.init_oracle_client(lib_dir='/opt/oracle/instantclient_19_10') + # oracledb.init_oracle_client(lib_dir='/opt/oracle/instantclient_19_10') self._conn = oracledb.connect(**self.connect_params) self._cursor = self._conn.cursor() except DatabaseError as err: From 3c9c494979390d6984fb78f92561ecb122759f1e Mon Sep 17 00:00:00 2001 From: Eric Date: Wed, 16 Aug 2023 15:04:01 +0800 Subject: [PATCH 162/177] =?UTF-8?q?perf:=20=E4=BF=AE=E5=A4=8D=E5=8F=91?= =?UTF-8?q?=E5=B8=83=E6=9C=BA=E5=9B=A0=E5=90=8C=E5=90=8D=E8=B4=A6=E5=8F=B7?= =?UTF-8?q?=E5=88=9B=E5=BB=BA=E9=80=A0=E6=88=90=E7=9A=84=E9=83=A8=E7=BD=B2?= =?UTF-8?q?=E5=BC=82=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/terminal/signal_handlers/applet.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/terminal/signal_handlers/applet.py b/apps/terminal/signal_handlers/applet.py index 912510901..3b1239901 100644 --- a/apps/terminal/signal_handlers/applet.py +++ b/apps/terminal/signal_handlers/applet.py @@ -29,10 +29,11 @@ def on_applet_host_create(sender, instance, created=False, **kwargs): @receiver(post_save, sender=User) -def on_user_create_create_account(sender, instance, created=False, **kwargs): +def on_user_create_create_account(sender, instance: User, created=False, **kwargs): if not created: return - + if instance.is_service_account: + return with tmp_to_builtin_org(system=1): applet_hosts = AppletHost.objects.all() for host in applet_hosts: From 689fd12141443391b7cb80c81fbeae3515418626 Mon Sep 17 00:00:00 2001 From: ibuler Date: Wed, 16 Aug 2023 14:17:35 +0800 Subject: [PATCH 163/177] =?UTF-8?q?perf:=20windows=20=E5=8F=AF=E4=BB=A5?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=20sftp?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/assets/const/host.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/assets/const/host.py b/apps/assets/const/host.py index cb841bbc2..be8f1d1bf 100644 --- a/apps/assets/const/host.py +++ b/apps/assets/const/host.py @@ -36,7 +36,7 @@ class HostTypes(BaseType): 'choices': ['ssh', 'sftp', 'telnet', 'vnc', 'rdp'] }, cls.WINDOWS: { - 'choices': ['rdp', 'ssh', 'vnc', 'winrm'] + 'choices': ['rdp', 'ssh', 'sftp', 'vnc', 'winrm'] } } From d02cbcc3a3be3fa8cf330ad64c3b2dab59a3b223 Mon Sep 17 00:00:00 2001 From: halo Date: Wed, 16 Aug 2023 16:43:40 +0800 Subject: [PATCH 164/177] =?UTF-8?q?perf:=20linux=E5=AE=A2=E6=88=B7?= =?UTF-8?q?=E7=AB=AF=E6=96=87=E4=BB=B6=E5=90=8E=E7=BC=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/templates/resource_download.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/templates/resource_download.html b/apps/templates/resource_download.html index 0ca87d29c..da801b2f3 100644 --- a/apps/templates/resource_download.html +++ b/apps/templates/resource_download.html @@ -24,8 +24,8 @@ p {
  • jumpserver-client-windows-x86_64.exe
  • jumpserver-client-darwin.dmg(Intel)
  • jumpserver-client-darwin.dmg(Apple Silicon)
  • -
  • jumpserver-client-linux-amd64.run
  • -
  • jumpserver-client-linux-arm64.run
  • +
  • jumpserver-client-linux-amd64.deb
  • +
  • jumpserver-client-linux-arm64.deb
From 8f10b84e94253728f1c334e4b375a4799a38fc5b Mon Sep 17 00:00:00 2001 From: Eric Date: Wed, 16 Aug 2023 16:18:53 +0800 Subject: [PATCH 165/177] =?UTF-8?q?perf:=20=E4=BF=AE=E5=A4=8D=20Chrome=20?= =?UTF-8?q?=E6=89=A7=E8=A1=8C=E8=84=9A=E6=9C=AC=E5=A4=B1=E8=B4=A5=EF=BC=8C?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2=E5=8D=A1=E5=9C=A8=E8=BF=9B=E5=BA=A6=E6=9D=A1?= =?UTF-8?q?=E7=95=8C=E9=9D=A2=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/terminal/applets/chrome/ChangeLog | 4 ++++ apps/terminal/applets/chrome/app.py | 1 - apps/terminal/applets/chrome/common.py | 6 +++++- apps/terminal/applets/chrome/manifest.yml | 2 +- 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/apps/terminal/applets/chrome/ChangeLog b/apps/terminal/applets/chrome/ChangeLog index 81529958b..d59b31125 100644 --- a/apps/terminal/applets/chrome/ChangeLog +++ b/apps/terminal/applets/chrome/ChangeLog @@ -1,3 +1,7 @@ +# 2023-08-16 Version 0.8 +## 功能优化 + - 修复代填失败,造成页面卡住的问题 + # 2023-07-28 Version 0.7 ## 功能优化 - 增加进度窗口,隐藏代填操作 diff --git a/apps/terminal/applets/chrome/app.py b/apps/terminal/applets/chrome/app.py index 14654386e..92ddd1e7c 100644 --- a/apps/terminal/applets/chrome/app.py +++ b/apps/terminal/applets/chrome/app.py @@ -121,7 +121,6 @@ def execute_action(driver: webdriver.Chrome, step: StepAction) -> bool: return step.execute(driver) except Exception as e: print(e) - notify_err_message(str(e)) return False diff --git a/apps/terminal/applets/chrome/common.py b/apps/terminal/applets/chrome/common.py index 161150a0d..8d2ab3df2 100644 --- a/apps/terminal/applets/chrome/common.py +++ b/apps/terminal/applets/chrome/common.py @@ -7,6 +7,7 @@ import subprocess import sys import time from subprocess import CREATE_NO_WINDOW +from threading import Thread _blockInput = None _messageBox = None @@ -36,7 +37,10 @@ def unblock_input(): def notify_err_message(msg): if _messageBox: - _messageBox(msg, 'Error') + # _messageBox 是阻塞当前线程的,所以需要开启一个新线程执行 + t = Thread(target=_messageBox, args=(msg, 'Error'), kwargs={}) + t.daemon = True + t.start() def decode_content(content: bytes) -> str: diff --git a/apps/terminal/applets/chrome/manifest.yml b/apps/terminal/applets/chrome/manifest.yml index c740b23a6..89b35a7dc 100644 --- a/apps/terminal/applets/chrome/manifest.yml +++ b/apps/terminal/applets/chrome/manifest.yml @@ -1,6 +1,6 @@ name: chrome display_name: "{{ 'Chrome Browser' | trans }}" -version: 0.7 +version: 0.8 comment: "{{ 'Chrome Browser Open URL Page Address' | trans }}" author: JumpServer Team exec_type: python From af9f7060beb3348f092ce0aa95aedca18fa0da95 Mon Sep 17 00:00:00 2001 From: Aaron3S Date: Wed, 16 Aug 2023 17:01:15 +0800 Subject: [PATCH 166/177] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=20shell=20?= =?UTF-8?q?=E6=89=B9=E9=87=8F=E5=91=BD=E4=BB=A4=E6=97=A0=E6=B3=95=E6=89=A7?= =?UTF-8?q?=E8=A1=8C=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/ops/models/job.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/apps/ops/models/job.py b/apps/ops/models/job.py index 23105f297..f27e6b309 100644 --- a/apps/ops/models/job.py +++ b/apps/ops/models/job.py @@ -60,7 +60,14 @@ class JMSPermedInventory(JMSInventory): host['error'] = _("No account available") return host - if protocol.name != self.module: + protocol_supported_modules_mapping = { + 'mysql': ['mysql'], + 'postgresql': ['postgresql'], + 'sqlserver': ['sqlserver'], + 'ssh': ['shell', 'python', 'win_shell'], + } + + if self.module not in protocol_supported_modules_mapping.get(protocol.name, []): host['error'] = "Module {} is not suitable for this asset".format(self.module) return host From 45e1723aa95dbc855112497f794c90fcb5ca2de9 Mon Sep 17 00:00:00 2001 From: Eric Date: Wed, 16 Aug 2023 18:17:32 +0800 Subject: [PATCH 167/177] =?UTF-8?q?perf:=20=E4=BF=AE=E5=A4=8D=E5=8F=91?= =?UTF-8?q?=E5=B8=83=E6=9C=BA=E4=BB=BB=E5=8A=A1=E6=89=A7=E8=A1=8C=E5=A4=B1?= =?UTF-8?q?=E8=B4=A5=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/terminal/api/applet/host.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/terminal/api/applet/host.py b/apps/terminal/api/applet/host.py index f0dce9785..6b06ee44e 100644 --- a/apps/terminal/api/applet/host.py +++ b/apps/terminal/api/applet/host.py @@ -1,3 +1,4 @@ +from django.db import transaction from rest_framework import status from rest_framework import viewsets from rest_framework.decorators import action @@ -58,7 +59,8 @@ class AppletHostDeploymentViewSet(viewsets.ModelViewSet): def create(self, request, *args, **kwargs): serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) - instance = serializer.save() + with transaction.atomic(): + instance = serializer.save() task = run_applet_host_deployment.delay(instance.id) instance.save_task(task.id) return Response({'task': str(task.id)}, status=201) From 40248077cd1b9939c1138ea45994cc3287467557 Mon Sep 17 00:00:00 2001 From: ibuler Date: Wed, 16 Aug 2023 18:30:29 +0800 Subject: [PATCH 168/177] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=20chrome=20?= =?UTF-8?q?=E6=8F=92=E4=BB=B6=E4=B8=8D=E7=94=9F=E6=95=88=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../disable_new_tab_window_menu/background.js | 19 ++++++++++++++----- .../disable_new_tab_window_menu/manifest.json | 2 +- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/apps/terminal/applets/chrome/extensions/disable_new_tab_window_menu/background.js b/apps/terminal/applets/chrome/extensions/disable_new_tab_window_menu/background.js index 7f2556ab8..0ea3a1353 100644 --- a/apps/terminal/applets/chrome/extensions/disable_new_tab_window_menu/background.js +++ b/apps/terminal/applets/chrome/extensions/disable_new_tab_window_menu/background.js @@ -6,24 +6,25 @@ const debug = console.log // 监听标签页的创建事件 chrome.tabs.onCreated.addListener(function (tab) { // 获取当前窗口的所有标签页 - debug('New tab add, tabs : ', tabs) + debug('New tab add, tabs : ', tabs.map(t => t.id)) tabs.push(tab) }); chrome.tabs.onUpdated.addListener(function (tabId, changeInfo, tab) { - debug('Tab changed xx: ', tabId, changeInfo, tab) + debug('Tab status changed: ', tabId, ' => ', changeInfo.status) if (changeInfo.status !== 'loading') { return } const tabFind = tabs.findIndex(t => t.id === tabId) if (tabFind === -1) { - debug('Tab not found: ', tabId, tabs) - return + tabs.push(tab) + } else { + Object.assign(tabs[tabFind], tab) } - Object.assign(tabs[tabFind], tab) const blockUrls = ['chrome://newtab/'] if (!tab.url || blockUrls.includes(tab.url) || tab.url.startsWith('chrome://')) { + alert('安全模式,禁止打开新标签页') debug('Blocked url, destroy: ', tab.url) chrome.tabs.remove(tabId); return @@ -52,3 +53,11 @@ chrome.tabs.onUpdated.addListener(function (tabId, changeInfo, tab) { chrome.tabs.remove(tabId); } }) + +chrome.tabs.onRemoved.addListener(function (tabId, removeInfo) { + debug('Tab removed: ', tabId) + const tabFind = tabs.findIndex(t => t.id === tabId) + if (tabFind !== -1) { + tabs.splice(tabFind, 1) + } +}) diff --git a/apps/terminal/applets/chrome/extensions/disable_new_tab_window_menu/manifest.json b/apps/terminal/applets/chrome/extensions/disable_new_tab_window_menu/manifest.json index 58ad2b4a1..6cef03a67 100644 --- a/apps/terminal/applets/chrome/extensions/disable_new_tab_window_menu/manifest.json +++ b/apps/terminal/applets/chrome/extensions/disable_new_tab_window_menu/manifest.json @@ -7,7 +7,7 @@ "scripts": [ "background.js" ], - "persistent": false + "persistent": true }, "content_scripts": [ { From f69703325227870c77b6a94fa1c4f37967254085 Mon Sep 17 00:00:00 2001 From: ibuler Date: Thu, 17 Aug 2023 10:18:27 +0800 Subject: [PATCH 169/177] perf: add iframe option --- apps/jumpserver/conf.py | 3 +++ apps/jumpserver/settings/base.py | 2 ++ 2 files changed, 5 insertions(+) diff --git a/apps/jumpserver/conf.py b/apps/jumpserver/conf.py index cab2ebf3a..1d513025c 100644 --- a/apps/jumpserver/conf.py +++ b/apps/jumpserver/conf.py @@ -220,6 +220,9 @@ class Config(dict): 'ANNOUNCEMENT_ENABLED': True, 'ANNOUNCEMENT': {}, + # Security + 'X_FRAME_OPTIONS': 'DENY', + # 未使用的配置 'CAPTCHA_TEST_MODE': None, 'DISPLAY_PER_PAGE': 25, diff --git a/apps/jumpserver/settings/base.py b/apps/jumpserver/settings/base.py index dbe6a59a7..5bd7fb84e 100644 --- a/apps/jumpserver/settings/base.py +++ b/apps/jumpserver/settings/base.py @@ -334,6 +334,8 @@ AUTH_USER_MODEL = 'users.User' FILE_UPLOAD_PERMISSIONS = 0o644 FILE_UPLOAD_DIRECTORY_PERMISSIONS = 0o755 +X_FRAME_OPTIONS = CONFIG.X_FRAME_OPTIONS + # Cache use redis REDIS_SSL_KEY = exist_or_default(os.path.join(CERTS_DIR, 'redis_client.key'), None) REDIS_SSL_CERT = exist_or_default(os.path.join(CERTS_DIR, 'redis_client.crt'), None) From bbd36fea03038ff92f0df93a5eb01036edc409be Mon Sep 17 00:00:00 2001 From: Eric Date: Thu, 17 Aug 2023 10:33:59 +0800 Subject: [PATCH 170/177] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=E5=8F=91?= =?UTF-8?q?=E5=B8=83=E6=9C=BA=E7=9A=84=E6=B3=A8=E5=86=8C=E5=90=8D=E7=A7=B0?= =?UTF-8?q?=EF=BC=8C=E9=81=BF=E5=85=8D=E9=87=8D=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/terminal/automations/deploy_applet_host/__init__.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/apps/terminal/automations/deploy_applet_host/__init__.py b/apps/terminal/automations/deploy_applet_host/__init__.py index 164340098..449306a92 100644 --- a/apps/terminal/automations/deploy_applet_host/__init__.py +++ b/apps/terminal/automations/deploy_applet_host/__init__.py @@ -6,7 +6,7 @@ from django.conf import settings from django.utils import timezone from common.db.utils import safe_db_connection -from common.utils import get_logger +from common.utils import get_logger, random_string from ops.ansible import PlaybookRunner, JMSInventory from terminal.models import Applet, AppletHostDeployment @@ -58,13 +58,15 @@ class DeployAppletHostManager: download_host = download_host.rstrip("/") def handler(plays): + applet_host_name = self.deployment.host.name + hostname = '{}-{}'.format(applet_host_name, random_string(7)) for play in plays: play["vars"].update(options) play["vars"]["APPLET_DOWNLOAD_HOST"] = download_host play["vars"]["CORE_HOST"] = core_host play["vars"]["BOOTSTRAP_TOKEN"] = bootstrap_token play["vars"]["HOST_ID"] = host_id - play["vars"]["HOST_NAME"] = self.deployment.host.name + play["vars"]["HOST_NAME"] = hostname return plays return self._generate_playbook("playbook.yml", handler) From 769d5fbd96f1065dda99c403be0918802d69deae Mon Sep 17 00:00:00 2001 From: ibuler Date: Thu, 17 Aug 2023 10:54:35 +0800 Subject: [PATCH 171/177] =?UTF-8?q?perf:=20applet=20=E4=B8=8A=E4=BC=A0?= =?UTF-8?q?=E6=A3=80=E6=9F=A5=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/locale/ja/LC_MESSAGES/django.po | 518 ++++++++++++++------------- apps/locale/zh/LC_MESSAGES/django.po | 518 ++++++++++++++------------- apps/terminal/api/applet/applet.py | 4 + 3 files changed, 526 insertions(+), 514 deletions(-) diff --git a/apps/locale/ja/LC_MESSAGES/django.po b/apps/locale/ja/LC_MESSAGES/django.po index 98f9f02bb..c406683cc 100644 --- a/apps/locale/ja/LC_MESSAGES/django.po +++ b/apps/locale/ja/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-08-15 16:45+0800\n" +"POT-Creation-Date: 2023-08-17 10:41+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -45,7 +45,7 @@ msgid "Access key" msgstr "アクセスキー" #: accounts/const/account.py:9 assets/models/_user.py:48 -#: authentication/models/sso_token.py:14 settings/serializers/feature.py:48 +#: authentication/models/sso_token.py:14 settings/serializers/feature.py:52 msgid "Token" msgstr "トークン" @@ -213,7 +213,7 @@ msgstr "HashiCorp Vault" #: terminal/serializers/session.py:26 #: terminal/templates/terminal/_msg_command_warning.html:4 #: terminal/templates/terminal/_msg_session_sharing.html:4 -#: tickets/models/ticket/apply_asset.py:16 xpack/plugins/cloud/models.py:253 +#: tickets/models/ticket/apply_asset.py:16 xpack/plugins/cloud/models.py:212 msgid "Asset" msgstr "資産" @@ -248,7 +248,7 @@ msgstr "ソース ID" #: terminal/backends/command/models.py:18 terminal/models/session/session.py:33 #: terminal/templates/terminal/_msg_command_warning.html:8 #: terminal/templates/terminal/_msg_session_sharing.html:8 -#: tickets/models/ticket/command_confirm.py:13 xpack/plugins/cloud/models.py:89 +#: tickets/models/ticket/command_confirm.py:13 xpack/plugins/cloud/models.py:85 msgid "Account" msgstr "アカウント" @@ -287,7 +287,7 @@ msgstr "アカウントバックアップ計画" #: accounts/models/automations/backup_account.py:91 #: assets/models/automations/base.py:115 audits/models.py:60 -#: ops/models/base.py:55 ops/models/celery.py:63 ops/models/job.py:221 +#: ops/models/base.py:55 ops/models/celery.py:63 ops/models/job.py:228 #: ops/templates/ops/celery_task_log.html:75 #: perms/models/asset_permission.py:72 terminal/models/applet/host.py:140 #: terminal/models/session/session.py:44 @@ -315,7 +315,7 @@ msgid "Trigger mode" msgstr "トリガーモード" #: accounts/models/automations/backup_account.py:105 audits/models.py:194 -#: terminal/models/session/sharing.py:121 xpack/plugins/cloud/models.py:205 +#: terminal/models/session/sharing.py:121 xpack/plugins/cloud/models.py:168 msgid "Reason" msgstr "理由" @@ -420,7 +420,7 @@ msgstr "開始日" #: accounts/models/automations/change_secret.py:91 #: assets/models/automations/base.py:116 ops/models/base.py:56 -#: ops/models/celery.py:64 ops/models/job.py:222 +#: ops/models/celery.py:64 ops/models/job.py:229 #: terminal/models/applet/host.py:141 msgid "Date finished" msgstr "終了日" @@ -506,7 +506,7 @@ msgstr "アカウントの確認" #: assets/serializers/platform.py:110 assets/serializers/platform.py:223 #: authentication/serializers/connect_token_secret.py:110 ops/mixin.py:21 #: ops/models/adhoc.py:20 ops/models/celery.py:15 ops/models/celery.py:57 -#: ops/models/job.py:119 ops/models/playbook.py:28 ops/serializers/job.py:20 +#: ops/models/job.py:126 ops/models/playbook.py:28 ops/serializers/job.py:20 #: orgs/models.py:82 perms/models/asset_permission.py:56 rbac/models/role.py:29 #: settings/models.py:32 settings/serializers/msg.py:82 #: terminal/models/applet/applet.py:32 terminal/models/component/endpoint.py:12 @@ -514,8 +514,7 @@ msgstr "アカウントの確認" #: terminal/models/component/storage.py:26 terminal/models/component/task.py:13 #: terminal/models/component/terminal.py:84 users/forms/profile.py:33 #: users/models/group.py:13 users/models/user.py:787 -#: xpack/plugins/cloud/models.py:32 xpack/plugins/cloud/models.py:273 -#: xpack/plugins/cloud/serializers/task.py:68 +#: xpack/plugins/cloud/models.py:28 msgid "Name" msgstr "名前" @@ -532,7 +531,7 @@ msgstr "特権アカウント" msgid "Is active" msgstr "アクティブです。" -#: accounts/models/template.py:19 xpack/plugins/cloud/models.py:325 +#: accounts/models/template.py:19 msgid "Account template" msgstr "アカウント テンプレート" @@ -638,8 +637,8 @@ msgstr "カテゴリ" #: assets/models/cmd_filter.py:74 assets/models/platform.py:90 #: assets/serializers/asset/common.py:122 assets/serializers/platform.py:112 #: assets/serializers/platform.py:127 audits/serializers.py:49 -#: authentication/serializers/connect_token_secret.py:123 ops/models/job.py:130 -#: perms/serializers/user_permission.py:27 settings/serializers/feature.py:42 +#: authentication/serializers/connect_token_secret.py:123 ops/models/job.py:137 +#: perms/serializers/user_permission.py:27 settings/serializers/feature.py:46 #: terminal/models/applet/applet.py:38 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:226 @@ -673,7 +672,7 @@ msgstr "編集済み" #: accounts/serializers/automations/base.py:22 acls/models/base.py:97 #: assets/models/automations/base.py:19 #: assets/serializers/automations/base.py:20 ops/models/base.py:17 -#: ops/models/job.py:132 ops/serializers/job.py:21 +#: ops/models/job.py:139 ops/serializers/job.py:21 #: terminal/templates/terminal/_msg_command_execute_alert.html:16 msgid "Assets" msgstr "資産" @@ -764,14 +763,14 @@ msgstr "" #: accounts/serializers/account/virtual.py:19 assets/models/_user.py:27 #: assets/models/cmd_filter.py:40 assets/models/cmd_filter.py:88 #: assets/models/group.py:20 common/db/models.py:36 ops/models/adhoc.py:26 -#: ops/models/job.py:138 ops/models/playbook.py:31 rbac/models/role.py:37 +#: ops/models/job.py:145 ops/models/playbook.py:31 rbac/models/role.py:37 #: settings/models.py:37 terminal/models/applet/applet.py:44 #: terminal/models/applet/applet.py:284 terminal/models/applet/host.py:142 #: terminal/models/component/endpoint.py:24 #: terminal/models/component/endpoint.py:104 #: terminal/models/session/session.py:46 tickets/models/comment.py:32 #: tickets/models/ticket/general.py:297 users/models/user.py:826 -#: xpack/plugins/cloud/models.py:39 xpack/plugins/cloud/models.py:109 +#: xpack/plugins/cloud/models.py:35 xpack/plugins/cloud/models.py:111 msgid "Comment" msgstr "コメント" @@ -892,13 +891,11 @@ msgstr "警告" #: acls/models/base.py:37 assets/models/_user.py:51 #: assets/models/cmd_filter.py:76 terminal/models/component/endpoint.py:97 -#: xpack/plugins/cloud/models.py:275 msgid "Priority" msgstr "優先順位" #: acls/models/base.py:38 assets/models/_user.py:51 #: assets/models/cmd_filter.py:76 terminal/models/component/endpoint.py:98 -#: xpack/plugins/cloud/models.py:276 msgid "1-100, the lower the value will be match first" msgstr "1-100、低い値は最初に一致します" @@ -935,7 +932,6 @@ msgid "Command" msgstr "コマンド" #: acls/models/command_acl.py:17 assets/models/cmd_filter.py:59 -#: xpack/plugins/cloud/models.py:291 msgid "Regex" msgstr "正規情報" @@ -1032,7 +1028,7 @@ msgid "None of the reviewers belong to Organization `{}`" msgstr "いずれのレビューアも組織 '{}' に属していません" #: acls/serializers/rules/rules.py:20 -#: xpack/plugins/cloud/serializers/task.py:133 +#: xpack/plugins/cloud/serializers/task.py:22 msgid "IP address invalid: `{}`" msgstr "IPアドレスが無効: '{}'" @@ -1060,7 +1056,7 @@ msgstr "期間" msgid "Applications" msgstr "アプリケーション" -#: applications/models.py:16 xpack/plugins/cloud/models.py:37 +#: applications/models.py:16 xpack/plugins/cloud/models.py:33 #: xpack/plugins/cloud/serializers/account.py:63 msgid "Attrs" msgstr "ツールバーの" @@ -1169,7 +1165,7 @@ msgstr "脚本" #: assets/const/category.py:10 assets/models/asset/host.py:8 #: settings/serializers/auth/radius.py:16 settings/serializers/auth/sms.py:67 -#: settings/serializers/feature.py:45 terminal/models/component/endpoint.py:13 +#: settings/serializers/feature.py:49 terminal/models/component/endpoint.py:13 #: terminal/serializers/applet.py:17 #: xpack/plugins/cloud/serializers/account_attrs.py:72 msgid "Host" @@ -1354,7 +1350,7 @@ msgstr "SSHパブリックキー" #: assets/models/_user.py:28 assets/models/automations/base.py:114 #: assets/models/cmd_filter.py:41 assets/models/group.py:19 -#: common/db/models.py:34 ops/models/base.py:54 ops/models/job.py:220 +#: common/db/models.py:34 ops/models/base.py:54 ops/models/job.py:227 #: users/models/user.py:1018 msgid "Date created" msgstr "作成された日付" @@ -1458,13 +1454,14 @@ msgstr "アドレス" #: assets/models/asset/common.py:151 assets/models/platform.py:119 #: authentication/serializers/connect_token_secret.py:115 -#: perms/serializers/user_permission.py:24 xpack/plugins/cloud/models.py:321 +#: perms/serializers/user_permission.py:24 +#: xpack/plugins/cloud/serializers/account_attrs.py:196 msgid "Platform" msgstr "プラットフォーム" #: assets/models/asset/common.py:153 assets/models/domain.py:21 #: authentication/serializers/connect_token_secret.py:133 -#: perms/serializers/user_permission.py:29 xpack/plugins/cloud/models.py:323 +#: perms/serializers/user_permission.py:29 msgid "Domain" msgstr "ドメイン" @@ -1521,7 +1518,7 @@ msgstr "証明書チェックを無視" msgid "Proxy" msgstr "プロキシー" -#: assets/models/automations/base.py:22 ops/models/job.py:216 +#: assets/models/automations/base.py:22 ops/models/job.py:223 #: settings/serializers/auth/sms.py:99 msgid "Parameters" msgstr "パラメータ" @@ -1535,13 +1532,13 @@ msgid "Asset automation task" msgstr "アセットの自動化タスク" #: assets/models/automations/base.py:113 audits/models.py:199 -#: audits/serializers.py:50 ops/models/base.py:49 ops/models/job.py:213 +#: audits/serializers.py:50 ops/models/base.py:49 ops/models/job.py:220 #: terminal/models/applet/applet.py:283 terminal/models/applet/host.py:139 #: terminal/models/component/status.py:30 terminal/serializers/applet.py:18 #: terminal/serializers/applet_host.py:115 tickets/models/ticket/general.py:283 #: tickets/serializers/super_ticket.py:13 -#: tickets/serializers/ticket/ticket.py:20 xpack/plugins/cloud/models.py:201 -#: xpack/plugins/cloud/models.py:257 +#: tickets/serializers/ticket/ticket.py:20 xpack/plugins/cloud/models.py:164 +#: xpack/plugins/cloud/models.py:216 msgid "Status" msgstr "ステータス" @@ -1605,7 +1602,7 @@ msgstr "資産グループ" #: assets/models/group.py:31 assets/models/platform.py:19 #: assets/serializers/platform.py:113 -#: xpack/plugins/cloud/providers/nutanix.py:30 +#: xpack/plugins/cloud/providers/nutanix.py:32 msgid "Default" msgstr "デフォルト" @@ -1655,7 +1652,7 @@ msgid "Parent key" msgstr "親キー" #: assets/models/node.py:558 perms/serializers/permission.py:35 -#: tickets/models/ticket/apply_asset.py:14 xpack/plugins/cloud/models.py:322 +#: tickets/models/ticket/apply_asset.py:14 xpack/plugins/cloud/models.py:96 msgid "Node" msgstr "ノード" @@ -1676,7 +1673,7 @@ msgid "Public" msgstr "開ける" #: assets/models/platform.py:21 assets/serializers/platform.py:48 -#: settings/serializers/settings.py:66 +#: settings/serializers/settings.py:65 #: users/templates/users/reset_password.html:29 msgid "Setting" msgstr "設定" @@ -1796,8 +1793,7 @@ msgstr "" #: assets/serializers/asset/common.py:124 assets/serializers/platform.py:129 #: authentication/serializers/connect_token_secret.py:29 #: authentication/serializers/connect_token_secret.py:72 -#: perms/serializers/user_permission.py:25 xpack/plugins/cloud/models.py:324 -#: xpack/plugins/cloud/serializers/task.py:31 +#: perms/serializers/user_permission.py:25 xpack/plugins/cloud/models.py:99 msgid "Protocols" msgstr "プロトコル" @@ -2299,7 +2295,7 @@ msgstr "ユーザー %s が現在のリソースでタスク (%s) を実行し msgid "SSH Key" msgstr "SSHキー" -#: audits/signal_handlers/login_log.py:29 settings/serializers/auth/sso.py:10 +#: audits/signal_handlers/login_log.py:29 settings/serializers/auth/sso.py:13 msgid "SSO" msgstr "SSO" @@ -2986,7 +2982,7 @@ msgstr "コードエラー" #: authentication/templates/authentication/_msg_reset_password_code.html:9 #: authentication/templates/authentication/_msg_rest_password_success.html:2 #: authentication/templates/authentication/_msg_rest_public_key_success.html:2 -#: jumpserver/conf.py:441 +#: jumpserver/conf.py:444 #: perms/templates/perms/_msg_item_permissions_expire.html:3 #: perms/templates/perms/_msg_permed_items_expire.html:3 #: tickets/templates/tickets/approve_check_password.html:33 @@ -3581,11 +3577,11 @@ msgstr "検索のエクスポート: %s" msgid "User %s view/export secret" msgstr "ユーザー %s がパスワードを閲覧/導き出しました" -#: jumpserver/conf.py:440 +#: jumpserver/conf.py:443 msgid "Create account successfully" msgstr "アカウントを正常に作成" -#: jumpserver/conf.py:442 +#: jumpserver/conf.py:445 msgid "Your account has been created successfully" msgstr "アカウントが正常に作成されました" @@ -3725,7 +3721,7 @@ msgstr "VCS" msgid "Adhoc" msgstr "コマンド#コマンド#" -#: ops/const.py:39 ops/models/job.py:128 +#: ops/const.py:39 ops/models/job.py:135 msgid "Playbook" msgstr "Playbook" @@ -3794,17 +3790,17 @@ msgstr "定期的または定期的に設定を行う必要があります" msgid "Pattern" msgstr "パターン" -#: ops/models/adhoc.py:23 ops/models/job.py:123 +#: ops/models/adhoc.py:23 ops/models/job.py:130 msgid "Module" msgstr "モジュール" -#: ops/models/adhoc.py:24 ops/models/celery.py:58 ops/models/job.py:122 +#: ops/models/adhoc.py:24 ops/models/celery.py:58 ops/models/job.py:129 #: terminal/models/component/task.py:14 msgid "Args" msgstr "アルグ" #: ops/models/adhoc.py:25 ops/models/base.py:16 ops/models/base.py:53 -#: ops/models/job.py:131 ops/models/job.py:219 ops/models/playbook.py:30 +#: ops/models/job.py:138 ops/models/job.py:226 ops/models/playbook.py:30 #: terminal/models/session/sharing.py:24 msgid "Creator" msgstr "作成者" @@ -3821,12 +3817,12 @@ msgstr "最後の実行" msgid "Date last run" msgstr "最終実行日" -#: ops/models/base.py:51 ops/models/job.py:217 -#: xpack/plugins/cloud/models.py:199 +#: ops/models/base.py:51 ops/models/job.py:224 +#: xpack/plugins/cloud/models.py:162 msgid "Result" msgstr "結果" -#: ops/models/base.py:52 ops/models/job.py:218 +#: ops/models/base.py:52 ops/models/job.py:225 msgid "Summary" msgstr "概要" @@ -3859,43 +3855,43 @@ msgstr "発売日" msgid "Celery Task Execution" msgstr "Celery タスク実行" -#: ops/models/job.py:125 +#: ops/models/job.py:132 msgid "Chdir" msgstr "実行ディレクトリ" -#: ops/models/job.py:126 +#: ops/models/job.py:133 msgid "Timeout (Seconds)" msgstr "タイムアウト(秒)" -#: ops/models/job.py:133 +#: ops/models/job.py:140 msgid "Use Parameter Define" msgstr "パラメータ定義を使用する" -#: ops/models/job.py:134 +#: ops/models/job.py:141 msgid "Parameters define" msgstr "パラメータ定義" -#: ops/models/job.py:135 +#: ops/models/job.py:142 msgid "Runas" msgstr "ユーザーとして実行" -#: ops/models/job.py:137 +#: ops/models/job.py:144 msgid "Runas policy" msgstr "ユーザー ポリシー" -#: ops/models/job.py:201 +#: ops/models/job.py:208 msgid "Job" msgstr "ジョブ#ジョブ#" -#: ops/models/job.py:224 +#: ops/models/job.py:231 msgid "Material" msgstr "Material" -#: ops/models/job.py:226 +#: ops/models/job.py:233 msgid "Material Type" msgstr "Material を選択してオプションを設定します。" -#: ops/models/job.py:526 +#: ops/models/job.py:533 msgid "Job Execution" msgstr "ジョブ実行" @@ -4370,7 +4366,8 @@ msgstr "リモートアプリケーション" msgid "Ticket comment" msgstr "チケットコメント" -#: rbac/tree.py:124 tickets/models/ticket/general.py:307 +#: rbac/tree.py:124 settings/serializers/feature.py:64 +#: tickets/models/ticket/general.py:307 msgid "Ticket" msgstr "チケット" @@ -4472,42 +4469,54 @@ msgid "Can change other setting" msgstr "他の設定を変えることができます" #: settings/serializers/auth/base.py:12 +#, fuzzy +#| msgid "MFA Auth" +msgid "LDAP Auth" +msgstr "MFA マルチファクタ認証" + +#: settings/serializers/auth/base.py:13 msgid "CAS Auth" msgstr "CAS 認証" -#: settings/serializers/auth/base.py:13 +#: settings/serializers/auth/base.py:14 msgid "OPENID Auth" msgstr "OPENID 認証" -#: settings/serializers/auth/base.py:14 -msgid "RADIUS Auth" -msgstr "RADIUS 認証" - #: settings/serializers/auth/base.py:15 -msgid "DingTalk Auth" -msgstr "くぎ 認証" - -#: settings/serializers/auth/base.py:16 -msgid "FeiShu Auth" -msgstr "飛本 認証" - -#: settings/serializers/auth/base.py:17 -msgid "WeCom Auth" -msgstr "企業微信 認証" - -#: settings/serializers/auth/base.py:18 -msgid "SSO Auth" -msgstr "SSO Token 認証" - -#: settings/serializers/auth/base.py:19 msgid "SAML2 Auth" msgstr "SAML2 認証" -#: settings/serializers/auth/base.py:22 settings/serializers/basic.py:17 +#: settings/serializers/auth/base.py:16 +#, fuzzy +#| msgid "Enable OAuth2 Auth" +msgid "OAuth2 Auth" +msgstr "OAuth2認証の有効化" + +#: settings/serializers/auth/base.py:17 +msgid "RADIUS Auth" +msgstr "RADIUS 認証" + +#: settings/serializers/auth/base.py:18 +msgid "DingTalk Auth" +msgstr "くぎ 認証" + +#: settings/serializers/auth/base.py:19 +msgid "FeiShu Auth" +msgstr "飛本 認証" + +#: settings/serializers/auth/base.py:20 +msgid "WeCom Auth" +msgstr "企業微信 認証" + +#: settings/serializers/auth/base.py:21 +msgid "SSO Auth" +msgstr "SSO Token 認証" + +#: settings/serializers/auth/base.py:24 msgid "Forgot password url" msgstr "パスワードのURLを忘れた" -#: settings/serializers/auth/base.py:28 +#: settings/serializers/auth/base.py:30 msgid "Enable login redirect msg" msgstr "ログインリダイレクトの有効化msg" @@ -4864,20 +4873,20 @@ msgstr "請求方法です" msgid "The value in the parameter must contain %s" msgstr "パラメータの値には必ず %s が含まれます" -#: settings/serializers/auth/sso.py:13 +#: settings/serializers/auth/sso.py:16 msgid "Enable SSO auth" msgstr "SSO Token認証の有効化" -#: settings/serializers/auth/sso.py:14 +#: settings/serializers/auth/sso.py:17 msgid "Other service can using SSO token login to JumpServer without password" msgstr "" "他のサービスはパスワードなしでJumpServerへのSSOトークンログインを使用できます" -#: settings/serializers/auth/sso.py:17 +#: settings/serializers/auth/sso.py:20 msgid "SSO auth key TTL" msgstr "Token有効期間" -#: settings/serializers/auth/sso.py:17 +#: settings/serializers/auth/sso.py:20 #: xpack/plugins/cloud/serializers/account_attrs.py:193 msgid "Unit: second" msgstr "単位: 秒" @@ -4904,35 +4913,27 @@ msgstr "ユーザーガイドurl" msgid "User first login update profile done redirect to it" msgstr "ユーザーの最初のログイン更新プロファイルがリダイレクトされました" -#: settings/serializers/basic.py:18 -msgid "" -"The forgot password url on login page, If you use ldap or cas external " -"authentication, you can set it" -msgstr "" -"ログインページでパスワードのURLを忘れてしまいました。ldapまたはcasの外部認証" -"を使用している場合は、設定できます。" - -#: settings/serializers/basic.py:22 +#: settings/serializers/basic.py:17 msgid "Global organization name" msgstr "グローバル組織名" -#: settings/serializers/basic.py:23 +#: settings/serializers/basic.py:18 msgid "The name of global organization to display" msgstr "表示するグローバル組織の名前" -#: settings/serializers/basic.py:26 +#: settings/serializers/basic.py:21 msgid "Help Docs URL" msgstr "ドキュメントリンク" -#: settings/serializers/basic.py:27 +#: settings/serializers/basic.py:22 msgid "default: http://docs.jumpserver.org" msgstr "デフォルト: http://docs.jumpserver.org" -#: settings/serializers/basic.py:30 +#: settings/serializers/basic.py:25 msgid "Help Support URL" msgstr "サポートリンク" -#: settings/serializers/basic.py:31 +#: settings/serializers/basic.py:26 msgid "default: http://www.jumpserver.org/support/" msgstr "デフォルト: http://www.jumpserver.org/support/" @@ -4984,51 +4985,63 @@ msgstr "件名" msgid "More url" msgstr "もっとURL" -#: settings/serializers/feature.py:35 -msgid "Enable announcement" -msgstr "アナウンスの有効化" - -#: settings/serializers/feature.py:36 +#: settings/serializers/feature.py:35 settings/serializers/feature.py:38 msgid "Announcement" msgstr "発表" -#: settings/serializers/feature.py:51 +#: settings/serializers/feature.py:37 +msgid "Enable announcement" +msgstr "アナウンスの有効化" + +#: settings/serializers/feature.py:42 +#, fuzzy +#| msgid "HCP Vault" +msgid "Vault" +msgstr "HashiCorp Vault" + +#: settings/serializers/feature.py:55 msgid "Mount Point" msgstr "" -#: settings/serializers/feature.py:60 +#: settings/serializers/feature.py:66 msgid "Enable tickets" msgstr "チケットを有効にする" -#: settings/serializers/feature.py:63 +#: settings/serializers/feature.py:69 msgid "Ticket authorize default time" msgstr "デフォルト製造オーダ承認時間" -#: settings/serializers/feature.py:66 +#: settings/serializers/feature.py:72 msgid "day" msgstr "日" -#: settings/serializers/feature.py:66 +#: settings/serializers/feature.py:72 msgid "hour" msgstr "時" -#: settings/serializers/feature.py:67 +#: settings/serializers/feature.py:73 msgid "Ticket authorize default time unit" msgstr "デフォルト製造オーダ承認時間単位" -#: settings/serializers/feature.py:73 +#: settings/serializers/feature.py:78 +#, fuzzy +#| msgid "Signature" +msgid "Feature" +msgstr "署名" + +#: settings/serializers/feature.py:81 msgid "Operation center" msgstr "職業センター" -#: settings/serializers/feature.py:74 +#: settings/serializers/feature.py:82 msgid "Allow user run batch command or not using ansible" msgstr "ユーザー実行バッチコマンドを許可するか、ansibleを使用しない" -#: settings/serializers/feature.py:78 +#: settings/serializers/feature.py:86 msgid "Operation center command blacklist" msgstr "オペレーション センター コマンド ブラックリスト" -#: settings/serializers/feature.py:79 +#: settings/serializers/feature.py:87 msgid "Commands that are not allowed execute." msgstr "実行が許可されていないコマンド" @@ -5427,7 +5440,7 @@ msgstr "メール受信者" msgid "Multiple user using , split" msgstr "複数のユーザーを使用して、分割" -#: settings/serializers/settings.py:70 +#: settings/serializers/settings.py:69 #, python-format msgid "[%s] %s" msgstr "[%s] %s" @@ -5813,6 +5826,10 @@ msgstr "オフラインビデオプレーヤー" msgid "Invalid zip file" msgstr "zip ファイルが無効です" +#: terminal/api/applet/applet.py:65 +msgid "This is enterprise edition applet" +msgstr "これはエンタープライズ版アプレットです" + #: terminal/api/component/endpoint.py:32 msgid "Not found protocol query params" msgstr "プロトコルクエリパラメータが見つかりません" @@ -6512,7 +6529,7 @@ msgstr "アクセスキー" msgid "Access key secret" msgstr "アクセスキーシークレット" -#: terminal/serializers/storage.py:67 xpack/plugins/cloud/models.py:250 +#: terminal/serializers/storage.py:67 xpack/plugins/cloud/models.py:209 msgid "Region" msgstr "リージョン" @@ -7074,7 +7091,7 @@ msgid "Not a valid ssh public key" msgstr "有効なssh公開鍵ではありません" #: users/forms/profile.py:173 users/models/user.py:820 -#: xpack/plugins/cloud/serializers/account_attrs.py:203 +#: xpack/plugins/cloud/serializers/account_attrs.py:206 msgid "Public key" msgstr "公開キー" @@ -7103,7 +7120,7 @@ msgid "OTP secret key" msgstr "OTP 秘密" #: users/models/user.py:817 -#: xpack/plugins/cloud/serializers/account_attrs.py:206 +#: xpack/plugins/cloud/serializers/account_attrs.py:209 msgid "Private key" msgstr "ssh秘密鍵" @@ -7542,11 +7559,11 @@ msgstr "パスワードの成功をリセットし、ログインページに戻 msgid "XPACK" msgstr "XPack" -#: xpack/plugins/cloud/api.py:56 +#: xpack/plugins/cloud/api.py:38 msgid "Test connection successful" msgstr "テスト接続成功" -#: xpack/plugins/cloud/api.py:58 +#: xpack/plugins/cloud/api.py:40 msgid "Test connection failed: {}" msgstr "テスト接続に失敗しました: {}" @@ -7634,7 +7651,7 @@ msgstr "プライベートIP" msgid "Public IP" msgstr "パブリックIP" -#: xpack/plugins/cloud/const.py:38 xpack/plugins/cloud/models.py:295 +#: xpack/plugins/cloud/const.py:38 msgid "Instance name" msgstr "インスタンス名" @@ -7662,158 +7679,78 @@ msgstr "同期済み" msgid "Released" msgstr "リリース済み" -#: xpack/plugins/cloud/manager.py:53 -msgid "Account unavailable" -msgstr "利用できないアカウント" - #: xpack/plugins/cloud/meta.py:9 msgid "Cloud center" msgstr "クラウドセンター" -#: xpack/plugins/cloud/models.py:34 +#: xpack/plugins/cloud/models.py:30 msgid "Provider" msgstr "プロバイダー" -#: xpack/plugins/cloud/models.py:38 +#: xpack/plugins/cloud/models.py:34 msgid "Validity" msgstr "有効性" -#: xpack/plugins/cloud/models.py:43 +#: xpack/plugins/cloud/models.py:39 msgid "Cloud account" msgstr "クラウドアカウント" -#: xpack/plugins/cloud/models.py:45 +#: xpack/plugins/cloud/models.py:41 msgid "Test cloud account" msgstr "クラウドアカウントのテスト" -#: xpack/plugins/cloud/models.py:92 xpack/plugins/cloud/serializers/task.py:147 +#: xpack/plugins/cloud/models.py:88 xpack/plugins/cloud/serializers/task.py:36 msgid "Regions" msgstr "リージョン" -#: xpack/plugins/cloud/models.py:95 +#: xpack/plugins/cloud/models.py:91 msgid "Hostname strategy" msgstr "ホスト名戦略" -#: xpack/plugins/cloud/models.py:100 -#: xpack/plugins/cloud/serializers/task.py:150 +#: xpack/plugins/cloud/models.py:102 xpack/plugins/cloud/serializers/task.py:39 msgid "IP network segment group" msgstr "IPネットワークセグメントグループ" -#: xpack/plugins/cloud/models.py:103 -#: xpack/plugins/cloud/serializers/task.py:155 +#: xpack/plugins/cloud/models.py:105 xpack/plugins/cloud/serializers/task.py:44 msgid "Sync IP type" msgstr "同期IPタイプ" -#: xpack/plugins/cloud/models.py:106 -#: xpack/plugins/cloud/serializers/task.py:173 +#: xpack/plugins/cloud/models.py:108 xpack/plugins/cloud/serializers/task.py:61 msgid "Always update" msgstr "常に更新" -#: xpack/plugins/cloud/models.py:112 +#: xpack/plugins/cloud/models.py:114 msgid "Date last sync" msgstr "最終同期日" -#: xpack/plugins/cloud/models.py:115 xpack/plugins/cloud/models.py:313 -#: xpack/plugins/cloud/models.py:337 -msgid "Strategy" -msgstr "戦略" - -#: xpack/plugins/cloud/models.py:120 xpack/plugins/cloud/models.py:197 +#: xpack/plugins/cloud/models.py:119 xpack/plugins/cloud/models.py:160 msgid "Sync instance task" msgstr "インスタンスの同期タスク" -#: xpack/plugins/cloud/models.py:208 xpack/plugins/cloud/models.py:260 +#: xpack/plugins/cloud/models.py:171 xpack/plugins/cloud/models.py:219 msgid "Date sync" msgstr "日付の同期" -#: xpack/plugins/cloud/models.py:212 -msgid "Sync instance snapshot" -msgstr "インスタンススナップショットの同期" - -#: xpack/plugins/cloud/models.py:216 +#: xpack/plugins/cloud/models.py:175 msgid "Sync instance task execution" msgstr "インスタンスタスクの同期実行" -#: xpack/plugins/cloud/models.py:240 +#: xpack/plugins/cloud/models.py:199 msgid "Sync task" msgstr "同期タスク" -#: xpack/plugins/cloud/models.py:244 +#: xpack/plugins/cloud/models.py:203 msgid "Sync instance task history" msgstr "インスタンスタスク履歴の同期" -#: xpack/plugins/cloud/models.py:247 +#: xpack/plugins/cloud/models.py:206 msgid "Instance" msgstr "インスタンス" -#: xpack/plugins/cloud/models.py:264 +#: xpack/plugins/cloud/models.py:223 msgid "Sync instance detail" msgstr "同期インスタンスの詳細" -#: xpack/plugins/cloud/models.py:281 -msgid "Task strategy" -msgstr "ミッション戦略です" - -#: xpack/plugins/cloud/models.py:285 -msgid "Exact" -msgstr "" - -#: xpack/plugins/cloud/models.py:286 -msgid "Not" -msgstr "否" - -#: xpack/plugins/cloud/models.py:287 -msgid "In" -msgstr "イン" - -#: xpack/plugins/cloud/models.py:288 -msgid "Contains" -msgstr "含む" - -#: xpack/plugins/cloud/models.py:289 -msgid "Startswith" -msgstr "始まる" - -#: xpack/plugins/cloud/models.py:290 -msgid "Endswith" -msgstr "終わる" - -#: xpack/plugins/cloud/models.py:296 -msgid "Instance platform" -msgstr "インスタンス名" - -#: xpack/plugins/cloud/models.py:297 -msgid "Instance address" -msgstr "インスタンスアドレス" - -#: xpack/plugins/cloud/models.py:304 -msgid "Rule attr" -msgstr "ルール属性" - -#: xpack/plugins/cloud/models.py:308 -msgid "Rule match" -msgstr "ルール一致" - -#: xpack/plugins/cloud/models.py:310 -msgid "Rule value" -msgstr "ルール値" - -#: xpack/plugins/cloud/models.py:317 -msgid "Strategy rule" -msgstr "戦略ルール" - -#: xpack/plugins/cloud/models.py:332 -msgid "Action attr" -msgstr "アクション属性" - -#: xpack/plugins/cloud/models.py:334 -msgid "Action value" -msgstr "アクション値" - -#: xpack/plugins/cloud/models.py:341 -msgid "Strategy action" -msgstr "戦略アクション" - #: xpack/plugins/cloud/providers/aws_international.py:18 msgid "China (Beijing)" msgstr "中国 (北京)" @@ -7922,7 +7859,7 @@ msgid "CN East-Suzhou" msgstr "華東-蘇州" #: xpack/plugins/cloud/providers/baiducloud.py:57 -#: xpack/plugins/cloud/providers/huaweicloud.py:49 +#: xpack/plugins/cloud/providers/huaweicloud.py:50 msgid "CN-Hong Kong" msgstr "中国-香港" @@ -7940,66 +7877,68 @@ msgid "CN East-Shanghai" msgstr "華東-上海" #: xpack/plugins/cloud/providers/baiducloud.py:61 -#: xpack/plugins/cloud/providers/huaweicloud.py:51 +#: xpack/plugins/cloud/providers/huaweicloud.py:49 msgid "AP-Singapore" msgstr "アジア太平洋-シンガポール" +#: xpack/plugins/cloud/providers/huaweicloud.py:37 +msgid "AF-Johannesburg" +msgstr "アフリカ-ヨハネスブルク" + +#: xpack/plugins/cloud/providers/huaweicloud.py:38 +msgid "CN North-Beijing4" +msgstr "華北-北京4" + #: xpack/plugins/cloud/providers/huaweicloud.py:39 msgid "CN North-Beijing1" msgstr "華北-北京1" #: xpack/plugins/cloud/providers/huaweicloud.py:40 -msgid "CN North-Beijing4" -msgstr "華北-北京4" - -#: xpack/plugins/cloud/providers/huaweicloud.py:41 -msgid "CN North-Ulanqab1" -msgstr "華北-ウランチャブ一" - -#: xpack/plugins/cloud/providers/huaweicloud.py:43 -msgid "CN South-Shenzhen" -msgstr "華南-広州" - -#: xpack/plugins/cloud/providers/huaweicloud.py:44 -msgid "CN South-Guangzhou-InvitationOnly" -msgstr "華南-広州-友好ユーザー環境" - -#: xpack/plugins/cloud/providers/huaweicloud.py:45 msgid "CN East-Shanghai2" msgstr "華東-上海2" -#: xpack/plugins/cloud/providers/huaweicloud.py:46 +#: xpack/plugins/cloud/providers/huaweicloud.py:41 msgid "CN East-Shanghai1" msgstr "華東-上海1" -#: xpack/plugins/cloud/providers/huaweicloud.py:48 -msgid "CN Southwest-Guiyang1" -msgstr "南西-貴陽1" - -#: xpack/plugins/cloud/providers/huaweicloud.py:50 -msgid "AP-Bangkok" -msgstr "アジア太平洋-バンコク" - -#: xpack/plugins/cloud/providers/huaweicloud.py:53 -msgid "AF-Johannesburg" -msgstr "アフリカ-ヨハネスブルク" - -#: xpack/plugins/cloud/providers/huaweicloud.py:54 +#: xpack/plugins/cloud/providers/huaweicloud.py:43 msgid "LA-Mexico City1" msgstr "LA-メキシコCity1" -#: xpack/plugins/cloud/providers/huaweicloud.py:55 +#: xpack/plugins/cloud/providers/huaweicloud.py:44 msgid "LA-Santiago" msgstr "ラテンアメリカ-サンディエゴ" -#: xpack/plugins/cloud/providers/huaweicloud.py:56 +#: xpack/plugins/cloud/providers/huaweicloud.py:45 msgid "LA-Sao Paulo1" msgstr "ラミー・サンパウロ1" -#: xpack/plugins/cloud/providers/huaweicloud.py:58 -msgid "TR-Istanbul" +#: xpack/plugins/cloud/providers/huaweicloud.py:46 +msgid "EU-Paris" msgstr "" +#: xpack/plugins/cloud/providers/huaweicloud.py:47 +msgid "CN Southwest-Guiyang1" +msgstr "南西-貴陽1" + +#: xpack/plugins/cloud/providers/huaweicloud.py:48 +msgid "AP-Bangkok" +msgstr "アジア太平洋-バンコク" + +#: xpack/plugins/cloud/providers/huaweicloud.py:52 +#, fuzzy +#| msgid "CN North-Baoding" +msgid "CN Northeast-Dalian" +msgstr "華北-保定" + +#: xpack/plugins/cloud/providers/huaweicloud.py:53 +msgid "CN North-Ulanqab1" +msgstr "華北-ウランチャブ一" + +#: xpack/plugins/cloud/providers/huaweicloud.py:54 +msgid "CN South-Guangzhou-InvitationOnly" +msgstr "華南-広州-友好ユーザー環境" + #: xpack/plugins/cloud/providers/jdcloud.py:126 msgid "CN East-Suqian" msgstr "華東-宿遷" @@ -8028,7 +7967,7 @@ msgstr "サブスクリプションID" #: xpack/plugins/cloud/serializers/account_attrs.py:103 #: xpack/plugins/cloud/serializers/account_attrs.py:119 #: xpack/plugins/cloud/serializers/account_attrs.py:149 -#: xpack/plugins/cloud/serializers/account_attrs.py:199 +#: xpack/plugins/cloud/serializers/account_attrs.py:202 msgid "API Endpoint" msgstr "APIエンドポイント" @@ -8094,11 +8033,11 @@ msgstr "テストポート" msgid "Test timeout" msgstr "テストタイムアウト" -#: xpack/plugins/cloud/serializers/account_attrs.py:209 +#: xpack/plugins/cloud/serializers/account_attrs.py:212 msgid "Project" msgstr "project" -#: xpack/plugins/cloud/serializers/task.py:139 +#: xpack/plugins/cloud/serializers/task.py:28 msgid "" "Only instances matching the IP range will be synced.
If the instance " "contains multiple IP addresses, the first IP address that matches will be " @@ -8112,11 +8051,11 @@ msgstr "" "ドレスをランダムに一致させることを意味します。
例: " "192.168.1.0/24,10.1.1.1-10.1.1.20。" -#: xpack/plugins/cloud/serializers/task.py:145 +#: xpack/plugins/cloud/serializers/task.py:34 msgid "History count" msgstr "実行回数" -#: xpack/plugins/cloud/serializers/task.py:146 +#: xpack/plugins/cloud/serializers/task.py:35 msgid "Instance count" msgstr "インスタンス数" @@ -8128,6 +8067,10 @@ msgstr "同期インスタンス タスクを実行する" msgid "Period clean sync instance task execution" msgstr "同期インスタンス タスクの実行記録を定期的にクリアする" +#: xpack/plugins/cloud/utils.py:68 +msgid "Account unavailable" +msgstr "利用できないアカウント" + #: xpack/plugins/interface/api.py:52 msgid "Restore default successfully." msgstr "デフォルトの復元に成功しました。" @@ -8191,3 +8134,64 @@ msgstr "究極のエディション" #: xpack/plugins/license/models.py:86 msgid "Community edition" msgstr "コミュニティ版" + +#~ msgid "" +#~ "The forgot password url on login page, If you use ldap or cas external " +#~ "authentication, you can set it" +#~ msgstr "" +#~ "ログインページでパスワードのURLを忘れてしまいました。ldapまたはcasの外部認" +#~ "証を使用している場合は、設定できます。" + +#~ msgid "Strategy" +#~ msgstr "戦略" + +#~ msgid "Sync instance snapshot" +#~ msgstr "インスタンススナップショットの同期" + +#~ msgid "Task strategy" +#~ msgstr "ミッション戦略です" + +#~ msgid "Not" +#~ msgstr "否" + +#~ msgid "In" +#~ msgstr "イン" + +#~ msgid "Contains" +#~ msgstr "含む" + +#~ msgid "Startswith" +#~ msgstr "始まる" + +#~ msgid "Endswith" +#~ msgstr "終わる" + +#~ msgid "Instance platform" +#~ msgstr "インスタンス名" + +#~ msgid "Instance address" +#~ msgstr "インスタンスアドレス" + +#~ msgid "Rule attr" +#~ msgstr "ルール属性" + +#~ msgid "Rule match" +#~ msgstr "ルール一致" + +#~ msgid "Rule value" +#~ msgstr "ルール値" + +#~ msgid "Strategy rule" +#~ msgstr "戦略ルール" + +#~ msgid "Action attr" +#~ msgstr "アクション属性" + +#~ msgid "Action value" +#~ msgstr "アクション値" + +#~ msgid "Strategy action" +#~ msgstr "戦略アクション" + +#~ msgid "CN South-Shenzhen" +#~ msgstr "華南-広州" diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po index 17302daba..1e5a836b4 100644 --- a/apps/locale/zh/LC_MESSAGES/django.po +++ b/apps/locale/zh/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: JumpServer 0.3.3\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-08-15 16:44+0800\n" +"POT-Creation-Date: 2023-08-17 10:41+0800\n" "PO-Revision-Date: 2021-05-20 10:54+0800\n" "Last-Translator: ibuler \n" "Language-Team: JumpServer team\n" @@ -44,7 +44,7 @@ msgid "Access key" msgstr "Access key" #: accounts/const/account.py:9 assets/models/_user.py:48 -#: authentication/models/sso_token.py:14 settings/serializers/feature.py:48 +#: authentication/models/sso_token.py:14 settings/serializers/feature.py:52 msgid "Token" msgstr "Token" @@ -212,7 +212,7 @@ msgstr "HashiCorp Vault" #: terminal/serializers/session.py:26 #: terminal/templates/terminal/_msg_command_warning.html:4 #: terminal/templates/terminal/_msg_session_sharing.html:4 -#: tickets/models/ticket/apply_asset.py:16 xpack/plugins/cloud/models.py:253 +#: tickets/models/ticket/apply_asset.py:16 xpack/plugins/cloud/models.py:212 msgid "Asset" msgstr "资产" @@ -247,7 +247,7 @@ msgstr "来源 ID" #: terminal/backends/command/models.py:18 terminal/models/session/session.py:33 #: terminal/templates/terminal/_msg_command_warning.html:8 #: terminal/templates/terminal/_msg_session_sharing.html:8 -#: tickets/models/ticket/command_confirm.py:13 xpack/plugins/cloud/models.py:89 +#: tickets/models/ticket/command_confirm.py:13 xpack/plugins/cloud/models.py:85 msgid "Account" msgstr "账号" @@ -286,7 +286,7 @@ msgstr "账号备份计划" #: accounts/models/automations/backup_account.py:91 #: assets/models/automations/base.py:115 audits/models.py:60 -#: ops/models/base.py:55 ops/models/celery.py:63 ops/models/job.py:221 +#: ops/models/base.py:55 ops/models/celery.py:63 ops/models/job.py:228 #: ops/templates/ops/celery_task_log.html:75 #: perms/models/asset_permission.py:72 terminal/models/applet/host.py:140 #: terminal/models/session/session.py:44 @@ -314,7 +314,7 @@ msgid "Trigger mode" msgstr "触发模式" #: accounts/models/automations/backup_account.py:105 audits/models.py:194 -#: terminal/models/session/sharing.py:121 xpack/plugins/cloud/models.py:205 +#: terminal/models/session/sharing.py:121 xpack/plugins/cloud/models.py:168 msgid "Reason" msgstr "原因" @@ -419,7 +419,7 @@ msgstr "开始日期" #: accounts/models/automations/change_secret.py:91 #: assets/models/automations/base.py:116 ops/models/base.py:56 -#: ops/models/celery.py:64 ops/models/job.py:222 +#: ops/models/celery.py:64 ops/models/job.py:229 #: terminal/models/applet/host.py:141 msgid "Date finished" msgstr "结束日期" @@ -505,7 +505,7 @@ msgstr "账号验证" #: assets/serializers/platform.py:110 assets/serializers/platform.py:223 #: authentication/serializers/connect_token_secret.py:110 ops/mixin.py:21 #: ops/models/adhoc.py:20 ops/models/celery.py:15 ops/models/celery.py:57 -#: ops/models/job.py:119 ops/models/playbook.py:28 ops/serializers/job.py:20 +#: ops/models/job.py:126 ops/models/playbook.py:28 ops/serializers/job.py:20 #: orgs/models.py:82 perms/models/asset_permission.py:56 rbac/models/role.py:29 #: settings/models.py:32 settings/serializers/msg.py:82 #: terminal/models/applet/applet.py:32 terminal/models/component/endpoint.py:12 @@ -513,8 +513,7 @@ msgstr "账号验证" #: terminal/models/component/storage.py:26 terminal/models/component/task.py:13 #: terminal/models/component/terminal.py:84 users/forms/profile.py:33 #: users/models/group.py:13 users/models/user.py:787 -#: xpack/plugins/cloud/models.py:32 xpack/plugins/cloud/models.py:273 -#: xpack/plugins/cloud/serializers/task.py:68 +#: xpack/plugins/cloud/models.py:28 msgid "Name" msgstr "名称" @@ -531,7 +530,7 @@ msgstr "特权账号" msgid "Is active" msgstr "激活" -#: accounts/models/template.py:19 xpack/plugins/cloud/models.py:325 +#: accounts/models/template.py:19 msgid "Account template" msgstr "账号模版" @@ -638,8 +637,8 @@ msgstr "类别" #: assets/models/cmd_filter.py:74 assets/models/platform.py:90 #: assets/serializers/asset/common.py:122 assets/serializers/platform.py:112 #: assets/serializers/platform.py:127 audits/serializers.py:49 -#: authentication/serializers/connect_token_secret.py:123 ops/models/job.py:130 -#: perms/serializers/user_permission.py:27 settings/serializers/feature.py:42 +#: authentication/serializers/connect_token_secret.py:123 ops/models/job.py:137 +#: perms/serializers/user_permission.py:27 settings/serializers/feature.py:46 #: terminal/models/applet/applet.py:38 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:226 @@ -673,7 +672,7 @@ msgstr "已修改" #: accounts/serializers/automations/base.py:22 acls/models/base.py:97 #: assets/models/automations/base.py:19 #: assets/serializers/automations/base.py:20 ops/models/base.py:17 -#: ops/models/job.py:132 ops/serializers/job.py:21 +#: ops/models/job.py:139 ops/serializers/job.py:21 #: terminal/templates/terminal/_msg_command_execute_alert.html:16 msgid "Assets" msgstr "资产" @@ -764,14 +763,14 @@ msgstr "" #: accounts/serializers/account/virtual.py:19 assets/models/_user.py:27 #: assets/models/cmd_filter.py:40 assets/models/cmd_filter.py:88 #: assets/models/group.py:20 common/db/models.py:36 ops/models/adhoc.py:26 -#: ops/models/job.py:138 ops/models/playbook.py:31 rbac/models/role.py:37 +#: ops/models/job.py:145 ops/models/playbook.py:31 rbac/models/role.py:37 #: settings/models.py:37 terminal/models/applet/applet.py:44 #: terminal/models/applet/applet.py:284 terminal/models/applet/host.py:142 #: terminal/models/component/endpoint.py:24 #: terminal/models/component/endpoint.py:104 #: terminal/models/session/session.py:46 tickets/models/comment.py:32 #: tickets/models/ticket/general.py:297 users/models/user.py:826 -#: xpack/plugins/cloud/models.py:39 xpack/plugins/cloud/models.py:109 +#: xpack/plugins/cloud/models.py:35 xpack/plugins/cloud/models.py:111 msgid "Comment" msgstr "备注" @@ -892,13 +891,11 @@ msgstr "告警" #: acls/models/base.py:37 assets/models/_user.py:51 #: assets/models/cmd_filter.py:76 terminal/models/component/endpoint.py:97 -#: xpack/plugins/cloud/models.py:275 msgid "Priority" msgstr "优先级" #: acls/models/base.py:38 assets/models/_user.py:51 #: assets/models/cmd_filter.py:76 terminal/models/component/endpoint.py:98 -#: xpack/plugins/cloud/models.py:276 msgid "1-100, the lower the value will be match first" msgstr "优先级可选范围为 1-100 (数值越小越优先)" @@ -935,7 +932,6 @@ msgid "Command" msgstr "命令" #: acls/models/command_acl.py:17 assets/models/cmd_filter.py:59 -#: xpack/plugins/cloud/models.py:291 msgid "Regex" msgstr "正则表达式" @@ -1031,7 +1027,7 @@ msgid "None of the reviewers belong to Organization `{}`" msgstr "所有复核人都不属于组织 `{}`" #: acls/serializers/rules/rules.py:20 -#: xpack/plugins/cloud/serializers/task.py:133 +#: xpack/plugins/cloud/serializers/task.py:22 msgid "IP address invalid: `{}`" msgstr "IP 地址无效: `{}`" @@ -1059,7 +1055,7 @@ msgstr "时段" msgid "Applications" msgstr "应用管理" -#: applications/models.py:16 xpack/plugins/cloud/models.py:37 +#: applications/models.py:16 xpack/plugins/cloud/models.py:33 #: xpack/plugins/cloud/serializers/account.py:63 msgid "Attrs" msgstr "属性" @@ -1166,7 +1162,7 @@ msgstr "脚本" #: assets/const/category.py:10 assets/models/asset/host.py:8 #: settings/serializers/auth/radius.py:16 settings/serializers/auth/sms.py:67 -#: settings/serializers/feature.py:45 terminal/models/component/endpoint.py:13 +#: settings/serializers/feature.py:49 terminal/models/component/endpoint.py:13 #: terminal/serializers/applet.py:17 #: xpack/plugins/cloud/serializers/account_attrs.py:72 msgid "Host" @@ -1352,7 +1348,7 @@ msgstr "SSH公钥" # msgstr "备注" #: assets/models/_user.py:28 assets/models/automations/base.py:114 #: assets/models/cmd_filter.py:41 assets/models/group.py:19 -#: common/db/models.py:34 ops/models/base.py:54 ops/models/job.py:220 +#: common/db/models.py:34 ops/models/base.py:54 ops/models/job.py:227 #: users/models/user.py:1018 msgid "Date created" msgstr "创建日期" @@ -1456,13 +1452,14 @@ msgstr "地址" #: assets/models/asset/common.py:151 assets/models/platform.py:119 #: authentication/serializers/connect_token_secret.py:115 -#: perms/serializers/user_permission.py:24 xpack/plugins/cloud/models.py:321 +#: perms/serializers/user_permission.py:24 +#: xpack/plugins/cloud/serializers/account_attrs.py:196 msgid "Platform" msgstr "系统平台" #: assets/models/asset/common.py:153 assets/models/domain.py:21 #: authentication/serializers/connect_token_secret.py:133 -#: perms/serializers/user_permission.py:29 xpack/plugins/cloud/models.py:323 +#: perms/serializers/user_permission.py:29 msgid "Domain" msgstr "网域" @@ -1519,7 +1516,7 @@ msgstr "忽略证书校验" msgid "Proxy" msgstr "代理" -#: assets/models/automations/base.py:22 ops/models/job.py:216 +#: assets/models/automations/base.py:22 ops/models/job.py:223 #: settings/serializers/auth/sms.py:99 msgid "Parameters" msgstr "参数" @@ -1533,13 +1530,13 @@ msgid "Asset automation task" msgstr "资产自动化任务" #: assets/models/automations/base.py:113 audits/models.py:199 -#: audits/serializers.py:50 ops/models/base.py:49 ops/models/job.py:213 +#: audits/serializers.py:50 ops/models/base.py:49 ops/models/job.py:220 #: terminal/models/applet/applet.py:283 terminal/models/applet/host.py:139 #: terminal/models/component/status.py:30 terminal/serializers/applet.py:18 #: terminal/serializers/applet_host.py:115 tickets/models/ticket/general.py:283 #: tickets/serializers/super_ticket.py:13 -#: tickets/serializers/ticket/ticket.py:20 xpack/plugins/cloud/models.py:201 -#: xpack/plugins/cloud/models.py:257 +#: tickets/serializers/ticket/ticket.py:20 xpack/plugins/cloud/models.py:164 +#: xpack/plugins/cloud/models.py:216 msgid "Status" msgstr "状态" @@ -1603,7 +1600,7 @@ msgstr "资产组" #: assets/models/group.py:31 assets/models/platform.py:19 #: assets/serializers/platform.py:113 -#: xpack/plugins/cloud/providers/nutanix.py:30 +#: xpack/plugins/cloud/providers/nutanix.py:32 msgid "Default" msgstr "默认" @@ -1653,7 +1650,7 @@ msgid "Parent key" msgstr "ssh私钥" #: assets/models/node.py:558 perms/serializers/permission.py:35 -#: tickets/models/ticket/apply_asset.py:14 xpack/plugins/cloud/models.py:322 +#: tickets/models/ticket/apply_asset.py:14 xpack/plugins/cloud/models.py:96 msgid "Node" msgstr "节点" @@ -1674,7 +1671,7 @@ msgid "Public" msgstr "开放的" #: assets/models/platform.py:21 assets/serializers/platform.py:48 -#: settings/serializers/settings.py:66 +#: settings/serializers/settings.py:65 #: users/templates/users/reset_password.html:29 msgid "Setting" msgstr "设置" @@ -1792,8 +1789,7 @@ msgstr "资产中批量更新平台,不符合平台类型跳过的资产" #: assets/serializers/asset/common.py:124 assets/serializers/platform.py:129 #: authentication/serializers/connect_token_secret.py:29 #: authentication/serializers/connect_token_secret.py:72 -#: perms/serializers/user_permission.py:25 xpack/plugins/cloud/models.py:324 -#: xpack/plugins/cloud/serializers/task.py:31 +#: perms/serializers/user_permission.py:25 xpack/plugins/cloud/models.py:99 msgid "Protocols" msgstr "协议组" @@ -2288,7 +2284,7 @@ msgstr "用户 %s 在当前资源, 执行了任务 (%s)" msgid "SSH Key" msgstr "SSH 密钥" -#: audits/signal_handlers/login_log.py:29 settings/serializers/auth/sso.py:10 +#: audits/signal_handlers/login_log.py:29 settings/serializers/auth/sso.py:13 msgid "SSO" msgstr "SSO" @@ -2959,7 +2955,7 @@ msgstr "代码错误" #: authentication/templates/authentication/_msg_reset_password_code.html:9 #: authentication/templates/authentication/_msg_rest_password_success.html:2 #: authentication/templates/authentication/_msg_rest_public_key_success.html:2 -#: jumpserver/conf.py:441 +#: jumpserver/conf.py:444 #: perms/templates/perms/_msg_item_permissions_expire.html:3 #: perms/templates/perms/_msg_permed_items_expire.html:3 #: tickets/templates/tickets/approve_check_password.html:33 @@ -3544,11 +3540,11 @@ msgstr "导出搜素: %s" msgid "User %s view/export secret" msgstr "用户 %s 查看/导出 了密码" -#: jumpserver/conf.py:440 +#: jumpserver/conf.py:443 msgid "Create account successfully" msgstr "创建账号成功" -#: jumpserver/conf.py:442 +#: jumpserver/conf.py:445 msgid "Your account has been created successfully" msgstr "你的账号已创建成功" @@ -3683,7 +3679,7 @@ msgstr "VCS" msgid "Adhoc" msgstr "命令" -#: ops/const.py:39 ops/models/job.py:128 +#: ops/const.py:39 ops/models/job.py:135 msgid "Playbook" msgstr "Playbook" @@ -3752,17 +3748,17 @@ msgstr "需要周期或定期设置" msgid "Pattern" msgstr "模式" -#: ops/models/adhoc.py:23 ops/models/job.py:123 +#: ops/models/adhoc.py:23 ops/models/job.py:130 msgid "Module" msgstr "模块" -#: ops/models/adhoc.py:24 ops/models/celery.py:58 ops/models/job.py:122 +#: ops/models/adhoc.py:24 ops/models/celery.py:58 ops/models/job.py:129 #: terminal/models/component/task.py:14 msgid "Args" msgstr "参数" #: ops/models/adhoc.py:25 ops/models/base.py:16 ops/models/base.py:53 -#: ops/models/job.py:131 ops/models/job.py:219 ops/models/playbook.py:30 +#: ops/models/job.py:138 ops/models/job.py:226 ops/models/playbook.py:30 #: terminal/models/session/sharing.py:24 msgid "Creator" msgstr "创建者" @@ -3779,12 +3775,12 @@ msgstr "最后执行" msgid "Date last run" msgstr "最后运行日期" -#: ops/models/base.py:51 ops/models/job.py:217 -#: xpack/plugins/cloud/models.py:199 +#: ops/models/base.py:51 ops/models/job.py:224 +#: xpack/plugins/cloud/models.py:162 msgid "Result" msgstr "结果" -#: ops/models/base.py:52 ops/models/job.py:218 +#: ops/models/base.py:52 ops/models/job.py:225 msgid "Summary" msgstr "汇总" @@ -3817,43 +3813,43 @@ msgstr "发布日期" msgid "Celery Task Execution" msgstr "Celery 任务执行" -#: ops/models/job.py:125 +#: ops/models/job.py:132 msgid "Chdir" msgstr "运行目录" -#: ops/models/job.py:126 +#: ops/models/job.py:133 msgid "Timeout (Seconds)" msgstr "超时时间 (秒)" -#: ops/models/job.py:133 +#: ops/models/job.py:140 msgid "Use Parameter Define" msgstr "使用参数定义" -#: ops/models/job.py:134 +#: ops/models/job.py:141 msgid "Parameters define" msgstr "参数定义" -#: ops/models/job.py:135 +#: ops/models/job.py:142 msgid "Runas" msgstr "运行用户" -#: ops/models/job.py:137 +#: ops/models/job.py:144 msgid "Runas policy" msgstr "用户策略" -#: ops/models/job.py:201 +#: ops/models/job.py:208 msgid "Job" msgstr "作业" -#: ops/models/job.py:224 +#: ops/models/job.py:231 msgid "Material" msgstr "Material" -#: ops/models/job.py:226 +#: ops/models/job.py:233 msgid "Material Type" msgstr "Material 类型" -#: ops/models/job.py:526 +#: ops/models/job.py:533 msgid "Job Execution" msgstr "作业执行" @@ -4326,7 +4322,8 @@ msgstr "远程应用" msgid "Ticket comment" msgstr "工单评论" -#: rbac/tree.py:124 tickets/models/ticket/general.py:307 +#: rbac/tree.py:124 settings/serializers/feature.py:64 +#: tickets/models/ticket/general.py:307 msgid "Ticket" msgstr "工单管理" @@ -4428,42 +4425,54 @@ msgid "Can change other setting" msgstr "其它设置" #: settings/serializers/auth/base.py:12 +#, fuzzy +#| msgid "MFA Auth" +msgid "LDAP Auth" +msgstr "MFA 多因子认证" + +#: settings/serializers/auth/base.py:13 msgid "CAS Auth" msgstr "CAS 认证" -#: settings/serializers/auth/base.py:13 +#: settings/serializers/auth/base.py:14 msgid "OPENID Auth" msgstr "OIDC 认证" -#: settings/serializers/auth/base.py:14 -msgid "RADIUS Auth" -msgstr "RADIUS 认证" - #: settings/serializers/auth/base.py:15 -msgid "DingTalk Auth" -msgstr "钉钉 认证" - -#: settings/serializers/auth/base.py:16 -msgid "FeiShu Auth" -msgstr "飞书 认证" - -#: settings/serializers/auth/base.py:17 -msgid "WeCom Auth" -msgstr "企业微信 认证" - -#: settings/serializers/auth/base.py:18 -msgid "SSO Auth" -msgstr "SSO 令牌认证" - -#: settings/serializers/auth/base.py:19 msgid "SAML2 Auth" msgstr "SAML2 认证" -#: settings/serializers/auth/base.py:22 settings/serializers/basic.py:17 +#: settings/serializers/auth/base.py:16 +#, fuzzy +#| msgid "Enable OAuth2 Auth" +msgid "OAuth2 Auth" +msgstr "启用 OAuth2 认证" + +#: settings/serializers/auth/base.py:17 +msgid "RADIUS Auth" +msgstr "RADIUS 认证" + +#: settings/serializers/auth/base.py:18 +msgid "DingTalk Auth" +msgstr "钉钉 认证" + +#: settings/serializers/auth/base.py:19 +msgid "FeiShu Auth" +msgstr "飞书 认证" + +#: settings/serializers/auth/base.py:20 +msgid "WeCom Auth" +msgstr "企业微信 认证" + +#: settings/serializers/auth/base.py:21 +msgid "SSO Auth" +msgstr "SSO 令牌认证" + +#: settings/serializers/auth/base.py:24 msgid "Forgot password url" msgstr "忘记密码 URL" -#: settings/serializers/auth/base.py:28 +#: settings/serializers/auth/base.py:30 msgid "Enable login redirect msg" msgstr "启用登录跳转提示" @@ -4819,19 +4828,19 @@ msgstr "请求方式" msgid "The value in the parameter must contain %s" msgstr "参数中的值必须包含 %s" -#: settings/serializers/auth/sso.py:13 +#: settings/serializers/auth/sso.py:16 msgid "Enable SSO auth" msgstr "启用 SSO 令牌认证" -#: settings/serializers/auth/sso.py:14 +#: settings/serializers/auth/sso.py:17 msgid "Other service can using SSO token login to JumpServer without password" msgstr "其它系统可以使用 SSO Token 对接 JumpServer, 免去登录的过程" -#: settings/serializers/auth/sso.py:17 +#: settings/serializers/auth/sso.py:20 msgid "SSO auth key TTL" msgstr "令牌有效期" -#: settings/serializers/auth/sso.py:17 +#: settings/serializers/auth/sso.py:20 #: xpack/plugins/cloud/serializers/account_attrs.py:193 msgid "Unit: second" msgstr "单位: 秒" @@ -4858,35 +4867,27 @@ msgstr "用户向导URL" msgid "User first login update profile done redirect to it" msgstr "用户第一次登录,修改profile后重定向到地址, 可以是 wiki 或 其他说明文档" -#: settings/serializers/basic.py:18 -msgid "" -"The forgot password url on login page, If you use ldap or cas external " -"authentication, you can set it" -msgstr "" -"登录页面忘记密码URL, 如果使用了 LDAP, OPENID 等外部认证系统,可以自定义用户重" -"置密码访问的地址" - -#: settings/serializers/basic.py:22 +#: settings/serializers/basic.py:17 msgid "Global organization name" msgstr "全局组织名" -#: settings/serializers/basic.py:23 +#: settings/serializers/basic.py:18 msgid "The name of global organization to display" msgstr "全局组织的显示名称,默认为 全局组织" -#: settings/serializers/basic.py:26 +#: settings/serializers/basic.py:21 msgid "Help Docs URL" msgstr "文档链接" -#: settings/serializers/basic.py:27 +#: settings/serializers/basic.py:22 msgid "default: http://docs.jumpserver.org" msgstr "默认: http://dev.jumpserver.org:8080" -#: settings/serializers/basic.py:30 +#: settings/serializers/basic.py:25 msgid "Help Support URL" msgstr "支持链接" -#: settings/serializers/basic.py:31 +#: settings/serializers/basic.py:26 msgid "default: http://www.jumpserver.org/support/" msgstr "默认: http://www.jumpserver.org/support/" @@ -4937,51 +4938,63 @@ msgstr "主题" msgid "More url" msgstr "更多信息 URL" -#: settings/serializers/feature.py:35 -msgid "Enable announcement" -msgstr "启用公告" - -#: settings/serializers/feature.py:36 +#: settings/serializers/feature.py:35 settings/serializers/feature.py:38 msgid "Announcement" msgstr "公告" -#: settings/serializers/feature.py:51 +#: settings/serializers/feature.py:37 +msgid "Enable announcement" +msgstr "启用公告" + +#: settings/serializers/feature.py:42 +#, fuzzy +#| msgid "HCP Vault" +msgid "Vault" +msgstr "HashiCorp Vault" + +#: settings/serializers/feature.py:55 msgid "Mount Point" msgstr "" -#: settings/serializers/feature.py:60 +#: settings/serializers/feature.py:66 msgid "Enable tickets" msgstr "启用工单" -#: settings/serializers/feature.py:63 +#: settings/serializers/feature.py:69 msgid "Ticket authorize default time" msgstr "默认工单授权时间" -#: settings/serializers/feature.py:66 +#: settings/serializers/feature.py:72 msgid "day" msgstr "天" -#: settings/serializers/feature.py:66 +#: settings/serializers/feature.py:72 msgid "hour" msgstr "时" -#: settings/serializers/feature.py:67 +#: settings/serializers/feature.py:73 msgid "Ticket authorize default time unit" msgstr "默认工单授权时间单位" -#: settings/serializers/feature.py:73 +#: settings/serializers/feature.py:78 +#, fuzzy +#| msgid "Signature" +msgid "Feature" +msgstr "签名" + +#: settings/serializers/feature.py:81 msgid "Operation center" msgstr "作业中心" -#: settings/serializers/feature.py:74 +#: settings/serializers/feature.py:82 msgid "Allow user run batch command or not using ansible" msgstr "是否允许用户使用 ansible 执行批量命令" -#: settings/serializers/feature.py:78 +#: settings/serializers/feature.py:86 msgid "Operation center command blacklist" msgstr "作业中心命令黑名单" -#: settings/serializers/feature.py:79 +#: settings/serializers/feature.py:87 msgid "Commands that are not allowed execute." msgstr "不允许执行的命令" @@ -5358,7 +5371,7 @@ msgstr "邮件收件人" msgid "Multiple user using , split" msgstr "多个用户,使用 , 分割" -#: settings/serializers/settings.py:70 +#: settings/serializers/settings.py:69 #, python-format msgid "[%s] %s" msgstr "[%s] %s" @@ -5730,6 +5743,10 @@ msgstr "离线录像播放器" msgid "Invalid zip file" msgstr "无效的 zip 文件" +#: terminal/api/applet/applet.py:65 +msgid "This is enterprise edition applet" +msgstr "企业版远程应用,在社区版中不能使用" + #: terminal/api/component/endpoint.py:32 msgid "Not found protocol query params" msgstr "未发现 protocol 查询参数" @@ -6423,7 +6440,7 @@ msgstr "Access key ID(AK)" msgid "Access key secret" msgstr "Access key secret(SK)" -#: terminal/serializers/storage.py:67 xpack/plugins/cloud/models.py:250 +#: terminal/serializers/storage.py:67 xpack/plugins/cloud/models.py:209 msgid "Region" msgstr "地域" @@ -6979,7 +6996,7 @@ msgid "Not a valid ssh public key" msgstr "SSH密钥不合法" #: users/forms/profile.py:173 users/models/user.py:820 -#: xpack/plugins/cloud/serializers/account_attrs.py:203 +#: xpack/plugins/cloud/serializers/account_attrs.py:206 msgid "Public key" msgstr "SSH公钥" @@ -7008,7 +7025,7 @@ msgid "OTP secret key" msgstr "OTP 密钥" #: users/models/user.py:817 -#: xpack/plugins/cloud/serializers/account_attrs.py:206 +#: xpack/plugins/cloud/serializers/account_attrs.py:209 msgid "Private key" msgstr "ssh私钥" @@ -7434,11 +7451,11 @@ msgstr "重置密码成功,返回到登录页面" msgid "XPACK" msgstr "XPack" -#: xpack/plugins/cloud/api.py:56 +#: xpack/plugins/cloud/api.py:38 msgid "Test connection successful" msgstr "测试成功" -#: xpack/plugins/cloud/api.py:58 +#: xpack/plugins/cloud/api.py:40 msgid "Test connection failed: {}" msgstr "测试连接失败:{}" @@ -7526,7 +7543,7 @@ msgstr "私有IP" msgid "Public IP" msgstr "公网IP" -#: xpack/plugins/cloud/const.py:38 xpack/plugins/cloud/models.py:295 +#: xpack/plugins/cloud/const.py:38 msgid "Instance name" msgstr "实例名称" @@ -7554,158 +7571,78 @@ msgstr "已同步" msgid "Released" msgstr "已释放" -#: xpack/plugins/cloud/manager.py:53 -msgid "Account unavailable" -msgstr "账号无效" - #: xpack/plugins/cloud/meta.py:9 msgid "Cloud center" msgstr "云管中心" -#: xpack/plugins/cloud/models.py:34 +#: xpack/plugins/cloud/models.py:30 msgid "Provider" msgstr "云服务商" -#: xpack/plugins/cloud/models.py:38 +#: xpack/plugins/cloud/models.py:34 msgid "Validity" msgstr "有效" -#: xpack/plugins/cloud/models.py:43 +#: xpack/plugins/cloud/models.py:39 msgid "Cloud account" msgstr "云账号" -#: xpack/plugins/cloud/models.py:45 +#: xpack/plugins/cloud/models.py:41 msgid "Test cloud account" msgstr "测试云账号" -#: xpack/plugins/cloud/models.py:92 xpack/plugins/cloud/serializers/task.py:147 +#: xpack/plugins/cloud/models.py:88 xpack/plugins/cloud/serializers/task.py:36 msgid "Regions" msgstr "地域" -#: xpack/plugins/cloud/models.py:95 +#: xpack/plugins/cloud/models.py:91 msgid "Hostname strategy" msgstr "主机名策略" -#: xpack/plugins/cloud/models.py:100 -#: xpack/plugins/cloud/serializers/task.py:150 +#: xpack/plugins/cloud/models.py:102 xpack/plugins/cloud/serializers/task.py:39 msgid "IP network segment group" msgstr "IP网段组" -#: xpack/plugins/cloud/models.py:103 -#: xpack/plugins/cloud/serializers/task.py:155 +#: xpack/plugins/cloud/models.py:105 xpack/plugins/cloud/serializers/task.py:44 msgid "Sync IP type" msgstr "同步IP类型" -#: xpack/plugins/cloud/models.py:106 -#: xpack/plugins/cloud/serializers/task.py:173 +#: xpack/plugins/cloud/models.py:108 xpack/plugins/cloud/serializers/task.py:61 msgid "Always update" msgstr "总是更新" -#: xpack/plugins/cloud/models.py:112 +#: xpack/plugins/cloud/models.py:114 msgid "Date last sync" msgstr "最后同步日期" -#: xpack/plugins/cloud/models.py:115 xpack/plugins/cloud/models.py:313 -#: xpack/plugins/cloud/models.py:337 -msgid "Strategy" -msgstr "策略" - -#: xpack/plugins/cloud/models.py:120 xpack/plugins/cloud/models.py:197 +#: xpack/plugins/cloud/models.py:119 xpack/plugins/cloud/models.py:160 msgid "Sync instance task" msgstr "同步实例任务" -#: xpack/plugins/cloud/models.py:208 xpack/plugins/cloud/models.py:260 +#: xpack/plugins/cloud/models.py:171 xpack/plugins/cloud/models.py:219 msgid "Date sync" msgstr "同步日期" -#: xpack/plugins/cloud/models.py:212 -msgid "Sync instance snapshot" -msgstr "同步实例快照" - -#: xpack/plugins/cloud/models.py:216 +#: xpack/plugins/cloud/models.py:175 msgid "Sync instance task execution" msgstr "同步实例任务执行" -#: xpack/plugins/cloud/models.py:240 +#: xpack/plugins/cloud/models.py:199 msgid "Sync task" msgstr "同步任务" -#: xpack/plugins/cloud/models.py:244 +#: xpack/plugins/cloud/models.py:203 msgid "Sync instance task history" msgstr "同步实例任务历史" -#: xpack/plugins/cloud/models.py:247 +#: xpack/plugins/cloud/models.py:206 msgid "Instance" msgstr "实例" -#: xpack/plugins/cloud/models.py:264 +#: xpack/plugins/cloud/models.py:223 msgid "Sync instance detail" msgstr "同步实例详情" -#: xpack/plugins/cloud/models.py:281 -msgid "Task strategy" -msgstr "任务策略" - -#: xpack/plugins/cloud/models.py:285 -msgid "Exact" -msgstr "" - -#: xpack/plugins/cloud/models.py:286 -msgid "Not" -msgstr "否" - -#: xpack/plugins/cloud/models.py:287 -msgid "In" -msgstr "在..里面" - -#: xpack/plugins/cloud/models.py:288 -msgid "Contains" -msgstr "包含" - -#: xpack/plugins/cloud/models.py:289 -msgid "Startswith" -msgstr "以..开头" - -#: xpack/plugins/cloud/models.py:290 -msgid "Endswith" -msgstr "以..结尾" - -#: xpack/plugins/cloud/models.py:296 -msgid "Instance platform" -msgstr "实例平台" - -#: xpack/plugins/cloud/models.py:297 -msgid "Instance address" -msgstr "实例地址" - -#: xpack/plugins/cloud/models.py:304 -msgid "Rule attr" -msgstr "规则属性" - -#: xpack/plugins/cloud/models.py:308 -msgid "Rule match" -msgstr "规则匹配" - -#: xpack/plugins/cloud/models.py:310 -msgid "Rule value" -msgstr "规则值" - -#: xpack/plugins/cloud/models.py:317 -msgid "Strategy rule" -msgstr "策略规则" - -#: xpack/plugins/cloud/models.py:332 -msgid "Action attr" -msgstr "动作属性" - -#: xpack/plugins/cloud/models.py:334 -msgid "Action value" -msgstr "动作值" - -#: xpack/plugins/cloud/models.py:341 -msgid "Strategy action" -msgstr "策略动作" - #: xpack/plugins/cloud/providers/aws_international.py:18 msgid "China (Beijing)" msgstr "中国 (北京)" @@ -7814,7 +7751,7 @@ msgid "CN East-Suzhou" msgstr "华东-苏州" #: xpack/plugins/cloud/providers/baiducloud.py:57 -#: xpack/plugins/cloud/providers/huaweicloud.py:49 +#: xpack/plugins/cloud/providers/huaweicloud.py:50 msgid "CN-Hong Kong" msgstr "中国-香港" @@ -7832,66 +7769,68 @@ msgid "CN East-Shanghai" msgstr "华东-上海" #: xpack/plugins/cloud/providers/baiducloud.py:61 -#: xpack/plugins/cloud/providers/huaweicloud.py:51 +#: xpack/plugins/cloud/providers/huaweicloud.py:49 msgid "AP-Singapore" msgstr "亚太-新加坡" +#: xpack/plugins/cloud/providers/huaweicloud.py:37 +msgid "AF-Johannesburg" +msgstr "非洲-约翰内斯堡" + +#: xpack/plugins/cloud/providers/huaweicloud.py:38 +msgid "CN North-Beijing4" +msgstr "华北-北京4" + #: xpack/plugins/cloud/providers/huaweicloud.py:39 msgid "CN North-Beijing1" msgstr "华北-北京1" #: xpack/plugins/cloud/providers/huaweicloud.py:40 -msgid "CN North-Beijing4" -msgstr "华北-北京4" - -#: xpack/plugins/cloud/providers/huaweicloud.py:41 -msgid "CN North-Ulanqab1" -msgstr "华北-乌兰察布一" - -#: xpack/plugins/cloud/providers/huaweicloud.py:43 -msgid "CN South-Shenzhen" -msgstr "华南-广州" - -#: xpack/plugins/cloud/providers/huaweicloud.py:44 -msgid "CN South-Guangzhou-InvitationOnly" -msgstr "华南-广州-友好用户环境" - -#: xpack/plugins/cloud/providers/huaweicloud.py:45 msgid "CN East-Shanghai2" msgstr "华东-上海2" -#: xpack/plugins/cloud/providers/huaweicloud.py:46 +#: xpack/plugins/cloud/providers/huaweicloud.py:41 msgid "CN East-Shanghai1" msgstr "华东-上海1" -#: xpack/plugins/cloud/providers/huaweicloud.py:48 -msgid "CN Southwest-Guiyang1" -msgstr "西南-贵阳1" - -#: xpack/plugins/cloud/providers/huaweicloud.py:50 -msgid "AP-Bangkok" -msgstr "亚太-曼谷" - -#: xpack/plugins/cloud/providers/huaweicloud.py:53 -msgid "AF-Johannesburg" -msgstr "非洲-约翰内斯堡" - -#: xpack/plugins/cloud/providers/huaweicloud.py:54 +#: xpack/plugins/cloud/providers/huaweicloud.py:43 msgid "LA-Mexico City1" msgstr "拉美-墨西哥城一" -#: xpack/plugins/cloud/providers/huaweicloud.py:55 +#: xpack/plugins/cloud/providers/huaweicloud.py:44 msgid "LA-Santiago" msgstr "拉美-圣地亚哥" -#: xpack/plugins/cloud/providers/huaweicloud.py:56 +#: xpack/plugins/cloud/providers/huaweicloud.py:45 msgid "LA-Sao Paulo1" msgstr "拉美-圣保罗一" -#: xpack/plugins/cloud/providers/huaweicloud.py:58 -msgid "TR-Istanbul" +#: xpack/plugins/cloud/providers/huaweicloud.py:46 +msgid "EU-Paris" msgstr "" +#: xpack/plugins/cloud/providers/huaweicloud.py:47 +msgid "CN Southwest-Guiyang1" +msgstr "西南-贵阳1" + +#: xpack/plugins/cloud/providers/huaweicloud.py:48 +msgid "AP-Bangkok" +msgstr "亚太-曼谷" + +#: xpack/plugins/cloud/providers/huaweicloud.py:52 +#, fuzzy +#| msgid "CN North-Baoding" +msgid "CN Northeast-Dalian" +msgstr "华北-保定" + +#: xpack/plugins/cloud/providers/huaweicloud.py:53 +msgid "CN North-Ulanqab1" +msgstr "华北-乌兰察布一" + +#: xpack/plugins/cloud/providers/huaweicloud.py:54 +msgid "CN South-Guangzhou-InvitationOnly" +msgstr "华南-广州-友好用户环境" + #: xpack/plugins/cloud/providers/jdcloud.py:126 msgid "CN East-Suqian" msgstr "华东-宿迁" @@ -7920,7 +7859,7 @@ msgstr "订阅 ID" #: xpack/plugins/cloud/serializers/account_attrs.py:103 #: xpack/plugins/cloud/serializers/account_attrs.py:119 #: xpack/plugins/cloud/serializers/account_attrs.py:149 -#: xpack/plugins/cloud/serializers/account_attrs.py:199 +#: xpack/plugins/cloud/serializers/account_attrs.py:202 msgid "API Endpoint" msgstr "API 端点" @@ -7985,11 +7924,11 @@ msgstr "测试端口" msgid "Test timeout" msgstr "测试超时时间" -#: xpack/plugins/cloud/serializers/account_attrs.py:209 +#: xpack/plugins/cloud/serializers/account_attrs.py:212 msgid "Project" msgstr "project" -#: xpack/plugins/cloud/serializers/task.py:139 +#: xpack/plugins/cloud/serializers/task.py:28 msgid "" "Only instances matching the IP range will be synced.
If the instance " "contains multiple IP addresses, the first IP address that matches will be " @@ -8001,11 +7940,11 @@ msgstr "" "到的 IP 地址将被用作创建的资产的 IP。
默认值 * 表示同步所有实例和随机匹配 " "IP 地址。
例如: 192.168.1.0/24,10.1.1.1-10.1.1.20。" -#: xpack/plugins/cloud/serializers/task.py:145 +#: xpack/plugins/cloud/serializers/task.py:34 msgid "History count" msgstr "执行次数" -#: xpack/plugins/cloud/serializers/task.py:146 +#: xpack/plugins/cloud/serializers/task.py:35 msgid "Instance count" msgstr "实例个数" @@ -8017,6 +7956,10 @@ msgstr "执行同步实例任务" msgid "Period clean sync instance task execution" msgstr "定期清除同步实例任务执行记录" +#: xpack/plugins/cloud/utils.py:68 +msgid "Account unavailable" +msgstr "账号无效" + #: xpack/plugins/interface/api.py:52 msgid "Restore default successfully." msgstr "恢复默认成功!" @@ -8080,3 +8023,64 @@ msgstr "旗舰版" #: xpack/plugins/license/models.py:86 msgid "Community edition" msgstr "社区版" + +#~ msgid "" +#~ "The forgot password url on login page, If you use ldap or cas external " +#~ "authentication, you can set it" +#~ msgstr "" +#~ "登录页面忘记密码URL, 如果使用了 LDAP, OPENID 等外部认证系统,可以自定义用" +#~ "户重置密码访问的地址" + +#~ msgid "Strategy" +#~ msgstr "策略" + +#~ msgid "Sync instance snapshot" +#~ msgstr "同步实例快照" + +#~ msgid "Task strategy" +#~ msgstr "任务策略" + +#~ msgid "Not" +#~ msgstr "否" + +#~ msgid "In" +#~ msgstr "在..里面" + +#~ msgid "Contains" +#~ msgstr "包含" + +#~ msgid "Startswith" +#~ msgstr "以..开头" + +#~ msgid "Endswith" +#~ msgstr "以..结尾" + +#~ msgid "Instance platform" +#~ msgstr "实例平台" + +#~ msgid "Instance address" +#~ msgstr "实例地址" + +#~ msgid "Rule attr" +#~ msgstr "规则属性" + +#~ msgid "Rule match" +#~ msgstr "规则匹配" + +#~ msgid "Rule value" +#~ msgstr "规则值" + +#~ msgid "Strategy rule" +#~ msgstr "策略规则" + +#~ msgid "Action attr" +#~ msgstr "动作属性" + +#~ msgid "Action value" +#~ msgstr "动作值" + +#~ msgid "Strategy action" +#~ msgstr "策略动作" + +#~ msgid "CN South-Shenzhen" +#~ msgstr "华南-广州" diff --git a/apps/terminal/api/applet/applet.py b/apps/terminal/api/applet/applet.py index ae984ba2f..90b4f162c 100644 --- a/apps/terminal/api/applet/applet.py +++ b/apps/terminal/api/applet/applet.py @@ -60,6 +60,10 @@ class DownloadUploadMixin: name = manifest['name'] update = request.query_params.get('update') + is_enterprise = manifest.get('edition') == Applet.Edition.enterprise + if is_enterprise and not settings.XPACK_ENABLED: + raise ValidationError({'error': _('This is enterprise edition applet')}) + instance = Applet.objects.filter(name=name).first() if instance and not update: return Response({'error': 'Applet already exists: {}'.format(name)}, status=400) From b20abb494f5ef03be02cfa0e4f4041a6dfd0b329 Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Thu, 17 Aug 2023 12:12:58 +0800 Subject: [PATCH 172/177] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=20vault=20?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=20(#11313)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: feng <1304903146@qq.com> --- apps/accounts/backends/__init__.py | 4 ++-- apps/accounts/backends/base.py | 5 +---- apps/accounts/tasks/vault.py | 7 +++---- apps/jumpserver/conf.py | 2 +- apps/jumpserver/settings/auth.py | 2 +- apps/settings/api/vault.py | 2 +- apps/settings/serializers/feature.py | 10 ++-------- apps/settings/serializers/public.py | 2 +- config_example.yml | 4 ++-- 9 files changed, 14 insertions(+), 24 deletions(-) diff --git a/apps/accounts/backends/__init__.py b/apps/accounts/backends/__init__.py index 1b12e6be8..0143d75c8 100644 --- a/apps/accounts/backends/__init__.py +++ b/apps/accounts/backends/__init__.py @@ -12,8 +12,9 @@ logger = get_logger(__file__) def get_vault_client(raise_exception=False, **kwargs): + enabled = kwargs.get('VAULT_ENABLED') + tp = 'hcp' if enabled else 'local' try: - tp = kwargs.get('VAULT_TYPE') module_path = f'apps.accounts.backends.{tp}.main' client = import_module(module_path).Vault(**kwargs) except Exception as e: @@ -22,7 +23,6 @@ def get_vault_client(raise_exception=False, **kwargs): raise tp = VaultTypeChoices.local module_path = f'apps.accounts.backends.{tp}.main' - kwargs['VAULT_TYPE'] = tp client = import_module(module_path).Vault(**kwargs) return client diff --git a/apps/accounts/backends/base.py b/apps/accounts/backends/base.py index 0af8e0167..f7648caed 100644 --- a/apps/accounts/backends/base.py +++ b/apps/accounts/backends/base.py @@ -8,10 +8,7 @@ __all__ = ['BaseVault'] class BaseVault(ABC): def __init__(self, *args, **kwargs): - self.type = kwargs.get('VAULT_TYPE') - - def is_type(self, tp): - return self.type == tp + self.enabled = kwargs.get('VAULT_ENABLED') def get(self, instance): """ 返回 secret 值 """ diff --git a/apps/accounts/tasks/vault.py b/apps/accounts/tasks/vault.py index 90e78cebf..6429b7133 100644 --- a/apps/accounts/tasks/vault.py +++ b/apps/accounts/tasks/vault.py @@ -8,7 +8,6 @@ from accounts.backends import vault_client from accounts.models import Account, AccountTemplate from common.utils import get_logger from orgs.utils import tmp_to_root_org -from ..const import VaultTypeChoices logger = get_logger(__name__) @@ -31,9 +30,9 @@ def sync_instance(instance): @shared_task(verbose_name=_('Sync secret to vault')) def sync_secret_to_vault(): - if vault_client.is_type(VaultTypeChoices.local): - # 这里不能判断 settings.VAULT_TYPE, 必须判断当前 vault_client 的类型 - print('\033[35m>>> 当前 Vault 类型为本地数据库, 不需要同步') + if not vault_client.enabled: + # 这里不能判断 settings.VAULT_ENABLED, 必须判断当前 vault_client 的类型 + print('\033[35m>>> 当前 Vault 功能未开启, 不需要同步') return failed, skipped, succeeded = 0, 0, 0 diff --git a/apps/jumpserver/conf.py b/apps/jumpserver/conf.py index 1d513025c..60d665a04 100644 --- a/apps/jumpserver/conf.py +++ b/apps/jumpserver/conf.py @@ -255,7 +255,7 @@ class Config(dict): 'AUTH_TEMP_TOKEN': False, # Vault - 'VAULT_TYPE': 'local', + 'VAULT_ENABLED': False, 'VAULT_HCP_HOST': '', 'VAULT_HCP_TOKEN': '', 'VAULT_HCP_MOUNT_POINT': 'jumpserver', diff --git a/apps/jumpserver/settings/auth.py b/apps/jumpserver/settings/auth.py index 23c95df69..1654ae63c 100644 --- a/apps/jumpserver/settings/auth.py +++ b/apps/jumpserver/settings/auth.py @@ -175,7 +175,7 @@ AUTH_OAUTH2_LOGOUT_URL_NAME = "authentication:oauth2:logout" AUTH_TEMP_TOKEN = CONFIG.AUTH_TEMP_TOKEN # Vault -VAULT_TYPE = CONFIG.VAULT_TYPE +VAULT_ENABLED = CONFIG.VAULT_ENABLED VAULT_HCP_HOST = CONFIG.VAULT_HCP_HOST VAULT_HCP_TOKEN = CONFIG.VAULT_HCP_TOKEN VAULT_HCP_MOUNT_POINT = CONFIG.VAULT_HCP_MOUNT_POINT diff --git a/apps/settings/api/vault.py b/apps/settings/api/vault.py index 7cbe4c39e..a17eeca5c 100644 --- a/apps/settings/api/vault.py +++ b/apps/settings/api/vault.py @@ -29,7 +29,7 @@ class VaultTestingAPI(GenericAPIView): def post(self, request): config = self.get_config(request) - config['VAULT_TYPE'] = settings.VAULT_TYPE + config['VAULT_ENABLED'] = settings.VAULT_ENABLED try: client = get_vault_client(raise_exception=True, **config) ok, error = client.is_active() diff --git a/apps/settings/serializers/feature.py b/apps/settings/serializers/feature.py index d9d6d7ec5..3d11da9d6 100644 --- a/apps/settings/serializers/feature.py +++ b/apps/settings/serializers/feature.py @@ -3,7 +3,6 @@ import uuid from django.utils.translation import gettext_lazy as _ from rest_framework import serializers -from accounts.const import VaultTypeChoices from common.serializers.fields import EncryptedField __all__ = [ @@ -41,9 +40,8 @@ class AnnouncementSettingSerializer(serializers.Serializer): class VaultSettingSerializer(serializers.Serializer): PREFIX_TITLE = _('Vault') - VAULT_TYPE = serializers.ChoiceField( - default=VaultTypeChoices.local, choices=VaultTypeChoices.choices, - required=False, label=_('Type') + VAULT_ENABLED = serializers.BooleanField( + required=False, label=_('Enable Vault'), read_only=True ) VAULT_HCP_HOST = serializers.CharField( max_length=256, allow_blank=True, required=False, label=_('Host') @@ -55,10 +53,6 @@ class VaultSettingSerializer(serializers.Serializer): max_length=256, allow_blank=True, required=False, label=_('Mount Point') ) - def validate(self, attrs): - attrs.pop('VAULT_TYPE', None) - return attrs - class TicketSettingSerializer(serializers.Serializer): PREFIX_TITLE = _('Ticket') diff --git a/apps/settings/serializers/public.py b/apps/settings/serializers/public.py index 7fb1308ae..02f900d5f 100644 --- a/apps/settings/serializers/public.py +++ b/apps/settings/serializers/public.py @@ -53,7 +53,7 @@ class PrivateSettingSerializer(PublicSettingSerializer): TICKETS_ENABLED = serializers.BooleanField() CONNECTION_TOKEN_REUSABLE = serializers.BooleanField() CACHE_LOGIN_PASSWORD_ENABLED = serializers.BooleanField() - VAULT_TYPE = serializers.CharField() + VAULT_ENABLED = serializers.BooleanField() class ServerInfoSerializer(serializers.Serializer): diff --git a/config_example.yml b/config_example.yml index bab9b35f5..03cc0aa03 100644 --- a/config_example.yml +++ b/config_example.yml @@ -96,6 +96,6 @@ REDIS_PORT: 6379 # 仅允许已存在的用户登录,不允许第三方认证后,自动创建用户 # ONLY_ALLOW_EXIST_USER_AUTH: False -# 当前存储的类型,默认 local,新增类型 hcp 为远端 vault 存储 -# VAULT_TYPE: local +# 开启 Vault 账号存储 +# VAULT_ENABLED: False From c0f3769f9f5ef5897dbd7bb45216d4a3de8c490d Mon Sep 17 00:00:00 2001 From: jiangweidong Date: Thu, 17 Aug 2023 14:42:30 +0800 Subject: [PATCH 173/177] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=E7=BB=84?= =?UTF-8?q?=E4=BB=B6=E7=9A=84=E6=93=8D=E4=BD=9C=E8=A1=8C=E4=B8=BA=E4=B8=8D?= =?UTF-8?q?=E8=AE=B0=E5=BD=95=E5=88=B0=E6=93=8D=E4=BD=9C=E6=97=A5=E5=BF=97?= =?UTF-8?q?=E4=B8=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/audits/signal_handlers/operate_log.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/apps/audits/signal_handlers/operate_log.py b/apps/audits/signal_handlers/operate_log.py index 302e89190..69e6a5a50 100644 --- a/apps/audits/signal_handlers/operate_log.py +++ b/apps/audits/signal_handlers/operate_log.py @@ -14,6 +14,7 @@ from audits.handler import ( from audits.utils import model_to_dict_for_operate_log as model_to_dict from common.const.signals import POST_ADD, POST_REMOVE, POST_CLEAR, SKIP_SIGNAL from common.signals import django_ready +from jumpserver.utils import current_request from ..const import MODELS_NEED_RECORD, ActionChoices M2M_ACTION = { @@ -73,6 +74,10 @@ def signal_of_operate_log_whether_continue( condition = False if instance and getattr(instance, SKIP_SIGNAL, False): condition = False + # 不记录组件的操作日志 + user = current_request.user if current_request else None + if not user or user.is_service_account: + condition = False # 终端模型的 create 事件由系统产生,不记录 if instance._meta.object_name == 'Terminal' and created: condition = False From 7b89055fbfe53ff479e9d4409dc8f3e8e10ffa52 Mon Sep 17 00:00:00 2001 From: Bai Date: Thu, 17 Aug 2023 14:49:12 +0800 Subject: [PATCH 174/177] =?UTF-8?q?fix:=20=E8=B4=A6=E5=8F=B7=E5=A4=87?= =?UTF-8?q?=E4=BB=BD=E5=8F=82=E6=95=B0=E6=8E=A7=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/accounts/tasks/backup_account.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/accounts/tasks/backup_account.py b/apps/accounts/tasks/backup_account.py index 16eafaf5e..c9b881b4d 100644 --- a/apps/accounts/tasks/backup_account.py +++ b/apps/accounts/tasks/backup_account.py @@ -23,7 +23,7 @@ def task_activity_callback(self, pid, trigger, *args, **kwargs): @shared_task(verbose_name=_('Execute account backup plan'), activity_callback=task_activity_callback) -def execute_account_backup_task(pid, trigger): +def execute_account_backup_task(pid, trigger, **kwargs): from accounts.models import AccountBackupAutomation with tmp_to_root_org(): plan = get_object_or_none(AccountBackupAutomation, pk=pid) From 6c36b5be9243399960f80a8a2aa166e856970aca Mon Sep 17 00:00:00 2001 From: ibuler Date: Thu, 17 Aug 2023 15:25:44 +0800 Subject: [PATCH 175/177] =?UTF-8?q?perf:=20=E6=9B=B4=E6=96=B0=20poetry=20l?= =?UTF-8?q?ock?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/assets/filters.py | 5 +- poetry.lock | 174 ++++++++++++++++++++++++----------------- pyproject.toml | 3 +- 3 files changed, 104 insertions(+), 78 deletions(-) diff --git a/apps/assets/filters.py b/apps/assets/filters.py index a9cb5a614..17e8414bf 100644 --- a/apps/assets/filters.py +++ b/apps/assets/filters.py @@ -1,14 +1,11 @@ # -*- coding: utf-8 -*- # from django.db.models import Q -from django_filters import rest_framework as drf_filters from rest_framework import filters from rest_framework.compat import coreapi, coreschema from assets.utils import get_node_from_request, is_query_node_all_assets -from common.drf.filters import BaseFilterSet - -from .models import Label, Node +from .models import Label class AssetByNodeFilterBackend(filters.BaseFilterBackend): diff --git a/poetry.lock b/poetry.lock index 4cc282799..7a3397d29 100644 --- a/poetry.lock +++ b/poetry.lock @@ -576,13 +576,13 @@ reference = "tsinghua" [[package]] name = "async-timeout" -version = "4.0.2" +version = "4.0.3" description = "Timeout context manager for asyncio programs" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" files = [ - {file = "async-timeout-4.0.2.tar.gz", hash = "sha256:2163e1640ddb52b7a8c80d0a67a08587e5d245cc9c553a74a847056bc2976b15"}, - {file = "async_timeout-4.0.2-py3-none-any.whl", hash = "sha256:8ca1e4fcf50d07413d66d1a5e416e42cfdf5851c981d679a09851a6853383b3c"}, + {file = "async-timeout-4.0.3.tar.gz", hash = "sha256:4640d96be84d82d02ed59ea2b7105a0f7b33abe8703703cd0ab0bf87c427522f"}, + {file = "async_timeout-4.0.3-py3-none-any.whl", hash = "sha256:7405140ff1230c310e51dc27b3145b9092d659ce68ff733fb0cefe3ee42be028"}, ] [package.source] @@ -687,19 +687,19 @@ reference = "tsinghua" [[package]] name = "azure-core" -version = "1.28.0" +version = "1.29.2" description = "Microsoft Azure Core Library for Python" optional = false python-versions = ">=3.7" files = [ - {file = "azure-core-1.28.0.zip", hash = "sha256:e9eefc66fc1fde56dab6f04d4e5d12c60754d5a9fa49bdcfd8534fc96ed936bd"}, - {file = "azure_core-1.28.0-py3-none-any.whl", hash = "sha256:dec36dfc8eb0b052a853f30c07437effec2f9e3e1fc8f703d9bdaa5cfc0043d9"}, + {file = "azure-core-1.29.2.zip", hash = "sha256:beb0fe88d1043d8457318e8fb841d9caa648211092eda213c16b376401f3710d"}, + {file = "azure_core-1.29.2-py3-none-any.whl", hash = "sha256:8e6602f322dc1070caf7e17754beb53b69ffa09df0f4786009a3107e9a00c793"}, ] [package.dependencies] requests = ">=2.18.4" six = ">=1.11.0" -typing-extensions = ">=4.3.0" +typing-extensions = ">=4.6.0" [package.extras] aio = ["aiohttp (>=3.0)"] @@ -1824,7 +1824,7 @@ description = "" optional = false python-versions = ">=3.7" files = [ - {file = "django-cas-ng-4.3.1.zip", hash = "sha256:c3c068b979927333475fb82b8f3597210384ca9ba764496874fc532463d40e3d"}, + {file = "django-cas-ng-4.3.1.zip", hash = "sha256:aeea96ad7958e3cb40d9bb5ef6a1add66f720835dfe87cc1dfe163f92d084690"}, ] [package.dependencies] @@ -2133,13 +2133,13 @@ reference = "tsinghua" [[package]] name = "dnspython" -version = "2.4.1" +version = "2.4.2" description = "DNS toolkit" optional = false python-versions = ">=3.8,<4.0" files = [ - {file = "dnspython-2.4.1-py3-none-any.whl", hash = "sha256:5b7488477388b8c0b70a8ce93b227c5603bc7b77f1565afe8e729c36c51447d7"}, - {file = "dnspython-2.4.1.tar.gz", hash = "sha256:c33971c79af5be968bb897e95c2448e11a645ee84d93b265ce0b7aabe5dfdca8"}, + {file = "dnspython-2.4.2-py3-none-any.whl", hash = "sha256:57c6fbaaeaaf39c891292012060beb141791735dbb4004798328fc2c467402d8"}, + {file = "dnspython-2.4.2.tar.gz", hash = "sha256:8dcfae8c7460a2f84b4072e26f1c9f4101ca20c071649cb7c34e8b6a93d58984"}, ] [package.extras] @@ -3011,13 +3011,13 @@ reference = "tsinghua" [[package]] name = "humanize" -version = "4.7.0" +version = "4.8.0" description = "Python humanize utilities" optional = false python-versions = ">=3.8" files = [ - {file = "humanize-4.7.0-py3-none-any.whl", hash = "sha256:df7c429c2d27372b249d3f26eb53b07b166b661326e0325793e0a988082e3889"}, - {file = "humanize-4.7.0.tar.gz", hash = "sha256:7ca0e43e870981fa684acb5b062deb307218193bca1a01f2b2676479df849b3a"}, + {file = "humanize-4.8.0-py3-none-any.whl", hash = "sha256:8bc9e2bb9315e61ec06bf690151ae35aeb65651ab091266941edf97c90836404"}, + {file = "humanize-4.8.0.tar.gz", hash = "sha256:9783373bf1eec713a770ecaa7c2d7a7902c98398009dfa3d8a2df91eec9311e8"}, ] [package.extras] @@ -4148,21 +4148,48 @@ reference = "tsinghua" [[package]] name = "oracledb" -version = "1.4.0b1" +version = "1.4.0" description = "Python interface to Oracle Database" optional = false python-versions = ">=3.6" -files = [] -develop = false +files = [ + {file = "oracledb-1.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3893da5f390a2ff8cb0914c025c33255cda6e0c9da506b26c3da6c309a2e9b2a"}, + {file = "oracledb-1.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38c0ad3cf563123080d0c36bf1e7b28884663b297e4269b69a3f597891808707"}, + {file = "oracledb-1.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:117e8b33bcb9de98912e13a25d1fed28db3510e7229b27b295b413ba03e2b176"}, + {file = "oracledb-1.4.0-cp310-cp310-win32.whl", hash = "sha256:e9c205e69bafaf8f16ea5f1d06ab713f3f75cab1a4e22995d688f380c92f7aeb"}, + {file = "oracledb-1.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:411acaf2f11076485a66efb42273ec25ed97cb060df191e0d309f02455f2abbd"}, + {file = "oracledb-1.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:1fc16c738c2287cbc26b2fe5e6292508f78f6b7ae833f3f371c804cc4fd01027"}, + {file = "oracledb-1.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:44a1f44bdc068a0051058dcb639bb504c78167cc48c6d5181b1c066cba1e5050"}, + {file = "oracledb-1.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eec1b828a6bb1d626c1555746ea411a9d853ed8428aafed8eef0aff6d90b66c9"}, + {file = "oracledb-1.4.0-cp311-cp311-win32.whl", hash = "sha256:5a452671d4c079a35c4086fed2f4635f4a902d607c05bab48ea2eb919794f0d0"}, + {file = "oracledb-1.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:f1ed9b6f857ec70cf33ace4ab16403ce00232d875e68922168ac5e96c9fbea65"}, + {file = "oracledb-1.4.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f52d6184a161508e759797857ebd6fdc8ba1439072c9572718dde9a196924856"}, + {file = "oracledb-1.4.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b236339d2cd502a6637b462adeef14616afd358a6393608d83cf71e502495b28"}, + {file = "oracledb-1.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:72165e6e84f7d6b2c3c290f4fadd123cd03c11f715d99f9a3f0117569bf40f3e"}, + {file = "oracledb-1.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a55c509ec54661901b2ae2a60169b8997de480d0646bb458ac92a05fbb77441"}, + {file = "oracledb-1.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1b9fe90ec793ce13f72e2051e4734ad0002cd12dd009141f585c13dc51c314a9"}, + {file = "oracledb-1.4.0-cp37-cp37m-win32.whl", hash = "sha256:be54c63a9424964a4bdccdfa2368188b77e1b00e065b81776b762cbb8559ff2f"}, + {file = "oracledb-1.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:c7272f60f6da7a921a3597db91c323c7efdd44a9682ec4bbfb4483f6c039c810"}, + {file = "oracledb-1.4.0-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:473fab2bf20092690c3bf87e3d966e3a6fb9186b8cea40e65a73b5980f4f5bd4"}, + {file = "oracledb-1.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a7890bb93137b6ed369fd25fb54ccdff64e41dccac65b3eaca18f08b4f3dffd4"}, + {file = "oracledb-1.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf5d1b0ea16e0f5168819fbb25b045c6f82f2c019bebddee18c0a8967946f681"}, + {file = "oracledb-1.4.0-cp38-cp38-win32.whl", hash = "sha256:64574cb4f69c3dd2767779c0f71f7b8c4307688b50183027740c6e3ceb2440f6"}, + {file = "oracledb-1.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:0dcd691da66b7ee34725cfd55d059360b5474e624f0eb18886d3fc9cefd3bf33"}, + {file = "oracledb-1.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:6432d1d2609c0a65ad23c074c0136025f29c5aa47a7093554481de0447f087e9"}, + {file = "oracledb-1.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aadab02421f76c6e2affc72e1719c8ea0c52022dad391fd46024e76f91ac3a02"}, + {file = "oracledb-1.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:25aa5299b981fb52dee19011282dacbd865e5d616e942435763a2a1b76614da2"}, + {file = "oracledb-1.4.0-cp39-cp39-win32.whl", hash = "sha256:269e4f58d874f067605d12f35e701838d58aff4cac05890be6549deec09fe6ae"}, + {file = "oracledb-1.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:e6a3c8b8c526f6b10af47951f30bee5a599286dfe18073b053cae1a9d9b1bdec"}, + {file = "oracledb-1.4.0.tar.gz", hash = "sha256:96ba508f783892c7ca648f268acbcb8a4a9c8037c7dd4a509f05f2c89d6231be"}, +] [package.dependencies] cryptography = ">=3.2.1" [package.source] -type = "git" -url = "https://github.com/oracle/python-oracledb.git" -reference = "main" -resolved_reference = "9f1019a10813d98fe667283e04d6b64d05438867" +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" [[package]] name = "os-service-types" @@ -4636,24 +4663,24 @@ reference = "tsinghua" [[package]] name = "protobuf" -version = "4.23.4" +version = "4.24.0" description = "" optional = false python-versions = ">=3.7" files = [ - {file = "protobuf-4.23.4-cp310-abi3-win32.whl", hash = "sha256:5fea3c64d41ea5ecf5697b83e41d09b9589e6f20b677ab3c48e5f242d9b7897b"}, - {file = "protobuf-4.23.4-cp310-abi3-win_amd64.whl", hash = "sha256:7b19b6266d92ca6a2a87effa88ecc4af73ebc5cfde194dc737cf8ef23a9a3b12"}, - {file = "protobuf-4.23.4-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:8547bf44fe8cec3c69e3042f5c4fb3e36eb2a7a013bb0a44c018fc1e427aafbd"}, - {file = "protobuf-4.23.4-cp37-abi3-manylinux2014_aarch64.whl", hash = "sha256:fee88269a090ada09ca63551bf2f573eb2424035bcf2cb1b121895b01a46594a"}, - {file = "protobuf-4.23.4-cp37-abi3-manylinux2014_x86_64.whl", hash = "sha256:effeac51ab79332d44fba74660d40ae79985901ac21bca408f8dc335a81aa597"}, - {file = "protobuf-4.23.4-cp37-cp37m-win32.whl", hash = "sha256:c3e0939433c40796ca4cfc0fac08af50b00eb66a40bbbc5dee711998fb0bbc1e"}, - {file = "protobuf-4.23.4-cp37-cp37m-win_amd64.whl", hash = "sha256:9053df6df8e5a76c84339ee4a9f5a2661ceee4a0dab019e8663c50ba324208b0"}, - {file = "protobuf-4.23.4-cp38-cp38-win32.whl", hash = "sha256:e1c915778d8ced71e26fcf43c0866d7499891bca14c4368448a82edc61fdbc70"}, - {file = "protobuf-4.23.4-cp38-cp38-win_amd64.whl", hash = "sha256:351cc90f7d10839c480aeb9b870a211e322bf05f6ab3f55fcb2f51331f80a7d2"}, - {file = "protobuf-4.23.4-cp39-cp39-win32.whl", hash = "sha256:6dd9b9940e3f17077e820b75851126615ee38643c2c5332aa7a359988820c720"}, - {file = "protobuf-4.23.4-cp39-cp39-win_amd64.whl", hash = "sha256:0a5759f5696895de8cc913f084e27fd4125e8fb0914bb729a17816a33819f474"}, - {file = "protobuf-4.23.4-py3-none-any.whl", hash = "sha256:e9d0be5bf34b275b9f87ba7407796556abeeba635455d036c7351f7c183ef8ff"}, - {file = "protobuf-4.23.4.tar.gz", hash = "sha256:ccd9430c0719dce806b93f89c91de7977304729e55377f872a92465d548329a9"}, + {file = "protobuf-4.24.0-cp310-abi3-win32.whl", hash = "sha256:81cb9c4621d2abfe181154354f63af1c41b00a4882fb230b4425cbaed65e8f52"}, + {file = "protobuf-4.24.0-cp310-abi3-win_amd64.whl", hash = "sha256:6c817cf4a26334625a1904b38523d1b343ff8b637d75d2c8790189a4064e51c3"}, + {file = "protobuf-4.24.0-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:ae97b5de10f25b7a443b40427033e545a32b0e9dda17bcd8330d70033379b3e5"}, + {file = "protobuf-4.24.0-cp37-abi3-manylinux2014_aarch64.whl", hash = "sha256:567fe6b0647494845d0849e3d5b260bfdd75692bf452cdc9cb660d12457c055d"}, + {file = "protobuf-4.24.0-cp37-abi3-manylinux2014_x86_64.whl", hash = "sha256:a6b1ca92ccabfd9903c0c7dde8876221dc7d8d87ad5c42e095cc11b15d3569c7"}, + {file = "protobuf-4.24.0-cp37-cp37m-win32.whl", hash = "sha256:a38400a692fd0c6944c3c58837d112f135eb1ed6cdad5ca6c5763336e74f1a04"}, + {file = "protobuf-4.24.0-cp37-cp37m-win_amd64.whl", hash = "sha256:5ab19ee50037d4b663c02218a811a5e1e7bb30940c79aac385b96e7a4f9daa61"}, + {file = "protobuf-4.24.0-cp38-cp38-win32.whl", hash = "sha256:e8834ef0b4c88666ebb7c7ec18045aa0f4325481d724daa624a4cf9f28134653"}, + {file = "protobuf-4.24.0-cp38-cp38-win_amd64.whl", hash = "sha256:8bb52a2be32db82ddc623aefcedfe1e0eb51da60e18fcc908fb8885c81d72109"}, + {file = "protobuf-4.24.0-cp39-cp39-win32.whl", hash = "sha256:ae7a1835721086013de193311df858bc12cd247abe4ef9710b715d930b95b33e"}, + {file = "protobuf-4.24.0-cp39-cp39-win_amd64.whl", hash = "sha256:44825e963008f8ea0d26c51911c30d3e82e122997c3c4568fd0385dd7bacaedf"}, + {file = "protobuf-4.24.0-py3-none-any.whl", hash = "sha256:82e6e9ebdd15b8200e8423676eab38b774624d6a1ad696a60d86a2ac93f18201"}, + {file = "protobuf-4.24.0.tar.gz", hash = "sha256:5d0ceb9de6e08311832169e601d1fc71bd8e8c779f3ee38a97a78554945ecb85"}, ] [package.source] @@ -6144,18 +6171,18 @@ reference = "tsinghua" [[package]] name = "setuptools" -version = "68.0.0" +version = "68.1.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "setuptools-68.0.0-py3-none-any.whl", hash = "sha256:11e52c67415a381d10d6b462ced9cfb97066179f0e871399e006c4ab101fc85f"}, - {file = "setuptools-68.0.0.tar.gz", hash = "sha256:baf1fdb41c6da4cd2eae722e135500da913332ab3f2f5c7d33af9b492acb5235"}, + {file = "setuptools-68.1.0-py3-none-any.whl", hash = "sha256:e13e1b0bc760e9b0127eda042845999b2f913e12437046e663b833aa96d89715"}, + {file = "setuptools-68.1.0.tar.gz", hash = "sha256:d59c97e7b774979a5ccb96388efc9eb65518004537e85d52e81eaee89ab6dd91"}, ] [package.extras] -docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (==0.8.3)", "sphinx-reredirects", "sphinxcontrib-towncrier"] -testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (==0.8.3)", "sphinx-reredirects", "sphinxcontrib-towncrier"] +testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] [package.source] @@ -6461,22 +6488,22 @@ reference = "tsinghua" [[package]] name = "tornado" -version = "6.3.2" +version = "6.3.3" description = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed." optional = false python-versions = ">= 3.8" files = [ - {file = "tornado-6.3.2-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:c367ab6c0393d71171123ca5515c61ff62fe09024fa6bf299cd1339dc9456829"}, - {file = "tornado-6.3.2-cp38-abi3-macosx_10_9_x86_64.whl", hash = "sha256:b46a6ab20f5c7c1cb949c72c1994a4585d2eaa0be4853f50a03b5031e964fc7c"}, - {file = "tornado-6.3.2-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c2de14066c4a38b4ecbbcd55c5cc4b5340eb04f1c5e81da7451ef555859c833f"}, - {file = "tornado-6.3.2-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:05615096845cf50a895026f749195bf0b10b8909f9be672f50b0fe69cba368e4"}, - {file = "tornado-6.3.2-cp38-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5b17b1cf5f8354efa3d37c6e28fdfd9c1c1e5122f2cb56dac121ac61baa47cbe"}, - {file = "tornado-6.3.2-cp38-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:29e71c847a35f6e10ca3b5c2990a52ce38b233019d8e858b755ea6ce4dcdd19d"}, - {file = "tornado-6.3.2-cp38-abi3-musllinux_1_1_i686.whl", hash = "sha256:834ae7540ad3a83199a8da8f9f2d383e3c3d5130a328889e4cc991acc81e87a0"}, - {file = "tornado-6.3.2-cp38-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:6a0848f1aea0d196a7c4f6772197cbe2abc4266f836b0aac76947872cd29b411"}, - {file = "tornado-6.3.2-cp38-abi3-win32.whl", hash = "sha256:7efcbcc30b7c654eb6a8c9c9da787a851c18f8ccd4a5a3a95b05c7accfa068d2"}, - {file = "tornado-6.3.2-cp38-abi3-win_amd64.whl", hash = "sha256:0c325e66c8123c606eea33084976c832aa4e766b7dff8aedd7587ea44a604cdf"}, - {file = "tornado-6.3.2.tar.gz", hash = "sha256:4b927c4f19b71e627b13f3db2324e4ae660527143f9e1f2e2fb404f3a187e2ba"}, + {file = "tornado-6.3.3-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:502fba735c84450974fec147340016ad928d29f1e91f49be168c0a4c18181e1d"}, + {file = "tornado-6.3.3-cp38-abi3-macosx_10_9_x86_64.whl", hash = "sha256:805d507b1f588320c26f7f097108eb4023bbaa984d63176d1652e184ba24270a"}, + {file = "tornado-6.3.3-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1bd19ca6c16882e4d37368e0152f99c099bad93e0950ce55e71daed74045908f"}, + {file = "tornado-6.3.3-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7ac51f42808cca9b3613f51ffe2a965c8525cb1b00b7b2d56828b8045354f76a"}, + {file = "tornado-6.3.3-cp38-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:71a8db65160a3c55d61839b7302a9a400074c9c753040455494e2af74e2501f2"}, + {file = "tornado-6.3.3-cp38-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:ceb917a50cd35882b57600709dd5421a418c29ddc852da8bcdab1f0db33406b0"}, + {file = "tornado-6.3.3-cp38-abi3-musllinux_1_1_i686.whl", hash = "sha256:7d01abc57ea0dbb51ddfed477dfe22719d376119844e33c661d873bf9c0e4a16"}, + {file = "tornado-6.3.3-cp38-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:9dc4444c0defcd3929d5c1eb5706cbe1b116e762ff3e0deca8b715d14bf6ec17"}, + {file = "tornado-6.3.3-cp38-abi3-win32.whl", hash = "sha256:65ceca9500383fbdf33a98c0087cb975b2ef3bfb874cb35b8de8740cf7f41bd3"}, + {file = "tornado-6.3.3-cp38-abi3-win_amd64.whl", hash = "sha256:22d3c2fa10b5793da13c807e6fc38ff49a4f6e1e3868b0a6f4164768bb8e20f5"}, + {file = "tornado-6.3.3.tar.gz", hash = "sha256:e7d8db41c0181c80d76c982aacc442c0783a2c54d6400fe028954201a2e032fe"}, ] [package.source] @@ -6571,27 +6598,30 @@ reference = "tsinghua" [[package]] name = "twisted-iocpsupport" -version = "1.0.3" +version = "1.0.4" description = "An extension for use in the twisted I/O Completion Ports reactor." optional = false python-versions = "*" files = [ - {file = "twisted-iocpsupport-1.0.3.tar.gz", hash = "sha256:afb00801fdfbaccf0d0173a722626500023d4a19719ac9f129d1347a32e2fc66"}, - {file = "twisted_iocpsupport-1.0.3-cp310-cp310-win32.whl", hash = "sha256:a379ef56a576c8090889f74441bc3822ca31ac82253cc61e8d50631bcb0c26d0"}, - {file = "twisted_iocpsupport-1.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:1ea2c3fbdb739c95cc8b3355305cd593d2c9ec56d709207aa1a05d4d98671e85"}, - {file = "twisted_iocpsupport-1.0.3-cp311-cp311-win32.whl", hash = "sha256:7efcdfafb377f32db90f42bd5fc5bb32cd1e3637ee936cdaf3aff4f4786ab3bf"}, - {file = "twisted_iocpsupport-1.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:1dbfac706972bf9ec5ce1ddbc735d2ebba406ad363345df8751ffd5252aa1618"}, - {file = "twisted_iocpsupport-1.0.3-cp36-cp36m-win32.whl", hash = "sha256:1ddfc5fa22ec6f913464b736b3f46e642237f17ac41be47eed6fa9bd52f5d0e0"}, - {file = "twisted_iocpsupport-1.0.3-cp36-cp36m-win_amd64.whl", hash = "sha256:1bdccbb22199fc69fd7744d6d2dfd22d073c028c8611d994b41d2d2ad0e0f40d"}, - {file = "twisted_iocpsupport-1.0.3-cp37-cp37m-win32.whl", hash = "sha256:db11c80054b52dbdea44d63d5474a44c9a6531882f0e2960268b15123088641a"}, - {file = "twisted_iocpsupport-1.0.3-cp37-cp37m-win_amd64.whl", hash = "sha256:67bec1716eb8f466ef366bbf262e1467ecc9e20940111207663ac24049785bad"}, - {file = "twisted_iocpsupport-1.0.3-cp38-cp38-win32.whl", hash = "sha256:98a6f16ab215f8c1446e9fc60aaed0ab7c746d566aa2f3492a23cea334e6bebb"}, - {file = "twisted_iocpsupport-1.0.3-cp38-cp38-win_amd64.whl", hash = "sha256:4f249d0baac836bb431d6fa0178be063a310136bc489465a831e3abd2d7acafd"}, - {file = "twisted_iocpsupport-1.0.3-cp39-cp39-win32.whl", hash = "sha256:aaca8f30c3b7c80d27a33fe9fe0d0bac42b1b012ddc60f677175c30e1becc1f3"}, - {file = "twisted_iocpsupport-1.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:dff43136c33665c2d117a73706aef6f7d6433e5c4560332a118fe066b16b8695"}, - {file = "twisted_iocpsupport-1.0.3-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:8faceae553cfadc42ad791b1790e7cdecb7751102608c405217f6a26e877e0c5"}, - {file = "twisted_iocpsupport-1.0.3-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:6f8c433faaad5d53d30d1da6968d5a3730df415e2efb6864847267a9b51290cd"}, - {file = "twisted_iocpsupport-1.0.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:3f39c41c0213a81a9ce0961e30d0d7650f371ad80f8d261007d15a2deb6d5be3"}, + {file = "twisted-iocpsupport-1.0.4.tar.gz", hash = "sha256:858096c0d15e33f15ac157f455d8f86f2f2cdd223963e58c0f682a3af8362d89"}, + {file = "twisted_iocpsupport-1.0.4-cp310-cp310-win32.whl", hash = "sha256:afa2b630797f9ed2f27f3d9f55e3f72b4244911e45a8c82756f44babbf0b243e"}, + {file = "twisted_iocpsupport-1.0.4-cp310-cp310-win_amd64.whl", hash = "sha256:0058c963c8957bcd3deda62122e89953c9de1e867a274facc9b15dde1a9f31e8"}, + {file = "twisted_iocpsupport-1.0.4-cp311-cp311-win32.whl", hash = "sha256:196f7c7ccad4ba4d1783b1c4e1d1b22d93c04275cd780bf7498d16c77319ad6e"}, + {file = "twisted_iocpsupport-1.0.4-cp311-cp311-win_amd64.whl", hash = "sha256:4e5f97bcbabdd79cbaa969b63439b89801ea560f11d42b0a387634275c633623"}, + {file = "twisted_iocpsupport-1.0.4-cp312-cp312-win32.whl", hash = "sha256:6081bd7c2f4fcf9b383dcdb3b3385d75a26a7c9d2be25b6950c3d8ea652d2d2d"}, + {file = "twisted_iocpsupport-1.0.4-cp312-cp312-win_amd64.whl", hash = "sha256:76f7e67cec1f1d097d1f4ed7de41be3d74546e1a4ede0c7d56e775c4dce5dfb0"}, + {file = "twisted_iocpsupport-1.0.4-cp36-cp36m-win32.whl", hash = "sha256:3d306fc4d88a6bcf61ce9d572c738b918578121bfd72891625fab314549024b5"}, + {file = "twisted_iocpsupport-1.0.4-cp36-cp36m-win_amd64.whl", hash = "sha256:391ac4d6002a80e15f35adc4ad6056f4fe1c17ceb0d1f98ba01b0f4f917adfd7"}, + {file = "twisted_iocpsupport-1.0.4-cp37-cp37m-win32.whl", hash = "sha256:0c1b5cf37f0b2d96cc3c9bc86fff16613b9f5d0ca565c96cf1f1fb8cfca4b81c"}, + {file = "twisted_iocpsupport-1.0.4-cp37-cp37m-win_amd64.whl", hash = "sha256:3c5dc11d72519e55f727320e3cee535feedfaee09c0f0765ed1ca7badff1ab3c"}, + {file = "twisted_iocpsupport-1.0.4-cp38-cp38-win32.whl", hash = "sha256:cc86c2ef598c15d824a243c2541c29459881c67fc3c0adb6efe2242f8f0ec3af"}, + {file = "twisted_iocpsupport-1.0.4-cp38-cp38-win_amd64.whl", hash = "sha256:c27985e949b9b1a1fb4c20c71d315c10ea0f93fdf3ccdd4a8c158b5926edd8c8"}, + {file = "twisted_iocpsupport-1.0.4-cp39-cp39-win32.whl", hash = "sha256:e311dfcb470696e3c077249615893cada598e62fa7c4e4ca090167bd2b7d331f"}, + {file = "twisted_iocpsupport-1.0.4-cp39-cp39-win_amd64.whl", hash = "sha256:4574eef1f3bb81501fb02f911298af3c02fe8179c31a33b361dd49180c3e644d"}, + {file = "twisted_iocpsupport-1.0.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:872747a3b64e2909aee59c803ccd0bceb9b75bf27915520ebd32d69687040fa2"}, + {file = "twisted_iocpsupport-1.0.4-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:c2712b778bacf1db434e3e065adfed3db300754186a29aecac1efae9ef4bcaff"}, + {file = "twisted_iocpsupport-1.0.4-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:7c66fa0aa4236b27b3c61cb488662d85dae746a6d1c7b0d91cf7aae118445adf"}, + {file = "twisted_iocpsupport-1.0.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:300437af17396a945a58dcfffd77863303a8b6d9e65c6e81f1d2eed55b50d444"}, ] [package.source] @@ -7193,4 +7223,4 @@ reference = "tsinghua" [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "062b7b8ab32d3eeacc77b6b160764bc7083b599f32a653da3a1ccaa353041fc8" +content-hash = "0bc2878f163c8b2f48d1103d96314c56f722f10d8f8adf6dfaba0452e6eac368" diff --git a/pyproject.toml b/pyproject.toml index 48e24921d..00d18bf29 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -159,8 +159,7 @@ tencentcloud-sdk-python = "3.0.941" aliyun-python-sdk-core-v3 = "2.13.33" aliyun-python-sdk-ecs = "4.24.64" keystoneauth1 = "5.2.1" -# oracledb = "1.4.0" -oracledb = { git = "https://github.com/oracle/python-oracledb.git", branch = "main" } +oracledb = "1.4.0" psycopg2-binary = "2.9.6" pymssql = "2.2.8" psycopg2 = "2.9.6" From 7dd6ee5f1a046b325d9a55b4a3563de1b559ab1f Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Thu, 17 Aug 2023 15:34:50 +0800 Subject: [PATCH 176/177] perf: translate (#11319) Co-authored-by: feng <1304903146@qq.com> --- apps/locale/ja/LC_MESSAGES/django.po | 406 +++++++++--------- apps/locale/zh/LC_MESSAGES/django.po | 406 +++++++++--------- apps/settings/serializers/feature.py | 2 +- .../terminal/_msg_session_sharing.html | 2 +- 4 files changed, 414 insertions(+), 402 deletions(-) diff --git a/apps/locale/ja/LC_MESSAGES/django.po b/apps/locale/ja/LC_MESSAGES/django.po index c406683cc..e541c9c8c 100644 --- a/apps/locale/ja/LC_MESSAGES/django.po +++ b/apps/locale/ja/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-08-17 10:41+0800\n" +"POT-Creation-Date: 2023-08-17 15:30+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -45,7 +45,7 @@ msgid "Access key" msgstr "アクセスキー" #: accounts/const/account.py:9 assets/models/_user.py:48 -#: authentication/models/sso_token.py:14 settings/serializers/feature.py:52 +#: authentication/models/sso_token.py:14 settings/serializers/feature.py:50 msgid "Token" msgstr "トークン" @@ -192,7 +192,7 @@ msgstr "作成のみ" msgid "Database" msgstr "データベース" -#: accounts/const/vault.py:9 +#: accounts/const/vault.py:9 settings/serializers/feature.py:41 msgid "HCP Vault" msgstr "HashiCorp Vault" @@ -213,7 +213,7 @@ msgstr "HashiCorp Vault" #: terminal/serializers/session.py:26 #: terminal/templates/terminal/_msg_command_warning.html:4 #: terminal/templates/terminal/_msg_session_sharing.html:4 -#: tickets/models/ticket/apply_asset.py:16 xpack/plugins/cloud/models.py:212 +#: tickets/models/ticket/apply_asset.py:16 xpack/plugins/cloud/models.py:253 msgid "Asset" msgstr "資産" @@ -248,7 +248,7 @@ msgstr "ソース ID" #: terminal/backends/command/models.py:18 terminal/models/session/session.py:33 #: terminal/templates/terminal/_msg_command_warning.html:8 #: terminal/templates/terminal/_msg_session_sharing.html:8 -#: tickets/models/ticket/command_confirm.py:13 xpack/plugins/cloud/models.py:85 +#: tickets/models/ticket/command_confirm.py:13 xpack/plugins/cloud/models.py:89 msgid "Account" msgstr "アカウント" @@ -315,7 +315,7 @@ msgid "Trigger mode" msgstr "トリガーモード" #: accounts/models/automations/backup_account.py:105 audits/models.py:194 -#: terminal/models/session/sharing.py:121 xpack/plugins/cloud/models.py:168 +#: terminal/models/session/sharing.py:121 xpack/plugins/cloud/models.py:205 msgid "Reason" msgstr "理由" @@ -514,7 +514,8 @@ msgstr "アカウントの確認" #: terminal/models/component/storage.py:26 terminal/models/component/task.py:13 #: terminal/models/component/terminal.py:84 users/forms/profile.py:33 #: users/models/group.py:13 users/models/user.py:787 -#: xpack/plugins/cloud/models.py:28 +#: xpack/plugins/cloud/models.py:32 xpack/plugins/cloud/models.py:273 +#: xpack/plugins/cloud/serializers/task.py:68 msgid "Name" msgstr "名前" @@ -531,7 +532,7 @@ msgstr "特権アカウント" msgid "Is active" msgstr "アクティブです。" -#: accounts/models/template.py:19 +#: accounts/models/template.py:19 xpack/plugins/cloud/models.py:325 msgid "Account template" msgstr "アカウント テンプレート" @@ -638,8 +639,8 @@ msgstr "カテゴリ" #: assets/serializers/asset/common.py:122 assets/serializers/platform.py:112 #: assets/serializers/platform.py:127 audits/serializers.py:49 #: authentication/serializers/connect_token_secret.py:123 ops/models/job.py:137 -#: perms/serializers/user_permission.py:27 settings/serializers/feature.py:46 -#: terminal/models/applet/applet.py:38 terminal/models/component/storage.py:57 +#: perms/serializers/user_permission.py:27 terminal/models/applet/applet.py:38 +#: 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:226 #: terminal/serializers/storage.py:238 tickets/models/comment.py:26 @@ -770,7 +771,7 @@ msgstr "" #: terminal/models/component/endpoint.py:104 #: terminal/models/session/session.py:46 tickets/models/comment.py:32 #: tickets/models/ticket/general.py:297 users/models/user.py:826 -#: xpack/plugins/cloud/models.py:35 xpack/plugins/cloud/models.py:111 +#: xpack/plugins/cloud/models.py:39 xpack/plugins/cloud/models.py:109 msgid "Comment" msgstr "コメント" @@ -840,7 +841,7 @@ msgstr "資産の口座番号を収集する" msgid "Push accounts to assets" msgstr "アカウントをアセットにプッシュ:" -#: accounts/tasks/vault.py:32 +#: accounts/tasks/vault.py:31 msgid "Sync secret to vault" msgstr "秘密をVaultに同期する" @@ -891,11 +892,13 @@ msgstr "警告" #: acls/models/base.py:37 assets/models/_user.py:51 #: assets/models/cmd_filter.py:76 terminal/models/component/endpoint.py:97 +#: xpack/plugins/cloud/models.py:275 msgid "Priority" msgstr "優先順位" #: acls/models/base.py:38 assets/models/_user.py:51 #: assets/models/cmd_filter.py:76 terminal/models/component/endpoint.py:98 +#: xpack/plugins/cloud/models.py:276 msgid "1-100, the lower the value will be match first" msgstr "1-100、低い値は最初に一致します" @@ -932,11 +935,12 @@ msgid "Command" msgstr "コマンド" #: acls/models/command_acl.py:17 assets/models/cmd_filter.py:59 +#: xpack/plugins/cloud/models.py:291 msgid "Regex" msgstr "正規情報" #: acls/models/command_acl.py:26 assets/models/cmd_filter.py:79 -#: settings/serializers/feature.py:18 xpack/plugins/license/models.py:30 +#: settings/serializers/feature.py:17 xpack/plugins/license/models.py:30 msgid "Content" msgstr "コンテンツ" @@ -1028,7 +1032,7 @@ msgid "None of the reviewers belong to Organization `{}`" msgstr "いずれのレビューアも組織 '{}' に属していません" #: acls/serializers/rules/rules.py:20 -#: xpack/plugins/cloud/serializers/task.py:22 +#: xpack/plugins/cloud/serializers/task.py:133 msgid "IP address invalid: `{}`" msgstr "IPアドレスが無効: '{}'" @@ -1056,7 +1060,7 @@ msgstr "期間" msgid "Applications" msgstr "アプリケーション" -#: applications/models.py:16 xpack/plugins/cloud/models.py:33 +#: applications/models.py:16 xpack/plugins/cloud/models.py:37 #: xpack/plugins/cloud/serializers/account.py:63 msgid "Attrs" msgstr "ツールバーの" @@ -1165,7 +1169,7 @@ msgstr "脚本" #: assets/const/category.py:10 assets/models/asset/host.py:8 #: settings/serializers/auth/radius.py:16 settings/serializers/auth/sms.py:67 -#: settings/serializers/feature.py:49 terminal/models/component/endpoint.py:13 +#: settings/serializers/feature.py:47 terminal/models/component/endpoint.py:13 #: terminal/serializers/applet.py:17 #: xpack/plugins/cloud/serializers/account_attrs.py:72 msgid "Host" @@ -1454,14 +1458,13 @@ msgstr "アドレス" #: assets/models/asset/common.py:151 assets/models/platform.py:119 #: authentication/serializers/connect_token_secret.py:115 -#: perms/serializers/user_permission.py:24 -#: xpack/plugins/cloud/serializers/account_attrs.py:196 +#: perms/serializers/user_permission.py:24 xpack/plugins/cloud/models.py:321 msgid "Platform" msgstr "プラットフォーム" #: assets/models/asset/common.py:153 assets/models/domain.py:21 #: authentication/serializers/connect_token_secret.py:133 -#: perms/serializers/user_permission.py:29 +#: perms/serializers/user_permission.py:29 xpack/plugins/cloud/models.py:323 msgid "Domain" msgstr "ドメイン" @@ -1537,8 +1540,8 @@ msgstr "アセットの自動化タスク" #: terminal/models/component/status.py:30 terminal/serializers/applet.py:18 #: terminal/serializers/applet_host.py:115 tickets/models/ticket/general.py:283 #: tickets/serializers/super_ticket.py:13 -#: tickets/serializers/ticket/ticket.py:20 xpack/plugins/cloud/models.py:164 -#: xpack/plugins/cloud/models.py:216 +#: tickets/serializers/ticket/ticket.py:20 xpack/plugins/cloud/models.py:201 +#: xpack/plugins/cloud/models.py:257 msgid "Status" msgstr "ステータス" @@ -1602,7 +1605,7 @@ msgstr "資産グループ" #: assets/models/group.py:31 assets/models/platform.py:19 #: assets/serializers/platform.py:113 -#: xpack/plugins/cloud/providers/nutanix.py:32 +#: xpack/plugins/cloud/providers/nutanix.py:30 msgid "Default" msgstr "デフォルト" @@ -1652,7 +1655,7 @@ msgid "Parent key" msgstr "親キー" #: assets/models/node.py:558 perms/serializers/permission.py:35 -#: tickets/models/ticket/apply_asset.py:14 xpack/plugins/cloud/models.py:96 +#: tickets/models/ticket/apply_asset.py:14 xpack/plugins/cloud/models.py:322 msgid "Node" msgstr "ノード" @@ -1793,7 +1796,8 @@ msgstr "" #: assets/serializers/asset/common.py:124 assets/serializers/platform.py:129 #: authentication/serializers/connect_token_secret.py:29 #: authentication/serializers/connect_token_secret.py:72 -#: perms/serializers/user_permission.py:25 xpack/plugins/cloud/models.py:99 +#: perms/serializers/user_permission.py:25 xpack/plugins/cloud/models.py:324 +#: xpack/plugins/cloud/serializers/task.py:31 msgid "Protocols" msgstr "プロトコル" @@ -3818,7 +3822,7 @@ msgid "Date last run" msgstr "最終実行日" #: ops/models/base.py:51 ops/models/job.py:224 -#: xpack/plugins/cloud/models.py:162 +#: xpack/plugins/cloud/models.py:199 msgid "Result" msgstr "結果" @@ -4366,7 +4370,7 @@ msgstr "リモートアプリケーション" msgid "Ticket comment" msgstr "チケットコメント" -#: rbac/tree.py:124 settings/serializers/feature.py:64 +#: rbac/tree.py:124 settings/serializers/feature.py:58 #: tickets/models/ticket/general.py:307 msgid "Ticket" msgstr "チケット" @@ -4469,10 +4473,8 @@ msgid "Can change other setting" msgstr "他の設定を変えることができます" #: settings/serializers/auth/base.py:12 -#, fuzzy -#| msgid "MFA Auth" msgid "LDAP Auth" -msgstr "MFA マルチファクタ認証" +msgstr "LDAP 認証" #: settings/serializers/auth/base.py:13 msgid "CAS Auth" @@ -4487,10 +4489,8 @@ msgid "SAML2 Auth" msgstr "SAML2 認証" #: settings/serializers/auth/base.py:16 -#, fuzzy -#| msgid "Enable OAuth2 Auth" msgid "OAuth2 Auth" -msgstr "OAuth2認証の有効化" +msgstr "OAuth2 認証" #: settings/serializers/auth/base.py:17 msgid "RADIUS Auth" @@ -4977,71 +4977,67 @@ msgstr "" msgid "Activity log keep days (day)" msgstr "活動ログは日数を保持します(天)" -#: settings/serializers/feature.py:17 +#: settings/serializers/feature.py:16 msgid "Subject" msgstr "件名" -#: settings/serializers/feature.py:21 +#: settings/serializers/feature.py:20 msgid "More url" msgstr "もっとURL" -#: settings/serializers/feature.py:35 settings/serializers/feature.py:38 +#: settings/serializers/feature.py:34 settings/serializers/feature.py:37 msgid "Announcement" msgstr "発表" -#: settings/serializers/feature.py:37 +#: settings/serializers/feature.py:36 msgid "Enable announcement" msgstr "アナウンスの有効化" -#: settings/serializers/feature.py:42 -#, fuzzy -#| msgid "HCP Vault" -msgid "Vault" -msgstr "HashiCorp Vault" +#: settings/serializers/feature.py:44 +msgid "Enable Vault" +msgstr "有効化 Vault" -#: settings/serializers/feature.py:55 +#: settings/serializers/feature.py:53 msgid "Mount Point" -msgstr "" +msgstr "マウントポイント" -#: settings/serializers/feature.py:66 +#: settings/serializers/feature.py:60 msgid "Enable tickets" msgstr "チケットを有効にする" -#: settings/serializers/feature.py:69 +#: settings/serializers/feature.py:63 msgid "Ticket authorize default time" msgstr "デフォルト製造オーダ承認時間" -#: settings/serializers/feature.py:72 +#: settings/serializers/feature.py:66 msgid "day" msgstr "日" -#: settings/serializers/feature.py:72 +#: settings/serializers/feature.py:66 msgid "hour" msgstr "時" -#: settings/serializers/feature.py:73 +#: settings/serializers/feature.py:67 msgid "Ticket authorize default time unit" msgstr "デフォルト製造オーダ承認時間単位" -#: settings/serializers/feature.py:78 -#, fuzzy -#| msgid "Signature" +#: settings/serializers/feature.py:72 msgid "Feature" -msgstr "署名" +msgstr "機能" -#: settings/serializers/feature.py:81 +#: settings/serializers/feature.py:75 msgid "Operation center" msgstr "職業センター" -#: settings/serializers/feature.py:82 +#: settings/serializers/feature.py:76 msgid "Allow user run batch command or not using ansible" msgstr "ユーザー実行バッチコマンドを許可するか、ansibleを使用しない" -#: settings/serializers/feature.py:86 +#: settings/serializers/feature.py:80 msgid "Operation center command blacklist" msgstr "オペレーション センター コマンド ブラックリスト" -#: settings/serializers/feature.py:87 +#: settings/serializers/feature.py:81 msgid "Commands that are not allowed execute." msgstr "実行が許可されていないコマンド" @@ -5420,6 +5416,7 @@ msgid "Remember manual auth" msgstr "手動入力パスワードの保存" #: settings/serializers/security.py:207 +#: terminal/templates/terminal/_msg_session_sharing.html:10 msgid "Session share" msgstr "セッション共有" @@ -6529,7 +6526,7 @@ msgstr "アクセスキー" msgid "Access key secret" msgstr "アクセスキーシークレット" -#: terminal/serializers/storage.py:67 xpack/plugins/cloud/models.py:209 +#: terminal/serializers/storage.py:67 xpack/plugins/cloud/models.py:250 msgid "Region" msgstr "リージョン" @@ -6613,10 +6610,6 @@ msgstr "チェックコマンドと録画ストレージの接続性" msgid "view" msgstr "表示" -#: terminal/templates/terminal/_msg_session_sharing.html:10 -msgid "Session sharing URL" -msgstr "セッション共有 URL" - #: terminal/utils/db_port_mapper.py:85 msgid "" "No available port is matched. The number of databases may have exceeded the " @@ -7091,7 +7084,7 @@ msgid "Not a valid ssh public key" msgstr "有効なssh公開鍵ではありません" #: users/forms/profile.py:173 users/models/user.py:820 -#: xpack/plugins/cloud/serializers/account_attrs.py:206 +#: xpack/plugins/cloud/serializers/account_attrs.py:203 msgid "Public key" msgstr "公開キー" @@ -7120,7 +7113,7 @@ msgid "OTP secret key" msgstr "OTP 秘密" #: users/models/user.py:817 -#: xpack/plugins/cloud/serializers/account_attrs.py:209 +#: xpack/plugins/cloud/serializers/account_attrs.py:206 msgid "Private key" msgstr "ssh秘密鍵" @@ -7559,11 +7552,11 @@ msgstr "パスワードの成功をリセットし、ログインページに戻 msgid "XPACK" msgstr "XPack" -#: xpack/plugins/cloud/api.py:38 +#: xpack/plugins/cloud/api.py:56 msgid "Test connection successful" msgstr "テスト接続成功" -#: xpack/plugins/cloud/api.py:40 +#: xpack/plugins/cloud/api.py:58 msgid "Test connection failed: {}" msgstr "テスト接続に失敗しました: {}" @@ -7651,7 +7644,7 @@ msgstr "プライベートIP" msgid "Public IP" msgstr "パブリックIP" -#: xpack/plugins/cloud/const.py:38 +#: xpack/plugins/cloud/const.py:38 xpack/plugins/cloud/models.py:295 msgid "Instance name" msgstr "インスタンス名" @@ -7679,78 +7672,158 @@ msgstr "同期済み" msgid "Released" msgstr "リリース済み" +#: xpack/plugins/cloud/manager.py:53 +msgid "Account unavailable" +msgstr "利用できないアカウント" + #: xpack/plugins/cloud/meta.py:9 msgid "Cloud center" msgstr "クラウドセンター" -#: xpack/plugins/cloud/models.py:30 +#: xpack/plugins/cloud/models.py:34 msgid "Provider" msgstr "プロバイダー" -#: xpack/plugins/cloud/models.py:34 +#: xpack/plugins/cloud/models.py:38 msgid "Validity" msgstr "有効性" -#: xpack/plugins/cloud/models.py:39 +#: xpack/plugins/cloud/models.py:43 msgid "Cloud account" msgstr "クラウドアカウント" -#: xpack/plugins/cloud/models.py:41 +#: xpack/plugins/cloud/models.py:45 msgid "Test cloud account" msgstr "クラウドアカウントのテスト" -#: xpack/plugins/cloud/models.py:88 xpack/plugins/cloud/serializers/task.py:36 +#: xpack/plugins/cloud/models.py:92 xpack/plugins/cloud/serializers/task.py:147 msgid "Regions" msgstr "リージョン" -#: xpack/plugins/cloud/models.py:91 +#: xpack/plugins/cloud/models.py:95 msgid "Hostname strategy" msgstr "ホスト名戦略" -#: xpack/plugins/cloud/models.py:102 xpack/plugins/cloud/serializers/task.py:39 +#: xpack/plugins/cloud/models.py:100 +#: xpack/plugins/cloud/serializers/task.py:150 msgid "IP network segment group" msgstr "IPネットワークセグメントグループ" -#: xpack/plugins/cloud/models.py:105 xpack/plugins/cloud/serializers/task.py:44 +#: xpack/plugins/cloud/models.py:103 +#: xpack/plugins/cloud/serializers/task.py:155 msgid "Sync IP type" msgstr "同期IPタイプ" -#: xpack/plugins/cloud/models.py:108 xpack/plugins/cloud/serializers/task.py:61 +#: xpack/plugins/cloud/models.py:106 +#: xpack/plugins/cloud/serializers/task.py:173 msgid "Always update" msgstr "常に更新" -#: xpack/plugins/cloud/models.py:114 +#: xpack/plugins/cloud/models.py:112 msgid "Date last sync" msgstr "最終同期日" -#: xpack/plugins/cloud/models.py:119 xpack/plugins/cloud/models.py:160 +#: xpack/plugins/cloud/models.py:115 xpack/plugins/cloud/models.py:313 +#: xpack/plugins/cloud/models.py:337 +msgid "Strategy" +msgstr "戦略" + +#: xpack/plugins/cloud/models.py:120 xpack/plugins/cloud/models.py:197 msgid "Sync instance task" msgstr "インスタンスの同期タスク" -#: xpack/plugins/cloud/models.py:171 xpack/plugins/cloud/models.py:219 +#: xpack/plugins/cloud/models.py:208 xpack/plugins/cloud/models.py:260 msgid "Date sync" msgstr "日付の同期" -#: xpack/plugins/cloud/models.py:175 +#: xpack/plugins/cloud/models.py:212 +msgid "Sync instance snapshot" +msgstr "インスタンススナップショットの同期" + +#: xpack/plugins/cloud/models.py:216 msgid "Sync instance task execution" msgstr "インスタンスタスクの同期実行" -#: xpack/plugins/cloud/models.py:199 +#: xpack/plugins/cloud/models.py:240 msgid "Sync task" msgstr "同期タスク" -#: xpack/plugins/cloud/models.py:203 +#: xpack/plugins/cloud/models.py:244 msgid "Sync instance task history" msgstr "インスタンスタスク履歴の同期" -#: xpack/plugins/cloud/models.py:206 +#: xpack/plugins/cloud/models.py:247 msgid "Instance" msgstr "インスタンス" -#: xpack/plugins/cloud/models.py:223 +#: xpack/plugins/cloud/models.py:264 msgid "Sync instance detail" msgstr "同期インスタンスの詳細" +#: xpack/plugins/cloud/models.py:281 +msgid "Task strategy" +msgstr "ミッション戦略です" + +#: xpack/plugins/cloud/models.py:285 +msgid "Exact" +msgstr "" + +#: xpack/plugins/cloud/models.py:286 +msgid "Not" +msgstr "否" + +#: xpack/plugins/cloud/models.py:287 +msgid "In" +msgstr "イン" + +#: xpack/plugins/cloud/models.py:288 +msgid "Contains" +msgstr "含む" + +#: xpack/plugins/cloud/models.py:289 +msgid "Startswith" +msgstr "始まる" + +#: xpack/plugins/cloud/models.py:290 +msgid "Endswith" +msgstr "終わる" + +#: xpack/plugins/cloud/models.py:296 +msgid "Instance platform" +msgstr "インスタンス名" + +#: xpack/plugins/cloud/models.py:297 +msgid "Instance address" +msgstr "インスタンスアドレス" + +#: xpack/plugins/cloud/models.py:304 +msgid "Rule attr" +msgstr "ルール属性" + +#: xpack/plugins/cloud/models.py:308 +msgid "Rule match" +msgstr "ルール一致" + +#: xpack/plugins/cloud/models.py:310 +msgid "Rule value" +msgstr "ルール値" + +#: xpack/plugins/cloud/models.py:317 +msgid "Strategy rule" +msgstr "戦略ルール" + +#: xpack/plugins/cloud/models.py:332 +msgid "Action attr" +msgstr "アクション属性" + +#: xpack/plugins/cloud/models.py:334 +msgid "Action value" +msgstr "アクション値" + +#: xpack/plugins/cloud/models.py:341 +msgid "Strategy action" +msgstr "戦略アクション" + #: xpack/plugins/cloud/providers/aws_international.py:18 msgid "China (Beijing)" msgstr "中国 (北京)" @@ -7859,7 +7932,7 @@ msgid "CN East-Suzhou" msgstr "華東-蘇州" #: xpack/plugins/cloud/providers/baiducloud.py:57 -#: xpack/plugins/cloud/providers/huaweicloud.py:50 +#: xpack/plugins/cloud/providers/huaweicloud.py:49 msgid "CN-Hong Kong" msgstr "中国-香港" @@ -7877,68 +7950,66 @@ msgid "CN East-Shanghai" msgstr "華東-上海" #: xpack/plugins/cloud/providers/baiducloud.py:61 -#: xpack/plugins/cloud/providers/huaweicloud.py:49 +#: xpack/plugins/cloud/providers/huaweicloud.py:51 msgid "AP-Singapore" msgstr "アジア太平洋-シンガポール" -#: xpack/plugins/cloud/providers/huaweicloud.py:37 -msgid "AF-Johannesburg" -msgstr "アフリカ-ヨハネスブルク" - -#: xpack/plugins/cloud/providers/huaweicloud.py:38 -msgid "CN North-Beijing4" -msgstr "華北-北京4" - #: xpack/plugins/cloud/providers/huaweicloud.py:39 msgid "CN North-Beijing1" msgstr "華北-北京1" #: xpack/plugins/cloud/providers/huaweicloud.py:40 -msgid "CN East-Shanghai2" -msgstr "華東-上海2" +msgid "CN North-Beijing4" +msgstr "華北-北京4" #: xpack/plugins/cloud/providers/huaweicloud.py:41 -msgid "CN East-Shanghai1" -msgstr "華東-上海1" - -#: xpack/plugins/cloud/providers/huaweicloud.py:43 -msgid "LA-Mexico City1" -msgstr "LA-メキシコCity1" - -#: xpack/plugins/cloud/providers/huaweicloud.py:44 -msgid "LA-Santiago" -msgstr "ラテンアメリカ-サンディエゴ" - -#: xpack/plugins/cloud/providers/huaweicloud.py:45 -msgid "LA-Sao Paulo1" -msgstr "ラミー・サンパウロ1" - -#: xpack/plugins/cloud/providers/huaweicloud.py:46 -msgid "EU-Paris" -msgstr "" - -#: xpack/plugins/cloud/providers/huaweicloud.py:47 -msgid "CN Southwest-Guiyang1" -msgstr "南西-貴陽1" - -#: xpack/plugins/cloud/providers/huaweicloud.py:48 -msgid "AP-Bangkok" -msgstr "アジア太平洋-バンコク" - -#: xpack/plugins/cloud/providers/huaweicloud.py:52 -#, fuzzy -#| msgid "CN North-Baoding" -msgid "CN Northeast-Dalian" -msgstr "華北-保定" - -#: xpack/plugins/cloud/providers/huaweicloud.py:53 msgid "CN North-Ulanqab1" msgstr "華北-ウランチャブ一" -#: xpack/plugins/cloud/providers/huaweicloud.py:54 +#: xpack/plugins/cloud/providers/huaweicloud.py:43 +msgid "CN South-Shenzhen" +msgstr "華南-広州" + +#: xpack/plugins/cloud/providers/huaweicloud.py:44 msgid "CN South-Guangzhou-InvitationOnly" msgstr "華南-広州-友好ユーザー環境" +#: xpack/plugins/cloud/providers/huaweicloud.py:45 +msgid "CN East-Shanghai2" +msgstr "華東-上海2" + +#: xpack/plugins/cloud/providers/huaweicloud.py:46 +msgid "CN East-Shanghai1" +msgstr "華東-上海1" + +#: xpack/plugins/cloud/providers/huaweicloud.py:48 +msgid "CN Southwest-Guiyang1" +msgstr "南西-貴陽1" + +#: xpack/plugins/cloud/providers/huaweicloud.py:50 +msgid "AP-Bangkok" +msgstr "アジア太平洋-バンコク" + +#: xpack/plugins/cloud/providers/huaweicloud.py:53 +msgid "AF-Johannesburg" +msgstr "アフリカ-ヨハネスブルク" + +#: xpack/plugins/cloud/providers/huaweicloud.py:54 +msgid "LA-Mexico City1" +msgstr "LA-メキシコCity1" + +#: xpack/plugins/cloud/providers/huaweicloud.py:55 +msgid "LA-Santiago" +msgstr "ラテンアメリカ-サンディエゴ" + +#: xpack/plugins/cloud/providers/huaweicloud.py:56 +msgid "LA-Sao Paulo1" +msgstr "ラミー・サンパウロ1" + +#: xpack/plugins/cloud/providers/huaweicloud.py:58 +msgid "TR-Istanbul" +msgstr "" + #: xpack/plugins/cloud/providers/jdcloud.py:126 msgid "CN East-Suqian" msgstr "華東-宿遷" @@ -7967,7 +8038,7 @@ msgstr "サブスクリプションID" #: xpack/plugins/cloud/serializers/account_attrs.py:103 #: xpack/plugins/cloud/serializers/account_attrs.py:119 #: xpack/plugins/cloud/serializers/account_attrs.py:149 -#: xpack/plugins/cloud/serializers/account_attrs.py:202 +#: xpack/plugins/cloud/serializers/account_attrs.py:199 msgid "API Endpoint" msgstr "APIエンドポイント" @@ -8033,11 +8104,11 @@ msgstr "テストポート" msgid "Test timeout" msgstr "テストタイムアウト" -#: xpack/plugins/cloud/serializers/account_attrs.py:212 +#: xpack/plugins/cloud/serializers/account_attrs.py:209 msgid "Project" msgstr "project" -#: xpack/plugins/cloud/serializers/task.py:28 +#: xpack/plugins/cloud/serializers/task.py:139 msgid "" "Only instances matching the IP range will be synced.
If the instance " "contains multiple IP addresses, the first IP address that matches will be " @@ -8051,11 +8122,11 @@ msgstr "" "ドレスをランダムに一致させることを意味します。
例: " "192.168.1.0/24,10.1.1.1-10.1.1.20。" -#: xpack/plugins/cloud/serializers/task.py:34 +#: xpack/plugins/cloud/serializers/task.py:145 msgid "History count" msgstr "実行回数" -#: xpack/plugins/cloud/serializers/task.py:35 +#: xpack/plugins/cloud/serializers/task.py:146 msgid "Instance count" msgstr "インスタンス数" @@ -8067,10 +8138,6 @@ msgstr "同期インスタンス タスクを実行する" msgid "Period clean sync instance task execution" msgstr "同期インスタンス タスクの実行記録を定期的にクリアする" -#: xpack/plugins/cloud/utils.py:68 -msgid "Account unavailable" -msgstr "利用できないアカウント" - #: xpack/plugins/interface/api.py:52 msgid "Restore default successfully." msgstr "デフォルトの復元に成功しました。" @@ -8134,64 +8201,3 @@ msgstr "究極のエディション" #: xpack/plugins/license/models.py:86 msgid "Community edition" msgstr "コミュニティ版" - -#~ msgid "" -#~ "The forgot password url on login page, If you use ldap or cas external " -#~ "authentication, you can set it" -#~ msgstr "" -#~ "ログインページでパスワードのURLを忘れてしまいました。ldapまたはcasの外部認" -#~ "証を使用している場合は、設定できます。" - -#~ msgid "Strategy" -#~ msgstr "戦略" - -#~ msgid "Sync instance snapshot" -#~ msgstr "インスタンススナップショットの同期" - -#~ msgid "Task strategy" -#~ msgstr "ミッション戦略です" - -#~ msgid "Not" -#~ msgstr "否" - -#~ msgid "In" -#~ msgstr "イン" - -#~ msgid "Contains" -#~ msgstr "含む" - -#~ msgid "Startswith" -#~ msgstr "始まる" - -#~ msgid "Endswith" -#~ msgstr "終わる" - -#~ msgid "Instance platform" -#~ msgstr "インスタンス名" - -#~ msgid "Instance address" -#~ msgstr "インスタンスアドレス" - -#~ msgid "Rule attr" -#~ msgstr "ルール属性" - -#~ msgid "Rule match" -#~ msgstr "ルール一致" - -#~ msgid "Rule value" -#~ msgstr "ルール値" - -#~ msgid "Strategy rule" -#~ msgstr "戦略ルール" - -#~ msgid "Action attr" -#~ msgstr "アクション属性" - -#~ msgid "Action value" -#~ msgstr "アクション値" - -#~ msgid "Strategy action" -#~ msgstr "戦略アクション" - -#~ msgid "CN South-Shenzhen" -#~ msgstr "華南-広州" diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po index 1e5a836b4..5f14e8671 100644 --- a/apps/locale/zh/LC_MESSAGES/django.po +++ b/apps/locale/zh/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: JumpServer 0.3.3\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-08-17 10:41+0800\n" +"POT-Creation-Date: 2023-08-17 15:30+0800\n" "PO-Revision-Date: 2021-05-20 10:54+0800\n" "Last-Translator: ibuler \n" "Language-Team: JumpServer team\n" @@ -44,7 +44,7 @@ msgid "Access key" msgstr "Access key" #: accounts/const/account.py:9 assets/models/_user.py:48 -#: authentication/models/sso_token.py:14 settings/serializers/feature.py:52 +#: authentication/models/sso_token.py:14 settings/serializers/feature.py:50 msgid "Token" msgstr "Token" @@ -191,7 +191,7 @@ msgstr "仅创建" msgid "Database" msgstr "数据库" -#: accounts/const/vault.py:9 +#: accounts/const/vault.py:9 settings/serializers/feature.py:41 msgid "HCP Vault" msgstr "HashiCorp Vault" @@ -212,7 +212,7 @@ msgstr "HashiCorp Vault" #: terminal/serializers/session.py:26 #: terminal/templates/terminal/_msg_command_warning.html:4 #: terminal/templates/terminal/_msg_session_sharing.html:4 -#: tickets/models/ticket/apply_asset.py:16 xpack/plugins/cloud/models.py:212 +#: tickets/models/ticket/apply_asset.py:16 xpack/plugins/cloud/models.py:253 msgid "Asset" msgstr "资产" @@ -247,7 +247,7 @@ msgstr "来源 ID" #: terminal/backends/command/models.py:18 terminal/models/session/session.py:33 #: terminal/templates/terminal/_msg_command_warning.html:8 #: terminal/templates/terminal/_msg_session_sharing.html:8 -#: tickets/models/ticket/command_confirm.py:13 xpack/plugins/cloud/models.py:85 +#: tickets/models/ticket/command_confirm.py:13 xpack/plugins/cloud/models.py:89 msgid "Account" msgstr "账号" @@ -314,7 +314,7 @@ msgid "Trigger mode" msgstr "触发模式" #: accounts/models/automations/backup_account.py:105 audits/models.py:194 -#: terminal/models/session/sharing.py:121 xpack/plugins/cloud/models.py:168 +#: terminal/models/session/sharing.py:121 xpack/plugins/cloud/models.py:205 msgid "Reason" msgstr "原因" @@ -513,7 +513,8 @@ msgstr "账号验证" #: terminal/models/component/storage.py:26 terminal/models/component/task.py:13 #: terminal/models/component/terminal.py:84 users/forms/profile.py:33 #: users/models/group.py:13 users/models/user.py:787 -#: xpack/plugins/cloud/models.py:28 +#: xpack/plugins/cloud/models.py:32 xpack/plugins/cloud/models.py:273 +#: xpack/plugins/cloud/serializers/task.py:68 msgid "Name" msgstr "名称" @@ -530,7 +531,7 @@ msgstr "特权账号" msgid "Is active" msgstr "激活" -#: accounts/models/template.py:19 +#: accounts/models/template.py:19 xpack/plugins/cloud/models.py:325 msgid "Account template" msgstr "账号模版" @@ -638,8 +639,8 @@ msgstr "类别" #: assets/serializers/asset/common.py:122 assets/serializers/platform.py:112 #: assets/serializers/platform.py:127 audits/serializers.py:49 #: authentication/serializers/connect_token_secret.py:123 ops/models/job.py:137 -#: perms/serializers/user_permission.py:27 settings/serializers/feature.py:46 -#: terminal/models/applet/applet.py:38 terminal/models/component/storage.py:57 +#: perms/serializers/user_permission.py:27 terminal/models/applet/applet.py:38 +#: 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:226 #: terminal/serializers/storage.py:238 tickets/models/comment.py:26 @@ -770,7 +771,7 @@ msgstr "" #: terminal/models/component/endpoint.py:104 #: terminal/models/session/session.py:46 tickets/models/comment.py:32 #: tickets/models/ticket/general.py:297 users/models/user.py:826 -#: xpack/plugins/cloud/models.py:35 xpack/plugins/cloud/models.py:111 +#: xpack/plugins/cloud/models.py:39 xpack/plugins/cloud/models.py:109 msgid "Comment" msgstr "备注" @@ -840,7 +841,7 @@ msgstr "收集资产上的账号" msgid "Push accounts to assets" msgstr "推送账号到资产" -#: accounts/tasks/vault.py:32 +#: accounts/tasks/vault.py:31 msgid "Sync secret to vault" msgstr "同步密文到 vault" @@ -891,11 +892,13 @@ msgstr "告警" #: acls/models/base.py:37 assets/models/_user.py:51 #: assets/models/cmd_filter.py:76 terminal/models/component/endpoint.py:97 +#: xpack/plugins/cloud/models.py:275 msgid "Priority" msgstr "优先级" #: acls/models/base.py:38 assets/models/_user.py:51 #: assets/models/cmd_filter.py:76 terminal/models/component/endpoint.py:98 +#: xpack/plugins/cloud/models.py:276 msgid "1-100, the lower the value will be match first" msgstr "优先级可选范围为 1-100 (数值越小越优先)" @@ -932,11 +935,12 @@ msgid "Command" msgstr "命令" #: acls/models/command_acl.py:17 assets/models/cmd_filter.py:59 +#: xpack/plugins/cloud/models.py:291 msgid "Regex" msgstr "正则表达式" #: acls/models/command_acl.py:26 assets/models/cmd_filter.py:79 -#: settings/serializers/feature.py:18 xpack/plugins/license/models.py:30 +#: settings/serializers/feature.py:17 xpack/plugins/license/models.py:30 msgid "Content" msgstr "内容" @@ -1027,7 +1031,7 @@ msgid "None of the reviewers belong to Organization `{}`" msgstr "所有复核人都不属于组织 `{}`" #: acls/serializers/rules/rules.py:20 -#: xpack/plugins/cloud/serializers/task.py:22 +#: xpack/plugins/cloud/serializers/task.py:133 msgid "IP address invalid: `{}`" msgstr "IP 地址无效: `{}`" @@ -1055,7 +1059,7 @@ msgstr "时段" msgid "Applications" msgstr "应用管理" -#: applications/models.py:16 xpack/plugins/cloud/models.py:33 +#: applications/models.py:16 xpack/plugins/cloud/models.py:37 #: xpack/plugins/cloud/serializers/account.py:63 msgid "Attrs" msgstr "属性" @@ -1162,7 +1166,7 @@ msgstr "脚本" #: assets/const/category.py:10 assets/models/asset/host.py:8 #: settings/serializers/auth/radius.py:16 settings/serializers/auth/sms.py:67 -#: settings/serializers/feature.py:49 terminal/models/component/endpoint.py:13 +#: settings/serializers/feature.py:47 terminal/models/component/endpoint.py:13 #: terminal/serializers/applet.py:17 #: xpack/plugins/cloud/serializers/account_attrs.py:72 msgid "Host" @@ -1452,14 +1456,13 @@ msgstr "地址" #: assets/models/asset/common.py:151 assets/models/platform.py:119 #: authentication/serializers/connect_token_secret.py:115 -#: perms/serializers/user_permission.py:24 -#: xpack/plugins/cloud/serializers/account_attrs.py:196 +#: perms/serializers/user_permission.py:24 xpack/plugins/cloud/models.py:321 msgid "Platform" msgstr "系统平台" #: assets/models/asset/common.py:153 assets/models/domain.py:21 #: authentication/serializers/connect_token_secret.py:133 -#: perms/serializers/user_permission.py:29 +#: perms/serializers/user_permission.py:29 xpack/plugins/cloud/models.py:323 msgid "Domain" msgstr "网域" @@ -1535,8 +1538,8 @@ msgstr "资产自动化任务" #: terminal/models/component/status.py:30 terminal/serializers/applet.py:18 #: terminal/serializers/applet_host.py:115 tickets/models/ticket/general.py:283 #: tickets/serializers/super_ticket.py:13 -#: tickets/serializers/ticket/ticket.py:20 xpack/plugins/cloud/models.py:164 -#: xpack/plugins/cloud/models.py:216 +#: tickets/serializers/ticket/ticket.py:20 xpack/plugins/cloud/models.py:201 +#: xpack/plugins/cloud/models.py:257 msgid "Status" msgstr "状态" @@ -1600,7 +1603,7 @@ msgstr "资产组" #: assets/models/group.py:31 assets/models/platform.py:19 #: assets/serializers/platform.py:113 -#: xpack/plugins/cloud/providers/nutanix.py:32 +#: xpack/plugins/cloud/providers/nutanix.py:30 msgid "Default" msgstr "默认" @@ -1650,7 +1653,7 @@ msgid "Parent key" msgstr "ssh私钥" #: assets/models/node.py:558 perms/serializers/permission.py:35 -#: tickets/models/ticket/apply_asset.py:14 xpack/plugins/cloud/models.py:96 +#: tickets/models/ticket/apply_asset.py:14 xpack/plugins/cloud/models.py:322 msgid "Node" msgstr "节点" @@ -1789,7 +1792,8 @@ msgstr "资产中批量更新平台,不符合平台类型跳过的资产" #: assets/serializers/asset/common.py:124 assets/serializers/platform.py:129 #: authentication/serializers/connect_token_secret.py:29 #: authentication/serializers/connect_token_secret.py:72 -#: perms/serializers/user_permission.py:25 xpack/plugins/cloud/models.py:99 +#: perms/serializers/user_permission.py:25 xpack/plugins/cloud/models.py:324 +#: xpack/plugins/cloud/serializers/task.py:31 msgid "Protocols" msgstr "协议组" @@ -3776,7 +3780,7 @@ msgid "Date last run" msgstr "最后运行日期" #: ops/models/base.py:51 ops/models/job.py:224 -#: xpack/plugins/cloud/models.py:162 +#: xpack/plugins/cloud/models.py:199 msgid "Result" msgstr "结果" @@ -4322,7 +4326,7 @@ msgstr "远程应用" msgid "Ticket comment" msgstr "工单评论" -#: rbac/tree.py:124 settings/serializers/feature.py:64 +#: rbac/tree.py:124 settings/serializers/feature.py:58 #: tickets/models/ticket/general.py:307 msgid "Ticket" msgstr "工单管理" @@ -4425,10 +4429,8 @@ msgid "Can change other setting" msgstr "其它设置" #: settings/serializers/auth/base.py:12 -#, fuzzy -#| msgid "MFA Auth" msgid "LDAP Auth" -msgstr "MFA 多因子认证" +msgstr "LDAP 认证" #: settings/serializers/auth/base.py:13 msgid "CAS Auth" @@ -4443,10 +4445,8 @@ msgid "SAML2 Auth" msgstr "SAML2 认证" #: settings/serializers/auth/base.py:16 -#, fuzzy -#| msgid "Enable OAuth2 Auth" msgid "OAuth2 Auth" -msgstr "启用 OAuth2 认证" +msgstr "OAuth2 认证" #: settings/serializers/auth/base.py:17 msgid "RADIUS Auth" @@ -4930,71 +4930,67 @@ msgstr "" msgid "Activity log keep days (day)" msgstr "活动记录 (天)" -#: settings/serializers/feature.py:17 +#: settings/serializers/feature.py:16 msgid "Subject" msgstr "主题" -#: settings/serializers/feature.py:21 +#: settings/serializers/feature.py:20 msgid "More url" msgstr "更多信息 URL" -#: settings/serializers/feature.py:35 settings/serializers/feature.py:38 +#: settings/serializers/feature.py:34 settings/serializers/feature.py:37 msgid "Announcement" msgstr "公告" -#: settings/serializers/feature.py:37 +#: settings/serializers/feature.py:36 msgid "Enable announcement" msgstr "启用公告" -#: settings/serializers/feature.py:42 -#, fuzzy -#| msgid "HCP Vault" -msgid "Vault" -msgstr "HashiCorp Vault" +#: settings/serializers/feature.py:44 +msgid "Enable Vault" +msgstr "启用 Vault" -#: settings/serializers/feature.py:55 +#: settings/serializers/feature.py:53 msgid "Mount Point" -msgstr "" +msgstr "挂在点" -#: settings/serializers/feature.py:66 +#: settings/serializers/feature.py:60 msgid "Enable tickets" msgstr "启用工单" -#: settings/serializers/feature.py:69 +#: settings/serializers/feature.py:63 msgid "Ticket authorize default time" msgstr "默认工单授权时间" -#: settings/serializers/feature.py:72 +#: settings/serializers/feature.py:66 msgid "day" msgstr "天" -#: settings/serializers/feature.py:72 +#: settings/serializers/feature.py:66 msgid "hour" msgstr "时" -#: settings/serializers/feature.py:73 +#: settings/serializers/feature.py:67 msgid "Ticket authorize default time unit" msgstr "默认工单授权时间单位" -#: settings/serializers/feature.py:78 -#, fuzzy -#| msgid "Signature" +#: settings/serializers/feature.py:72 msgid "Feature" -msgstr "签名" +msgstr "功能" -#: settings/serializers/feature.py:81 +#: settings/serializers/feature.py:75 msgid "Operation center" msgstr "作业中心" -#: settings/serializers/feature.py:82 +#: settings/serializers/feature.py:76 msgid "Allow user run batch command or not using ansible" msgstr "是否允许用户使用 ansible 执行批量命令" -#: settings/serializers/feature.py:86 +#: settings/serializers/feature.py:80 msgid "Operation center command blacklist" msgstr "作业中心命令黑名单" -#: settings/serializers/feature.py:87 +#: settings/serializers/feature.py:81 msgid "Commands that are not allowed execute." msgstr "不允许执行的命令" @@ -5352,6 +5348,7 @@ msgid "Remember manual auth" msgstr "保存手动输入密码" #: settings/serializers/security.py:207 +#: terminal/templates/terminal/_msg_session_sharing.html:10 msgid "Session share" msgstr "会话分享" @@ -6440,7 +6437,7 @@ msgstr "Access key ID(AK)" msgid "Access key secret" msgstr "Access key secret(SK)" -#: terminal/serializers/storage.py:67 xpack/plugins/cloud/models.py:209 +#: terminal/serializers/storage.py:67 xpack/plugins/cloud/models.py:250 msgid "Region" msgstr "地域" @@ -6524,10 +6521,6 @@ msgstr "检查命令及录像存储可连接性 " msgid "view" msgstr "查看" -#: terminal/templates/terminal/_msg_session_sharing.html:10 -msgid "Session sharing URL" -msgstr "会话分享 URL" - #: terminal/utils/db_port_mapper.py:85 msgid "" "No available port is matched. The number of databases may have exceeded the " @@ -6996,7 +6989,7 @@ msgid "Not a valid ssh public key" msgstr "SSH密钥不合法" #: users/forms/profile.py:173 users/models/user.py:820 -#: xpack/plugins/cloud/serializers/account_attrs.py:206 +#: xpack/plugins/cloud/serializers/account_attrs.py:203 msgid "Public key" msgstr "SSH公钥" @@ -7025,7 +7018,7 @@ msgid "OTP secret key" msgstr "OTP 密钥" #: users/models/user.py:817 -#: xpack/plugins/cloud/serializers/account_attrs.py:209 +#: xpack/plugins/cloud/serializers/account_attrs.py:206 msgid "Private key" msgstr "ssh私钥" @@ -7451,11 +7444,11 @@ msgstr "重置密码成功,返回到登录页面" msgid "XPACK" msgstr "XPack" -#: xpack/plugins/cloud/api.py:38 +#: xpack/plugins/cloud/api.py:56 msgid "Test connection successful" msgstr "测试成功" -#: xpack/plugins/cloud/api.py:40 +#: xpack/plugins/cloud/api.py:58 msgid "Test connection failed: {}" msgstr "测试连接失败:{}" @@ -7543,7 +7536,7 @@ msgstr "私有IP" msgid "Public IP" msgstr "公网IP" -#: xpack/plugins/cloud/const.py:38 +#: xpack/plugins/cloud/const.py:38 xpack/plugins/cloud/models.py:295 msgid "Instance name" msgstr "实例名称" @@ -7571,78 +7564,158 @@ msgstr "已同步" msgid "Released" msgstr "已释放" +#: xpack/plugins/cloud/manager.py:53 +msgid "Account unavailable" +msgstr "账号无效" + #: xpack/plugins/cloud/meta.py:9 msgid "Cloud center" msgstr "云管中心" -#: xpack/plugins/cloud/models.py:30 +#: xpack/plugins/cloud/models.py:34 msgid "Provider" msgstr "云服务商" -#: xpack/plugins/cloud/models.py:34 +#: xpack/plugins/cloud/models.py:38 msgid "Validity" msgstr "有效" -#: xpack/plugins/cloud/models.py:39 +#: xpack/plugins/cloud/models.py:43 msgid "Cloud account" msgstr "云账号" -#: xpack/plugins/cloud/models.py:41 +#: xpack/plugins/cloud/models.py:45 msgid "Test cloud account" msgstr "测试云账号" -#: xpack/plugins/cloud/models.py:88 xpack/plugins/cloud/serializers/task.py:36 +#: xpack/plugins/cloud/models.py:92 xpack/plugins/cloud/serializers/task.py:147 msgid "Regions" msgstr "地域" -#: xpack/plugins/cloud/models.py:91 +#: xpack/plugins/cloud/models.py:95 msgid "Hostname strategy" msgstr "主机名策略" -#: xpack/plugins/cloud/models.py:102 xpack/plugins/cloud/serializers/task.py:39 +#: xpack/plugins/cloud/models.py:100 +#: xpack/plugins/cloud/serializers/task.py:150 msgid "IP network segment group" msgstr "IP网段组" -#: xpack/plugins/cloud/models.py:105 xpack/plugins/cloud/serializers/task.py:44 +#: xpack/plugins/cloud/models.py:103 +#: xpack/plugins/cloud/serializers/task.py:155 msgid "Sync IP type" msgstr "同步IP类型" -#: xpack/plugins/cloud/models.py:108 xpack/plugins/cloud/serializers/task.py:61 +#: xpack/plugins/cloud/models.py:106 +#: xpack/plugins/cloud/serializers/task.py:173 msgid "Always update" msgstr "总是更新" -#: xpack/plugins/cloud/models.py:114 +#: xpack/plugins/cloud/models.py:112 msgid "Date last sync" msgstr "最后同步日期" -#: xpack/plugins/cloud/models.py:119 xpack/plugins/cloud/models.py:160 +#: xpack/plugins/cloud/models.py:115 xpack/plugins/cloud/models.py:313 +#: xpack/plugins/cloud/models.py:337 +msgid "Strategy" +msgstr "策略" + +#: xpack/plugins/cloud/models.py:120 xpack/plugins/cloud/models.py:197 msgid "Sync instance task" msgstr "同步实例任务" -#: xpack/plugins/cloud/models.py:171 xpack/plugins/cloud/models.py:219 +#: xpack/plugins/cloud/models.py:208 xpack/plugins/cloud/models.py:260 msgid "Date sync" msgstr "同步日期" -#: xpack/plugins/cloud/models.py:175 +#: xpack/plugins/cloud/models.py:212 +msgid "Sync instance snapshot" +msgstr "同步实例快照" + +#: xpack/plugins/cloud/models.py:216 msgid "Sync instance task execution" msgstr "同步实例任务执行" -#: xpack/plugins/cloud/models.py:199 +#: xpack/plugins/cloud/models.py:240 msgid "Sync task" msgstr "同步任务" -#: xpack/plugins/cloud/models.py:203 +#: xpack/plugins/cloud/models.py:244 msgid "Sync instance task history" msgstr "同步实例任务历史" -#: xpack/plugins/cloud/models.py:206 +#: xpack/plugins/cloud/models.py:247 msgid "Instance" msgstr "实例" -#: xpack/plugins/cloud/models.py:223 +#: xpack/plugins/cloud/models.py:264 msgid "Sync instance detail" msgstr "同步实例详情" +#: xpack/plugins/cloud/models.py:281 +msgid "Task strategy" +msgstr "任务策略" + +#: xpack/plugins/cloud/models.py:285 +msgid "Exact" +msgstr "" + +#: xpack/plugins/cloud/models.py:286 +msgid "Not" +msgstr "否" + +#: xpack/plugins/cloud/models.py:287 +msgid "In" +msgstr "在..里面" + +#: xpack/plugins/cloud/models.py:288 +msgid "Contains" +msgstr "包含" + +#: xpack/plugins/cloud/models.py:289 +msgid "Startswith" +msgstr "以..开头" + +#: xpack/plugins/cloud/models.py:290 +msgid "Endswith" +msgstr "以..结尾" + +#: xpack/plugins/cloud/models.py:296 +msgid "Instance platform" +msgstr "实例平台" + +#: xpack/plugins/cloud/models.py:297 +msgid "Instance address" +msgstr "实例地址" + +#: xpack/plugins/cloud/models.py:304 +msgid "Rule attr" +msgstr "规则属性" + +#: xpack/plugins/cloud/models.py:308 +msgid "Rule match" +msgstr "规则匹配" + +#: xpack/plugins/cloud/models.py:310 +msgid "Rule value" +msgstr "规则值" + +#: xpack/plugins/cloud/models.py:317 +msgid "Strategy rule" +msgstr "策略规则" + +#: xpack/plugins/cloud/models.py:332 +msgid "Action attr" +msgstr "动作属性" + +#: xpack/plugins/cloud/models.py:334 +msgid "Action value" +msgstr "动作值" + +#: xpack/plugins/cloud/models.py:341 +msgid "Strategy action" +msgstr "策略动作" + #: xpack/plugins/cloud/providers/aws_international.py:18 msgid "China (Beijing)" msgstr "中国 (北京)" @@ -7751,7 +7824,7 @@ msgid "CN East-Suzhou" msgstr "华东-苏州" #: xpack/plugins/cloud/providers/baiducloud.py:57 -#: xpack/plugins/cloud/providers/huaweicloud.py:50 +#: xpack/plugins/cloud/providers/huaweicloud.py:49 msgid "CN-Hong Kong" msgstr "中国-香港" @@ -7769,68 +7842,66 @@ msgid "CN East-Shanghai" msgstr "华东-上海" #: xpack/plugins/cloud/providers/baiducloud.py:61 -#: xpack/plugins/cloud/providers/huaweicloud.py:49 +#: xpack/plugins/cloud/providers/huaweicloud.py:51 msgid "AP-Singapore" msgstr "亚太-新加坡" -#: xpack/plugins/cloud/providers/huaweicloud.py:37 -msgid "AF-Johannesburg" -msgstr "非洲-约翰内斯堡" - -#: xpack/plugins/cloud/providers/huaweicloud.py:38 -msgid "CN North-Beijing4" -msgstr "华北-北京4" - #: xpack/plugins/cloud/providers/huaweicloud.py:39 msgid "CN North-Beijing1" msgstr "华北-北京1" #: xpack/plugins/cloud/providers/huaweicloud.py:40 -msgid "CN East-Shanghai2" -msgstr "华东-上海2" +msgid "CN North-Beijing4" +msgstr "华北-北京4" #: xpack/plugins/cloud/providers/huaweicloud.py:41 -msgid "CN East-Shanghai1" -msgstr "华东-上海1" - -#: xpack/plugins/cloud/providers/huaweicloud.py:43 -msgid "LA-Mexico City1" -msgstr "拉美-墨西哥城一" - -#: xpack/plugins/cloud/providers/huaweicloud.py:44 -msgid "LA-Santiago" -msgstr "拉美-圣地亚哥" - -#: xpack/plugins/cloud/providers/huaweicloud.py:45 -msgid "LA-Sao Paulo1" -msgstr "拉美-圣保罗一" - -#: xpack/plugins/cloud/providers/huaweicloud.py:46 -msgid "EU-Paris" -msgstr "" - -#: xpack/plugins/cloud/providers/huaweicloud.py:47 -msgid "CN Southwest-Guiyang1" -msgstr "西南-贵阳1" - -#: xpack/plugins/cloud/providers/huaweicloud.py:48 -msgid "AP-Bangkok" -msgstr "亚太-曼谷" - -#: xpack/plugins/cloud/providers/huaweicloud.py:52 -#, fuzzy -#| msgid "CN North-Baoding" -msgid "CN Northeast-Dalian" -msgstr "华北-保定" - -#: xpack/plugins/cloud/providers/huaweicloud.py:53 msgid "CN North-Ulanqab1" msgstr "华北-乌兰察布一" -#: xpack/plugins/cloud/providers/huaweicloud.py:54 +#: xpack/plugins/cloud/providers/huaweicloud.py:43 +msgid "CN South-Shenzhen" +msgstr "华南-广州" + +#: xpack/plugins/cloud/providers/huaweicloud.py:44 msgid "CN South-Guangzhou-InvitationOnly" msgstr "华南-广州-友好用户环境" +#: xpack/plugins/cloud/providers/huaweicloud.py:45 +msgid "CN East-Shanghai2" +msgstr "华东-上海2" + +#: xpack/plugins/cloud/providers/huaweicloud.py:46 +msgid "CN East-Shanghai1" +msgstr "华东-上海1" + +#: xpack/plugins/cloud/providers/huaweicloud.py:48 +msgid "CN Southwest-Guiyang1" +msgstr "西南-贵阳1" + +#: xpack/plugins/cloud/providers/huaweicloud.py:50 +msgid "AP-Bangkok" +msgstr "亚太-曼谷" + +#: xpack/plugins/cloud/providers/huaweicloud.py:53 +msgid "AF-Johannesburg" +msgstr "非洲-约翰内斯堡" + +#: xpack/plugins/cloud/providers/huaweicloud.py:54 +msgid "LA-Mexico City1" +msgstr "拉美-墨西哥城一" + +#: xpack/plugins/cloud/providers/huaweicloud.py:55 +msgid "LA-Santiago" +msgstr "拉美-圣地亚哥" + +#: xpack/plugins/cloud/providers/huaweicloud.py:56 +msgid "LA-Sao Paulo1" +msgstr "拉美-圣保罗一" + +#: xpack/plugins/cloud/providers/huaweicloud.py:58 +msgid "TR-Istanbul" +msgstr "" + #: xpack/plugins/cloud/providers/jdcloud.py:126 msgid "CN East-Suqian" msgstr "华东-宿迁" @@ -7859,7 +7930,7 @@ msgstr "订阅 ID" #: xpack/plugins/cloud/serializers/account_attrs.py:103 #: xpack/plugins/cloud/serializers/account_attrs.py:119 #: xpack/plugins/cloud/serializers/account_attrs.py:149 -#: xpack/plugins/cloud/serializers/account_attrs.py:202 +#: xpack/plugins/cloud/serializers/account_attrs.py:199 msgid "API Endpoint" msgstr "API 端点" @@ -7924,11 +7995,11 @@ msgstr "测试端口" msgid "Test timeout" msgstr "测试超时时间" -#: xpack/plugins/cloud/serializers/account_attrs.py:212 +#: xpack/plugins/cloud/serializers/account_attrs.py:209 msgid "Project" msgstr "project" -#: xpack/plugins/cloud/serializers/task.py:28 +#: xpack/plugins/cloud/serializers/task.py:139 msgid "" "Only instances matching the IP range will be synced.
If the instance " "contains multiple IP addresses, the first IP address that matches will be " @@ -7940,11 +8011,11 @@ msgstr "" "到的 IP 地址将被用作创建的资产的 IP。
默认值 * 表示同步所有实例和随机匹配 " "IP 地址。
例如: 192.168.1.0/24,10.1.1.1-10.1.1.20。" -#: xpack/plugins/cloud/serializers/task.py:34 +#: xpack/plugins/cloud/serializers/task.py:145 msgid "History count" msgstr "执行次数" -#: xpack/plugins/cloud/serializers/task.py:35 +#: xpack/plugins/cloud/serializers/task.py:146 msgid "Instance count" msgstr "实例个数" @@ -7956,10 +8027,6 @@ msgstr "执行同步实例任务" msgid "Period clean sync instance task execution" msgstr "定期清除同步实例任务执行记录" -#: xpack/plugins/cloud/utils.py:68 -msgid "Account unavailable" -msgstr "账号无效" - #: xpack/plugins/interface/api.py:52 msgid "Restore default successfully." msgstr "恢复默认成功!" @@ -8023,64 +8090,3 @@ msgstr "旗舰版" #: xpack/plugins/license/models.py:86 msgid "Community edition" msgstr "社区版" - -#~ msgid "" -#~ "The forgot password url on login page, If you use ldap or cas external " -#~ "authentication, you can set it" -#~ msgstr "" -#~ "登录页面忘记密码URL, 如果使用了 LDAP, OPENID 等外部认证系统,可以自定义用" -#~ "户重置密码访问的地址" - -#~ msgid "Strategy" -#~ msgstr "策略" - -#~ msgid "Sync instance snapshot" -#~ msgstr "同步实例快照" - -#~ msgid "Task strategy" -#~ msgstr "任务策略" - -#~ msgid "Not" -#~ msgstr "否" - -#~ msgid "In" -#~ msgstr "在..里面" - -#~ msgid "Contains" -#~ msgstr "包含" - -#~ msgid "Startswith" -#~ msgstr "以..开头" - -#~ msgid "Endswith" -#~ msgstr "以..结尾" - -#~ msgid "Instance platform" -#~ msgstr "实例平台" - -#~ msgid "Instance address" -#~ msgstr "实例地址" - -#~ msgid "Rule attr" -#~ msgstr "规则属性" - -#~ msgid "Rule match" -#~ msgstr "规则匹配" - -#~ msgid "Rule value" -#~ msgstr "规则值" - -#~ msgid "Strategy rule" -#~ msgstr "策略规则" - -#~ msgid "Action attr" -#~ msgstr "动作属性" - -#~ msgid "Action value" -#~ msgstr "动作值" - -#~ msgid "Strategy action" -#~ msgstr "策略动作" - -#~ msgid "CN South-Shenzhen" -#~ msgstr "华南-广州" diff --git a/apps/settings/serializers/feature.py b/apps/settings/serializers/feature.py index 3d11da9d6..f2efe5b03 100644 --- a/apps/settings/serializers/feature.py +++ b/apps/settings/serializers/feature.py @@ -38,7 +38,7 @@ class AnnouncementSettingSerializer(serializers.Serializer): class VaultSettingSerializer(serializers.Serializer): - PREFIX_TITLE = _('Vault') + PREFIX_TITLE = _('HCP Vault') VAULT_ENABLED = serializers.BooleanField( required=False, label=_('Enable Vault'), read_only=True diff --git a/apps/terminal/templates/terminal/_msg_session_sharing.html b/apps/terminal/templates/terminal/_msg_session_sharing.html index d634304e5..e13d5b808 100644 --- a/apps/terminal/templates/terminal/_msg_session_sharing.html +++ b/apps/terminal/templates/terminal/_msg_session_sharing.html @@ -7,7 +7,7 @@
{% trans 'Account' %}: {{ account }}
- {% trans 'Session sharing URL' %}: {% trans 'View' %} + {% trans 'Session share' %}: {% trans 'View' %}
{% trans 'Verify code' %}: {{ verify_code }}
From cf6ce0fa2e2753a62efdbec1d8a0a2fbd1950997 Mon Sep 17 00:00:00 2001 From: jiangweidong Date: Thu, 17 Aug 2023 16:21:30 +0800 Subject: [PATCH 177/177] =?UTF-8?q?fix:=20=E6=93=8D=E4=BD=9C=E6=97=A5?= =?UTF-8?q?=E5=BF=97=E5=88=A4=E6=96=ADis=5Fservice=5Faccount=E4=B8=BA?= =?UTF-8?q?=E5=8C=BF=E5=90=8D=E7=94=A8=E6=88=B7=E4=BC=9A=E6=8A=A5=E9=94=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/audits/signal_handlers/operate_log.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/audits/signal_handlers/operate_log.py b/apps/audits/signal_handlers/operate_log.py index 69e6a5a50..826c11c8b 100644 --- a/apps/audits/signal_handlers/operate_log.py +++ b/apps/audits/signal_handlers/operate_log.py @@ -76,7 +76,7 @@ def signal_of_operate_log_whether_continue( condition = False # 不记录组件的操作日志 user = current_request.user if current_request else None - if not user or user.is_service_account: + if not user or getattr(user, 'is_service_account', False): condition = False # 终端模型的 create 事件由系统产生,不记录 if instance._meta.object_name == 'Terminal' and created: