Unverified Commit 719bea68 authored by 老广's avatar 老广 Committed by GitHub

Merge pull request #3313 from jumpserver/dev

Dev
parents 7502a372 dc5598f8
...@@ -25,10 +25,12 @@ class NodeSerializer(BulkOrgResourceModelSerializer): ...@@ -25,10 +25,12 @@ class NodeSerializer(BulkOrgResourceModelSerializer):
read_only_fields = ['key', 'org_id'] read_only_fields = ['key', 'org_id']
def validate_value(self, data): def validate_value(self, data):
if not self.instance and not data: if self.instance:
return data instance = self.instance
instance = self.instance siblings = instance.get_siblings()
siblings = instance.get_siblings() else:
instance = Node.org_root()
siblings = instance.get_children()
if siblings.filter(value=data): if siblings.filter(value=data):
raise serializers.ValidationError( raise serializers.ValidationError(
_('The same level node name cannot be the same') _('The same level node name cannot be the same')
......
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# #
import os import os
from django.conf import settings
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
PERIOD_TASK_ENABLED = os.environ.get("PERIOD_TASK", "on") == 'on' ENV_PERIOD_TASK = os.environ.get("PERIOD_TASK", "on") == 'on'
PERIOD_TASK_ENABLED = settings.PERIOD_TASK_ENABLED and ENV_PERIOD_TASK
UPDATE_ASSETS_HARDWARE_TASKS = [ UPDATE_ASSETS_HARDWARE_TASKS = [
{ {
......
...@@ -374,6 +374,10 @@ defaults = { ...@@ -374,6 +374,10 @@ defaults = {
'RADIUS_SERVER': 'localhost', 'RADIUS_SERVER': 'localhost',
'RADIUS_PORT': 1812, 'RADIUS_PORT': 1812,
'RADIUS_SECRET': '', 'RADIUS_SECRET': '',
'AUTH_LDAP_SEARCH_PAGED_SIZE': 1000,
'AUTH_LDAP_SYNC_IS_PERIODIC': False,
'AUTH_LDAP_SYNC_INTERVAL': None,
'AUTH_LDAP_SYNC_CRONTAB': None,
'HTTP_BIND_HOST': '0.0.0.0', 'HTTP_BIND_HOST': '0.0.0.0',
'HTTP_LISTEN_PORT': 8080, 'HTTP_LISTEN_PORT': 8080,
'WS_LISTEN_PORT': 8070, 'WS_LISTEN_PORT': 8070,
...@@ -386,8 +390,8 @@ defaults = { ...@@ -386,8 +390,8 @@ defaults = {
'PERM_SINGLE_ASSET_TO_UNGROUP_NODE': False, 'PERM_SINGLE_ASSET_TO_UNGROUP_NODE': False,
'WINDOWS_SSH_DEFAULT_SHELL': 'cmd', 'WINDOWS_SSH_DEFAULT_SHELL': 'cmd',
'FLOWER_URL': "127.0.0.1:5555", 'FLOWER_URL': "127.0.0.1:5555",
'AUTH_LDAP_SEARCH_PAGED_SIZE': 1000,
'DEFAULT_ORG_SHOW_ALL_USERS': True, 'DEFAULT_ORG_SHOW_ALL_USERS': True,
'PERIOD_TASK_ENABLED': True,
} }
......
...@@ -357,6 +357,7 @@ EMAIL_PORT = 25 ...@@ -357,6 +357,7 @@ EMAIL_PORT = 25
EMAIL_HOST_USER = 'noreply@jumpserver.org' EMAIL_HOST_USER = 'noreply@jumpserver.org'
EMAIL_HOST_PASSWORD = '' EMAIL_HOST_PASSWORD = ''
EMAIL_FROM = '' EMAIL_FROM = ''
EMAIL_RECIPIENT = ''
EMAIL_USE_SSL = False EMAIL_USE_SSL = False
EMAIL_USE_TLS = False EMAIL_USE_TLS = False
EMAIL_SUBJECT_PREFIX = '[JMS] ' EMAIL_SUBJECT_PREFIX = '[JMS] '
...@@ -425,6 +426,10 @@ OTP_VALID_WINDOW = CONFIG.OTP_VALID_WINDOW ...@@ -425,6 +426,10 @@ OTP_VALID_WINDOW = CONFIG.OTP_VALID_WINDOW
# Auth LDAP settings # Auth LDAP settings
AUTH_LDAP = False AUTH_LDAP = False
AUTH_LDAP_SEARCH_PAGED_SIZE = CONFIG.AUTH_LDAP_SEARCH_PAGED_SIZE AUTH_LDAP_SEARCH_PAGED_SIZE = CONFIG.AUTH_LDAP_SEARCH_PAGED_SIZE
AUTH_LDAP_SYNC_IS_PERIODIC = CONFIG.AUTH_LDAP_SYNC_IS_PERIODIC
AUTH_LDAP_SYNC_INTERVAL = CONFIG.AUTH_LDAP_SYNC_INTERVAL
AUTH_LDAP_SYNC_CRONTAB = CONFIG.AUTH_LDAP_SYNC_CRONTAB
AUTH_LDAP_SERVER_URI = 'ldap://localhost:389' AUTH_LDAP_SERVER_URI = 'ldap://localhost:389'
AUTH_LDAP_BIND_DN = 'cn=admin,dc=jumpserver,dc=org' AUTH_LDAP_BIND_DN = 'cn=admin,dc=jumpserver,dc=org'
AUTH_LDAP_BIND_PASSWORD = '' AUTH_LDAP_BIND_PASSWORD = ''
...@@ -645,3 +650,6 @@ CHANNEL_LAYERS = { ...@@ -645,3 +650,6 @@ CHANNEL_LAYERS = {
}, },
}, },
} }
# Enable internal period task
PERIOD_TASK_ENABLED = CONFIG.PERIOD_TASK_ENABLED
This diff is collapsed.
...@@ -114,8 +114,6 @@ def hello(name, callback=None): ...@@ -114,8 +114,6 @@ def hello(name, callback=None):
# @after_app_shutdown_clean_periodic # @after_app_shutdown_clean_periodic
# @register_as_period_task(interval=30) # @register_as_period_task(interval=30)
def hello123(): def hello123():
p = subprocess.Popen('ls /tmp', shell=True)
print("{} Hello world".format(datetime.datetime.now().strftime("%H:%M:%S")))
return None return None
......
...@@ -24,6 +24,8 @@ ...@@ -24,6 +24,8 @@
var port = document.location.port ? ":" + document.location.port : ""; var port = document.location.port ? ":" + document.location.port : "";
var url = "/ws/ops/tasks/" + "{{ task_id }}" + "/log/"; var url = "/ws/ops/tasks/" + "{{ task_id }}" + "/log/";
var wsURL = scheme + "://" + document.location.hostname + port + url; var wsURL = scheme + "://" + document.location.hostname + port + url;
var failOverPort = "{{ ws_port }}";
var failOverWsURL = scheme + "://" + document.location.hostname + ':' + failOverPort + url;
var term; var term;
var ws; var ws;
...@@ -38,13 +40,21 @@ ...@@ -38,13 +40,21 @@
}); });
term.open(document.getElementById('term')); term.open(document.getElementById('term'));
term.resize(120, 30); term.resize(120, 30);
ws = new WebSocket(wsURL); ws = new WebSocket(wsURL);
ws.onmessage = function(e) { ws.onmessage = function(e) {
var data = JSON.parse(e.data); var data = JSON.parse(e.data);
term.write(data.message); term.write(data.message);
}; };
ws.onerror = function (e) { ws.onerror = function (e) {
term.write("Connect websocket server error") ws = new WebSocket(failOverWsURL);
ws.onmessage = function(e) {
var data = JSON.parse(e.data);
term.write(data.message);
};
ws.onerror = function (e) {
term.write("Connect websocket server error")
}
} }
}); });
</script> </script>
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# #
from django.views.generic import TemplateView from django.views.generic import TemplateView
from django.conf import settings
from common.permissions import PermissionsMixin, IsOrgAdmin, IsOrgAuditor from common.permissions import PermissionsMixin, IsOrgAdmin, IsOrgAuditor
...@@ -14,5 +15,8 @@ class CeleryTaskLogView(PermissionsMixin, TemplateView): ...@@ -14,5 +15,8 @@ class CeleryTaskLogView(PermissionsMixin, TemplateView):
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs) context = super().get_context_data(**kwargs)
context.update({'task_id': self.kwargs.get('pk')}) context.update({
'task_id': self.kwargs.get('pk'),
'ws_port': settings.CONFIG.WS_LISTEN_PORT
})
return context return context
...@@ -30,6 +30,7 @@ class MailTestingAPI(APIView): ...@@ -30,6 +30,7 @@ class MailTestingAPI(APIView):
serializer = self.serializer_class(data=request.data) serializer = self.serializer_class(data=request.data)
if serializer.is_valid(): if serializer.is_valid():
email_from = serializer.validated_data["EMAIL_FROM"] email_from = serializer.validated_data["EMAIL_FROM"]
email_recipient = serializer.validated_data["EMAIL_RECIPIENT"]
email_host_user = serializer.validated_data["EMAIL_HOST_USER"] email_host_user = serializer.validated_data["EMAIL_HOST_USER"]
for k, v in serializer.validated_data.items(): for k, v in serializer.validated_data.items():
if k.startswith('EMAIL'): if k.startswith('EMAIL'):
...@@ -38,11 +39,12 @@ class MailTestingAPI(APIView): ...@@ -38,11 +39,12 @@ class MailTestingAPI(APIView):
subject = "Test" subject = "Test"
message = "Test smtp setting" message = "Test smtp setting"
email_from = email_from or email_host_user email_from = email_from or email_host_user
send_mail(subject, message, email_from, [email_from]) email_recipient = email_recipient or email_from
send_mail(subject, message, email_from, [email_recipient])
except Exception as e: except Exception as e:
return Response({"error": str(e)}, status=401) return Response({"error": str(e)}, status=401)
return Response({"msg": self.success_message.format(email_host_user)}) return Response({"msg": self.success_message.format(email_recipient)})
else: else:
return Response({"error": str(serializer.errors)}, status=401) return Response({"error": str(serializer.errors)}, status=401)
......
...@@ -89,6 +89,10 @@ class EmailSettingForm(BaseForm): ...@@ -89,6 +89,10 @@ class EmailSettingForm(BaseForm):
"Tips: Send mail account, default SMTP account as the send account" "Tips: Send mail account, default SMTP account as the send account"
) )
) )
EMAIL_RECIPIENT = forms.CharField(
max_length=128, label=_("Test recipient"), initial='', required=False,
help_text=_("Tips: Used only as a test mail recipient")
)
EMAIL_USE_SSL = forms.BooleanField( EMAIL_USE_SSL = forms.BooleanField(
label=_("Use SSL"), initial=False, required=False, label=_("Use SSL"), initial=False, required=False,
help_text=_("If SMTP port is 465, may be select") help_text=_("If SMTP port is 465, may be select")
......
...@@ -7,6 +7,7 @@ class MailTestSerializer(serializers.Serializer): ...@@ -7,6 +7,7 @@ class MailTestSerializer(serializers.Serializer):
EMAIL_HOST_USER = serializers.CharField(max_length=1024) EMAIL_HOST_USER = serializers.CharField(max_length=1024)
EMAIL_HOST_PASSWORD = serializers.CharField(required=False, allow_blank=True) EMAIL_HOST_PASSWORD = serializers.CharField(required=False, allow_blank=True)
EMAIL_FROM = serializers.CharField(required=False, allow_blank=True) EMAIL_FROM = serializers.CharField(required=False, allow_blank=True)
EMAIL_RECIPIENT = serializers.CharField(required=False, allow_blank=True)
EMAIL_USE_SSL = serializers.BooleanField(default=False) EMAIL_USE_SSL = serializers.BooleanField(default=False)
EMAIL_USE_TLS = serializers.BooleanField(default=False) EMAIL_USE_TLS = serializers.BooleanField(default=False)
......
...@@ -170,7 +170,7 @@ class LDAPUtil: ...@@ -170,7 +170,7 @@ class LDAPUtil:
email = construct_user_email(username, email) email = construct_user_email(username, email)
return email return email
def create_or_update_users(self, user_items, force_update=True): def create_or_update_users(self, user_items):
succeed = failed = 0 succeed = failed = 0
for user_item in user_items: for user_item in user_items:
exist = user_item.pop('existing', False) exist = user_item.pop('existing', False)
...@@ -180,13 +180,14 @@ class LDAPUtil: ...@@ -180,13 +180,14 @@ class LDAPUtil:
else: else:
ok, error = self.update_user(user_item) ok, error = self.update_user(user_item)
if not ok: if not ok:
logger.info("Failed User: {}".format(user_item))
failed += 1 failed += 1
else: else:
succeed += 1 succeed += 1
result = {'total': len(user_items), 'succeed': succeed, 'failed': failed} result = {'total': len(user_items), 'succeed': succeed, 'failed': failed}
return result return result
def sync_users(self, username_list): def sync_users(self, username_list=None):
user_items = self.search_filter_user_items(username_list) user_items = self.search_filter_user_items(username_list)
result = self.create_or_update_users(user_items) result = self.create_or_update_users(user_items)
return result return result
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
# #
from celery import shared_task from celery import shared_task
from django.conf import settings
from ops.celery.utils import create_or_update_celery_periodic_tasks from ops.celery.utils import create_or_update_celery_periodic_tasks
from ops.celery.decorator import after_app_ready_start from ops.celery.decorator import after_app_ready_start
...@@ -10,6 +11,7 @@ from .models import User ...@@ -10,6 +11,7 @@ from .models import User
from .utils import ( from .utils import (
send_password_expiration_reminder_mail, send_user_expiration_reminder_mail send_password_expiration_reminder_mail, send_user_expiration_reminder_mail
) )
from settings.utils import LDAPUtil
logger = get_logger(__file__) logger = get_logger(__file__)
...@@ -66,3 +68,36 @@ def check_user_expired_periodic(): ...@@ -66,3 +68,36 @@ def check_user_expired_periodic():
} }
create_or_update_celery_periodic_tasks(tasks) create_or_update_celery_periodic_tasks(tasks)
@shared_task
def sync_ldap_user():
logger.info("Start sync ldap user periodic task")
util = LDAPUtil()
result = util.sync_users()
logger.info("Result: {}".format(result))
@shared_task
@after_app_ready_start
def sync_ldap_user_periodic():
if not settings.AUTH_LDAP:
return
if not settings.AUTH_LDAP_SYNC_IS_PERIODIC:
return
interval = settings.AUTH_LDAP_SYNC_INTERVAL
if isinstance(interval, int):
interval = interval * 3600
else:
interval = None
crontab = settings.AUTH_LDAP_SYNC_CRONTAB
tasks = {
'sync_ldap_user_periodic': {
'task': sync_ldap_user.name,
'interval': interval,
'crontab': crontab,
'enabled': True,
}
}
create_or_update_celery_periodic_tasks(tasks)
...@@ -72,6 +72,13 @@ REDIS_PORT: 6379 ...@@ -72,6 +72,13 @@ REDIS_PORT: 6379
# RADIUS_PORT: 1812 # RADIUS_PORT: 1812
# RADIUS_SECRET: # RADIUS_SECRET:
# LDAP/AD 设置定时同步参数
# 启用/禁用
# AUTH_LDAP_SYNC_IS_PERIODIC: True
# 单位: 时
# AUTH_LDAP_SYNC_INTERVAL: 12
# Crontab 表达式
# AUTH_LDAP_SYNC_CRONTAB: * 6 * * *
# OTP settings # OTP settings
# OTP/MFA 配置 # OTP/MFA 配置
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment