mirror of https://github.com/jumpserver/jumpserver
Finish user permission revoke
parent
dde9ffb2ae
commit
69f2bf664b
|
@ -32,7 +32,7 @@ $(document).ready(function(){
|
||||||
ele: $('#admin_user_list_table'),
|
ele: $('#admin_user_list_table'),
|
||||||
columnDefs: [
|
columnDefs: [
|
||||||
{targets: 1, createdCell: function (td, cellData, rowData) {
|
{targets: 1, createdCell: function (td, cellData, rowData) {
|
||||||
var detail_btn = '<a href="{% url "assets:api-admin-user-detail" pk=99991937 %}">' + cellData + '</a>';
|
var detail_btn = '<a href="{% url "assets:admin-user-detail" pk=99991937 %}">' + cellData + '</a>';
|
||||||
$(td).html(detail_btn.replace('99991937', rowData.id));
|
$(td).html(detail_btn.replace('99991937', rowData.id));
|
||||||
}},
|
}},
|
||||||
{targets: 5, createdCell: function (td, cellData) {
|
{targets: 5, createdCell: function (td, cellData) {
|
||||||
|
|
|
@ -248,4 +248,11 @@ def validate_ssh_public_key(text):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def setattr_bulk(seq, key, value):
|
||||||
|
def set_attr(obj):
|
||||||
|
setattr(obj, key, value)
|
||||||
|
return obj
|
||||||
|
return map(set_attr, seq)
|
||||||
|
|
||||||
|
|
||||||
signer = Signer()
|
signer = Signer()
|
|
@ -5,8 +5,10 @@ from rest_framework.views import APIView, Response
|
||||||
from rest_framework.generics import ListCreateAPIView
|
from rest_framework.generics import ListCreateAPIView
|
||||||
from rest_framework import viewsets
|
from rest_framework import viewsets
|
||||||
from users.backends import IsValidUser, IsSuperUser
|
from users.backends import IsValidUser, IsSuperUser
|
||||||
from .utils import get_user_granted_assets, get_user_granted_asset_groups
|
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 .models import AssetPermission
|
from .models import AssetPermission
|
||||||
|
from .hands import User
|
||||||
from . import serializers
|
from . import serializers
|
||||||
|
|
||||||
|
|
||||||
|
@ -18,11 +20,41 @@ 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', '')
|
||||||
if user_id:
|
if user_id and user_id.isdigit():
|
||||||
queryset = queryset.filter(users__id=user_id)
|
from users.models import User
|
||||||
|
self.user_id = user_id
|
||||||
|
user = get_object_or_none(User, id=int(user_id))
|
||||||
|
if user:
|
||||||
|
queryset = get_user_asset_permissions(user)
|
||||||
|
print(queryset)
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
|
def get_serializer_class(self):
|
||||||
|
if getattr(self, 'user_id', ''):
|
||||||
|
return serializers.UserAssetPermissionSerializer
|
||||||
|
return serializers.AssetPermissionSerializer
|
||||||
|
|
||||||
|
|
||||||
|
class RevokeUserAssetPermission(APIView):
|
||||||
|
permission_classes = (IsSuperUser,)
|
||||||
|
|
||||||
|
def put(self, request, *args, **kwargs):
|
||||||
|
permission_id = str(request.data.get('id', ''))
|
||||||
|
user_id = str(request.data.get('user_id', ''))
|
||||||
|
|
||||||
|
if permission_id and user_id and permission_id.isdigit() and user_id.isdigit():
|
||||||
|
permission_id = int(permission_id)
|
||||||
|
user_id = int(user_id)
|
||||||
|
asset_permission = get_object_or_none(AssetPermission, id=permission_id)
|
||||||
|
user = get_object_or_none(User, id=user_id)
|
||||||
|
print(asset_permission)
|
||||||
|
print(user)
|
||||||
|
|
||||||
|
if asset_permission and user:
|
||||||
|
asset_permission.users.remove(user)
|
||||||
|
return Response({'msg': 'success'})
|
||||||
|
return Response({'msg': 'failed'}, status=404)
|
||||||
|
|
||||||
|
|
||||||
class UserAssetsApi(APIView):
|
class UserAssetsApi(APIView):
|
||||||
permission_classes = (IsValidUser,)
|
permission_classes = (IsValidUser,)
|
||||||
|
|
|
@ -1,34 +1,26 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
|
|
||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
|
from common.utils import get_object_or_none
|
||||||
from .models import AssetPermission
|
from .models import AssetPermission
|
||||||
|
from .hands import User
|
||||||
|
|
||||||
|
|
||||||
class AssetPermissionSerializer(serializers.ModelSerializer):
|
class AssetPermissionSerializer(serializers.ModelSerializer):
|
||||||
# users_amount = serializers.SerializerMethodField()
|
|
||||||
# user_groups_amount = serializers.SerializerMethodField()
|
|
||||||
# assets_amount = serializers.SerializerMethodField()
|
|
||||||
# asset_groups_amount = serializers.SerializerMethodField()
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = AssetPermission
|
model = AssetPermission
|
||||||
fields = ['id', 'name', 'users', 'user_groups', 'assets', 'asset_groups',
|
|
||||||
'system_users', 'is_active', 'comment', 'date_expired']
|
|
||||||
|
|
||||||
# @staticmethod
|
|
||||||
# def get_users_amount(obj):
|
class UserAssetPermissionSerializer(AssetPermissionSerializer):
|
||||||
# return obj.users.count()
|
is_inherited = serializers.SerializerMethodField()
|
||||||
#
|
|
||||||
# @staticmethod
|
@staticmethod
|
||||||
# def get_user_groups_amount(obj):
|
def get_is_inherited(obj):
|
||||||
# return obj.user_groups.count()
|
if getattr(obj, 'inherited', ''):
|
||||||
#
|
return True
|
||||||
# @staticmethod
|
else:
|
||||||
# def get_assets_amount(obj):
|
return False
|
||||||
# return obj.assets.count()
|
|
||||||
#
|
|
||||||
# @staticmethod
|
|
||||||
# def get_asset_groups_amount(obj):
|
|
||||||
# return obj.asset_groups.count()
|
|
||||||
|
|
||||||
|
|
|
@ -26,10 +26,10 @@ 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(),
|
url(r'^v1/user/assets/$', api.UserAssetsApi.as_view(), name='user-assets'),
|
||||||
name='user-assets'),
|
url(r'^v1/asset-permissions/user/revoke/', api.RevokeUserAssetPermission.as_view(),
|
||||||
url(r'^v1/user/asset-groups/$', api.UserAssetsGroupsApi.as_view(),
|
name='revoke-user-asset-permission'),
|
||||||
name='user-asset-groups'),
|
url(r'^v1/user/asset-groups/$', api.UserAssetsGroupsApi.as_view(), name='user-asset-groups'),
|
||||||
url(r'^v1/user/asset-groups/(?P<pk>[0-9]+)/assets/$', api.UserAssetsGroupAssetsApi.as_view(),
|
url(r'^v1/user/asset-groups/(?P<pk>[0-9]+)/assets/$', api.UserAssetsGroupAssetsApi.as_view(),
|
||||||
name='user-asset-groups-assets'),
|
name='user-asset-groups-assets'),
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
from __future__ import absolute_import, unicode_literals
|
from __future__ import absolute_import, unicode_literals
|
||||||
|
|
||||||
|
from common.utils import setattr_bulk
|
||||||
from .hands import User, UserGroup, Asset, AssetGroup, SystemUser
|
from .hands import User, UserGroup, Asset, AssetGroup, SystemUser
|
||||||
|
|
||||||
|
|
||||||
|
@ -7,7 +8,7 @@ def get_user_group_granted_asset_groups(user_group):
|
||||||
"""Return asset groups granted of the user group
|
"""Return asset groups granted of the user group
|
||||||
|
|
||||||
:param user_group: Instance of :class: ``UserGroup``
|
:param user_group: Instance of :class: ``UserGroup``
|
||||||
:return: {asset1: {system_user1, }, asset1: {system_user1, system_user2]}
|
:return: {asset_group1: {system_user1, }, asset_group2: {system_user1, system_user2]}
|
||||||
"""
|
"""
|
||||||
asset_groups = {}
|
asset_groups = {}
|
||||||
asset_permissions = user_group.asset_permissions.all()
|
asset_permissions = user_group.asset_permissions.all()
|
||||||
|
@ -41,7 +42,6 @@ def get_user_group_granted_assets(user_group):
|
||||||
assets[asset] |= set(asset_permission.system_users.all())
|
assets[asset] |= set(asset_permission.system_users.all())
|
||||||
else:
|
else:
|
||||||
assets[asset] = set(asset_permission.system_users.all())
|
assets[asset] = set(asset_permission.system_users.all())
|
||||||
|
|
||||||
return assets
|
return assets
|
||||||
|
|
||||||
|
|
||||||
|
@ -112,7 +112,6 @@ def get_user_granted_asset_groups(user):
|
||||||
asset_groups[asset_group] |= asset_groups_direct[asset_group]
|
asset_groups[asset_group] |= asset_groups_direct[asset_group]
|
||||||
else:
|
else:
|
||||||
asset_groups[asset_group] = asset_groups_direct[asset_group]
|
asset_groups[asset_group] = asset_groups_direct[asset_group]
|
||||||
|
|
||||||
return asset_groups
|
return asset_groups
|
||||||
|
|
||||||
|
|
||||||
|
@ -175,10 +174,25 @@ def get_user_granted_assets(user):
|
||||||
assets[asset] |= assets_direct[asset]
|
assets[asset] |= assets_direct[asset]
|
||||||
else:
|
else:
|
||||||
assets[asset] = assets_direct[asset]
|
assets[asset] = assets_direct[asset]
|
||||||
|
|
||||||
return assets
|
return assets
|
||||||
|
|
||||||
|
|
||||||
|
def get_user_group_asset_permissions(user_group):
|
||||||
|
permissions = user_group.asset_permissions.all()
|
||||||
|
return permissions
|
||||||
|
|
||||||
|
|
||||||
|
def get_user_asset_permissions(user):
|
||||||
|
user_group_permissions = set()
|
||||||
|
direct_permissions = set(setattr_bulk(user.asset_permissions.all(), 'inherited', 0))
|
||||||
|
|
||||||
|
for user_group in user.groups.all():
|
||||||
|
permissions = get_user_group_asset_permissions(user_group)
|
||||||
|
user_group_permissions |= set(permissions)
|
||||||
|
user_group_permissions = set(setattr_bulk(user_group_permissions, 'inherited', 1))
|
||||||
|
return direct_permissions | user_group_permissions
|
||||||
|
|
||||||
|
|
||||||
def get_user_groups_granted_in_asset(asset):
|
def get_user_groups_granted_in_asset(asset):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
|
@ -198,19 +198,18 @@ function APIUpdateAttr(props) {
|
||||||
contentType: props.content_type || "application/json; charset=utf-8",
|
contentType: props.content_type || "application/json; charset=utf-8",
|
||||||
dataType: props.data_type || "json"
|
dataType: props.data_type || "json"
|
||||||
}).done(function(data, textStatue, jqXHR) {
|
}).done(function(data, textStatue, jqXHR) {
|
||||||
|
toastr.success(success_message);
|
||||||
if (typeof props.success === 'function') {
|
if (typeof props.success === 'function') {
|
||||||
return props.success(data);
|
return props.success(data);
|
||||||
} else {
|
|
||||||
toastr.success(success_message);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}).fail(function(jqXHR, textStatue, errorThrown) {
|
}).fail(function(jqXHR, textStatue, errorThrown) {
|
||||||
|
toastr.error(fail_message);
|
||||||
if (typeof props.error === 'function') {
|
if (typeof props.error === 'function') {
|
||||||
return props.error(errorThrown);
|
return props.error(errorThrown);
|
||||||
} else {
|
|
||||||
toastr.error(textStatue);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return true;
|
// return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sweet Alert for Delete
|
// Sweet Alert for Delete
|
||||||
|
|
|
@ -6,8 +6,8 @@ from django.utils.translation import gettext_lazy as _
|
||||||
from captcha.fields import CaptchaField
|
from captcha.fields import CaptchaField
|
||||||
|
|
||||||
from common.utils import validate_ssh_public_key
|
from common.utils import validate_ssh_public_key
|
||||||
|
from perms.models import AssetPermission
|
||||||
from .models import User, UserGroup
|
from .models import User, UserGroup
|
||||||
from .hands import AssetPermission
|
|
||||||
|
|
||||||
|
|
||||||
class UserLoginForm(AuthenticationForm):
|
class UserLoginForm(AuthenticationForm):
|
||||||
|
@ -101,7 +101,7 @@ 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.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
|
||||||
|
|
|
@ -11,5 +11,5 @@
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from terminal.models import Terminal
|
from terminal.models import Terminal
|
||||||
from perms.models import AssetPermission
|
# from perms.models import AssetPermission
|
||||||
from perms.utils import get_user_granted_assets, get_user_granted_asset_groups
|
# from perms.utils import get_user_granted_assets, get_user_granted_asset_groups
|
||||||
|
|
|
@ -17,16 +17,16 @@
|
||||||
<div class="panel-options">
|
<div class="panel-options">
|
||||||
<ul class="nav nav-tabs">
|
<ul class="nav nav-tabs">
|
||||||
<li>
|
<li>
|
||||||
<a href="{% url 'users:user-detail' pk=user_object.id %}" class="text-center"><i class="fa fa-laptop"></i> {% trans 'User detail' %} </a>
|
<a href="{% url 'users:user-detail' pk=user.id %}" class="text-center"><i class="fa fa-laptop"></i> {% trans 'User detail' %} </a>
|
||||||
</li>
|
</li>
|
||||||
<li class="active">
|
<li class="active">
|
||||||
<a href="{% url 'users:user-asset-permission' pk=user_object.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>
|
<li>
|
||||||
<a href="{% url 'users:user-granted-asset' pk=user_object.id %}" class="text-center"><i class="fa fa-cubes"></i> {% trans 'Asset granted' %}</a>
|
<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>
|
||||||
<li>
|
<li>
|
||||||
<a href="{% url 'users:user-login-history' pk=user_object.id %}" class="text-center"><i class="fa fa-calculator-o"></i> {% trans 'Login history' %}</a>
|
<a href="{% url 'users:user-login-history' pk=user.id %}" class="text-center"><i class="fa fa-calculator-o"></i> {% trans 'Login history' %}</a>
|
||||||
</li>
|
</li>
|
||||||
<form id="search_form" method="get" action="" class="pull-right mail-search">
|
<form id="search_form" method="get" action="" class="pull-right mail-search">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
|
@ -44,7 +44,7 @@
|
||||||
<div class="col-sm-7" style="padding-left: 0;">
|
<div class="col-sm-7" style="padding-left: 0;">
|
||||||
<div class="ibox float-e-margins">
|
<div class="ibox float-e-margins">
|
||||||
<div class="ibox-title">
|
<div class="ibox-title">
|
||||||
<span style="float: left">{% trans 'Asset permission of ' %} <b>{{ user_object.name }}</b></span>
|
<span style="float: left">{% trans 'Asset permission of ' %} <b>{{ user.name }}</b></span>
|
||||||
<div class="ibox-tools">
|
<div class="ibox-tools">
|
||||||
<a class="collapse-link">
|
<a class="collapse-link">
|
||||||
<i class="fa fa-chevron-up"></i>
|
<i class="fa fa-chevron-up"></i>
|
||||||
|
@ -60,52 +60,23 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="ibox-content">
|
<div class="ibox-content">
|
||||||
<table class="table table-hover">
|
<table class="table table-hover " id="user_permissions_table" >
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th class="text-center"><a href="{% url 'perms:asset-permission-list' %}?sort=name">{% trans 'Name' %}</a></th>
|
|
||||||
<th class="text-center">{% trans 'User ' %}</th>
|
|
||||||
<th class="text-center">{% trans 'User group ' %}</th>
|
|
||||||
<th class="text-center">{% trans 'Asset ' %}</th>
|
|
||||||
<th class="text-center">{% trans 'Asset group ' %}</th>
|
|
||||||
<th class="text-center">{% trans 'System user ' %}</th>
|
|
||||||
<th class="text-center">
|
<th class="text-center">
|
||||||
<a href="#">{% trans 'Is valid' %}</a>
|
<input type="checkbox" id="check_all" class="ipt_check_all" >
|
||||||
</th>
|
</th>
|
||||||
|
<th>{% trans 'Name' %}</th>
|
||||||
|
<th>{% trans 'Asset' %}</th>
|
||||||
|
<th>{% trans 'Asset group' %}</th>
|
||||||
|
<th>{% trans 'System user' %}</th>
|
||||||
|
<th>{% trans 'Valid' %}</th>
|
||||||
<th></th>
|
<th></th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for asset_permission in object_list %}
|
|
||||||
<tr class="gradeX">
|
|
||||||
<td class="text-center">
|
|
||||||
<a href="{% url 'perms:asset-permission-detail' pk=asset_permission.id %}">
|
|
||||||
{{ asset_permission.name }}
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
<td class="text-center">{{ asset_permission.users.count}}</td>
|
|
||||||
<td class="text-center">{{ asset_permission.user_groups.count}}</td>
|
|
||||||
<td class="text-center">{{ asset_permission.assets.count }}</td>
|
|
||||||
<td class="text-center">{{ asset_permission.asset_groups.count }}</td>
|
|
||||||
<td class="text-center">{{ asset_permission.system_users.count }}</td>
|
|
||||||
<td class="text-center">
|
|
||||||
{% if asset_permission.is_valid %}
|
|
||||||
<i class="fa fa-check text-navy"></i>
|
|
||||||
{% else %}
|
|
||||||
<i class="fa fa-times text-danger"></i>
|
|
||||||
{% endif %}
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<button class="btn btn-danger btn-xs btn_delete_user_group {% if asset_permission.is_inherit_from_user_groups %} disabled {% endif %}" type="button" style="float: right;"><i class="fa fa-minus"></i></button>
|
|
||||||
</td>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<div class="row">
|
|
||||||
{% include '_pagination.html' %}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -115,38 +86,38 @@
|
||||||
<i class="fa fa-info-circle"></i> {% trans 'Quick create permission for user' %}
|
<i class="fa fa-info-circle"></i> {% trans 'Quick create permission for user' %}
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<form method="post" action="{% url 'users:user-asset-permission-create' pk=user_object.id %}">
|
{# <form method="post" action="{% url 'users:user-asset-permission-create' pk=user.id %}">#}
|
||||||
<table class="table">
|
{# <table class="table">#}
|
||||||
<tbody>
|
{# <tbody>#}
|
||||||
{% csrf_token %}
|
{# {% csrf_token %}#}
|
||||||
<tr class="no-borders-tr">
|
{# <tr class="no-borders-tr">#}
|
||||||
<td colspan="1" style="padding-top: 0">
|
{# <td colspan="1" style="padding-top: 0">#}
|
||||||
{{ form.name|bootstrap }}
|
{# {{ form.name|bootstrap }}#}
|
||||||
</td>
|
{# </td>#}
|
||||||
</tr>
|
{# </tr>#}
|
||||||
<tr class="no-borders-tr">
|
{# <tr class="no-borders-tr">#}
|
||||||
<td colspan="1" style="padding-top: 0">
|
{# <td colspan="1" style="padding-top: 0">#}
|
||||||
{{ form.assets|bootstrap }}
|
{# {{ form.assets|bootstrap }}#}
|
||||||
</td>
|
{# </td>#}
|
||||||
</tr>
|
{# </tr>#}
|
||||||
<tr class="no-borders-tr">
|
{# <tr class="no-borders-tr">#}
|
||||||
<td colspan="1" style="padding-top: 0">
|
{# <td colspan="1" style="padding-top: 0">#}
|
||||||
{{ form.asset_groups|bootstrap }}
|
{# {{ form.asset_groups|bootstrap }}#}
|
||||||
</td>
|
{# </td>#}
|
||||||
</tr>
|
{# </tr>#}
|
||||||
<tr class="no-borders-tr">
|
{# <tr class="no-borders-tr">#}
|
||||||
<td colspan="1" style="padding-top: 0">
|
{# <td colspan="1" style="padding-top: 0">#}
|
||||||
{{ form.system_users|bootstrap }}
|
{# {{ form.system_users|bootstrap }}#}
|
||||||
</td>
|
{# </td>#}
|
||||||
</tr>
|
{# </tr>#}
|
||||||
<tr class="no-borders-tr">
|
{# <tr class="no-borders-tr">#}
|
||||||
<td>
|
{# <td>#}
|
||||||
<button type="submit" class="btn btn-primary btn-sm">{% trans 'Submit' %}</button>
|
{# <button type="submit" class="btn btn-primary btn-sm">{% trans 'Submit' %}</button>#}
|
||||||
</td>
|
{# </td>#}
|
||||||
</tr>
|
{# </tr>#}
|
||||||
</tbody>
|
{# </tbody>#}
|
||||||
</table>
|
{# </table>#}
|
||||||
</form>
|
{# </form>#}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -159,25 +130,69 @@
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block custom_foot_js %}
|
{% block custom_foot_js %}
|
||||||
<script>
|
<script>
|
||||||
{# function switch_user_status(obj) {#}
|
|
||||||
{# var status = $(obj).prop('checked');#}
|
|
||||||
{##}
|
|
||||||
{# $.ajax({#}
|
|
||||||
{# url: "{% url 'users:user-active-api' pk=user_object.id %}",#}
|
|
||||||
{# type: "PUT",#}
|
|
||||||
{# data: {#}
|
|
||||||
{# 'is_active': status#}
|
|
||||||
{# },#}
|
|
||||||
{# success: function (data, status) {#}
|
|
||||||
{# console.log(data)#}
|
|
||||||
{# },#}
|
|
||||||
{# error: function () {#}
|
|
||||||
{# console.log('error')#}
|
|
||||||
{# }#}
|
|
||||||
{# })#}
|
|
||||||
{# }#}
|
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
$('.select2').select2();
|
$('.select2').select2();
|
||||||
|
var options = {
|
||||||
|
ele: $('#user_permissions_table'),
|
||||||
|
buttons: [],
|
||||||
|
order: [],
|
||||||
|
select: [],
|
||||||
|
columnDefs: [
|
||||||
|
{targets: 1, createdCell: function (td, cellData, rowData) {
|
||||||
|
var detail_btn = '<a href="{% url "perms:asset-permission-detail" pk=99991937 %}">' + cellData + '</a>';
|
||||||
|
$(td).html(detail_btn.replace('99991937', rowData.id));
|
||||||
|
}},
|
||||||
|
{targets: 2, createdCell: function (td, cellData, rowData) {
|
||||||
|
var dataLength = cellData.length;
|
||||||
|
$(td).html(dataLength);
|
||||||
|
}},
|
||||||
|
{targets: 3, createdCell: function (td, cellData, rowData) {
|
||||||
|
var dataLength = cellData.length;
|
||||||
|
$(td).html(dataLength);
|
||||||
|
}},
|
||||||
|
{targets: 4, createdCell: function (td, cellData, rowData) {
|
||||||
|
var dataLength = cellData.length;
|
||||||
|
$(td).html(dataLength);
|
||||||
|
}},
|
||||||
|
{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>')
|
||||||
|
}
|
||||||
|
}},
|
||||||
|
{targets: 6, createdCell: function (td, cellData, rowData) {
|
||||||
|
var btn = '<button class="btn btn-danger btn-xs btn_del_permission disabled" id=99991937 type="button" style="float: right;"><i class="fa fa-minus"></i></button>';
|
||||||
|
if (rowData.is_inherited) {
|
||||||
|
$(td).html(btn)
|
||||||
|
} else {
|
||||||
|
btn = btn.replace('99991937', cellData);
|
||||||
|
$(td).html(btn.replace('disabled', ''));
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
],
|
||||||
|
ajax_url: '{% url "perms:api-asset-permission-list" %}?user={{ user.id }}',
|
||||||
|
columns: [{data: function(){return ""}}, {data: "name" }, {data: "assets" }, {data: "asset_groups"},
|
||||||
|
{data: "system_users"}, {data: "is_active"}, {data: "id"}]
|
||||||
|
};
|
||||||
|
jumpserver.initDataTable(options);
|
||||||
|
}).on('click', '.btn_del_permission', function () {
|
||||||
|
var $this = $(this);
|
||||||
|
var body = {
|
||||||
|
id: $this.attr('id'),
|
||||||
|
user_id: {{ user.id }}
|
||||||
|
};
|
||||||
|
var the_url = "{% url 'perms:revoke-user-asset-permission' %}";
|
||||||
|
var success = function () {
|
||||||
|
$this.closest('tr').remove();
|
||||||
|
};
|
||||||
|
APIUpdateAttr({
|
||||||
|
url: the_url,
|
||||||
|
body: JSON.stringify(body),
|
||||||
|
method: 'PUT',
|
||||||
|
success_message: '{% trans "Revoke Successfully!" %}',
|
||||||
|
success: success
|
||||||
});
|
});
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
|
@ -313,7 +313,6 @@ $(document).ready(function() {
|
||||||
var user_groups = $('.bdg_user_group').map(function() {
|
var user_groups = $('.bdg_user_group').map(function() {
|
||||||
return $(this).data('gid');
|
return $(this).data('gid');
|
||||||
}).get();
|
}).get();
|
||||||
console.log(user_groups);
|
|
||||||
updateUserGroups(user_groups)
|
updateUserGroups(user_groups)
|
||||||
}).on('click', '#btn_reset_password', function() {
|
}).on('click', '#btn_reset_password', function() {
|
||||||
function doReset() {
|
function doReset() {
|
||||||
|
|
|
@ -53,7 +53,7 @@ $(document).ready(function(){
|
||||||
$(td).html(detail_btn.replace('99991937', rowData.id));
|
$(td).html(detail_btn.replace('99991937', rowData.id));
|
||||||
}},
|
}},
|
||||||
{targets: 4, createdCell: function (td, cellData) {
|
{targets: 4, createdCell: function (td, cellData) {
|
||||||
var innerHtml = cellData.length > 8 ? cellData.substring(0, 8) + '...': cellData;
|
var innerHtml = cellData.length > 20 ? cellData.substring(0, 20) + '...': cellData;
|
||||||
$(td).html('<a href="javascript:void(0);" data-toggle="tooltip" title="' + cellData + '">' + innerHtml + '</a>');
|
$(td).html('<a href="javascript:void(0);" data-toggle="tooltip" title="' + cellData + '">' + innerHtml + '</a>');
|
||||||
}},
|
}},
|
||||||
{targets: 6, createdCell: function (td, cellData) {
|
{targets: 6, createdCell: function (td, cellData) {
|
||||||
|
|
|
@ -19,13 +19,13 @@ urlpatterns = [
|
||||||
url(r'^user/(?P<pk>[0-9]+)$', views.UserDetailView.as_view(), name='user-detail'),
|
url(r'^user/(?P<pk>[0-9]+)$', views.UserDetailView.as_view(), name='user-detail'),
|
||||||
url(r'^user/(?P<pk>[0-9]+)/asset-permission$', views.UserAssetPermissionView.as_view(),
|
url(r'^user/(?P<pk>[0-9]+)/asset-permission$', views.UserAssetPermissionView.as_view(),
|
||||||
name='user-asset-permission'),
|
name='user-asset-permission'),
|
||||||
url(r'^user/(?P<pk>[0-9]+)/asset-permission/create$', views.UserAssetPermissionCreateView.as_view(),
|
# url(r'^user/(?P<pk>[0-9]+)/asset-permission/create$', views.UserAssetPermissionCreateView.as_view(),
|
||||||
name='user-asset-permission-create'),
|
# name='user-asset-permission-create'),
|
||||||
url(r'^user/(?P<pk>[0-9]+)/granted-asset', views.UserGrantedAssetView.as_view(), name='user-granted-asset'),
|
url(r'^user/(?P<pk>[0-9]+)/granted-asset', views.UserGrantedAssetView.as_view(), name='user-granted-asset'),
|
||||||
url(r'^user/(?P<pk>[0-9]+)/login-history', views.UserDetailView.as_view(), name='user-login-history'),
|
url(r'^user/(?P<pk>[0-9]+)/login-history', views.UserDetailView.as_view(), name='user-login-history'),
|
||||||
url(r'^first-login/$', views.UserFirstLoginView.as_view(), name='user-first-login'),
|
url(r'^first-login/$', views.UserFirstLoginView.as_view(), name='user-first-login'),
|
||||||
url(r'^import/$', views.BulkImportUserView.as_view(), name='user-import'),
|
url(r'^import/$', views.BulkImportUserView.as_view(), name='user-import'),
|
||||||
url(r'^user/(?P<pk>[0-9]+)/assets-perm$', views.UserDetailView.as_view(), name='user-detail'),
|
# url(r'^user/(?P<pk>[0-9]+)/assets-perm$', views.UserDetailView.as_view(), name='user-detail'),
|
||||||
url(r'^user/create$', views.UserCreateView.as_view(), name='user-create'),
|
url(r'^user/create$', views.UserCreateView.as_view(), name='user-create'),
|
||||||
url(r'^user/(?P<pk>[0-9]+)/update$', views.UserUpdateView.as_view(), name='user-update'),
|
url(r'^user/(?P<pk>[0-9]+)/update$', views.UserUpdateView.as_view(), name='user-update'),
|
||||||
|
|
||||||
|
|
|
@ -120,60 +120,60 @@ def send_reset_ssh_key_mail(user):
|
||||||
send_mail_async.delay(subject, message, recipient_list, html_message=message)
|
send_mail_async.delay(subject, message, recipient_list, html_message=message)
|
||||||
|
|
||||||
|
|
||||||
def validate_ssh_pk(text):
|
# def validate_ssh_pk(text):
|
||||||
"""
|
# """
|
||||||
Expects a SSH private key as string.
|
# Expects a SSH private key as string.
|
||||||
Returns a boolean and a error message.
|
# Returns a boolean and a error message.
|
||||||
If the text is parsed as private key successfully,
|
# If the text is parsed as private key successfully,
|
||||||
(True,'') is returned. Otherwise,
|
# (True,'') is returned. Otherwise,
|
||||||
(False, <message describing the error>) is returned.
|
# (False, <message describing the error>) is returned.
|
||||||
|
#
|
||||||
from https://github.com/githubnemo/SSH-private-key-validator/blob/master/validate.py
|
# from https://github.com/githubnemo/SSH-private-key-validator/blob/master/validate.py
|
||||||
|
#
|
||||||
"""
|
# """
|
||||||
|
#
|
||||||
if not text:
|
# if not text:
|
||||||
return False, 'No text given'
|
# return False, 'No text given'
|
||||||
|
#
|
||||||
startPattern = re.compile("^-----BEGIN [A-Z]+ PRIVATE KEY-----")
|
# startPattern = re.compile("^-----BEGIN [A-Z]+ PRIVATE KEY-----")
|
||||||
optionPattern = re.compile("^.+: .+")
|
# optionPattern = re.compile("^.+: .+")
|
||||||
contentPattern = re.compile("^([a-zA-Z0-9+/]{64}|[a-zA-Z0-9+/]{1,64}[=]{0,2})$")
|
# contentPattern = re.compile("^([a-zA-Z0-9+/]{64}|[a-zA-Z0-9+/]{1,64}[=]{0,2})$")
|
||||||
endPattern = re.compile("^-----END [A-Z]+ PRIVATE KEY-----")
|
# endPattern = re.compile("^-----END [A-Z]+ PRIVATE KEY-----")
|
||||||
|
#
|
||||||
def contentState(text):
|
# def contentState(text):
|
||||||
for i in range(0, len(text)):
|
# for i in range(0, len(text)):
|
||||||
line = text[i]
|
# line = text[i]
|
||||||
|
#
|
||||||
if endPattern.match(line):
|
# if endPattern.match(line):
|
||||||
if i == len(text) - 1 or len(text[i + 1]) == 0:
|
# if i == len(text) - 1 or len(text[i + 1]) == 0:
|
||||||
return True, ''
|
# return True, ''
|
||||||
else:
|
# else:
|
||||||
return False, 'At end but content coming'
|
# return False, 'At end but content coming'
|
||||||
|
#
|
||||||
elif not contentPattern.match(line):
|
# elif not contentPattern.match(line):
|
||||||
return False, 'Wrong string in content section'
|
# return False, 'Wrong string in content section'
|
||||||
|
#
|
||||||
return False, 'No content or missing end line'
|
# return False, 'No content or missing end line'
|
||||||
|
#
|
||||||
def optionState(text):
|
# def optionState(text):
|
||||||
for i in range(0, len(text)):
|
# for i in range(0, len(text)):
|
||||||
line = text[i]
|
# line = text[i]
|
||||||
|
#
|
||||||
if line[-1:] == '\\':
|
# if line[-1:] == '\\':
|
||||||
return optionState(text[i + 2:])
|
# return optionState(text[i + 2:])
|
||||||
|
#
|
||||||
if not optionPattern.match(line):
|
# if not optionPattern.match(line):
|
||||||
return contentState(text[i + 1:])
|
# return contentState(text[i + 1:])
|
||||||
|
#
|
||||||
return False, 'Expected option, found nothing'
|
# return False, 'Expected option, found nothing'
|
||||||
|
|
||||||
def startState(text):
|
|
||||||
if len(text) == 0 or not startPattern.match(text[0]):
|
|
||||||
return False, 'Header is wrong'
|
|
||||||
return optionState(text[1:])
|
|
||||||
|
|
||||||
return startState([n.strip() for n in text.splitlines()])
|
|
||||||
|
|
||||||
|
# def startState(text):
|
||||||
|
# if len(text) == 0 or not startPattern.match(text[0]):
|
||||||
|
# return False, 'Header is wrong'
|
||||||
|
# return optionState(text[1:])
|
||||||
|
#
|
||||||
|
# return startState([n.strip() for n in text.splitlines()])
|
||||||
|
#
|
||||||
|
|
||||||
def check_user_valid(**kwargs):
|
def check_user_valid(**kwargs):
|
||||||
password = kwargs.pop('password', None)
|
password = kwargs.pop('password', None)
|
||||||
|
|
|
@ -21,14 +21,14 @@ from django.views.generic.list import ListView
|
||||||
from django.views.generic.edit import CreateView, DeleteView, UpdateView, FormView, SingleObjectMixin, \
|
from django.views.generic.edit import CreateView, DeleteView, UpdateView, FormView, SingleObjectMixin, \
|
||||||
FormMixin
|
FormMixin
|
||||||
from django.views.generic.detail import DetailView
|
from django.views.generic.detail import DetailView
|
||||||
|
|
||||||
from formtools.wizard.views import SessionWizardView
|
from formtools.wizard.views import SessionWizardView
|
||||||
|
|
||||||
from common.mixins import JSONResponseMixin
|
from common.mixins import JSONResponseMixin
|
||||||
from common.utils import get_object_or_none, get_logger
|
from common.utils import get_object_or_none, get_logger
|
||||||
|
from perms.models import AssetPermission
|
||||||
from .models import User, UserGroup
|
from .models import User, UserGroup
|
||||||
from .utils import AdminUserRequiredMixin, user_add_success_next, send_reset_password_mail
|
from .utils import AdminUserRequiredMixin, user_add_success_next, send_reset_password_mail
|
||||||
from .hands import AssetPermission, get_user_granted_asset_groups, get_user_granted_assets
|
# from .hands import AssetPermission, get_user_granted_asset_groups, get_user_granted_assets
|
||||||
from . import forms
|
from . import forms
|
||||||
|
|
||||||
|
|
||||||
|
@ -341,32 +341,33 @@ class UserFirstLoginView(LoginRequiredMixin, SessionWizardView):
|
||||||
return form
|
return form
|
||||||
|
|
||||||
|
|
||||||
class UserAssetPermissionView(AdminUserRequiredMixin, FormMixin, SingleObjectMixin, ListView):
|
class UserAssetPermissionView(AdminUserRequiredMixin, DetailView):
|
||||||
paginate_by = settings.CONFIG.DISPLAY_PER_PAGE
|
model = User
|
||||||
template_name = 'users/user_asset_permission.html'
|
template_name = 'users/user_asset_permission.html'
|
||||||
context_object_name = 'user_object'
|
context_object_name = 'user'
|
||||||
form_class = forms.UserPrivateAssetPermissionForm
|
|
||||||
|
|
||||||
def get(self, request, *args, **kwargs):
|
# form_class = forms.UserPrivateAssetPermissionForm
|
||||||
self.object = self.get_object(queryset=User.objects.all())
|
|
||||||
return super(UserAssetPermissionView, self).get(request, *args, **kwargs)
|
|
||||||
|
|
||||||
def get_asset_permission_inherit_from_user_group(self):
|
# def get(self, request, *args, **kwargs):
|
||||||
asset_permissions = set()
|
# self.object = self.get_object(queryset=User.objects.all())
|
||||||
user_groups = self.object.groups.all()
|
# return super(UserAssetPermissionView, self).get(request, *args, **kwargs)
|
||||||
|
|
||||||
for user_group in user_groups:
|
# def get_asset_permission_inherit_from_user_group(self):
|
||||||
for asset_permission in user_group.asset_permissions.all():
|
# asset_permissions = set()
|
||||||
setattr(asset_permission, 'is_inherit_from_user_groups', True)
|
# user_groups = self.object.groups.all()
|
||||||
setattr(asset_permission, 'inherit_from_user_groups',
|
#
|
||||||
getattr(asset_permission, b'inherit_from_user_groups', set()).add(user_group))
|
# for user_group in user_groups:
|
||||||
asset_permissions.add(asset_permission)
|
# for asset_permission in user_group.asset_permissions.all():
|
||||||
return asset_permissions
|
# setattr(asset_permission, 'is_inherit_from_user_groups', True)
|
||||||
|
# setattr(asset_permission, 'inherit_from_user_groups',
|
||||||
def get_queryset(self):
|
# getattr(asset_permission, b'inherit_from_user_groups', set()).add(user_group))
|
||||||
asset_permissions = set(self.object.asset_permissions.all()) \
|
# asset_permissions.add(asset_permission)
|
||||||
| self.get_asset_permission_inherit_from_user_group()
|
# return asset_permissions
|
||||||
return list(asset_permissions)
|
#
|
||||||
|
# def get_queryset(self):
|
||||||
|
# asset_permissions = set(self.object.asset_permissions.all()) \
|
||||||
|
# | self.get_asset_permission_inherit_from_user_group()
|
||||||
|
# return list(asset_permissions)
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
context = {
|
context = {
|
||||||
|
@ -414,18 +415,19 @@ class UserGrantedAssetView(AdminUserRequiredMixin, SingleObjectMixin, ListView):
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
# Convert format from {'asset': ['system_users'], ..} to
|
# Convert format from {'asset': ['system_users'], ..} to
|
||||||
# [('asset', ['system_users']), ('asset', ['system_users']))
|
# [('asset', ['system_users']), ('asset', ['system_users']))
|
||||||
assets_granted = [(asset, system_users) for asset, system_users in
|
# assets_granted = [(asset, system_users) for asset, system_users in
|
||||||
get_user_granted_assets(self.object).items()]
|
# get_user_granted_assets(self.object).items()]
|
||||||
|
|
||||||
return assets_granted
|
# return assets_granted
|
||||||
|
return []
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
asset_groups = [(asset_group, system_users) for asset_group, system_users in
|
# asset_groups = [(asset_group, system_users) for asset_group, system_users in
|
||||||
get_user_granted_asset_groups(self.object).items()]
|
# get_user_granted_asset_groups(self.object).items()]
|
||||||
context = {
|
context = {
|
||||||
'app': 'User',
|
'app': 'User',
|
||||||
'action': 'User granted asset',
|
'action': 'User granted asset',
|
||||||
'asset_groups': asset_groups,
|
# 'asset_groups': asset_groups,
|
||||||
}
|
}
|
||||||
kwargs.update(context)
|
kwargs.update(context)
|
||||||
return super(UserGrantedAssetView, self).get_context_data(**kwargs)
|
return super(UserGrantedAssetView, self).get_context_data(**kwargs)
|
||||||
|
|
Loading…
Reference in New Issue