Commit db8b0022 authored by ibuler's avatar ibuler

Update usergroup detail

parent bd882c8b
...@@ -24,12 +24,10 @@ from common.utils import validate_ssh_private_key, ssh_pubkey_gen ...@@ -24,12 +24,10 @@ from common.utils import validate_ssh_private_key, ssh_pubkey_gen
# #
class AssetCreateForm(forms.ModelForm): class AssetCreateForm(forms.ModelForm):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
instance = kwargs.get('instance', None) instance = kwargs.get('instance', None)
if instance: if instance:
initial = kwargs.get('initial', {}) initial = kwargs.get('initial', {})
#tags = instance.tags.all()
initial['tags'] = [t.pk for t in kwargs['instance'].tags.all()] initial['tags'] = [t.pk for t in kwargs['instance'].tags.all()]
super(AssetCreateForm, self).__init__(*args, **kwargs) super(AssetCreateForm, self).__init__(*args, **kwargs)
......
...@@ -8,7 +8,7 @@ from rest_framework_bulk import BulkListSerializer, BulkSerializerMixin ...@@ -8,7 +8,7 @@ from rest_framework_bulk import BulkListSerializer, BulkSerializerMixin
class AssetGroupSerializer(serializers.ModelSerializer): class AssetGroupSerializer(serializers.ModelSerializer):
assets_amount = serializers.SerializerMethodField() assets_amount = serializers.SerializerMethodField()
assets = serializers.PrimaryKeyRelatedField(many=True, read_only=True) # assets = serializers.PrimaryKeyRelatedField(many=True, read_only=True)
class Meta: class Meta:
model = AssetGroup model = AssetGroup
......
...@@ -5,13 +5,6 @@ ...@@ -5,13 +5,6 @@
{% block custom_head_css_js %} {% block custom_head_css_js %}
<link href="{% static 'css/plugins/select2/select2.min.css' %}" rel="stylesheet"> <link href="{% static 'css/plugins/select2/select2.min.css' %}" rel="stylesheet">
<script src="{% static 'js/plugins/select2/select2.full.min.js' %}"></script> <script src="{% static 'js/plugins/select2/select2.full.min.js' %}"></script>
<style>
div.dataTables_wrapper div.dataTables_filter,
.dataTables_length {
float: left;
}
</style>
{% endblock %} {% endblock %}
{% block content %} {% block content %}
<div class="wrapper wrapper-content animated fadeInRight"> <div class="wrapper wrapper-content animated fadeInRight">
...@@ -94,7 +87,7 @@ div.dataTables_wrapper div.dataTables_filter, ...@@ -94,7 +87,7 @@ div.dataTables_wrapper div.dataTables_filter,
$(document).ready(function () { $(document).ready(function () {
$('.select2').select2(); $('.select2').select2();
$('.select2-system-user').select2(); $('.select2-system-user').select2();
}) });
$('#add_asset').on('click',function(){ $('#add_asset').on('click',function(){
$('#modal').modal('show'); $('#modal').modal('show');
...@@ -104,7 +97,7 @@ div.dataTables_wrapper div.dataTables_filter, ...@@ -104,7 +97,7 @@ div.dataTables_wrapper div.dataTables_filter,
show: false, show: false,
backdrop: 'static', backdrop: 'static',
keyboard: 'false', keyboard: 'false',
remote:"{% url 'assets:asset-modal-list' %}?group_id={{ group_id }}", remote:"{% url 'assets:asset-modal-list' %}?group_id={{ group_id }}"
}); });
$('#modal').on('show.bs.modal',function(){ $('#modal').on('show.bs.modal',function(){
......
...@@ -46,9 +46,7 @@ ...@@ -46,9 +46,7 @@
</div> </div>
<script type="text/javascript"> <script type="text/javascript">
$(document).ready(function(){ $(document).ready(function(){
var table = $('#editable').DataTable({ var table = $('#editable').DataTable({
"aLengthMenu": [[10, 25, 50, -1], ["10", "25", "50", "all"]], "aLengthMenu": [[10, 25, 50, -1], ["10", "25", "50", "all"]],
"iDisplayLength":25, "iDisplayLength":25,
......
...@@ -208,7 +208,7 @@ class AssetModalListView(AdminUserRequiredMixin, ListView): ...@@ -208,7 +208,7 @@ class AssetModalListView(AdminUserRequiredMixin, ListView):
plain_id_lists = self.request.GET.get('plain_id_lists') plain_id_lists = self.request.GET.get('plain_id_lists')
self.s = self.request.GET.get('plain_id_lists') self.s = self.request.GET.get('plain_id_lists')
if "," in str(self.s): if "," in str(self.s):
self.plain_id_lists = [int(x) for x in self.s.split(',')] self.plain_id_lists = [int(x) for x in self.s.split(',')]
else: else:
self.plain_id_lists = [self.s] self.plain_id_lists = [self.s]
...@@ -218,19 +218,19 @@ class AssetModalListView(AdminUserRequiredMixin, ListView): ...@@ -218,19 +218,19 @@ class AssetModalListView(AdminUserRequiredMixin, ListView):
else: else:
plain_id_lists = [int(self.s)] plain_id_lists = [int(self.s)]
context = { context = {
'all_assets':plain_id_lists 'all_assets' :plain_id_lists
} }
kwargs.update(context) kwargs.update(context)
if group_id: if group_id:
group = AssetGroup.objects.get(id=group_id) group = AssetGroup.objects.get(id=group_id)
context = { context = {
'all_assets':[x.id for x in group.assets.all()] 'all_assets': [x.id for x in group.assets.all()]
} }
kwargs.update(context) kwargs.update(context)
if tag_id: if tag_id:
tag = Tag.objects.get(id=tag_id) tag = Tag.objects.get(id=tag_id)
context = { context = {
'all_assets':[x.id for x in tag.asset_set.all()] 'all_assets': [x.id for x in tag.asset_set.all()]
} }
kwargs.update(context) kwargs.update(context)
return super(AssetModalListView, self).get_context_data(**kwargs) return super(AssetModalListView, self).get_context_data(**kwargs)
......
...@@ -2,6 +2,3 @@ from __future__ import absolute_import, unicode_literals ...@@ -2,6 +2,3 @@ from __future__ import absolute_import, unicode_literals
from django.shortcuts import render from django.shortcuts import render
from django.views.generic import TemplateView from django.views.generic import TemplateView
...@@ -2,13 +2,14 @@ ...@@ -2,13 +2,14 @@
# #
from rest_framework.views import APIView, Response from rest_framework.views import APIView, Response
from rest_framework.generics import ListAPIView from rest_framework.generics import ListAPIView, get_object_or_404
from rest_framework import viewsets from rest_framework import viewsets
from users.backends import IsValidUser, IsSuperUser from users.backends import IsValidUser, IsSuperUser
from common.utils import get_object_or_none from common.utils import get_object_or_none
from .utils import get_user_granted_assets, get_user_granted_asset_groups, get_user_asset_permissions from .utils import get_user_granted_assets, get_user_granted_asset_groups, get_user_asset_permissions, \
get_user_group_asset_permissions, get_user_group_granted_assets
from .models import AssetPermission from .models import AssetPermission
from .hands import AssetGrantedSerializer, User, AssetGroup, Asset, AssetGroup from .hands import AssetGrantedSerializer, User, UserGroup, AssetGroup, Asset, AssetGroup, AssetGroupSerializer
from . import serializers from . import serializers
...@@ -20,12 +21,15 @@ class AssetPermissionViewSet(viewsets.ModelViewSet): ...@@ -20,12 +21,15 @@ class AssetPermissionViewSet(viewsets.ModelViewSet):
def get_queryset(self): def get_queryset(self):
queryset = super(AssetPermissionViewSet, self).get_queryset() queryset = super(AssetPermissionViewSet, self).get_queryset()
user_id = self.request.query_params.get('user', '') user_id = self.request.query_params.get('user', '')
user_group_id = self.request.query_params.get('user-group', '')
if user_id and user_id.isdigit(): if user_id and user_id.isdigit():
self.user_id = user_id user = get_object_or_404(User, id=int(user_id))
user = get_object_or_none(User, id=int(user_id)) queryset = get_user_asset_permissions(user)
if user:
queryset = get_user_asset_permissions(user) if user_group_id:
print(queryset) user_group = get_object_or_404(UserGroup, id=user_group_id)
queryset = get_user_group_asset_permissions(user_group)
return queryset return queryset
def get_serializer_class(self): def get_serializer_class(self):
...@@ -42,8 +46,8 @@ class RevokeUserAssetPermission(APIView): ...@@ -42,8 +46,8 @@ class RevokeUserAssetPermission(APIView):
user_id = str(request.data.get('user_id', '')) user_id = str(request.data.get('user_id', ''))
if permission_id and user_id and permission_id.isdigit() and user_id.isdigit(): if permission_id and user_id and permission_id.isdigit() and user_id.isdigit():
asset_permission = get_object_or_none(AssetPermission, id=int(permission_id)) asset_permission = get_object_or_404(AssetPermission, id=int(permission_id))
user = get_object_or_none(User, id=int(user_id)) user = get_object_or_404(User, id=int(user_id))
if asset_permission and user: if asset_permission and user:
asset_permission.users.remove(user) asset_permission.users.remove(user)
...@@ -51,7 +55,54 @@ class RevokeUserAssetPermission(APIView): ...@@ -51,7 +55,54 @@ class RevokeUserAssetPermission(APIView):
return Response({'msg': 'failed'}, status=404) return Response({'msg': 'failed'}, status=404)
class UserAssetsApi(ListAPIView): class RevokeUserGroupAssetPermission(APIView):
permission_classes = (IsSuperUser,)
def put(self, request, *args, **kwargs):
permission_id = str(request.data.get('id', ''))
user_group_id = str(request.data.get('user_group_id', ''))
if permission_id and user_group_id and permission_id.isdigit() and user_group_id.isdigit():
asset_permission = get_object_or_404(AssetPermission, id=int(permission_id))
user_group = get_object_or_404(UserGroup, id=int(user_group_id))
if asset_permission and user_group:
asset_permission.user_groups.remove(user_group)
return Response({'msg': 'success'})
return Response({'msg': 'failed'}, status=404)
class UserGrantedAssetsApi(ListAPIView):
permission_classes = (IsSuperUser,)
serializer_class = AssetGrantedSerializer
def get_queryset(self):
user_id = self.kwargs.get('pk', '')
if user_id:
user = get_object_or_404(User, id=user_id)
queryset = get_user_granted_assets(user)
else:
queryset = []
return queryset
class UserGrantedAssetGroupsApi(ListAPIView):
permission_classes = (IsSuperUser,)
serializer_class = AssetGroupSerializer
def get_queryset(self):
user_id = self.kwargs.get('pk', '')
if user_id:
user = get_object_or_404(User, id=user_id)
queryset = get_user_granted_asset_groups(user)
else:
queryset = []
return queryset
class MyGrantedAssetsApi(ListAPIView):
permission_classes = (IsValidUser,) permission_classes = (IsValidUser,)
serializer_class = AssetGrantedSerializer serializer_class = AssetGrantedSerializer
...@@ -59,11 +110,12 @@ class UserAssetsApi(ListAPIView): ...@@ -59,11 +110,12 @@ class UserAssetsApi(ListAPIView):
user = self.request.user user = self.request.user
if user: if user:
queryset = get_user_granted_assets(user) queryset = get_user_granted_assets(user)
return queryset else:
return [] queryset = []
return queryset
class UserAssetsGroupsApi(APIView): class MyGrantedAssetsGroupsApi(APIView):
permission_classes = (IsValidUser,) permission_classes = (IsValidUser,)
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
...@@ -87,7 +139,7 @@ class UserAssetsGroupsApi(APIView): ...@@ -87,7 +139,7 @@ class UserAssetsGroupsApi(APIView):
return Response(asset_groups_json, status=200) return Response(asset_groups_json, status=200)
class UserAssetsGroupAssetsApi(ListAPIView): class MyAssetGroupAssetsApi(ListAPIView):
permission_classes = (IsValidUser,) permission_classes = (IsValidUser,)
serializer_class = AssetGrantedSerializer serializer_class = AssetGrantedSerializer
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
from users.utils import AdminUserRequiredMixin from users.utils import AdminUserRequiredMixin
from users.models import User, UserGroup from users.models import User, UserGroup
from assets.models import Asset, AssetGroup, SystemUser from assets.models import Asset, AssetGroup, SystemUser
from assets.serializers import AssetGrantedSerializer from assets.serializers import AssetGrantedSerializer, AssetGroupSerializer
def associate_system_users_with_assets(system_users, assets, asset_groups): def associate_system_users_with_assets(system_users, assets, asset_groups):
......
...@@ -26,12 +26,21 @@ router = routers.DefaultRouter() ...@@ -26,12 +26,21 @@ router = routers.DefaultRouter()
router.register('v1/asset-permissions', api.AssetPermissionViewSet, 'api-asset-permission') router.register('v1/asset-permissions', api.AssetPermissionViewSet, 'api-asset-permission')
urlpatterns += [ urlpatterns += [
url(r'^v1/user/assets/$', api.UserAssetsApi.as_view(), name='api-user-assets'), url(r'^v1/user/my/assets/$', api.MyGrantedAssetsApi.as_view(), name='api-my-assets'),
url(r'^v1/user/my/asset-groups/$', api.MyGrantedAssetsGroupsApi.as_view(), name='api-my-asset-groups'),
url(r'^v1/user/my/asset-group/(?P<pk>[0-9]+)/assets/$', api.MyAssetGroupAssetsApi.as_view(),
name='user-my-asset-group-assets'),
# Select user or user group permission of asset or asset group
url(r'^v1/user/(?P<pk>[0-9]+)/assets/$', api.UserGrantedAssetsApi.as_view(), name='api-user-assets'),
url(r'^v1/user/(?P<pk>[0-9]+)/asset-groups/$', api.UserGrantedAssetGroupsApi.as_view(),
name='api-user-asset-groups'),
# Revoke permission api
url(r'^v1/asset-permissions/user/revoke/', api.RevokeUserAssetPermission.as_view(), url(r'^v1/asset-permissions/user/revoke/', api.RevokeUserAssetPermission.as_view(),
name='revoke-user-asset-permission'), name='revoke-user-asset-permission'),
url(r'^v1/user/asset-groups/$', api.UserAssetsGroupsApi.as_view(), name='api-user-asset-groups'), url(r'^v1/asset-permissions/user-group/revoke/', api.RevokeUserGroupAssetPermission.as_view(),
url(r'^v1/user/asset-group/(?P<pk>[0-9]+)/assets/$', api.UserAssetsGroupAssetsApi.as_view(), name='revoke-user-group-asset-permission'),
name='user-asset-groups-assets'),
] ]
urlpatterns += router.urls urlpatterns += router.urls
...@@ -19,7 +19,6 @@ class UserLoginForm(AuthenticationForm): ...@@ -19,7 +19,6 @@ class UserLoginForm(AuthenticationForm):
class UserCreateUpdateForm(forms.ModelForm): class UserCreateUpdateForm(forms.ModelForm):
class Meta: class Meta:
model = User model = User
fields = [ fields = [
...@@ -37,7 +36,6 @@ class UserCreateUpdateForm(forms.ModelForm): ...@@ -37,7 +36,6 @@ class UserCreateUpdateForm(forms.ModelForm):
class UserBulkImportForm(forms.ModelForm): class UserBulkImportForm(forms.ModelForm):
class Meta: class Meta:
model = User model = User
fields = ['username', 'email', 'enable_otp', 'role'] fields = ['username', 'email', 'enable_otp', 'role']
...@@ -62,7 +60,6 @@ class UserBulkImportForm(forms.ModelForm): ...@@ -62,7 +60,6 @@ class UserBulkImportForm(forms.ModelForm):
class UserGroupForm(forms.ModelForm): class UserGroupForm(forms.ModelForm):
class Meta: class Meta:
model = UserGroup model = UserGroup
fields = [ fields = [
...@@ -101,7 +98,6 @@ class UserPrivateAssetPermissionForm(forms.ModelForm): ...@@ -101,7 +98,6 @@ class UserPrivateAssetPermissionForm(forms.ModelForm):
def save(self, commit=True): def save(self, commit=True):
self.instance = super(UserPrivateAssetPermissionForm, self).save(commit=commit) self.instance = super(UserPrivateAssetPermissionForm, self).save(commit=commit)
self.instance.private_for = 'U'
self.instance.users = [self.user] self.instance.users = [self.user]
self.instance.save() self.instance.save()
return self.instance return self.instance
...@@ -121,5 +117,28 @@ class UserPrivateAssetPermissionForm(forms.ModelForm): ...@@ -121,5 +117,28 @@ class UserPrivateAssetPermissionForm(forms.ModelForm):
} }
class UserGroupPrivateAssetPermissionForm(forms.ModelForm):
def save(self, commit=True):
self.instance = super(UserGroupPrivateAssetPermissionForm, self).save(commit=commit)
self.instance.user_groups = [self.user_group]
self.instance.save()
return self.instance
class Meta:
model = AssetPermission
fields = [
'assets', 'asset_groups', 'system_users', 'name',
]
widgets = {
'assets': forms.SelectMultiple(attrs={'class': 'select2',
'data-placeholder': _('Select assets')}),
'asset_groups': forms.SelectMultiple(attrs={'class': 'select2',
'data-placeholder': _('Select asset groups')}),
'system_users': forms.SelectMultiple(attrs={'class': 'select2',
'data-placeholder': _('Select system users')}),
}
class FileForm(forms.Form): class FileForm(forms.Form):
excel = forms.FileField() excel = forms.FileField()
...@@ -23,7 +23,9 @@ ...@@ -23,7 +23,9 @@
<li> <li>
<a href="{% url 'users:user-asset-permission' pk=user.id %}" class="text-center"><i class="fa fa-bar-chart-o"></i> {% trans 'Asset permission' %}</a> <a href="{% url 'users:user-asset-permission' pk=user.id %}" class="text-center"><i class="fa fa-bar-chart-o"></i> {% trans 'Asset permission' %}</a>
</li> </li>
<li><a href="{% url 'users:user-granted-asset' pk=user.id %}" class="text-center"><i class="fa fa-cubes"></i> {% trans 'Asset granted' %}</a></li> <li>
<a href="{% url 'users:user-granted-asset' pk=user.id %}" class="text-center"><i class="fa fa-cubes"></i> {% trans 'Asset granted' %}</a>
</li>
<li class="pull-right"> <li class="pull-right">
<a class="btn btn-outline btn-default" href="{% url 'users:user-update' pk=user.id %}"><i class="fa fa-edit"></i>Update</a> <a class="btn btn-outline btn-default" href="{% url 'users:user-update' pk=user.id %}"><i class="fa fa-edit"></i>Update</a>
</li> </li>
...@@ -53,7 +55,7 @@ ...@@ -53,7 +55,7 @@
<tbody> <tbody>
<tr class="no-borders-tr"> <tr class="no-borders-tr">
<td colspan="2"> <td colspan="2">
<img src="{{ user | user_avatar_url }}" class="img-circle" width="64" height="64"> <img src="{{ user|user_avatar_url }}" class="img-circle" width="64" height="64">
</td> </td>
</tr> </tr>
<tr> <tr>
...@@ -185,7 +187,7 @@ ...@@ -185,7 +187,7 @@
<form> <form>
<tr> <tr>
<td colspan="2" class="no-borders"> <td colspan="2" class="no-borders">
<select data-placeholder="{% trans 'Join user groups' %}" id="slct_groups" class="select2" style="width: 100%" multiple="" tabindex="4"> <select data-placeholder="{% trans 'Join user groups' %}" id="groups_selected" class="select2" style="width: 100%" multiple="" tabindex="4">
{% for group in groups %} {% for group in groups %}
<option value="{{ group.id }}" id="opt_{{ group.id }}">{{ group.name }}</option> <option value="{{ group.id }}" id="opt_{{ group.id }}">{{ group.name }}</option>
{% endfor %} {% endfor %}
...@@ -194,16 +196,18 @@ ...@@ -194,16 +196,18 @@
</tr> </tr>
<tr> <tr>
<td colspan="2" class="no-borders"> <td colspan="2" class="no-borders">
<button type="button" class="btn btn-info btn-small" id="btn_add_user_group">{% trans 'Join' %}</button> <button type="button" class="btn btn-info btn-small" id="btn_join_group">{% trans 'Join' %}</button>
</td> </td>
</tr> </tr>
</form> </form>
{% for group in user.groups.all %} {% for group in user.groups.all %}
<tr> <tr>
<td ><b class="bdg_user_group" data-gid={{ group.id }}>{{ group.name }}</b></td> <td >
<b class="bdg_group" data-gid={{ group.id }}>{{ group.name }}</b>
</td>
<td> <td>
<button class="btn btn-danger pull-right btn-xs btn_delete_user_group" type="button"><i class="fa fa-minus"></i></button> <button class="btn btn-danger pull-right btn-xs btn_leave_group" type="button"><i class="fa fa-minus"></i></button>
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}
...@@ -221,29 +225,29 @@ ...@@ -221,29 +225,29 @@
{% endblock %} {% endblock %}
{% block custom_foot_js %} {% block custom_foot_js %}
<script> <script>
jumpserver.selected_groups = {}; jumpserver.groups_selected = {};
function updateUserGroups(user_groups) { function updateUserGroups(groups) {
var the_url = "{% url 'users:api-user-update-group' pk=user.id %}"; var the_url = "{% url 'users:api-user-update-group' pk=user.id %}";
var body = { var body = {
groups: Object.assign([], user_groups) groups: Object.assign([], groups)
}; };
var success = function(data) { var success = function(data) {
// remove all the selected groups from select > option and rendered ul element; // remove all the selected groups from select > option and rendered ul element;
$('.select2-selection__rendered').empty(); $('.select2-selection__rendered').empty();
$('#slct_groups').val(''); $('#groups_selected').val('');
$.map(jumpserver.selected_groups, function(group_name, index) { $.map(jumpserver.groups_selected, function(group_name, index) {
$('#opt_' + index).remove(); $('#opt_' + index).remove();
// change tr html of user groups. // change tr html of user groups.
$('.group_edit tbody').append( $('.group_edit tbody').append(
'<tr>' + '<tr>' +
'<td><b class="bdg_user_group" data-gid="' + index + '">' + group_name + '</b></td>' + '<td><b class="bdg_group" data-gid="' + index + '">' + group_name + '</b></td>' +
'<td><button class="btn btn-danger btn-xs pull-right btn_delete_user_group" type="button"><i class="fa fa-minus"></i></button></td>' + '<td><button class="btn btn-danger btn-xs pull-right btn_leave_group" type="button"><i class="fa fa-minus"></i></button></td>' +
'</tr>' '</tr>'
) )
}); });
// clear jumpserver.selected_groups // clear jumpserver.groups_selected
jumpserver.selected_groups = {}; jumpserver.groups_selected = {};
}; };
APIUpdateAttr({ APIUpdateAttr({
url: the_url, url: the_url,
...@@ -255,10 +259,10 @@ $(document).ready(function() { ...@@ -255,10 +259,10 @@ $(document).ready(function() {
$('.select2').select2() $('.select2').select2()
.on('select2:select', function(evt) { .on('select2:select', function(evt) {
var data = evt.params.data; var data = evt.params.data;
jumpserver.selected_groups[data.id] = data.text; jumpserver.groups_selected[data.id] = data.text;
}).on('select2:unselect', function(evt) { }).on('select2:unselect', function(evt) {
var data = evt.params.data; var data = evt.params.data;
delete jumpserver.selected_groups[data.id] delete jumpserver.groups_selected[data.id]
}) })
}).on('click', '#is_active', function() { }).on('click', '#is_active', function() {
var the_url = "{% url 'users:api-user-detail' pk=user.id %}"; var the_url = "{% url 'users:api-user-detail' pk=user.id %}";
...@@ -284,32 +288,32 @@ $(document).ready(function() { ...@@ -284,32 +288,32 @@ $(document).ready(function() {
body: JSON.stringify(body), body: JSON.stringify(body),
success_message: success success_message: success
}); });
}).on('click', '#btn_add_user_group', function() { }).on('click', '#btn_join_group', function() {
if (Object.keys(jumpserver.selected_groups).length === 0) { if (Object.keys(jumpserver.groups_selected).length === 0) {
return false; return false;
} }
var user_groups = $('.bdg_user_group').map(function() { var groups = $('.bdg_group').map(function() {
return $(this).data('gid'); return $(this).data('gid');
}).get(); }).get();
$.map(jumpserver.selected_groups, function(value, index) { $.map(jumpserver.groups_selected, function(value, index) {
user_groups.push(parseInt(index)); groups.push(parseInt(index));
$('#opt_' + index).remove(); $('#opt_' + index).remove();
}); });
updateUserGroups(user_groups) updateUserGroups(groups)
}).on('click', '.btn_delete_user_group', function() { }).on('click', '.btn_leave_group', function() {
var $this = $(this); var $this = $(this);
var $tr = $this.closest('tr'); var $tr = $this.closest('tr');
var $badge = $tr.find('.bdg_user_group'); var $badge = $tr.find('.bdg_group');
var gid = $badge.data('gid'); var gid = $badge.data('gid');
var group_name = $badge.html() || $badge.text(); var group_name = $badge.html() || $badge.text();
$('#slct_groups').append( $('#groups_selected').append(
'<option value="' + gid + '" id="opt_' + gid + '">' + group_name + '</option>' '<option value="' + gid + '" id="opt_' + gid + '">' + group_name + '</option>'
); );
$tr.remove(); $tr.remove();
var user_groups = $('.bdg_user_group').map(function() { var groups = $('.bdg_group').map(function() {
return $(this).data('gid'); return $(this).data('gid');
}).get(); }).get();
updateUserGroups(user_groups) updateUserGroups(groups)
}).on('click', '#btn_reset_password', function() { }).on('click', '#btn_reset_password', function() {
function doReset() { function doReset() {
var the_url = '{% url "users:api-user-reset-password" pk=user.id %}'; var the_url = '{% url "users:api-user-reset-password" pk=user.id %}';
......
This diff is collapsed.
...@@ -19,20 +19,21 @@ ...@@ -19,20 +19,21 @@
<form method="post" class="form-horizontal" action="" > <form method="post" class="form-horizontal" action="" >
{% csrf_token %} {% csrf_token %}
{{ form.name|bootstrap_horizontal }} {{ form.name|bootstrap_horizontal }}
<div class="form-group"> <div class="form-group">
<label for="users" class="col-sm-2 control-label">{% trans 'Users' %}</label> <label for="users" class="col-sm-2 control-label">{% trans 'Users' %}</label>
<div class="col-sm-9"> <div class="col-sm-9">
<select name="users" id="users" data-placeholder="{% trans 'Select User' %}" class="select2 form-control m-b" multiple tabindex="2"> <select name="users" id="id_users" data-placeholder="{% trans 'Select User' %}" class="select2 form-control m-b" multiple tabindex="2">
{% for user in users %} {% for user in users %}
<option value="{{ user.id }}">{{ user.name }}</option> {% if user.id in group_users %}
<option value="{{ user.id }}" selected>{{ user.name }}</option>
{% else %}
<option value="{{ user.id }}">{{ user.name }}</option>
{% endif %}
{% endfor %} {% endfor %}
</select> </select>
</div> </div>
</div> </div>
{{ form.comment|bootstrap_horizontal }} {{ form.comment|bootstrap_horizontal }}
<div class="form-group"> <div class="form-group">
<div class="col-sm-4 col-sm-offset-2"> <div class="col-sm-4 col-sm-offset-2">
<button class="btn btn-white" type="reset">{% trans 'Cancel' %}</button> <button class="btn btn-white" type="reset">{% trans 'Cancel' %}</button>
...@@ -45,11 +46,12 @@ ...@@ -45,11 +46,12 @@
</div> </div>
</div> </div>
</div> </div>
{% include "users/_select_user_modal.html" %}
{% endblock %} {% endblock %}
{% block custom_foot_js %} {% block custom_foot_js %}
<script> <script>
$(document).ready(function () { $(document).ready(function () {
$('.select2').select2().val([{{ group_users }}]).trigger("change"); $('.select2').select2();
}) })
</script> </script>
{% endblock %} {% endblock %}
{% extends 'base.html' %}
{% load common_tags %}
{% load users_tags %}
{% load bootstrap %}
{% load static %}
{% load i18n %}
{% block custom_head_css_js %}
<link href="{% static "css/plugins/select2/select2.min.css" %}" rel="stylesheet">
<script src="{% static "js/plugins/select2/select2.full.min.js" %}"></script>
{% endblock %}
{% block content %}
<div class="wrapper wrapper-content animated fadeInRight">
<div class="row">
<div class="col-sm-12">
<div class="ibox float-e-margins">
<div class="panel-options">
<ul class="nav nav-tabs">
<li>
<a href="{% url 'users:user-group-detail' pk=user_group.id %}" class="text-center"><i class="fa fa-laptop"></i> {% trans 'User detail' %} </a>
</li>
<li>
<a href="{% url 'users:user-group-asset-permission' pk=user_group.id %}" class="text-center"><i class="fa fa-bar-chart-o"></i> {% trans 'Asset permission' %}</a>
</li>
<li class="active">
<a href="{% url 'users:user-group-granted-asset' pk=user_group.id %}" class="text-center"><i class="fa fa-cubes"></i> {% trans 'Asset granted' %}</a>
</li>
</ul>
</div>
<div class="tab-content">
<div class="col-sm-7" style="padding-left: 0;">
<div class="ibox float-e-margins">
<div class="ibox-title">
<span style="float: left">{% trans 'Assets granted of ' %} <b>{{ user_group.name }}</b></span>
<div class="ibox-tools">
<a class="collapse-link">
<i class="fa fa-chevron-up"></i>
</a>
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
<i class="fa fa-wrench"></i>
</a>
<ul class="dropdown-menu dropdown-user">
</ul>
<a class="close-link">
<i class="fa fa-times"></i>
</a>
</div>
</div>
<div class="ibox-content">
<table class="table table-hover " id="user_assets_table" >
<thead>
<tr>
<th class="text-center"></th>
<th>{% trans 'Hostname' %}</th>
<th>{% trans 'IP' %}</th>
<th>{% trans 'Port' %}</th>
<th>{% trans 'System user' %}</th>
<th>{% trans 'Valid' %}</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
</div>
<div class="col-sm-5" style="padding-left: 0;padding-right: 0">
<div class="ibox float-e-margins">
<div class="ibox-title">
<span style="float: left">{% trans 'Asset groups granted of ' %} <b>{{ user_group.name }}</b></span>
<div class="ibox-tools">
<a class="collapse-link">
<i class="fa fa-chevron-up"></i>
</a>
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
<i class="fa fa-wrench"></i>
</a>
<ul class="dropdown-menu dropdown-user">
</ul>
<a class="close-link">
<i class="fa fa-times"></i>
</a>
</div>
</div>
<div class="ibox-content">
<table class="table table-hover" id="user_asset_groups_table" >
<thead>
<tr>
<th></th>
<th>{% trans 'Name' %}</th>
<th>{% trans 'Asset' %}</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% block custom_foot_js %}
<script>
$(document).ready(function () {
$('.select2').select2();
var options = {
ele: $('#user_assets_table'),
buttons: [],
order: [],
select: [],
columnDefs: [
{targets: 1, createdCell: function (td, cellData, rowData) {
var detail_btn = '<a href="{% url "assets:asset-detail" pk=99991937 %}">' + cellData + '</a>';
$(td).html(detail_btn.replace('99991937', rowData.id));
}},
{targets: 4, createdCell: function (td, cellData, rowData) {
if (cellData.length > 10){
$(td).html(cellData.substring(1, 10) + '..')
} else {
$(td).html(cellData)
}
}},
{targets: 5, createdCell: function (td, cellData) {
if (!cellData) {
$(td).html('<i class="fa fa-times text-danger"></i>')
} else {
$(td).html('<i class="fa fa-check text-navy"></i>')
}
}}
],
ajax_url: '{% url "perms:api-user-assets" %}',
columns: [{data: function(){return ""}}, {data: "hostname" }, {data: "ip" }, {data: "port"},
{data: "system_users_join"}, {data: "is_active"}]
};
var options2 = {
ele: $('#user_asset_groups_table'),
buttons: [],
order: [],
select: [],
columnDefs: [
{targets: 1, createdCell: function (td, cellData, rowData) {
var detail_btn = '<a href="{% url "assets:asset-group-detail" pk=99991937 %}">' + cellData + '</a>';
$(td).html(detail_btn.replace('99991937', rowData.id));
}}
],
ajax_url: '{% url "perms:api-user-asset-groups" %}',
columns: [{data: function(){return ""}}, {data: "name" }, {data: "asset_amount" }]
};
jumpserver.initDataTable(options);
jumpserver.initDataTable(options2);
});
</script>
{% endblock %}
\ No newline at end of file
{% extends 'users/_user.html' %} {% extends 'users/_user.html' %}
{% load i18n %} {% load i18n %}
{% block user_template_title %}{% trans "Update user" %}{% endblock %} {% block user_template_title %}{% trans "Update user" %}{% endblock %}
{#{% block username %}#}
{# <div class="form-group">#}
{# <label for="{{ form.username.id_for_label }}" class="col-sm-2 control-label">{% trans 'Username' %}</label>#}
{# <div class="col-sm-9 controls" >#}
{# <input id="{{ form.username.id_for_label }}" name="{{ form.username.html_name }}" type="text" value="{{ user_object.username }}" readonly class="form-control">#}
{# </div>#}
{# </div>#}
{#{% endblock %}#}
{% block password %} {% block password %}
<h3>{% trans 'Password' %}</h3> <h3>{% trans 'Password' %}</h3>
<div class="form-group"> <div class="form-group">
......
...@@ -34,6 +34,12 @@ urlpatterns = [ ...@@ -34,6 +34,12 @@ urlpatterns = [
url(r'^user-group/(?P<pk>[0-9]+)$', views.UserGroupDetailView.as_view(), name='user-group-detail'), url(r'^user-group/(?P<pk>[0-9]+)$', views.UserGroupDetailView.as_view(), name='user-group-detail'),
url(r'^user-group/create$', views.UserGroupCreateView.as_view(), name='user-group-create'), url(r'^user-group/create$', views.UserGroupCreateView.as_view(), name='user-group-create'),
url(r'^user-group/(?P<pk>[0-9]+)/update$', views.UserGroupUpdateView.as_view(), name='user-group-update'), url(r'^user-group/(?P<pk>[0-9]+)/update$', views.UserGroupUpdateView.as_view(), name='user-group-update'),
url(r'^user-group/(?P<pk>[0-9]+)/asset-permission$', views.UserGroupAssetPermissionView.as_view(),
name='user-group-asset-permission'),
url(r'^user-group/(?P<pk>[0-9]+)/asset-permission/create$', views.UserAssetPermissionCreateView.as_view(),
name='user-group-asset-permission-create'),
url(r'^user-group/(?P<pk>[0-9]+)/assets', views.UserGroupGrantedAssetView.as_view(),
name='user-group-granted-asset'),
] ]
......
...@@ -166,7 +166,7 @@ class UserGroupListView(AdminUserRequiredMixin, TemplateView): ...@@ -166,7 +166,7 @@ class UserGroupListView(AdminUserRequiredMixin, TemplateView):
class UserGroupCreateView(AdminUserRequiredMixin, CreateView): class UserGroupCreateView(AdminUserRequiredMixin, CreateView):
model = UserGroup model = UserGroup
form_class = forms.UserGroupForm form_class = forms.UserGroupForm
template_name = 'users/user_group_create.html' template_name = 'users/user_group_create_update.html'
success_url = reverse_lazy('users:user-group-list') success_url = reverse_lazy('users:user-group-list')
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
...@@ -188,14 +188,14 @@ class UserGroupCreateView(AdminUserRequiredMixin, CreateView): ...@@ -188,14 +188,14 @@ class UserGroupCreateView(AdminUserRequiredMixin, CreateView):
class UserGroupUpdateView(AdminUserRequiredMixin, UpdateView): class UserGroupUpdateView(AdminUserRequiredMixin, UpdateView):
model = UserGroup model = UserGroup
form_class = forms.UserGroupForm form_class = forms.UserGroupForm
template_name = 'users/user_group_create.html' template_name = 'users/user_group_create_update.html'
success_url = reverse_lazy('users:user-group-list') success_url = reverse_lazy('users:user-group-list')
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
self.object = self.get_object() # self.object = self.get_object()
context = super(UserGroupUpdateView, self).get_context_data(**kwargs) context = super(UserGroupUpdateView, self).get_context_data(**kwargs)
users = User.objects.all() users = User.objects.all()
group_users = ",".join([str(u.id) for u in self.object.users.all()]) group_users = [user.id for user in self.object.users.all()]
context.update({ context.update({
'app': _('Users'), 'app': _('Users'),
'action': _('Update User Group'), 'action': _('Update User Group'),
...@@ -370,29 +370,71 @@ class UserAssetPermissionView(AdminUserRequiredMixin, FormMixin, SingleObjectMix ...@@ -370,29 +370,71 @@ class UserAssetPermissionView(AdminUserRequiredMixin, FormMixin, SingleObjectMix
return super(UserAssetPermissionView, self).get_context_data(**kwargs) return super(UserAssetPermissionView, self).get_context_data(**kwargs)
class UserGroupAssetPermissionView(AdminUserRequiredMixin, FormMixin, SingleObjectMixin, ListView):
model = UserGroup
template_name = 'users/user_group_asset_permission.html'
context_object_name = 'user_group'
form_class = forms.UserPrivateAssetPermissionForm
def get(self, request, *args, **kwargs):
self.object = self.get_object(queryset=UserGroup.objects.all())
return super(UserGroupAssetPermissionView, self).get(request, *args, **kwargs)
def get_context_data(self, **kwargs):
context = {
'app': 'Users',
'action': 'User group asset permissions',
}
kwargs.update(context)
return super(UserGroupAssetPermissionView, self).get_context_data(**kwargs)
class UserAssetPermissionCreateView(AdminUserRequiredMixin, CreateView): class UserAssetPermissionCreateView(AdminUserRequiredMixin, CreateView):
form_class = forms.UserPrivateAssetPermissionForm form_class = forms.UserPrivateAssetPermissionForm
model = AssetPermission model = AssetPermission
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
user_object = self.get_object(queryset=User.objects.all()) user = self.get_object(queryset=User.objects.all())
return redirect(reverse('users:user-asset-permission', kwargs={'pk': user_object.id})) return redirect(reverse('users:user-asset-permission', kwargs={'pk': user.id}))
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
self.user_object = self.get_object(queryset=User.objects.all()) self.user = self.get_object(queryset=User.objects.all())
return super(UserAssetPermissionCreateView, self).post(request, *args, **kwargs) return super(UserAssetPermissionCreateView, self).post(request, *args, **kwargs)
def get_form(self, form_class=None): def get_form(self, form_class=None):
form = super(UserAssetPermissionCreateView, self).get_form(form_class=form_class) form = super(UserAssetPermissionCreateView, self).get_form(form_class=form_class)
form.user = self.user_object form.user = self.user
return form
def form_invalid(self, form):
return redirect(reverse('users:user-asset-permission', kwargs={'pk': self.user.id}))
def get_success_url(self):
return reverse('users:user-asset-permission', kwargs={'pk': self.user.id})
class UserGroupAssetPermissionCreateView(AdminUserRequiredMixin, CreateView):
form_class = forms.UserPrivateAssetPermissionForm
model = AssetPermission
def get(self, request, *args, **kwargs):
user_group = self.get_object(queryset=UserGroup.objects.all())
return redirect(reverse('users:user-group-asset-permission', kwargs={'pk': user_group.id}))
def post(self, request, *args, **kwargs):
self.user_group = self.get_object(queryset=UserGroup.objects.all())
return super(UserGroupAssetPermissionCreateView, self).post(request, *args, **kwargs)
def get_form(self, form_class=None):
form = super(UserGroupAssetPermissionCreateView, self).get_form(form_class=form_class)
form.user_group = self.user_group
return form return form
def form_invalid(self, form): def form_invalid(self, form):
print(form.errors) return redirect(reverse('users:user-group-asset-permission', kwargs={'pk': self.user_group.id}))
return redirect(reverse('users:user-asset-permission', kwargs={'pk': self.user_object.id}))
def get_success_url(self): def get_success_url(self):
return reverse('users:user-asset-permission', kwargs={'pk': self.user_object.id}) return reverse('users:user-group-asset-permission', kwargs={'pk': self.user_group.id})
class UserGrantedAssetView(AdminUserRequiredMixin, DetailView): class UserGrantedAssetView(AdminUserRequiredMixin, DetailView):
...@@ -413,6 +455,24 @@ class UserGrantedAssetView(AdminUserRequiredMixin, DetailView): ...@@ -413,6 +455,24 @@ class UserGrantedAssetView(AdminUserRequiredMixin, DetailView):
return super(UserGrantedAssetView, self).get_context_data(**kwargs) return super(UserGrantedAssetView, self).get_context_data(**kwargs)
class UserGroupGrantedAssetView(AdminUserRequiredMixin, DetailView):
model = User
template_name = 'users/user_group_granted_asset.html'
context_object_name = 'user_group'
def get(self, request, *args, **kwargs):
self.object = self.get_object(queryset=UserGroup.objects.all())
return super(UserGroupGrantedAssetView, self).get(request, *args, **kwargs)
def get_context_data(self, **kwargs):
context = {
'app': 'User',
'action': 'User group granted asset',
}
kwargs.update(context)
return super(UserGroupGrantedAssetView, self).get_context_data(**kwargs)
class BulkImportUserView(AdminUserRequiredMixin, JSONResponseMixin, FormView): class BulkImportUserView(AdminUserRequiredMixin, JSONResponseMixin, FormView):
form_class = forms.FileForm form_class = forms.FileForm
......
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