Unverified Commit bf92b61b authored by BaiJiangJie's avatar BaiJiangJie Committed by GitHub

Merge pull request #3389 from jumpserver/dev

Dev
parents 69bcf3de f6d2ac9b
......@@ -4,11 +4,11 @@
from django.utils.translation import ugettext_lazy as _
GENERAL_LIMIT_SPECIAL_CHARACTERS_HELP_TEXT = _(
'Only Numbers、letters、 chinese and characters ( {} ) are allowed'
).format(" ".join(['.', '_', '@', '-']))
GENERAL_FORBIDDEN_SPECIAL_CHARACTERS_HELP_TEXT = _(
'Cannot contain special characters: [ {} ]'
).format(" ".join(['/', '\\']))
GENERAL_LIMIT_SPECIAL_CHARACTERS_PATTERN = r"^[\._@\w-]+$"
GENERAL_FORBIDDEN_SPECIAL_CHARACTERS_PATTERN = r"[/\\]"
GENERAL_LIMIT_SPECIAL_CHARACTERS_ERROR_MSG = \
GENERAL_FORBIDDEN_SPECIAL_CHARACTERS_ERROR_MSG = \
_("* The contains characters that are not allowed")
......@@ -7,7 +7,7 @@ from common.utils import get_logger
from orgs.mixins.forms import OrgModelForm
from ..models import Asset, Node
from ..const import GENERAL_LIMIT_SPECIAL_CHARACTERS_HELP_TEXT
from ..const import GENERAL_FORBIDDEN_SPECIAL_CHARACTERS_HELP_TEXT
logger = get_logger(__file__)
......@@ -69,7 +69,7 @@ class AssetCreateForm(OrgModelForm):
'nodes': _("Node"),
}
help_texts = {
'hostname': GENERAL_LIMIT_SPECIAL_CHARACTERS_HELP_TEXT,
'hostname': GENERAL_FORBIDDEN_SPECIAL_CHARACTERS_HELP_TEXT,
'admin_user': _(
'root or other NOPASSWD sudo privilege user existed in asset,'
'If asset is windows or other set any one, more see admin user left menu'
......@@ -116,7 +116,7 @@ class AssetUpdateForm(OrgModelForm):
'nodes': _("Node"),
}
help_texts = {
'hostname': GENERAL_LIMIT_SPECIAL_CHARACTERS_HELP_TEXT,
'hostname': GENERAL_FORBIDDEN_SPECIAL_CHARACTERS_HELP_TEXT,
'admin_user': _(
'root or other NOPASSWD sudo privilege user existed in asset,'
'If asset is windows or other set any one, more see admin user left menu'
......
......@@ -6,7 +6,7 @@ from django.utils.translation import gettext_lazy as _
from common.utils import validate_ssh_private_key, ssh_pubkey_gen, get_logger
from orgs.mixins.forms import OrgModelForm
from ..models import AdminUser, SystemUser
from ..const import GENERAL_LIMIT_SPECIAL_CHARACTERS_HELP_TEXT
from ..const import GENERAL_FORBIDDEN_SPECIAL_CHARACTERS_HELP_TEXT
logger = get_logger(__file__)
__all__ = [
......@@ -99,7 +99,7 @@ class SystemUserForm(OrgModelForm, PasswordAndKeyAuthForm):
}),
}
help_texts = {
'name': GENERAL_LIMIT_SPECIAL_CHARACTERS_HELP_TEXT,
'name': GENERAL_FORBIDDEN_SPECIAL_CHARACTERS_HELP_TEXT,
'auto_push': _('Auto push system user to asset'),
'priority': _('1-100, High level will be using login asset as default, '
'if user was granted more than 2 system user'),
......
......@@ -9,8 +9,8 @@ from orgs.mixins.serializers import BulkOrgResourceModelSerializer
from common.serializers import AdaptedBulkListSerializer
from ..models import Asset, Node, Label
from ..const import (
GENERAL_LIMIT_SPECIAL_CHARACTERS_PATTERN,
GENERAL_LIMIT_SPECIAL_CHARACTERS_ERROR_MSG
GENERAL_FORBIDDEN_SPECIAL_CHARACTERS_PATTERN,
GENERAL_FORBIDDEN_SPECIAL_CHARACTERS_ERROR_MSG
)
from .base import ConnectivitySerializer
......@@ -98,10 +98,10 @@ class AssetSerializer(BulkOrgResourceModelSerializer):
@staticmethod
def validate_hostname(hostname):
pattern = GENERAL_LIMIT_SPECIAL_CHARACTERS_PATTERN
res = re.match(pattern, hostname)
if res is None:
msg = GENERAL_LIMIT_SPECIAL_CHARACTERS_ERROR_MSG
pattern = GENERAL_FORBIDDEN_SPECIAL_CHARACTERS_PATTERN
res = re.search(pattern, hostname)
if res is not None:
msg = GENERAL_FORBIDDEN_SPECIAL_CHARACTERS_ERROR_MSG
raise serializers.ValidationError(msg)
return hostname
......
......@@ -8,8 +8,8 @@ from common.utils import ssh_pubkey_gen
from orgs.mixins.serializers import BulkOrgResourceModelSerializer
from ..models import SystemUser
from ..const import (
GENERAL_LIMIT_SPECIAL_CHARACTERS_PATTERN,
GENERAL_LIMIT_SPECIAL_CHARACTERS_ERROR_MSG
GENERAL_FORBIDDEN_SPECIAL_CHARACTERS_PATTERN,
GENERAL_FORBIDDEN_SPECIAL_CHARACTERS_ERROR_MSG
)
from .base import AuthSerializer, AuthSerializerMixin
......@@ -41,10 +41,10 @@ class SystemUserSerializer(AuthSerializerMixin, BulkOrgResourceModelSerializer):
@staticmethod
def validate_name(name):
pattern = GENERAL_LIMIT_SPECIAL_CHARACTERS_PATTERN
res = re.match(pattern, name)
if res is None:
msg = GENERAL_LIMIT_SPECIAL_CHARACTERS_ERROR_MSG
pattern = GENERAL_FORBIDDEN_SPECIAL_CHARACTERS_PATTERN
res = re.search(pattern, name)
if res is not None:
msg = GENERAL_FORBIDDEN_SPECIAL_CHARACTERS_ERROR_MSG
raise serializers.ValidationError(msg)
return name
......
......@@ -380,6 +380,7 @@ defaults = {
'AUTH_LDAP_SYNC_INTERVAL': None,
'AUTH_LDAP_SYNC_CRONTAB': None,
'AUTH_LDAP_USER_LOGIN_ONLY_IN_USERS': False,
'AUTH_LDAP_OPTIONS_OPT_REFERRALS': -1,
'HTTP_BIND_HOST': '0.0.0.0',
'HTTP_LISTEN_PORT': 8080,
'WS_LISTEN_PORT': 8070,
......
......@@ -440,6 +440,7 @@ AUTH_LDAP_START_TLS = False
AUTH_LDAP_USER_ATTR_MAP = {"username": "cn", "name": "sn", "email": "mail"}
AUTH_LDAP_GLOBAL_OPTIONS = {
ldap.OPT_X_TLS_REQUIRE_CERT: ldap.OPT_X_TLS_NEVER,
ldap.OPT_REFERRALS: CONFIG.AUTH_LDAP_OPTIONS_OPT_REFERRALS
}
LDAP_CERT_FILE = os.path.join(PROJECT_DIR, "data", "certs", "ldap_ca.pem")
if os.path.isfile(LDAP_CERT_FILE):
......
This diff is collapsed.
......@@ -5,8 +5,8 @@ from rest_framework import serializers
from users.models import User, UserGroup
from assets.models import Asset, Domain, AdminUser, SystemUser, Label
from assets.const import (
GENERAL_LIMIT_SPECIAL_CHARACTERS_PATTERN,
GENERAL_LIMIT_SPECIAL_CHARACTERS_ERROR_MSG
GENERAL_FORBIDDEN_SPECIAL_CHARACTERS_PATTERN,
GENERAL_FORBIDDEN_SPECIAL_CHARACTERS_ERROR_MSG
)
from perms.models import AssetPermission
from common.serializers import AdaptedBulkListSerializer
......@@ -24,10 +24,10 @@ class OrgSerializer(ModelSerializer):
@staticmethod
def validate_name(name):
pattern = GENERAL_LIMIT_SPECIAL_CHARACTERS_PATTERN
res = re.match(pattern, name)
if res is None:
msg = GENERAL_LIMIT_SPECIAL_CHARACTERS_ERROR_MSG
pattern = GENERAL_FORBIDDEN_SPECIAL_CHARACTERS_PATTERN
res = re.search(pattern, name)
if res is not None:
msg = GENERAL_FORBIDDEN_SPECIAL_CHARACTERS_ERROR_MSG
raise serializers.ValidationError(msg)
return name
......
......@@ -20,6 +20,10 @@ class ActionField(forms.MultipleChoiceField):
kwargs['initial'] = Action.ALL
kwargs['label'] = _("Action")
kwargs['widget'] = forms.CheckboxSelectMultiple()
kwargs['help_text'] = _(
'Tips: The RDP protocol does not support separate controls '
'for uploading or downloading files'
)
super().__init__(*args, **kwargs)
def to_python(self, value):
......@@ -89,10 +93,6 @@ class AssetPermissionForm(OrgModelForm):
labels = {
'nodes': _("Node"),
}
help_texts = {
'actions': _('Tips: The RDP protocol does not support separate '
'controls for uploading or downloading files')
}
def clean_user_groups(self):
users = self.cleaned_data.get('users')
......
......@@ -409,6 +409,43 @@ function makeLabel(data) {
return "<label class='detail-key'><b>" + data[0] + ": </b></label>" + data[1] + "</br>"
}
function parseTableFilter(value) {
var cleanValues = [];
var valuesArray = value.split(':');
for (var i=0; i<valuesArray.length; i++) {
var v = valuesArray[i].trim();
if (!v) {
continue
}
// 如果是最后一个元素,直接push,不需要再处理了, 因为最后一个肯定不是key
if (i === valuesArray.length -1) {
cleanValues.push(v);
continue
}
v = v.split(' ');
// 如果长度是1,直接push上
// 如果长度不是1,根据空格分隔后,最后面的是key
if (v.length === 1) {
cleanValues.push(v[0]);
} else {
var leaveData = v.slice(0, -1).join(' ').trim();
cleanValues.push(leaveData);
cleanValues.push(v.slice(-1)[0]);
}
}
var filter = {};
var key = '';
for (i=0; i<cleanValues.length; i++) {
if (i%2 === 0) {
key = cleanValues[i]
} else {
value = cleanValues[i];
filter[key] = value
}
}
return filter;
}
var jumpserver = {};
jumpserver.checked = false;
......@@ -606,27 +643,17 @@ jumpserver.initServerSideDataTable = function (options) {
delete data.start;
}
if (data.search !== null) {
var search_val = data.search.value;
var search_list = search_val.split(" ");
var search_attr = {};
var search_raw = [];
search_list.map(function (val, index) {
var kv = val.split(":");
if (kv.length === 2) {
var value = kv[1];
var key = kv[0].trim();
value = value.replace("+", " ").trim();
search_attr[key] = value
var searchValue = data.search.value;
var searchFilter = parseTableFilter(searchValue);
if (Object.keys(searchFilter).length === 0) {
data.search = searchValue;
} else {
search_raw.push(kv)
}
});
data.search = search_raw.join("");
$.each(search_attr, function (k, v) {
data.search = '';
$.each(searchFilter, function (k, v) {
data[k] = v
})
}
}
if (data.order !== null && data.order.length === 1) {
var col = data.order[0].column;
var order = options.columns[col].data;
......
......@@ -73,16 +73,23 @@ REDIS_PORT: 6379
# RADIUS_SECRET:
# LDAP/AD settings
# LDAP 搜索分页数量
# AUTH_LDAP_SEARCH_PAGED_SIZE: 1000
#
# 定时同步用户
# 启用/禁用
# 启用 / 禁用
# AUTH_LDAP_SYNC_IS_PERIODIC: True
# 单位: 时
# 同步间隔 (单位: 时) (优先)
# AUTH_LDAP_SYNC_INTERVAL: 12
# Crontab 表达式
# AUTH_LDAP_SYNC_CRONTAB: * 6 * * *
#
# LDAP 用户登录时仅允许在用户列表中的用户执行 LDAP Server 认证
# AUTH_LDAP_USER_LOGIN_ONLY_IN_USERS: False
#
# LDAP 认证时如果日志中出现以下信息将参数设置为 0 (详情参见:https://www.python-ldap.org/en/latest/faq.html)
# In order to perform this operation a successful bind must be completed on the connection
# AUTH_LDAP_OPTIONS_OPT_REFERRALS: -1
# OTP settings
......
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