Commit 8081a864 authored by BaiJiangJie's avatar BaiJiangJie

Merge branch 'dev' into dev_ldap_sync_timing

parents 4b7cd796 1a82b858
...@@ -140,8 +140,7 @@ function replaceNodeAssetsAdminUser(nodes) { ...@@ -140,8 +140,7 @@ function replaceNodeAssetsAdminUser(nodes) {
jumpserver.nodes_selected = {}; jumpserver.nodes_selected = {};
$(document).ready(function () { $(document).ready(function () {
var url = "{% url 'api-assets:node-list' %}"; nodesSelect2Init(".nodes-select2")
nodesSelect2Init(".nodes-select2", url)
.on('select2:select', function(evt) { .on('select2:select', function(evt) {
var data = evt.params.data; var data = evt.params.data;
jumpserver.nodes_selected[data.id] = data.text; jumpserver.nodes_selected[data.id] = data.text;
......
...@@ -110,8 +110,7 @@ $(document).ready(function () { ...@@ -110,8 +110,7 @@ $(document).ready(function () {
$('.select2').select2({ $('.select2').select2({
allowClear: true allowClear: true
}); });
var url = "{% url 'api-assets:node-list' %}"; nodesSelect2Init(".nodes-select2");
nodesSelect2Init(".nodes-select2", url);
$(".labels").select2({ $(".labels").select2({
allowClear: true, allowClear: true,
templateSelection: format templateSelection: format
......
...@@ -287,8 +287,7 @@ function refreshAssetHardware() { ...@@ -287,8 +287,7 @@ function refreshAssetHardware() {
$(document).ready(function () { $(document).ready(function () {
var url = "{% url 'api-assets:node-list' %}"; nodesSelect2Init(".nodes-select2")
nodesSelect2Init(".nodes-select2", url)
.on('select2:select', function(evt) { .on('select2:select', function(evt) {
var data = evt.params.data; var data = evt.params.data;
jumpserver.nodes_selected[data.id] = data.text; jumpserver.nodes_selected[data.id] = data.text;
......
...@@ -153,8 +153,7 @@ jumpserver.nodes_selected = {}; ...@@ -153,8 +153,7 @@ jumpserver.nodes_selected = {};
$(document).ready(function () { $(document).ready(function () {
$('.select2').select2() $('.select2').select2()
var url = "{% url 'api-assets:node-list' %}"; nodesSelect2Init(".nodes-select2")
nodesSelect2Init(".nodes-select2", url)
.on('select2:select', function(evt) { .on('select2:select', function(evt) {
var data = evt.params.data; var data = evt.params.data;
jumpserver.nodes_selected[data.id] = data.text; jumpserver.nodes_selected[data.id] = data.text;
......
...@@ -15,7 +15,8 @@ ...@@ -15,7 +15,8 @@
</style> </style>
<div class="alert alert-info help-message" style="margin-left: 0px; margin-right: 0px;"> <div class="alert alert-info help-message" style="margin-left: 0px; margin-right: 0px;">
{% trans 'Using api key sign api header, every requests header difference'%}, <a href="https://tools.ietf.org/html/draft-cavage-http-signatures-08">{% trans 'docs' %} </a> {% trans 'Using api key sign api header, every requests header difference'%}
<a href="https://jumpserver.readthedocs.io/zh/master/api_auth.html#access-key" target="_blank">{% trans 'docs' %} </a>
</div> </div>
<div class="uc pull-left m-r-0 m-t-10"> <div class="uc pull-left m-r-0 m-t-10">
<button class="btn btn-primary btn-sm" id="create-btn" href="#"> {% trans "Create" %} </button> <button class="btn btn-primary btn-sm" id="create-btn" href="#"> {% trans "Create" %} </button>
......
...@@ -387,6 +387,7 @@ defaults = { ...@@ -387,6 +387,7 @@ defaults = {
'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, 'AUTH_LDAP_SEARCH_PAGED_SIZE': 1000,
'DEFAULT_ORG_SHOW_ALL_USERS': True,
} }
......
...@@ -624,6 +624,8 @@ ASSETS_PERM_CACHE_TIME = CONFIG.ASSETS_PERM_CACHE_TIME ...@@ -624,6 +624,8 @@ ASSETS_PERM_CACHE_TIME = CONFIG.ASSETS_PERM_CACHE_TIME
# Asset user auth external backend, default AuthBook backend # Asset user auth external backend, default AuthBook backend
BACKEND_ASSET_USER_AUTH_VAULT = False BACKEND_ASSET_USER_AUTH_VAULT = False
DEFAULT_ORG_SHOW_ALL_USERS = CONFIG.DEFAULT_ORG_SHOW_ALL_USERS
PERM_SINGLE_ASSET_TO_UNGROUP_NODE = CONFIG.PERM_SINGLE_ASSET_TO_UNGROUP_NODE PERM_SINGLE_ASSET_TO_UNGROUP_NODE = CONFIG.PERM_SINGLE_ASSET_TO_UNGROUP_NODE
WINDOWS_SSH_DEFAULT_SHELL = CONFIG.WINDOWS_SSH_DEFAULT_SHELL WINDOWS_SSH_DEFAULT_SHELL = CONFIG.WINDOWS_SSH_DEFAULT_SHELL
FLOWER_URL = CONFIG.FLOWER_URL FLOWER_URL = CONFIG.FLOWER_URL
......
...@@ -6135,7 +6135,7 @@ msgstr "管理员" ...@@ -6135,7 +6135,7 @@ msgstr "管理员"
#: xpack/plugins/orgs/forms.py:42 #: xpack/plugins/orgs/forms.py:42
msgid "Select auditor" msgid "Select auditor"
msgstr "选择审计员" msgstr "选择审计员"
#: xpack/plugins/orgs/meta.py:8 xpack/plugins/orgs/views.py:26 #: xpack/plugins/orgs/meta.py:8 xpack/plugins/orgs/views.py:26
#: xpack/plugins/orgs/views.py:43 xpack/plugins/orgs/views.py:60 #: xpack/plugins/orgs/views.py:43 xpack/plugins/orgs/views.py:60
......
import uuid import uuid
from django.conf import settings
from django.db import models from django.db import models
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
...@@ -75,7 +76,10 @@ class Organization(models.Model): ...@@ -75,7 +76,10 @@ class Organization(models.Model):
from users.models import User from users.models import User
if self.is_real(): if self.is_real():
return self.users.all() return self.users.all()
return User.objects.filter(role=User.ROLE_USER) users = User.objects.filter(role=User.ROLE_USER)
if self.is_default() and not settings.DEFAULT_ORG_SHOW_ALL_USERS:
users = users.filter(related_user_orgs__isnull=True)
return users
def get_org_admins(self): def get_org_admins(self):
from users.models import User from users.models import User
...@@ -130,7 +134,7 @@ class Organization(models.Model): ...@@ -130,7 +134,7 @@ class Organization(models.Model):
return admin_orgs return admin_orgs
@classmethod @classmethod
def get_user_user_orgs(self, user): def get_user_user_orgs(cls, user):
user_orgs = [] user_orgs = []
if user.is_anonymous: if user.is_anonymous:
return user_orgs return user_orgs
......
...@@ -11,8 +11,17 @@ def get_org_from_request(request): ...@@ -11,8 +11,17 @@ def get_org_from_request(request):
oid = request.session.get("oid") oid = request.session.get("oid")
if not oid: if not oid:
oid = request.META.get("HTTP_X_JMS_ORG") oid = request.META.get("HTTP_X_JMS_ORG")
request_params_oid = request.GET.get("oid")
if request_params_oid:
oid = request.GET.get("oid")
if not oid: if not oid:
oid = Organization.DEFAULT_ID oid = Organization.DEFAULT_ID
if oid.lower() == "default":
oid = Organization.DEFAULT_ID
elif oid.lower() == "root":
oid = Organization.ROOT_ID
org = Organization.get_instance(oid) org = Organization.get_instance(oid)
return org return org
......
...@@ -38,20 +38,21 @@ class AssetPermissionForm(OrgModelForm): ...@@ -38,20 +38,21 @@ class AssetPermissionForm(OrgModelForm):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
users_field = self.fields.get('users')
users_field.queryset = current_org.get_org_members(exclude=('Auditor',))
if self.data: if self.data:
return return
# 前端渲染优化, 防止过多资产 # 前端渲染优化, 防止过多资产
users_field = self.fields.get('users')
assets_field = self.fields['assets'] assets_field = self.fields['assets']
nodes_field = self.fields['nodes'] nodes_field = self.fields['nodes']
if self.instance: if self.instance:
assets_field.queryset = self.instance.assets.all() assets_field.queryset = self.instance.assets.all()
nodes_field.queryset = self.instance.nodes.all() nodes_field.queryset = self.instance.nodes.all()
users_field.queryset = self.instance.users.all()
else: else:
assets_field.queryset = Asset.objects.none() assets_field.queryset = Asset.objects.none()
nodes_field.queryset = Node.objects.none() nodes_field.queryset = Node.objects.none()
users_field.queryset = []
def set_nodes_initial(self, nodes): def set_nodes_initial(self, nodes):
field = self.fields['nodes'] field = self.fields['nodes']
...@@ -70,7 +71,7 @@ class AssetPermissionForm(OrgModelForm): ...@@ -70,7 +71,7 @@ class AssetPermissionForm(OrgModelForm):
) )
widgets = { widgets = {
'users': forms.SelectMultiple( 'users': forms.SelectMultiple(
attrs={'class': 'select2', 'data-placeholder': _("User")} attrs={'class': 'users-select2', 'data-placeholder': _("User")}
), ),
'user_groups': forms.SelectMultiple( 'user_groups': forms.SelectMultiple(
attrs={'class': 'select2', 'data-placeholder': _("User group")} attrs={'class': 'select2', 'data-placeholder': _("User group")}
......
...@@ -17,9 +17,12 @@ __all__ = [ ...@@ -17,9 +17,12 @@ __all__ = [
class RemoteAppPermissionCreateUpdateForm(OrgModelForm): class RemoteAppPermissionCreateUpdateForm(OrgModelForm):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
users_field = self.fields.get('users') users_field = self.fields.get('users')
if hasattr(users_field, 'queryset'): if self.instance:
users_field.queryset = current_org.get_org_members(exclude=('Auditor',)) users_field.queryset = self.instance.users.all()
else:
users_field.queryset = []
class Meta: class Meta:
model = RemoteAppPermission model = RemoteAppPermission
...@@ -28,7 +31,7 @@ class RemoteAppPermissionCreateUpdateForm(OrgModelForm): ...@@ -28,7 +31,7 @@ class RemoteAppPermissionCreateUpdateForm(OrgModelForm):
) )
widgets = { widgets = {
'users': forms.SelectMultiple( 'users': forms.SelectMultiple(
attrs={'class': 'select2', 'data-placeholder': _('User')} attrs={'class': 'users-select2', 'data-placeholder': _('User')}
), ),
'user_groups': forms.SelectMultiple( 'user_groups': forms.SelectMultiple(
attrs={'class': 'select2', 'data-placeholder': _('User group')} attrs={'class': 'select2', 'data-placeholder': _('User group')}
......
...@@ -204,8 +204,7 @@ $(document).ready(function () { ...@@ -204,8 +204,7 @@ $(document).ready(function () {
$('.select2').select2(); $('.select2').select2();
table = initAssetTable(); table = initAssetTable();
var nodeListUrl = "{% url 'api-assets:node-list' %}"; nodesSelect2Init(".nodes-select2");
nodesSelect2Init(".nodes-select2", nodeListUrl);
$("#id_assets").parent().find(".select2-selection").on('click', function (e) { $("#id_assets").parent().find(".select2-selection").on('click', function (e) {
if ($(e.target).attr('class') !== 'select2-selection__choice__remove'){ if ($(e.target).attr('class') !== 'select2-selection__choice__remove'){
......
...@@ -116,8 +116,8 @@ $(document).ready(function () { ...@@ -116,8 +116,8 @@ $(document).ready(function () {
$('.select2').select2({ $('.select2').select2({
closeOnSelect: false closeOnSelect: false
}); });
var url = "{% url 'api-assets:node-list' %}"; nodesSelect2Init(".nodes-select2");
nodesSelect2Init(".nodes-select2", url); usersSelect2Init(".users-select2");
$('#date_start').daterangepicker(dateOptions); $('#date_start').daterangepicker(dateOptions);
$('#date_expired').daterangepicker(dateOptions); $('#date_expired').daterangepicker(dateOptions);
......
...@@ -114,6 +114,7 @@ $(document).ready(function () { ...@@ -114,6 +114,7 @@ $(document).ready(function () {
$('.select2').select2({ $('.select2').select2({
closeOnSelect: false closeOnSelect: false
}); });
usersSelect2Init('.users-select2');
$('#date_start').daterangepicker(dateOptions); $('#date_start').daterangepicker(dateOptions);
$('#date_expired').daterangepicker(dateOptions); $('#date_expired').daterangepicker(dateOptions);
}) })
......
...@@ -1177,6 +1177,9 @@ function readFile(ref) { ...@@ -1177,6 +1177,9 @@ function readFile(ref) {
} }
function nodesSelect2Init(selector, url) { function nodesSelect2Init(selector, url) {
if (!url) {
url = '/api/v1/assets/nodes/'
}
return $(selector).select2({ return $(selector).select2({
closeOnSelect: false, closeOnSelect: false,
ajax: { ajax: {
...@@ -1201,6 +1204,36 @@ function nodesSelect2Init(selector, url) { ...@@ -1201,6 +1204,36 @@ function nodesSelect2Init(selector, url) {
}) })
} }
function usersSelect2Init(selector, url) {
if (!url) {
url = '/api/v1/users/users/'
}
return $(selector).select2({
closeOnSelect: false,
ajax: {
url: url,
data: function (params) {
var page = params.page || 1;
var query = {
search: params.term,
offset: (page - 1) * 10,
limit: 10
};
return query
},
processResults: function (data) {
var results = $.map(data.results, function (v, i) {
var display = v.name + '(' + v.username +')';
return {id: v.id, text: display}
});
var more = !!data.next;
return {results: results, pagination: {"more": more}}
}
},
})
}
function showCeleryTaskLog(taskId) { function showCeleryTaskLog(taskId) {
var url = '/ops/celery/task/taskId/log/'.replace('taskId', taskId); var url = '/ops/celery/task/taskId/log/'.replace('taskId', taskId);
window.open(url, '', 'width=900,height=600') window.open(url, '', 'width=900,height=600')
......
...@@ -12,7 +12,7 @@ from rest_framework_bulk import BulkModelViewSet ...@@ -12,7 +12,7 @@ from rest_framework_bulk import BulkModelViewSet
from common.permissions import ( from common.permissions import (
IsOrgAdmin, IsCurrentUserOrReadOnly, IsOrgAdminOrAppUser, IsOrgAdmin, IsCurrentUserOrReadOnly, IsOrgAdminOrAppUser,
CanUpdateDeleteUser, CanUpdateDeleteUser, IsSuperUser
) )
from common.mixins import CommonApiMixin from common.mixins import CommonApiMixin
from common.utils import get_logger from common.utils import get_logger
...@@ -52,12 +52,15 @@ class UserViewSet(CommonApiMixin, BulkModelViewSet): ...@@ -52,12 +52,15 @@ class UserViewSet(CommonApiMixin, BulkModelViewSet):
self.send_created_signal(users) self.send_created_signal(users)
def get_queryset(self): def get_queryset(self):
queryset = current_org.get_org_members().prefetch_related('groups') queryset = current_org.get_org_members()\
.prefetch_related('groups')
return queryset return queryset
def get_permissions(self): def get_permissions(self):
if self.action in ["retrieve", "list"]: if self.action in ["retrieve", "list"]:
self.permission_classes = (IsOrgAdminOrAppUser,) self.permission_classes = (IsOrgAdminOrAppUser,)
if self.request.query_params.get('all'):
self.permission_classes = (IsSuperUser,)
return super().get_permissions() return super().get_permissions()
def perform_bulk_destroy(self, objects): def perform_bulk_destroy(self, objects):
......
...@@ -308,11 +308,11 @@ class UserBulkUpdateForm(OrgModelForm): ...@@ -308,11 +308,11 @@ class UserBulkUpdateForm(OrgModelForm):
class UserGroupForm(OrgModelForm): class UserGroupForm(OrgModelForm):
users = forms.ModelMultipleChoiceField( users = forms.ModelMultipleChoiceField(
queryset=User.objects.all(), queryset=User.objects.none(),
label=_("User"), label=_("User"),
widget=forms.SelectMultiple( widget=forms.SelectMultiple(
attrs={ attrs={
'class': 'select2', 'class': 'users-select2',
'data-placeholder': _('Select users') 'data-placeholder': _('Select users')
} }
), ),
...@@ -329,8 +329,10 @@ class UserGroupForm(OrgModelForm): ...@@ -329,8 +329,10 @@ class UserGroupForm(OrgModelForm):
if 'initial' not in kwargs: if 'initial' not in kwargs:
return return
users_field = self.fields.get('users') users_field = self.fields.get('users')
if hasattr(users_field, 'queryset'): if instance:
users_field.queryset = current_org.get_org_members(exclude=('Auditor',)) users_field.queryset = instance.users.all()
else:
users_field.queryset = User.objects.none()
def save(self, commit=True): def save(self, commit=True):
group = super().save(commit=commit) group = super().save(commit=commit)
......
...@@ -46,6 +46,7 @@ $(document).ready(function () { ...@@ -46,6 +46,7 @@ $(document).ready(function () {
$('.select2').select2({ $('.select2').select2({
closeOnSelect: false closeOnSelect: false
}); });
usersSelect2Init('.users-select2')
}) })
.on("submit", "form", function (evt) { .on("submit", "form", function (evt) {
evt.preventDefault(); evt.preventDefault();
......
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