mirror of
https://github.com/jumpserver/jumpserver.git
synced 2025-06-24 14:02:01 +00:00
perf: rename ad to ds
This commit is contained in:
parent
3f452daee8
commit
acaa4cf2d5
@ -139,17 +139,25 @@ class Account(AbsConnectivity, LabeledMixin, BaseAccount, JSONFilterMixin):
|
||||
return self.id
|
||||
|
||||
@lazyproperty
|
||||
def ad_domain(self):
|
||||
def ds_id(self):
|
||||
if self.username.startswith('@'):
|
||||
return None
|
||||
if self.platform.category == 'ad':
|
||||
return self.asset.ad.domain_name
|
||||
if self.platform.category == 'ds':
|
||||
return self.asset.directoryservice.id
|
||||
return None
|
||||
|
||||
@lazyproperty
|
||||
def ds_domain(self):
|
||||
if self.username.startswith('@'):
|
||||
return None
|
||||
if self.ds_id:
|
||||
return self.asset.ds.domain_name
|
||||
return None
|
||||
|
||||
@lazyproperty
|
||||
def full_username(self):
|
||||
if self.ad_domain:
|
||||
return '{}@{}'.format(self.username, self.ad_domain)
|
||||
if self.ds_domain:
|
||||
return '{}@{}'.format(self.username, self.ds_domain)
|
||||
return self.username
|
||||
|
||||
@lazyproperty
|
||||
|
@ -241,7 +241,7 @@ class AccountSerializer(AccountCreateUpdateSerializerMixin, BaseAccountSerialize
|
||||
'date_change_secret', 'change_secret_status'
|
||||
]
|
||||
fields = BaseAccountSerializer.Meta.fields + [
|
||||
'su_from', 'asset', 'version', "ad_domain",
|
||||
'su_from', 'asset', 'version', 'ds_domain',
|
||||
'source', 'source_id', 'secret_reset',
|
||||
] + AccountCreateUpdateSerializerMixin.Meta.fields + automation_fields
|
||||
read_only_fields = BaseAccountSerializer.Meta.read_only_fields + automation_fields
|
||||
|
@ -87,7 +87,7 @@ class BaseAccountSerializer(
|
||||
"username": {
|
||||
"help_text": _(
|
||||
"* If no username is required for authentication, enter null. "
|
||||
"For AD accounts, use the format username@domain."
|
||||
"For DS accounts, use the format username@domain."
|
||||
)
|
||||
},
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ class VirtualAccountSerializer(serializers.ModelSerializer):
|
||||
'username': {'label': _('Username')},
|
||||
'secret_from_login': {
|
||||
'help_text': _(
|
||||
'Current only support login from AD/LDAP. Secret priority: '
|
||||
'Current only support login from DS/LDAP. Secret priority: '
|
||||
'Same account in asset secret > Login secret > Manual input. <br/ >'
|
||||
'For security, please set config CACHE_LOGIN_PASSWORD_ENABLED to true'
|
||||
)
|
||||
|
@ -3,8 +3,8 @@ from .cloud import *
|
||||
from .custom import *
|
||||
from .database import *
|
||||
from .device import *
|
||||
from .ds import *
|
||||
from .gpt import *
|
||||
from .host import *
|
||||
from .permission import *
|
||||
from .web import *
|
||||
from .ad import *
|
||||
|
@ -1,16 +0,0 @@
|
||||
from assets.models import AD, Asset
|
||||
from assets.serializers import ADSerializer
|
||||
|
||||
from .asset import AssetViewSet
|
||||
|
||||
__all__ = ['ADViewSet']
|
||||
|
||||
|
||||
class ADViewSet(AssetViewSet):
|
||||
model = AD
|
||||
perm_model = Asset
|
||||
|
||||
def get_serializer_classes(self):
|
||||
serializer_classes = super().get_serializer_classes()
|
||||
serializer_classes['default'] = ADSerializer
|
||||
return serializer_classes
|
16
apps/assets/api/asset/ds.py
Normal file
16
apps/assets/api/asset/ds.py
Normal file
@ -0,0 +1,16 @@
|
||||
from assets.models import DirectoryService, Asset
|
||||
from assets.serializers import DSSerializer
|
||||
|
||||
from .asset import AssetViewSet
|
||||
|
||||
__all__ = ['DSViewSet']
|
||||
|
||||
|
||||
class DSViewSet(AssetViewSet):
|
||||
model = DirectoryService
|
||||
perm_model = Asset
|
||||
|
||||
def get_serializer_classes(self):
|
||||
serializer_classes = super().get_serializer_classes()
|
||||
serializer_classes['default'] = DSSerializer
|
||||
return serializer_classes
|
@ -112,8 +112,7 @@ class BaseType(TextChoices):
|
||||
|
||||
@classmethod
|
||||
def get_choices(cls):
|
||||
if not settings.XPACK_LICENSE_IS_VALID:
|
||||
choices = cls.choices
|
||||
if not settings.XPACK_LICENSE_IS_VALID and hasattr(cls, 'get_community_types'):
|
||||
choices = [(tp.value, tp.label) for tp in cls.get_community_types()]
|
||||
else:
|
||||
choices = cls.choices
|
||||
return choices
|
||||
|
@ -12,7 +12,7 @@ class Category(ChoicesMixin, models.TextChoices):
|
||||
DATABASE = 'database', _("Database")
|
||||
CLOUD = 'cloud', _("Cloud service")
|
||||
WEB = 'web', _("Web")
|
||||
AD = 'ad', _("Active Directory")
|
||||
DS = 'ds', _("Directory service")
|
||||
CUSTOM = 'custom', _("Custom type")
|
||||
|
||||
@classmethod
|
||||
|
@ -20,7 +20,7 @@ class DeviceTypes(BaseType):
|
||||
'*': {
|
||||
'charset_enabled': False,
|
||||
'domain_enabled': True,
|
||||
'ad_enabled': False,
|
||||
'ds_enabled': False,
|
||||
'su_enabled': True,
|
||||
'su_methods': ['enable', 'super', 'super_level']
|
||||
}
|
||||
|
@ -3,11 +3,13 @@ from django.utils.translation import gettext_lazy as _
|
||||
from .base import BaseType
|
||||
|
||||
|
||||
class ADTypes(BaseType):
|
||||
AD = 'ad', _('Active Directory')
|
||||
class DirectoryTypes(BaseType):
|
||||
GENERAL = 'general', _('General')
|
||||
# LDAP = 'ldap', _('LDAP')
|
||||
# AD = 'ad', _('Active Directory')
|
||||
WINDOWS_AD = 'windows_ad', _('Windows Active Directory')
|
||||
LDAP = 'ldap', _('LDAP')
|
||||
AZURE_AD = 'azure_ad', _('Azure Active Directory')
|
||||
|
||||
# AZURE_AD = 'azure_ad', _('Azure Active Directory')
|
||||
|
||||
@classmethod
|
||||
def _get_base_constrains(cls) -> dict:
|
||||
@ -15,7 +17,7 @@ class ADTypes(BaseType):
|
||||
'*': {
|
||||
'charset_enabled': False,
|
||||
'domain_enabled': True,
|
||||
'ad_enabled': False,
|
||||
'ds_enabled': False,
|
||||
'su_enabled': True,
|
||||
}
|
||||
}
|
||||
@ -24,6 +26,9 @@ class ADTypes(BaseType):
|
||||
def _get_automation_constrains(cls) -> dict:
|
||||
constrains = {
|
||||
'*': {
|
||||
'ansible_enabled': False,
|
||||
},
|
||||
cls.WINDOWS_AD: {
|
||||
'ansible_enabled': True,
|
||||
'ping_enabled': True,
|
||||
'gather_facts_enabled': False,
|
||||
@ -38,36 +43,24 @@ class ADTypes(BaseType):
|
||||
@classmethod
|
||||
def _get_protocol_constrains(cls) -> dict:
|
||||
return {
|
||||
cls.GENERAL: {
|
||||
'choices': ['ssh']
|
||||
},
|
||||
cls.WINDOWS_AD: {
|
||||
'choices': ['rdp', 'ssh', 'vnc', 'winrm']
|
||||
},
|
||||
cls.LDAP: {
|
||||
'choices': ['ssh', 'ldap']
|
||||
},
|
||||
cls.AZURE_AD: {
|
||||
'choices': ['ldap']
|
||||
}
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def internal_platforms(cls):
|
||||
return {
|
||||
cls.AD: [
|
||||
{'name': 'Active Directory'}
|
||||
],
|
||||
cls.WINDOWS_AD: [
|
||||
{'name': 'Windows Active Directory'}
|
||||
],
|
||||
cls.LDAP: [
|
||||
{'name': 'LDAP'}
|
||||
],
|
||||
cls.AZURE_AD: [
|
||||
{'name': 'Azure Active Directory'}
|
||||
],
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def get_community_types(cls):
|
||||
return [
|
||||
cls.LDAP,
|
||||
cls.GENERAL,
|
||||
]
|
@ -20,7 +20,7 @@ class HostTypes(BaseType):
|
||||
'charset': 'utf-8', # default
|
||||
'domain_enabled': True,
|
||||
'su_enabled': True,
|
||||
'ad_enabled': True,
|
||||
'ds_enabled': True,
|
||||
'su_methods': ['sudo', 'su', 'only_sudo', 'only_su'],
|
||||
},
|
||||
cls.WINDOWS: {
|
||||
|
@ -13,10 +13,10 @@ from .cloud import CloudTypes
|
||||
from .custom import CustomTypes
|
||||
from .database import DatabaseTypes
|
||||
from .device import DeviceTypes
|
||||
from .ds import DirectoryTypes
|
||||
from .gpt import GPTTypes
|
||||
from .host import HostTypes
|
||||
from .web import WebTypes
|
||||
from .ad import ADTypes
|
||||
|
||||
|
||||
class AllTypes(ChoicesMixin):
|
||||
@ -24,7 +24,7 @@ class AllTypes(ChoicesMixin):
|
||||
includes = [
|
||||
HostTypes, DeviceTypes, DatabaseTypes,
|
||||
CloudTypes, WebTypes, CustomTypes,
|
||||
ADTypes, GPTTypes
|
||||
DirectoryTypes, GPTTypes
|
||||
]
|
||||
_category_constrains = {}
|
||||
_automation_methods = None
|
||||
@ -175,7 +175,7 @@ class AllTypes(ChoicesMixin):
|
||||
(Category.DATABASE, DatabaseTypes),
|
||||
(Category.WEB, WebTypes),
|
||||
(Category.CLOUD, CloudTypes),
|
||||
(Category.AD, ADTypes),
|
||||
(Category.DS, DirectoryTypes),
|
||||
(Category.CUSTOM, CustomTypes)
|
||||
]
|
||||
return types
|
||||
|
64
apps/assets/migrations/0016_auto_20250331_1149.bak
Normal file
64
apps/assets/migrations/0016_auto_20250331_1149.bak
Normal file
@ -0,0 +1,64 @@
|
||||
# Generated by Django 4.1.13 on 2025-03-31 02:49
|
||||
|
||||
import json
|
||||
|
||||
import django
|
||||
from django.db import migrations, models
|
||||
|
||||
from assets.const.types import AllTypes
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
dependencies = [
|
||||
("assets", "0015_automationexecution_type"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RunPython(add_ad_host_type),
|
||||
migrations.CreateModel(
|
||||
name="DS",
|
||||
fields=[
|
||||
(
|
||||
"asset_ptr",
|
||||
models.OneToOneField(
|
||||
auto_created=True,
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
parent_link=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
to="assets.asset",
|
||||
),
|
||||
),
|
||||
(
|
||||
"domain_name",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
default="",
|
||||
max_length=128,
|
||||
verbose_name="Domain name",
|
||||
),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"verbose_name": "Active Directory",
|
||||
},
|
||||
bases=("assets.asset",),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="platform",
|
||||
name="ds",
|
||||
field=models.ForeignKey(
|
||||
blank=True,
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.SET_NULL,
|
||||
related_name="ad_platforms",
|
||||
to="assets.ds",
|
||||
verbose_name="Active Directory",
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="platform",
|
||||
name="ds_enabled",
|
||||
field=models.BooleanField(default=False, verbose_name="DS enabled"),
|
||||
),
|
||||
]
|
@ -1,166 +0,0 @@
|
||||
# Generated by Django 4.1.13 on 2025-03-31 02:49
|
||||
|
||||
import json
|
||||
|
||||
import django
|
||||
from django.db import migrations, models
|
||||
|
||||
from assets.const.types import AllTypes
|
||||
|
||||
|
||||
def add_ad_host_type(apps, schema_editor):
|
||||
data = """
|
||||
[
|
||||
{
|
||||
"created_by": "system",
|
||||
"updated_by": "system",
|
||||
"comment": "",
|
||||
"name": "Windows AD",
|
||||
"category": "ad",
|
||||
"type": "windows_ad",
|
||||
"meta": {},
|
||||
"internal": true,
|
||||
"domain_enabled": true,
|
||||
"su_enabled": false,
|
||||
"su_method": null,
|
||||
"custom_fields": [],
|
||||
"automation": {
|
||||
"ansible_enabled": true,
|
||||
"ansible_config": {
|
||||
"ansible_shell_type": "cmd",
|
||||
"ansible_connection": "ssh"
|
||||
},
|
||||
"ping_enabled": true,
|
||||
"ping_method": "ping_by_rdp",
|
||||
"ping_params": {},
|
||||
"gather_facts_enabled": true,
|
||||
"gather_facts_method": "gather_facts_windows",
|
||||
"gather_facts_params": {},
|
||||
"change_secret_enabled": true,
|
||||
"change_secret_method": "change_secret_ad_windows",
|
||||
"change_secret_params": {},
|
||||
"push_account_enabled": true,
|
||||
"push_account_method": "push_account_ad_windows",
|
||||
"push_account_params": {},
|
||||
"verify_account_enabled": true,
|
||||
"verify_account_method": "verify_account_by_rdp",
|
||||
"verify_account_params": {},
|
||||
"gather_accounts_enabled": true,
|
||||
"gather_accounts_method": "gather_accounts_ad_windows",
|
||||
"gather_accounts_params": {},
|
||||
"remove_account_enabled": true,
|
||||
"remove_account_method": "remove_account_ad_windows",
|
||||
"remove_account_params": {}
|
||||
},
|
||||
"protocols": [
|
||||
{
|
||||
"name": "rdp",
|
||||
"port": 3389,
|
||||
"primary": true,
|
||||
"required": false,
|
||||
"default": false,
|
||||
"public": true,
|
||||
"setting": {
|
||||
"console": false,
|
||||
"security": "any"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ssh",
|
||||
"port": 22,
|
||||
"primary": false,
|
||||
"required": false,
|
||||
"default": false,
|
||||
"public": true,
|
||||
"setting": {
|
||||
"sftp_enabled": true,
|
||||
"sftp_home": "/tmp"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "vnc",
|
||||
"port": 5900,
|
||||
"primary": false,
|
||||
"required": false,
|
||||
"default": false,
|
||||
"public": true,
|
||||
"setting": {}
|
||||
},
|
||||
{
|
||||
"name": "winrm",
|
||||
"port": 5985,
|
||||
"primary": false,
|
||||
"required": false,
|
||||
"default": false,
|
||||
"public": false,
|
||||
"setting": {
|
||||
"use_ssl": false
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
"""
|
||||
platform_model = apps.get_model('assets', 'Platform')
|
||||
automation_cls = apps.get_model('assets', 'PlatformAutomation')
|
||||
platform_datas = json.loads(data)
|
||||
|
||||
for platform_data in platform_datas:
|
||||
AllTypes.create_or_update_by_platform_data(platform_data, platform_cls=platform_model,
|
||||
automation_cls=automation_cls)
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
dependencies = [
|
||||
("assets", "0015_automationexecution_type"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RunPython(add_ad_host_type),
|
||||
migrations.CreateModel(
|
||||
name="AD",
|
||||
fields=[
|
||||
(
|
||||
"asset_ptr",
|
||||
models.OneToOneField(
|
||||
auto_created=True,
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
parent_link=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
to="assets.asset",
|
||||
),
|
||||
),
|
||||
(
|
||||
"domain_name",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
default="",
|
||||
max_length=128,
|
||||
verbose_name="Domain name",
|
||||
),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"verbose_name": "Active Directory",
|
||||
},
|
||||
bases=("assets.asset",),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="platform",
|
||||
name="ad",
|
||||
field=models.ForeignKey(
|
||||
blank=True,
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.SET_NULL,
|
||||
related_name="ad_platforms",
|
||||
to="assets.ad",
|
||||
verbose_name="Active Directory",
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="platform",
|
||||
name="ad_enabled",
|
||||
field=models.BooleanField(default=False, verbose_name="AD enabled"),
|
||||
),
|
||||
]
|
59
apps/assets/migrations/0016_directory_service.py
Normal file
59
apps/assets/migrations/0016_directory_service.py
Normal file
@ -0,0 +1,59 @@
|
||||
# Generated by Django 4.1.13 on 2025-04-03 09:51
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
dependencies = [
|
||||
("assets", "0015_automationexecution_type"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name="DirectoryService",
|
||||
fields=[
|
||||
(
|
||||
"asset_ptr",
|
||||
models.OneToOneField(
|
||||
auto_created=True,
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
parent_link=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
to="assets.asset",
|
||||
),
|
||||
),
|
||||
(
|
||||
"domain_name",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
default="",
|
||||
max_length=128,
|
||||
verbose_name="Domain name",
|
||||
),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"verbose_name": "Directory service",
|
||||
},
|
||||
bases=("assets.asset",),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="platform",
|
||||
name="ds_enabled",
|
||||
field=models.BooleanField(default=False, verbose_name="DS enabled"),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="platform",
|
||||
name="ds",
|
||||
field=models.ForeignKey(
|
||||
blank=True,
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.SET_NULL,
|
||||
related_name="ds_platforms",
|
||||
to="assets.directoryservice",
|
||||
verbose_name="Active Directory",
|
||||
),
|
||||
),
|
||||
]
|
168
apps/assets/migrations/0017_auto_20250407_1124.py
Normal file
168
apps/assets/migrations/0017_auto_20250407_1124.py
Normal file
@ -0,0 +1,168 @@
|
||||
# Generated by Django 4.1.13 on 2025-04-07 03:24
|
||||
|
||||
import json
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
from assets.const import AllTypes
|
||||
|
||||
|
||||
def add_ds_platforms(apps, schema_editor):
|
||||
data = """
|
||||
[
|
||||
{
|
||||
"created_by": "system",
|
||||
"updated_by": "system",
|
||||
"comment": "",
|
||||
"name": "Windows active directory",
|
||||
"category": "ds",
|
||||
"type": "windows_ad",
|
||||
"meta": {},
|
||||
"internal": true,
|
||||
"domain_enabled": true,
|
||||
"su_enabled": false,
|
||||
"su_method": null,
|
||||
"custom_fields": [],
|
||||
"automation": {
|
||||
"ansible_enabled": true,
|
||||
"ansible_config": {
|
||||
"ansible_shell_type": "cmd",
|
||||
"ansible_connection": "ssh"
|
||||
},
|
||||
"ping_enabled": true,
|
||||
"ping_method": "ping_by_rdp",
|
||||
"ping_params": {},
|
||||
"gather_facts_enabled": true,
|
||||
"gather_facts_method": "gather_facts_windows",
|
||||
"gather_facts_params": {},
|
||||
"change_secret_enabled": true,
|
||||
"change_secret_method": "change_secret_ad_windows",
|
||||
"change_secret_params": {
|
||||
},
|
||||
"push_account_enabled": true,
|
||||
"push_account_method": "push_account_ad_windows",
|
||||
"push_account_params": {},
|
||||
"verify_account_enabled": true,
|
||||
"verify_account_method": "verify_account_by_rdp",
|
||||
"verify_account_params": {
|
||||
|
||||
},
|
||||
"gather_accounts_enabled": true,
|
||||
"gather_accounts_method": "gather_accounts_ad_windows",
|
||||
"gather_accounts_params": {
|
||||
|
||||
},
|
||||
"remove_account_enabled": true,
|
||||
"remove_account_method": "remove_account_ad_windows",
|
||||
"remove_account_params": {
|
||||
|
||||
}
|
||||
},
|
||||
"protocols": [
|
||||
{
|
||||
"name": "rdp",
|
||||
"port": 3389,
|
||||
"primary": true,
|
||||
"required": false,
|
||||
"default": false,
|
||||
"public": true,
|
||||
"setting": {
|
||||
"console": false,
|
||||
"security": "any"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ssh",
|
||||
"port": 22,
|
||||
"primary": false,
|
||||
"required": false,
|
||||
"default": false,
|
||||
"public": true,
|
||||
"setting": {
|
||||
"sftp_enabled": true,
|
||||
"sftp_home": "/tmp"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "vnc",
|
||||
"port": 5900,
|
||||
"primary": false,
|
||||
"required": false,
|
||||
"default": false,
|
||||
"public": true,
|
||||
"setting": {
|
||||
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "winrm",
|
||||
"port": 5985,
|
||||
"primary": false,
|
||||
"required": false,
|
||||
"default": false,
|
||||
"public": false,
|
||||
"setting": {
|
||||
"use_ssl": false
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"created_by": "system",
|
||||
"updated_by": "system",
|
||||
"comment": "",
|
||||
"name": "General",
|
||||
"category": "ds",
|
||||
"type": "general",
|
||||
"meta": {
|
||||
|
||||
},
|
||||
"internal": true,
|
||||
"domain_enabled": false,
|
||||
"su_enabled": false,
|
||||
"su_method": null,
|
||||
"custom_fields": [
|
||||
|
||||
],
|
||||
"automation": {
|
||||
"ansible_enabled": false,
|
||||
"ansible_config": {
|
||||
|
||||
}
|
||||
},
|
||||
"protocols": [
|
||||
{
|
||||
"name": "ssh",
|
||||
"port": 22,
|
||||
"primary": true,
|
||||
"required": false,
|
||||
"default": false,
|
||||
"public": true,
|
||||
"setting": {
|
||||
"sftp_enabled": true,
|
||||
"sftp_home": "/tmp"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
"""
|
||||
platform_model = apps.get_model('assets', 'Platform')
|
||||
automation_cls = apps.get_model('assets', 'PlatformAutomation')
|
||||
platform_datas = json.loads(data)
|
||||
|
||||
for platform_data in platform_datas:
|
||||
AllTypes.create_or_update_by_platform_data(
|
||||
platform_data, platform_cls=platform_model,
|
||||
automation_cls=automation_cls
|
||||
)
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
dependencies = [
|
||||
("assets", "0016_directory_service"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RunPython(add_ds_platforms)
|
||||
]
|
@ -1,9 +1,9 @@
|
||||
from .ad import *
|
||||
from .cloud import *
|
||||
from .common import *
|
||||
from .custom import *
|
||||
from .database import *
|
||||
from .device import *
|
||||
from .ds import *
|
||||
from .gpt import *
|
||||
from .host import *
|
||||
from .web import *
|
||||
|
@ -247,10 +247,10 @@ class Asset(NodesRelationMixin, LabeledMixin, AbsConnectivity, JSONFilterMixin,
|
||||
|
||||
@property
|
||||
def all_accounts(self):
|
||||
if not self.joined_ad_id:
|
||||
if not self.joined_dir_svc_id:
|
||||
queryset = self.accounts.all()
|
||||
else:
|
||||
queryset = self.accounts.model.objects.filter(asset__in=[self.id, self.joined_ad_id])
|
||||
queryset = self.accounts.model.objects.filter(asset__in=[self.id, self.joined_dir_svc_id])
|
||||
return queryset
|
||||
|
||||
@lazyproperty
|
||||
@ -273,15 +273,15 @@ class Asset(NodesRelationMixin, LabeledMixin, AbsConnectivity, JSONFilterMixin,
|
||||
protocol = self.protocols.all().filter(name=protocol).first()
|
||||
return protocol.port if protocol else 0
|
||||
|
||||
def is_ad(self):
|
||||
return self.category == const.Category.AD
|
||||
def is_dir_svc(self):
|
||||
return self.category == const.Category.DS
|
||||
|
||||
@property
|
||||
def joined_ad_id(self):
|
||||
return self.platform.ad_id
|
||||
def joined_dir_svc_id(self):
|
||||
return self.platform.ds_id
|
||||
|
||||
def is_joined_ad(self):
|
||||
if self.joined_ad_id:
|
||||
if self.joined_dir_svc_id:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
@ -3,11 +3,11 @@ from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from .common import Asset
|
||||
|
||||
__all__ = ['AD']
|
||||
__all__ = ['DirectoryService']
|
||||
|
||||
|
||||
class AD(Asset):
|
||||
class DirectoryService(Asset):
|
||||
domain_name = models.CharField(max_length=128, blank=True, default='', verbose_name=_("Domain name"))
|
||||
|
||||
class Meta:
|
||||
verbose_name = _("Active Directory")
|
||||
verbose_name = _("Directory service")
|
@ -102,10 +102,10 @@ class Platform(LabeledMixin, JMSBaseModel):
|
||||
max_length=8, verbose_name=_("Charset")
|
||||
)
|
||||
domain_enabled = models.BooleanField(default=True, verbose_name=_("Gateway enabled"))
|
||||
ad_enabled = models.BooleanField(default=False, verbose_name=_("AD enabled"))
|
||||
ad = models.ForeignKey(
|
||||
'assets.AD', on_delete=models.SET_NULL, null=True, blank=True,
|
||||
verbose_name=_("Active Directory"), related_name='ad_platforms'
|
||||
ds_enabled = models.BooleanField(default=False, verbose_name=_("DS enabled"))
|
||||
ds = models.ForeignKey(
|
||||
'DirectoryService', on_delete=models.SET_NULL, null=True, blank=True,
|
||||
verbose_name=_("Directory service"), related_name='ds_platforms'
|
||||
)
|
||||
# 账号有关的
|
||||
su_enabled = models.BooleanField(default=False, verbose_name=_("Su enabled"))
|
||||
@ -121,8 +121,8 @@ class Platform(LabeledMixin, JMSBaseModel):
|
||||
return self.assets.count()
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
if not self.ad_enabled:
|
||||
self.ad = None
|
||||
if not self.ds_enabled:
|
||||
self.ds = None
|
||||
super().save(*args, **kwargs)
|
||||
|
||||
@classmethod
|
||||
|
@ -4,7 +4,7 @@ from .common import *
|
||||
from .custom import *
|
||||
from .database import *
|
||||
from .device import *
|
||||
from .ds import *
|
||||
from .gpt import *
|
||||
from .host import *
|
||||
from .web import *
|
||||
from .ad import *
|
@ -1,15 +1,14 @@
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from rest_framework import serializers
|
||||
|
||||
from assets.models import AD
|
||||
from assets.models import DirectoryService
|
||||
from .common import AssetSerializer
|
||||
|
||||
__all__ = ['ADSerializer']
|
||||
__all__ = ['DSSerializer']
|
||||
|
||||
|
||||
class ADSerializer(AssetSerializer):
|
||||
class DSSerializer(AssetSerializer):
|
||||
class Meta(AssetSerializer.Meta):
|
||||
model = AD
|
||||
model = DirectoryService
|
||||
fields = AssetSerializer.Meta.fields + [
|
||||
'domain_name',
|
||||
]
|
@ -194,8 +194,8 @@ class PlatformSerializer(ResourceLabelsMixin, CommonSerializerMixin, WritableNes
|
||||
]
|
||||
fields_m2m = ['assets', 'assets_amount']
|
||||
fields = fields_small + fields_m2m + [
|
||||
"protocols", "domain_enabled", "su_enabled", "su_method", "ad_enabled", "ad",
|
||||
"automation", "comment", "custom_fields", "labels"
|
||||
"protocols", "domain_enabled", "su_enabled", "su_method",
|
||||
"ds_enabled", "ds", "automation", "comment", "custom_fields", "labels"
|
||||
] + read_only_fields
|
||||
extra_kwargs = {
|
||||
"su_enabled": {
|
||||
|
@ -16,7 +16,7 @@ router.register(r'databases', api.DatabaseViewSet, 'database')
|
||||
router.register(r'webs', api.WebViewSet, 'web')
|
||||
router.register(r'clouds', api.CloudViewSet, 'cloud')
|
||||
router.register(r'gpts', api.GPTViewSet, 'gpt')
|
||||
router.register(r'directories', api.ADViewSet, 'ad')
|
||||
router.register(r'directories', api.DSViewSet, 'ds')
|
||||
router.register(r'customs', api.CustomViewSet, 'custom')
|
||||
router.register(r'platforms', api.AssetPlatformViewSet, 'platform')
|
||||
router.register(r'nodes', api.NodeViewSet, 'node')
|
||||
|
@ -8,7 +8,6 @@ from django.db import models
|
||||
from django.shortcuts import get_object_or_404
|
||||
from django.utils import timezone
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.forms.models import model_to_dict
|
||||
from rest_framework.exceptions import PermissionDenied
|
||||
|
||||
from accounts.models import VirtualAccount
|
||||
@ -267,7 +266,7 @@ class ConnectionToken(JMSOrgBaseModel):
|
||||
input_secret=self.input_secret, from_permed=False
|
||||
)
|
||||
else:
|
||||
account = self.asset.accounts.filter(name=self.account).first()
|
||||
account = self.asset.all_valid_accounts.filter(id=self.account).first()
|
||||
if not account.secret and self.input_secret:
|
||||
account.secret = self.input_secret
|
||||
return account
|
||||
|
@ -40,6 +40,7 @@ class _ConnectionTokenAssetSerializer(serializers.ModelSerializer):
|
||||
|
||||
class _SimpleAccountSerializer(serializers.ModelSerializer):
|
||||
secret_type = LabeledChoiceField(choices=SecretType.choices, required=False, label=_('Secret type'))
|
||||
username = serializers.CharField(label=_('Username'), source='full_username', read_only=True)
|
||||
|
||||
class Meta:
|
||||
model = Account
|
||||
@ -49,6 +50,7 @@ class _SimpleAccountSerializer(serializers.ModelSerializer):
|
||||
class _ConnectionTokenAccountSerializer(serializers.ModelSerializer):
|
||||
su_from = serializers.SerializerMethodField(label=_('Su from'))
|
||||
secret_type = LabeledChoiceField(choices=SecretType.choices, required=False, label=_('Secret type'))
|
||||
username = serializers.CharField(label=_('Username'), source='full_username', read_only=True)
|
||||
|
||||
class Meta:
|
||||
model = Account
|
||||
|
@ -8,7 +8,7 @@ FILE_END_GUARD = ">>> Content End <<<"
|
||||
celery_task_pre_key = "CELERY_"
|
||||
KEY_CACHE_RESOURCE_IDS = "RESOURCE_IDS_{}"
|
||||
|
||||
# AD User AccountDisable
|
||||
# DS User AccountDisable
|
||||
# https://docs.microsoft.com/en-us/troubleshoot/windows-server/identity/useraccountcontrol-manipulate-account-properties
|
||||
LDAP_AD_ACCOUNT_DISABLE = 2
|
||||
UUID_PATTERN = re.compile(r'[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}')
|
||||
|
@ -121,8 +121,8 @@ LOGGING = {
|
||||
|
||||
if CONFIG.DEBUG_DEV:
|
||||
LOGGING['loggers']['django.db'] = {
|
||||
'handlers': ['console', 'file'],
|
||||
'level': 'DEBUG'
|
||||
'handlers': ['console', 'file'],
|
||||
'level': 'DEBUG'
|
||||
}
|
||||
|
||||
SYSLOG_ENABLE = CONFIG.SYSLOG_ENABLE
|
||||
@ -138,4 +138,3 @@ if CONFIG.SYSLOG_ADDR != '' and len(CONFIG.SYSLOG_ADDR.split(':')) == 2:
|
||||
|
||||
if not os.path.isdir(LOG_DIR):
|
||||
os.makedirs(LOG_DIR, mode=0o755)
|
||||
|
||||
|
@ -39,8 +39,8 @@ class TerminalSettingSerializer(serializers.Serializer):
|
||||
help_text=_(
|
||||
'* Allow users to log in to the KoKo component via Public key authentication'
|
||||
'<br/>'
|
||||
'If third-party authentication services, such as AD/LDAP, are enabled, you should '
|
||||
'disable this option to prevent users from logging in after being deleted from the AD/LDAP server'
|
||||
'If third-party authentication services, such as DS/LDAP, are enabled, you should '
|
||||
'disable this option to prevent users from logging in after being deleted from the DS/LDAP server'
|
||||
)
|
||||
)
|
||||
TERMINAL_ASSET_LIST_SORT_BY = serializers.ChoiceField(
|
||||
|
@ -197,7 +197,7 @@ class LDAPServerUtil(object):
|
||||
value = is_true(value)
|
||||
|
||||
if attr == 'groups' and mapping.lower() == 'memberof':
|
||||
# AD: {'groups': 'memberOf'}
|
||||
# DS: {'groups': 'memberOf'}
|
||||
if isinstance(value, str) and value:
|
||||
value = [value]
|
||||
if not isinstance(value, list):
|
||||
@ -366,7 +366,7 @@ class LDAPSyncUtil(object):
|
||||
|
||||
|
||||
class LDAPImportUtil(object):
|
||||
user_group_name_prefix = 'AD '
|
||||
user_group_name_prefix = 'DS '
|
||||
|
||||
def __init__(self, category=User.Source.ldap.value, is_sync_all=True):
|
||||
self.category = category
|
||||
@ -399,7 +399,7 @@ class LDAPImportUtil(object):
|
||||
continue
|
||||
if not isinstance(group, str):
|
||||
continue
|
||||
# get group name for AD, Such as: CN=Users,CN=Builtin,DC=jms,DC=com
|
||||
# get group name for DS, Such as: CN=Users,CN=Builtin,DC=jms,DC=com
|
||||
group_name = group.split(',')[0].split('=')[-1]
|
||||
group_name = f'{self.user_group_name_prefix}{group_name}'.strip()
|
||||
group_names.append(group_name)
|
||||
|
@ -81,7 +81,7 @@ class Migration(migrations.Migration):
|
||||
models.DateTimeField(auto_now_add=True, null=True, verbose_name='Date password last updated')),
|
||||
('need_update_password', models.BooleanField(default=False, verbose_name='Need update password')),
|
||||
('source', models.CharField(
|
||||
choices=[('local', 'Local'), ('ldap', 'LDAP/AD'), ('ldap_ha', 'LDAP/AD (HA)'), ('openid', 'OpenID'),
|
||||
choices=[('local', 'Local'), ('ldap', 'LDAP/DS'), ('ldap_ha', 'LDAP/DS (HA)'), ('openid', 'OpenID'),
|
||||
('radius', 'Radius'), ('cas', 'CAS'), ('saml2', 'SAML2'), ('oauth2', 'OAuth2'),
|
||||
('wecom', 'WeCom'), ('dingtalk', 'DingTalk'), ('feishu', 'FeiShu'), ('lark', 'Lark'),
|
||||
('slack', 'Slack'), ('custom', 'Custom')], default='local', max_length=30,
|
||||
|
@ -9,8 +9,8 @@ from django.utils.translation import gettext_lazy as _
|
||||
|
||||
class Source(models.TextChoices):
|
||||
local = "local", _("Local")
|
||||
ldap = "ldap", "LDAP/AD"
|
||||
ldap_ha = "ldap_ha", "LDAP/AD (HA)"
|
||||
ldap = "ldap", "LDAP/DS"
|
||||
ldap_ha = "ldap_ha", "LDAP/DS (HA)"
|
||||
openid = "openid", "OpenID"
|
||||
radius = "radius", "Radius"
|
||||
cas = "cas", "CAS"
|
||||
|
@ -247,7 +247,7 @@ class UserSerializer(
|
||||
},
|
||||
"source": {
|
||||
"help_text": _(
|
||||
"User source identifies where the user was created, which could be AD or other sources."
|
||||
"User source identifies where the user was created, which could be DS or other sources."
|
||||
"There are security settings that can restrict users to log in to the system only from the sources."
|
||||
),
|
||||
},
|
||||
|
@ -53,7 +53,7 @@ REDIS_PORT: 6379
|
||||
# REDIS_DB_CELERY: 3
|
||||
# REDIS_DB_CACHE: 4
|
||||
|
||||
# LDAP/AD settings
|
||||
# LDAP/DS settings
|
||||
# LDAP 搜索分页数量
|
||||
# AUTH_LDAP_SEARCH_PAGED_SIZE: 1000
|
||||
#
|
||||
|
Loading…
Reference in New Issue
Block a user