mirror of
https://github.com/jumpserver/jumpserver.git
synced 2025-12-18 01:52:46 +00:00
Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
98a5e97518 | ||
|
|
17be132497 | ||
|
|
0cbce5f07a | ||
|
|
26dfb729bc | ||
|
|
bbe03ddb73 | ||
|
|
c88645fa57 | ||
|
|
7271feb598 | ||
|
|
950183ca85 | ||
|
|
6b1aa752d6 |
@@ -33,7 +33,8 @@ class AuthValidateMixin(serializers.Serializer):
|
||||
return secret
|
||||
elif secret_type == SecretType.SSH_KEY:
|
||||
passphrase = passphrase if passphrase else None
|
||||
return validate_ssh_key(secret, passphrase)
|
||||
secret = validate_ssh_key(secret, passphrase)
|
||||
return secret
|
||||
else:
|
||||
return secret
|
||||
|
||||
@@ -41,8 +42,9 @@ class AuthValidateMixin(serializers.Serializer):
|
||||
secret_type = validated_data.get('secret_type')
|
||||
passphrase = validated_data.get('passphrase')
|
||||
secret = validated_data.pop('secret', None)
|
||||
self.handle_secret(secret, secret_type, passphrase)
|
||||
validated_data['secret'] = secret
|
||||
validated_data['secret'] = self.handle_secret(
|
||||
secret, secret_type, passphrase
|
||||
)
|
||||
for field in ('secret',):
|
||||
value = validated_data.get(field)
|
||||
if not value:
|
||||
|
||||
@@ -39,7 +39,7 @@ class Protocol(ChoicesMixin, models.TextChoices):
|
||||
'port': 3389,
|
||||
'secret_types': ['password'],
|
||||
'setting': {
|
||||
'console': True,
|
||||
'console': False,
|
||||
'security': 'any',
|
||||
}
|
||||
},
|
||||
|
||||
@@ -34,8 +34,9 @@ def migrate_database_to_asset(apps, *args):
|
||||
_attrs = app.attrs or {}
|
||||
attrs.update(_attrs)
|
||||
|
||||
name = 'DB-{}'.format(app.name)
|
||||
db = db_model(
|
||||
id=app.id, name=app.name, address=attrs['host'],
|
||||
id=app.id, name=name, address=attrs['host'],
|
||||
protocols='{}/{}'.format(app.type, attrs['port']),
|
||||
db_name=attrs['database'] or '',
|
||||
platform=platforms_map[app.type],
|
||||
@@ -61,8 +62,9 @@ def migrate_cloud_to_asset(apps, *args):
|
||||
for app in applications:
|
||||
attrs = app.attrs
|
||||
print("\t- Create cloud: {}".format(app.name))
|
||||
name = 'Cloud-{}'.format(app.name)
|
||||
cloud = cloud_model(
|
||||
id=app.id, name=app.name,
|
||||
id=app.id, name=name,
|
||||
address=attrs.get('cluster', ''),
|
||||
protocols='k8s/443', platform=platform,
|
||||
org_id=app.org_id,
|
||||
|
||||
29
apps/assets/migrations/0110_auto_20230315_1741.py
Normal file
29
apps/assets/migrations/0110_auto_20230315_1741.py
Normal file
@@ -0,0 +1,29 @@
|
||||
# Generated by Django 3.2.17 on 2023-03-15 09:41
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
def set_windows_platform_non_console(apps, schema_editor):
|
||||
Platform = apps.get_model('assets', 'Platform')
|
||||
names = ['Windows', 'Windows-RDP', 'Windows-TLS', 'RemoteAppHost']
|
||||
windows = Platform.objects.filter(name__in=names)
|
||||
if not windows:
|
||||
return
|
||||
|
||||
for p in windows:
|
||||
rdp = p.protocols.filter(name='rdp').first()
|
||||
if not rdp:
|
||||
continue
|
||||
rdp.setting['console'] = False
|
||||
rdp.save()
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('assets', '0109_alter_asset_options'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RunPython(set_windows_platform_non_console)
|
||||
]
|
||||
@@ -11,7 +11,7 @@ __all__ = ['Platform', 'PlatformProtocol', 'PlatformAutomation']
|
||||
|
||||
class PlatformProtocol(models.Model):
|
||||
SETTING_ATTRS = {
|
||||
'console': True,
|
||||
'console': False,
|
||||
'security': 'any,tls,rdp',
|
||||
'sftp_enabled': True,
|
||||
'sftp_home': '/tmp'
|
||||
|
||||
@@ -73,7 +73,7 @@ class AssetAccountSerializer(
|
||||
'is_active', 'version', 'secret_type',
|
||||
]
|
||||
fields_write_only = [
|
||||
'secret', 'push_now', 'template'
|
||||
'secret', 'passphrase', 'push_now', 'template'
|
||||
]
|
||||
fields = fields_mini + fields_write_only
|
||||
extra_kwargs = {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from rest_framework import serializers
|
||||
from django.core import validators
|
||||
|
||||
from assets.const.web import FillType
|
||||
from common.serializers import WritableNestedModelSerializer
|
||||
@@ -19,7 +18,7 @@ class ProtocolSettingSerializer(serializers.Serializer):
|
||||
("nla", "NLA"),
|
||||
]
|
||||
# RDP
|
||||
console = serializers.BooleanField(required=False)
|
||||
console = serializers.BooleanField(required=False, default=False)
|
||||
security = serializers.ChoiceField(choices=SECURITY_CHOICES, default="any")
|
||||
|
||||
# SFTP
|
||||
|
||||
@@ -60,7 +60,7 @@ class FeiShuQRMixin(UserConfirmRequiredExceptionMixin, PermissionsMixin, View):
|
||||
'state': state,
|
||||
'redirect_uri': redirect_uri,
|
||||
}
|
||||
url = URL.AUTHEN + '?' + urlencode(params)
|
||||
url = URL().authen + '?' + urlencode(params)
|
||||
return url
|
||||
|
||||
@staticmethod
|
||||
|
||||
@@ -2,4 +2,3 @@ from __future__ import absolute_import
|
||||
|
||||
# This will make sure the app is always imported when
|
||||
# Django starts so that shared_task will use this app.
|
||||
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
from werkzeug.local import Local
|
||||
|
||||
from django.utils import translation
|
||||
|
||||
|
||||
thread_local = Local()
|
||||
encrypted_field_set = {'password'}
|
||||
encrypted_field_set = {'password', 'secret'}
|
||||
|
||||
|
||||
def _find(attr):
|
||||
@@ -10,4 +13,5 @@ def _find(attr):
|
||||
|
||||
def add_encrypted_field_set(label):
|
||||
if label:
|
||||
encrypted_field_set.add(str(label))
|
||||
with translation.override('en'):
|
||||
encrypted_field_set.add(str(label))
|
||||
|
||||
@@ -3,6 +3,7 @@ import json
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from rest_framework.exceptions import APIException
|
||||
|
||||
from django.conf import settings
|
||||
from common.utils.common import get_logger
|
||||
from common.sdk.im.utils import digest
|
||||
from common.sdk.im.mixin import RequestMixin, BaseRequest
|
||||
@@ -11,14 +12,30 @@ logger = get_logger(__name__)
|
||||
|
||||
|
||||
class URL:
|
||||
AUTHEN = 'https://open.feishu.cn/open-apis/authen/v1/index'
|
||||
|
||||
GET_TOKEN = 'https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal/'
|
||||
|
||||
# https://open.feishu.cn/document/ukTMukTMukTM/uEDO4UjLxgDO14SM4gTN
|
||||
GET_USER_INFO_BY_CODE = 'https://open.feishu.cn/open-apis/authen/v1/access_token'
|
||||
@property
|
||||
def host(self):
|
||||
if settings.FEISHU_VERSION == 'feishu':
|
||||
h = 'https://open.feishu.cn'
|
||||
else:
|
||||
h = 'https://open.larksuite.com'
|
||||
return h
|
||||
|
||||
SEND_MESSAGE = 'https://open.feishu.cn/open-apis/im/v1/messages'
|
||||
@property
|
||||
def authen(self):
|
||||
return f'{self.host}/open-apis/authen/v1/index'
|
||||
|
||||
@property
|
||||
def get_token(self):
|
||||
return f'{self.host}/open-apis/auth/v3/tenant_access_token/internal/'
|
||||
|
||||
@property
|
||||
def get_user_info_by_code(self):
|
||||
return f'{self.host}/open-apis/authen/v1/access_token'
|
||||
|
||||
@property
|
||||
def send_message(self):
|
||||
return f'{self.host}/open-apis/im/v1/messages'
|
||||
|
||||
|
||||
class ErrorCode:
|
||||
@@ -51,7 +68,7 @@ class FeishuRequests(BaseRequest):
|
||||
|
||||
def request_access_token(self):
|
||||
data = {'app_id': self._app_id, 'app_secret': self._app_secret}
|
||||
response = self.raw_request('post', url=URL.GET_TOKEN, data=data)
|
||||
response = self.raw_request('post', url=URL().get_token, data=data)
|
||||
self.check_errcode_is_0(response)
|
||||
|
||||
access_token = response['tenant_access_token']
|
||||
@@ -86,7 +103,7 @@ class FeiShu(RequestMixin):
|
||||
'code': code
|
||||
}
|
||||
|
||||
data = self._requests.post(URL.GET_USER_INFO_BY_CODE, json=body, check_errcode_is_0=False)
|
||||
data = self._requests.post(URL().get_user_info_by_code, json=body, check_errcode_is_0=False)
|
||||
|
||||
self._requests.check_errcode_is_0(data)
|
||||
return data['data']['user_id']
|
||||
@@ -107,7 +124,7 @@ class FeiShu(RequestMixin):
|
||||
|
||||
try:
|
||||
logger.info(f'Feishu send text: user_ids={user_ids} msg={msg}')
|
||||
self._requests.post(URL.SEND_MESSAGE, params=params, json=body)
|
||||
self._requests.post(URL().send_message, params=params, json=body)
|
||||
except APIException as e:
|
||||
# 只处理可预知的错误
|
||||
logger.exception(e)
|
||||
|
||||
@@ -274,4 +274,4 @@ def ensure_last_char_is_ascii(data):
|
||||
def data_to_json(data, sort_keys=True, indent=2, cls=None):
|
||||
if cls is None:
|
||||
cls = DjangoJSONEncoder
|
||||
return json.dumps(data, sort_keys=sort_keys, indent=indent, cls=cls)
|
||||
return json.dumps(data, ensure_ascii=False, sort_keys=sort_keys, indent=indent, cls=cls)
|
||||
|
||||
@@ -376,6 +376,7 @@ class Config(dict):
|
||||
'AUTH_FEISHU': False,
|
||||
'FEISHU_APP_ID': '',
|
||||
'FEISHU_APP_SECRET': '',
|
||||
'FEISHU_VERSION': 'feishu',
|
||||
|
||||
'LOGIN_REDIRECT_TO_BACKEND': '', # 'OPENID / CAS / SAML2
|
||||
'LOGIN_REDIRECT_MSG_ENABLED': True,
|
||||
|
||||
@@ -137,6 +137,7 @@ DINGTALK_APPSECRET = CONFIG.DINGTALK_APPSECRET
|
||||
AUTH_FEISHU = CONFIG.AUTH_FEISHU
|
||||
FEISHU_APP_ID = CONFIG.FEISHU_APP_ID
|
||||
FEISHU_APP_SECRET = CONFIG.FEISHU_APP_SECRET
|
||||
FEISHU_VERSION = CONFIG.FEISHU_VERSION
|
||||
|
||||
# Saml2 auth
|
||||
AUTH_SAML2 = CONFIG.AUTH_SAML2
|
||||
|
||||
@@ -23,6 +23,7 @@ def migrate_app_perms_to_assets(apps, schema_editor):
|
||||
asset_permission = asset_permission_model()
|
||||
for attr in attrs:
|
||||
setattr(asset_permission, attr, getattr(app_perm, attr))
|
||||
asset_permission.name = f"App-{app_perm.name}"
|
||||
asset_permissions.append(asset_permission)
|
||||
asset_permission_model.objects.bulk_create(asset_permissions, ignore_conflicts=True)
|
||||
|
||||
|
||||
@@ -9,11 +9,11 @@ def migrate_system_user_to_accounts(apps, schema_editor):
|
||||
bulk_size = 10000
|
||||
while True:
|
||||
asset_permissions = asset_permission_model.objects \
|
||||
.prefetch_related('system_users')[count:bulk_size]
|
||||
.prefetch_related('system_users')[count:bulk_size]
|
||||
if not asset_permissions:
|
||||
break
|
||||
count += len(asset_permissions)
|
||||
|
||||
count += len(asset_permissions)
|
||||
updated = []
|
||||
for asset_permission in asset_permissions:
|
||||
asset_permission.accounts = [s.username for s in asset_permission.system_users.all()]
|
||||
|
||||
@@ -9,6 +9,13 @@ __all__ = ['FeiShuSettingSerializer']
|
||||
class FeiShuSettingSerializer(serializers.Serializer):
|
||||
PREFIX_TITLE = _('FeiShu')
|
||||
|
||||
VERSION_CHOICES = (
|
||||
('feishu', _('FeiShu')),
|
||||
('lark', 'Lark')
|
||||
)
|
||||
AUTH_FEISHU = serializers.BooleanField(default=False, label=_('Enable FeiShu Auth'))
|
||||
FEISHU_APP_ID = serializers.CharField(max_length=256, required=True, label='App ID')
|
||||
FEISHU_APP_SECRET = EncryptedField(max_length=256, required=False, label='App Secret')
|
||||
AUTH_FEISHU = serializers.BooleanField(default=False, label=_('Enable FeiShu Auth'))
|
||||
FEISHU_VERSION = serializers.ChoiceField(
|
||||
choices=VERSION_CHOICES, default='feishu', label=_('Version')
|
||||
)
|
||||
|
||||
@@ -105,9 +105,13 @@ class Session(OrgModelMixin):
|
||||
def find_ok_relative_path_in_storage(self, storage):
|
||||
session_paths = self.get_all_possible_relative_path()
|
||||
for rel_path in session_paths:
|
||||
if storage.exists(rel_path):
|
||||
return rel_path
|
||||
|
||||
# storage 为多个外部存储时, 可能会因部分不可用,
|
||||
# 抛出异常, 影响录像的获取
|
||||
try:
|
||||
if storage.exists(rel_path):
|
||||
return rel_path
|
||||
except:
|
||||
pass
|
||||
@property
|
||||
def asset_obj(self):
|
||||
return Asset.objects.get(id=self.asset_id)
|
||||
|
||||
Reference in New Issue
Block a user