Commit 84634eb8 authored by ibuler's avatar ibuler

[Update] 修改Permr认证

parent fffa0def
...@@ -30,6 +30,7 @@ from .. import serializers ...@@ -30,6 +30,7 @@ from .. import serializers
logger = get_logger(__file__) logger = get_logger(__file__)
__all__ = [ __all__ = [
'NodeViewSet', 'NodeChildrenApi', 'NodeViewSet', 'NodeChildrenApi',
'NodeAssetsApi', 'NodeWithAssetsApi',
'NodeAddAssetsApi', 'NodeRemoveAssetsApi', 'NodeAddAssetsApi', 'NodeRemoveAssetsApi',
'NodeAddChildrenApi', 'RefreshNodeHardwareInfoApi', 'NodeAddChildrenApi', 'RefreshNodeHardwareInfoApi',
'TestNodeConnectiveApi' 'TestNodeConnectiveApi'
...@@ -47,6 +48,34 @@ class NodeViewSet(BulkModelViewSet): ...@@ -47,6 +48,34 @@ class NodeViewSet(BulkModelViewSet):
serializer.save() serializer.save()
class NodeWithAssetsApi(generics.ListAPIView):
permission_classes = (IsSuperUser,)
serializers = serializers.NodeSerializer
def get_node(self):
pk = self.kwargs.get('pk') or self.request.query_params.get('node')
if not pk:
node = Node.root()
else:
node = get_object_or_404(Node, pk)
return node
def get_queryset(self):
queryset = []
node = self.get_node()
children = node.get_children()
assets = node.get_assets()
queryset.extend(list(children))
for asset in assets:
node = Node()
node.id = asset.id
node.parent = node.id
node.value = asset.hostname
queryset.append(node)
return queryset
class NodeChildrenApi(mixins.ListModelMixin, generics.CreateAPIView): class NodeChildrenApi(mixins.ListModelMixin, generics.CreateAPIView):
queryset = Node.objects.all() queryset = Node.objects.all()
permission_classes = (IsSuperUser,) permission_classes = (IsSuperUser,)
...@@ -69,14 +98,54 @@ class NodeChildrenApi(mixins.ListModelMixin, generics.CreateAPIView): ...@@ -69,14 +98,54 @@ class NodeChildrenApi(mixins.ListModelMixin, generics.CreateAPIView):
status=201, status=201,
) )
def get_object(self):
pk = self.kwargs.get('pk') or self.request.query_params.get('id')
if not pk:
node = Node.root()
else:
node = get_object_or_404(Node, pk=pk)
return node
def get_queryset(self):
queryset = []
query_all = self.request.query_params.get("all")
query_assets = self.request.query_params.get('assets')
node = self.get_object()
if node == Node.root():
queryset.append(node)
if query_all:
children = node.get_all_children()
else:
children = node.get_children()
queryset.extend(list(children))
if query_assets:
assets = node.get_assets()
for asset in assets:
node_fake = Node()
node_fake.id = asset.id
node_fake.parent = node
node_fake.value = asset.hostname
node_fake.is_asset = True
queryset.append(node_fake)
return queryset
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
instance = self.get_object() return super().list(request, *args, **kwargs)
if self.request.query_params.get("all"):
children = instance.get_all_children()
class NodeAssetsApi(generics.ListAPIView):
permission_classes = (IsSuperUser,)
serializer_class = serializers.AssetSerializer
def get_queryset(self):
node_id = self.kwargs.get('pk')
query_all = self.request.query_params.get('all')
instance = get_object_or_404(Node, pk=node_id)
if query_all:
return instance.get_all_assets()
else: else:
children = instance.get_children() return instance.get_assets()
response = [{"id": node.id, "key": node.key, "value": node.value} for node in children]
return Response(response, status=200)
class NodeAddChildrenApi(generics.UpdateAPIView): class NodeAddChildrenApi(generics.UpdateAPIView):
...@@ -146,4 +215,3 @@ class TestNodeConnectiveApi(APIView): ...@@ -146,4 +215,3 @@ class TestNodeConnectiveApi(APIView):
task_name = _("测试节点下资产是否可连接: {}".format(node.name)) task_name = _("测试节点下资产是否可连接: {}".format(node.name))
task = test_asset_connectability_util.delay(assets, task_name=task_name) task = test_asset_connectability_util.delay(assets, task_name=task_name)
return Response({"task": task.id}) return Response({"task": task.id})
...@@ -16,6 +16,8 @@ class Node(models.Model): ...@@ -16,6 +16,8 @@ class Node(models.Model):
child_mark = models.IntegerField(default=0) child_mark = models.IntegerField(default=0)
date_create = models.DateTimeField(auto_now_add=True) date_create = models.DateTimeField(auto_now_add=True)
is_asset = False
def __str__(self): def __str__(self):
return self.value return self.value
...@@ -73,6 +75,9 @@ class Node(models.Model): ...@@ -73,6 +75,9 @@ class Node(models.Model):
assets = Asset.objects.filter(nodes__in=nodes) assets = Asset.objects.filter(nodes__in=nodes)
return assets return assets
def has_assets(self):
return self.get_all_assets()
def get_all_active_assets(self): def get_all_active_assets(self):
return self.get_all_assets().filter(is_active=True) return self.get_all_assets().filter(is_active=True)
......
...@@ -123,8 +123,6 @@ class SystemUser(AssetUser): ...@@ -123,8 +123,6 @@ class SystemUser(AssetUser):
def get_assets(self): def get_assets(self):
assets = set(self.assets.all()) assets = set(self.assets.all())
for node in self.nodes.all():
assets.update(set(node.get_all_assets()))
return assets return assets
@property @property
......
...@@ -42,7 +42,7 @@ class NodeSerializer(serializers.ModelSerializer): ...@@ -42,7 +42,7 @@ class NodeSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = Node model = Node
fields = ['id', 'key', 'value', 'parent', 'assets_amount'] fields = ['id', 'key', 'value', 'parent', 'assets_amount', 'is_asset']
list_serializer_class = BulkListSerializer list_serializer_class = BulkListSerializer
@staticmethod @staticmethod
......
...@@ -276,7 +276,7 @@ def test_system_user_connectability_util(system_user, task_name): ...@@ -276,7 +276,7 @@ def test_system_user_connectability_util(system_user, task_name):
:return: :return:
""" """
from ops.utils import update_or_create_ansible_task from ops.utils import update_or_create_ansible_task
assets = system_user.assets assets = system_user.get_assets()
hosts = [asset.hostname for asset in assets if asset.is_active and asset.is_unixlike()] hosts = [asset.hostname for asset in assets if asset.is_active and asset.is_unixlike()]
tasks = const.TEST_SYSTEM_USER_CONN_TASKS tasks = const.TEST_SYSTEM_USER_CONN_TASKS
if not hosts: if not hosts:
......
...@@ -36,7 +36,9 @@ urlpatterns = [ ...@@ -36,7 +36,9 @@ urlpatterns = [
url(r'^v1/system-user/(?P<pk>[0-9a-zA-Z\-]{36})/connective/$', url(r'^v1/system-user/(?P<pk>[0-9a-zA-Z\-]{36})/connective/$',
api.SystemUserTestConnectiveApi.as_view(), name='system-user-connective'), api.SystemUserTestConnectiveApi.as_view(), name='system-user-connective'),
url(r'^v1/nodes/(?P<pk>[0-9a-zA-Z\-]{36})/children/$', api.NodeChildrenApi.as_view(), name='node-children'), url(r'^v1/nodes/(?P<pk>[0-9a-zA-Z\-]{36})/children/$', api.NodeChildrenApi.as_view(), name='node-children'),
url(r'^v1/nodes/children/$', api.NodeChildrenApi.as_view(), name='node-children-2'),
url(r'^v1/nodes/(?P<pk>[0-9a-zA-Z\-]{36})/children/add/$', api.NodeAddChildrenApi.as_view(), name='node-add-children'), url(r'^v1/nodes/(?P<pk>[0-9a-zA-Z\-]{36})/children/add/$', api.NodeAddChildrenApi.as_view(), name='node-add-children'),
url(r'^v1/nodes/(?P<pk>[0-9a-zA-Z\-]{36})/assets/$', api.NodeAssetsApi.as_view(), name='node-assets'),
url(r'^v1/nodes/(?P<pk>[0-9a-zA-Z\-]{36})/assets/add/$', api.NodeAddAssetsApi.as_view(), name='node-add-assets'), url(r'^v1/nodes/(?P<pk>[0-9a-zA-Z\-]{36})/assets/add/$', api.NodeAddAssetsApi.as_view(), name='node-add-assets'),
url(r'^v1/nodes/(?P<pk>[0-9a-zA-Z\-]{36})/assets/remove/$', api.NodeRemoveAssetsApi.as_view(), name='node-remove-assets'), url(r'^v1/nodes/(?P<pk>[0-9a-zA-Z\-]{36})/assets/remove/$', api.NodeRemoveAssetsApi.as_view(), name='node-remove-assets'),
url(r'^v1/nodes/(?P<pk>[0-9a-zA-Z\-]{36})/refresh-hardware-info/$', api.RefreshNodeHardwareInfoApi.as_view(), name='node-refresh-hardware-info'), url(r'^v1/nodes/(?P<pk>[0-9a-zA-Z\-]{36})/refresh-hardware-info/$', api.RefreshNodeHardwareInfoApi.as_view(), name='node-refresh-hardware-info'),
......
...@@ -43,3 +43,7 @@ class StringIDField(serializers.Field): ...@@ -43,3 +43,7 @@ class StringIDField(serializers.Field):
def to_representation(self, value): def to_representation(self, value):
return {"pk": value.pk, "name": value.__str__()} return {"pk": value.pk, "name": value.__str__()}
class StringManyToManyField(serializers.RelatedField):
def to_representation(self, value):
return value.__str__()
\ No newline at end of file
...@@ -6,6 +6,7 @@ from rest_framework.views import APIView, Response ...@@ -6,6 +6,7 @@ from rest_framework.views import APIView, Response
from rest_framework.generics import ListAPIView, get_object_or_404 from rest_framework.generics import ListAPIView, get_object_or_404
from rest_framework import viewsets from rest_framework import viewsets
from common.utils import set_or_append_attr_bulk
from users.permissions import IsValidUser, IsSuperUser, IsSuperUserOrAppUser from users.permissions import IsValidUser, IsSuperUser, IsSuperUserOrAppUser
from .utils import AssetPermissionUtil from .utils import AssetPermissionUtil
from .models import AssetPermission from .models import AssetPermission
...@@ -27,6 +28,31 @@ class AssetPermissionViewSet(viewsets.ModelViewSet): ...@@ -27,6 +28,31 @@ class AssetPermissionViewSet(viewsets.ModelViewSet):
return serializers.AssetPermissionListSerializer return serializers.AssetPermissionListSerializer
return self.serializer_class return self.serializer_class
def get_queryset(self):
queryset = super().get_queryset()
asset_id = self.request.query_params.get('asset')
node_id = self.request.query_params.get('node')
inherit_nodes = set()
if not asset_id and not node_id:
return queryset
permissions = set()
if asset_id:
asset = get_object_or_404(Asset, pk=asset_id)
permissions = set(queryset.filter(assets=asset))
for node in asset.nodes.all():
inherit_nodes.update(set(node.ancestor_with_node))
elif node_id:
node = get_object_or_404(Node, pk=node_id)
permissions = set(queryset.filter(nodes=node))
inherit_nodes = node.ancestor
for n in inherit_nodes:
_permissions = queryset.filter(nodes=n)
set_or_append_attr_bulk(_permissions, "inherit", n.value)
permissions.update(_permissions)
return permissions
class UserGrantedAssetsApi(ListAPIView): class UserGrantedAssetsApi(ListAPIView):
""" """
......
...@@ -33,3 +33,22 @@ class AssetPermissionForm(forms.ModelForm): ...@@ -33,3 +33,22 @@ class AssetPermissionForm(forms.ModelForm):
labels = { labels = {
'nodes': _("Node"), 'nodes': _("Node"),
} }
def clean_user_groups(self):
users = self.cleaned_data.get('users')
user_groups = self.cleaned_data.get('user_groups')
if not users and not user_groups:
raise forms.ValidationError(
_("User or group at least one required"))
return self.cleaned_data["user_groups"]
def clean_asset_groups(self):
assets = self.cleaned_data.get('assets')
asset_groups = self.cleaned_data.get('asset_groups')
if not assets and not asset_groups:
raise forms.ValidationError(
_("Asset or group at least one required"))
return self.cleaned_data["asset_groups"]
...@@ -31,7 +31,6 @@ class AssetPermission(models.Model): ...@@ -31,7 +31,6 @@ class AssetPermission(models.Model):
objects = models.Manager() objects = models.Manager()
valid = ValidManager() valid = ValidManager()
inherit_from = None
def __str__(self): def __str__(self):
return self.name return self.name
...@@ -46,78 +45,6 @@ class AssetPermission(models.Model): ...@@ -46,78 +45,6 @@ class AssetPermission(models.Model):
return True return True
return False return False
def get_granted_users(self):
return list(set(self.users.all()) | self.get_granted_user_groups_member())
def get_granted_user_groups_member(self):
users = set()
for user_group in self.user_groups.all():
for user in user_group.users.all():
setattr(user, 'is_inherit_from_user_groups', True)
setattr(user, 'inherit_from_user_groups',
getattr(user, 'inherit_from_user_groups', set()).add(user_group))
users.add(user)
return users
def get_granted_assets(self):
return list(set(self.assets.all()) | self.get_granted_asset_groups_member())
def get_granted_asset_groups_member(self):
assets = set()
for asset_group in self.asset_groups.all():
for asset in asset_group.assets.all():
setattr(asset, 'is_inherit_from_asset_groups', True)
setattr(asset, 'inherit_from_asset_groups',
getattr(asset, 'inherit_from_user_groups', set()).add(asset_group))
assets.add(asset)
return assets
def check_system_user_in_assets(self):
errors = {}
assets = self.get_granted_assets()
clusters = set([asset.cluster for asset in assets])
for system_user in self.system_users.all():
cluster_remain = clusters - set(system_user.cluster.all())
if cluster_remain:
errors[system_user] = cluster_remain
return errors
@property
def users_detail(self):
return " ".join([u.name for u in self.users.all()])
@property
def user_groups_detail(self):
return " ".join([g.name for g in self.user_groups.all()])
@property
def assets_detail(self):
return " ".join([a.hostname for a in self.assets.all()])
@property
def nodes_detail(self):
return " ".join([g.value for g in self.nodes.all()])
@property
def system_users_detail(self):
return " ".join([s.name for s in self.system_users.all()])
@property
def detail(self):
data = ""
if self.users.all():
comment = _("User")
users = "<b>{}: </b>".format(comment)
for u in self.users.all():
users += u.name + " "
data += users + "<br/>"
if self.assets.all():
assets = _("<b>Assets: </b>")
for a in self.assets.all():
assets += a.hostname + " "
data += assets + "<br/>"
return data
class NodePermission(models.Model): class NodePermission(models.Model):
id = models.UUIDField(default=uuid.uuid4, primary_key=True) id = models.UUIDField(default=uuid.uuid4, primary_key=True)
......
...@@ -3,19 +3,34 @@ ...@@ -3,19 +3,34 @@
from rest_framework import serializers from rest_framework import serializers
from .models import AssetPermission from .models import AssetPermission
from common.fields import StringManyToManyField
class AssetPermissionCreateUpdateSerializer(serializers.ModelSerializer): class AssetPermissionCreateUpdateSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = AssetPermission model = AssetPermission
exclude = ('id', 'create_by', 'date_created') exclude = ('id', 'created_by', 'date_created')
class AssetPermissionListSerializer(serializers.ModelSerializer): class AssetPermissionListSerializer(serializers.ModelSerializer):
users = StringManyToManyField(many=True, read_only=True)
user_groups = StringManyToManyField(many=True, read_only=True)
assets = StringManyToManyField(many=True, read_only=True)
nodes = StringManyToManyField(many=True, read_only=True)
system_users = StringManyToManyField(many=True, read_only=True)
inherit = serializers.SerializerMethodField()
class Meta: class Meta:
model = AssetPermission model = AssetPermission
fields = '__all__' fields = '__all__'
@staticmethod
def get_inherit(obj):
if hasattr(obj, 'inherit'):
return obj.inherit
else:
return None
class AssetPermissionUpdateUserSerializer(serializers.ModelSerializer): class AssetPermissionUpdateUserSerializer(serializers.ModelSerializer):
......
...@@ -9,7 +9,7 @@ urlpatterns = [ ...@@ -9,7 +9,7 @@ urlpatterns = [
url(r'^asset-permission$', views.AssetPermissionListView.as_view(), name='asset-permission-list'), url(r'^asset-permission$', views.AssetPermissionListView.as_view(), name='asset-permission-list'),
url(r'^asset-permission/create$', views.AssetPermissionCreateView.as_view(), name='asset-permission-create'), url(r'^asset-permission/create$', views.AssetPermissionCreateView.as_view(), name='asset-permission-create'),
url(r'^asset-permission/(?P<pk>[0-9a-zA-Z\-]{36})/update$', views.AssetPermissionUpdateView.as_view(), name='asset-permission-update'), url(r'^asset-permission/(?P<pk>[0-9a-zA-Z\-]{36})/update$', views.AssetPermissionUpdateView.as_view(), name='asset-permission-update'),
# url(r'^asset-permission/(?P<pk>[0-9a-zA-Z\-]{36})$', views.AssetPermissionDetailView.as_view(),name='asset-permission-detail'), url(r'^asset-permission/(?P<pk>[0-9a-zA-Z\-]{36})$', views.AssetPermissionDetailView.as_view(),name='asset-permission-detail'),
url(r'^asset-permission/(?P<pk>[0-9a-zA-Z\-]{36})/delete$', views.AssetPermissionDeleteView.as_view(), name='asset-permission-delete'), url(r'^asset-permission/(?P<pk>[0-9a-zA-Z\-]{36})/delete$', views.AssetPermissionDeleteView.as_view(), name='asset-permission-delete'),
# url(r'^asset-permission/(?P<pk>[0-9a-zA-Z\-]{36})/user$', views.AssetPermissionUserView.as_view(), name='asset-permission-user-list'), # url(r'^asset-permission/(?P<pk>[0-9a-zA-Z\-]{36})/user$', views.AssetPermissionUserView.as_view(), name='asset-permission-user-list'),
# url(r'^asset-permission/(?P<pk>[0-9a-zA-Z\-]{36})/asset$', views.AssetPermissionAssetView.as_view(), name='asset-permission-asset-list'), # url(r'^asset-permission/(?P<pk>[0-9a-zA-Z\-]{36})/asset$', views.AssetPermissionAssetView.as_view(), name='asset-permission-asset-list'),
......
...@@ -3,14 +3,14 @@ ...@@ -3,14 +3,14 @@
from __future__ import unicode_literals, absolute_import from __future__ import unicode_literals, absolute_import
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from django.views.generic import ListView, CreateView, UpdateView from django.views.generic import ListView, CreateView, UpdateView, DetailView
from django.views.generic.edit import DeleteView from django.views.generic.edit import DeleteView
from django.urls import reverse_lazy from django.urls import reverse_lazy
from django.conf import settings from django.conf import settings
from django.db.models import Q
from .hands import AdminUserRequiredMixin, Node, User, UserGroup, Asset, SystemUser from common.utils import get_object_or_none
from .models import AssetPermission, NodePermission from .hands import AdminUserRequiredMixin, Node, Asset
from .models import AssetPermission
from .forms import AssetPermissionForm from .forms import AssetPermissionForm
...@@ -20,51 +20,9 @@ class AssetPermissionListView(AdminUserRequiredMixin, ListView): ...@@ -20,51 +20,9 @@ class AssetPermissionListView(AdminUserRequiredMixin, ListView):
paginate_by = settings.DISPLAY_PER_PAGE paginate_by = settings.DISPLAY_PER_PAGE
user = user_group = asset = node = system_user = q = "" user = user_group = asset = node = system_user = q = ""
def get_queryset(self):
self.q = self.request.GET.get('q', '')
self.user = self.request.GET.get("user", '')
self.user_group = self.request.GET.get("user_group", '')
self.asset = self.request.GET.get('asset', '')
self.node = self.request.GET.get('node', '')
self.system_user = self.request.GET.get('system_user', '')
filter_kwargs = dict()
if self.user:
filter_kwargs['users__name'] = self.user
if self.user_group:
filter_kwargs['user_groups__name'] = self.user_group
if self.asset:
filter_kwargs['assets__hostname'] = self.asset
if self.node:
filter_kwargs['nodes__value'] = self.node
if self.system_user:
filter_kwargs['system_users__name'] = self.system_user
queryset = self.model.objects.filter(**filter_kwargs)
if self.q:
queryset = queryset.filter(
Q(name__contains=self.q) |
Q(users__name=self.q) |
Q(user_groups__name=self.q) |
Q(assets__hostname=self.q) |
Q(nodes__value=self.q) |
Q(system_users__name=self.q)
)
queryset = queryset.order_by('-date_start')
return queryset
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = { context = {
'app': _('Perms'), 'app': _('Perms'),
'user_list': User.objects.all().values_list('name', flat=True),
'user_group_list': UserGroup.objects.all().values_list('name', flat=True),
'asset_list': Asset.objects.all().values_list('hostname', flat=True),
'node_list': Node.objects.all().values_list('value', flat=True),
'system_user_list': SystemUser.objects.all().values_list('name', flat=True),
'user': self.user,
'user_group': self.user_group,
'asset': self.asset,
'node': self.node,
'system_user': self.system_user,
'q': self.q,
'action': _('Asset permission list'), 'action': _('Asset permission list'),
} }
kwargs.update(context) kwargs.update(context)
...@@ -77,6 +35,19 @@ class AssetPermissionCreateView(AdminUserRequiredMixin, CreateView): ...@@ -77,6 +35,19 @@ class AssetPermissionCreateView(AdminUserRequiredMixin, CreateView):
template_name = 'perms/asset_permission_create_update.html' template_name = 'perms/asset_permission_create_update.html'
success_url = reverse_lazy('perms:asset-permission-list') success_url = reverse_lazy('perms:asset-permission-list')
def get_form(self, form_class=None):
form = super().get_form(form_class=form_class)
nodes_id = self.request.GET.get("nodes").split(",")
assets_id = self.request.GET.get("assets").split(",")
if nodes_id:
nodes = Node.objects.filter(id__in=nodes_id)
form['nodes'].initial = nodes
if assets_id:
assets = Asset.objects.filter(id__in=assets_id)
form['assets'].initial = assets
return form
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = { context = {
'app': _('Perms'), 'app': _('Perms'),
...@@ -101,6 +72,21 @@ class AssetPermissionUpdateView(AdminUserRequiredMixin, UpdateView): ...@@ -101,6 +72,21 @@ class AssetPermissionUpdateView(AdminUserRequiredMixin, UpdateView):
return super().get_context_data(**kwargs) return super().get_context_data(**kwargs)
class AssetPermissionDetailView(AdminUserRequiredMixin, DetailView):
model = AssetPermission
form_class = AssetPermissionForm
template_name = 'perms/asset_permission_detail.html'
success_url = reverse_lazy("perms:asset-permission-list")
def get_context_data(self, **kwargs):
context = {
'app': _('Perms'),
'action': _('Update asset permission')
}
kwargs.update(context)
return super().get_context_data(**kwargs)
class AssetPermissionDeleteView(AdminUserRequiredMixin, DeleteView): class AssetPermissionDeleteView(AdminUserRequiredMixin, DeleteView):
model = AssetPermission model = AssetPermission
template_name = 'delete_confirm.html' template_name = 'delete_confirm.html'
......
...@@ -212,49 +212,49 @@ website: http://code.google.com/p/jquerytree/ ...@@ -212,49 +212,49 @@ website: http://code.google.com/p/jquerytree/
height: 20px; height: 20px;
} }
.ztree li span.button.root_open::before { .ztree li span.button.root_open::before {
content: "\f078"; content: "\f107";
padding-top: 10px; padding-top: 10px;
padding-left: 2px; padding-left: 2px;
display: inline-block; display: inline-block;
} }
.ztree li span.button.root_close::before { .ztree li span.button.root_close::before {
content: "\f054"; content: "\f105";
padding-top: 10px; padding-top: 10px;
padding-left: 2px; padding-left: 2px;
display: inline-block; display: inline-block;
} }
.ztree li span.button.roots_open::before { .ztree li span.button.roots_open::before {
content: "\f078"; content: "\f107";
padding-top: 10px; padding-top: 10px;
padding-left: 2px; padding-left: 2px;
display: inline-block; display: inline-block;
} }
.ztree li span.button.roots_close::before { .ztree li span.button.roots_close::before {
content: "\f054"; content: "\f105";
padding-top: 10px; padding-top: 10px;
padding-left: 2px; padding-left: 2px;
display: inline-block; display: inline-block;
} }
.ztree li span.button.center_open::before { .ztree li span.button.center_open::before {
content: "\f078"; content: "\f107";
padding-top: 10px; padding-top: 10px;
padding-left: 2px; padding-left: 2px;
display: inline-block; display: inline-block;
} }
.ztree li span.button.center_close::before { .ztree li span.button.center_close::before {
content: "\f054"; content: "\f105";
padding-top: 10px; padding-top: 10px;
padding-left: 2px; padding-left: 2px;
display: inline-block; display: inline-block;
} }
.ztree li span.button.bottom_open::before { .ztree li span.button.bottom_open::before {
content: "\f078"; content: "\f107";
padding-top: 10px; padding-top: 10px;
padding-left: 2px; padding-left: 2px;
display: inline-block; display: inline-block;
} }
.ztree li span.button.bottom_close::before { .ztree li span.button.bottom_close::before {
content: "\f054"; content: "\f105";
padding-top: 10px; padding-top: 10px;
padding-left: 2px; padding-left: 2px;
display: inline-block; display: inline-block;
...@@ -300,7 +300,31 @@ website: http://code.google.com/p/jquerytree/ ...@@ -300,7 +300,31 @@ website: http://code.google.com/p/jquerytree/
color: #676a6c; color: #676a6c;
} }
.ztree li span.button.ico_docu::before { .ztree li span.button.ico_docu::before {
content: "\f114"; content: "\f07b";
font-family: FontAwesome;
padding-top: 10px;
padding-left: 2px;
display: inline-block;
color: #676a6c;
}
.ztree li span.button.file_ico_docu::before {
content: "\f022";
font-family: FontAwesome;
padding-top: 10px;
padding-left: 2px;
display: inline-block;
color: #676a6c;
}
.ztree li span.button.linux_ico_docu::before {
content: "\f17c";
font-family: FontAwesome;
padding-top: 10px;
padding-left: 2px;
display: inline-block;
color: #676a6c;
}
.ztree li span.button.windows_ico_docu::before {
content: "\f17a";
font-family: FontAwesome; font-family: FontAwesome;
padding-top: 10px; padding-top: 10px;
padding-left: 2px; padding-left: 2px;
......
...@@ -39,11 +39,11 @@ website: http://code.google.com/p/jquerytree/ ...@@ -39,11 +39,11 @@ website: http://code.google.com/p/jquerytree/
margin:0; padding:5px; color:@color-normal; background-color: @color-bg; margin:0; padding:5px; color:@color-normal; background-color: @color-bg;
li { li {
padding:0; margin:0; list-style:none; line-height:17px; text-align:left; white-space:nowrap; outline:0; padding:0; margin:0; list-style:none; line-height:17px; text-align:left; white-space:nowrap; outline:0;
ul { ul {
margin: 0px; padding:0 0 0 18px; margin: 0px; padding:0 0 0 18px;
} }
ul.line { } ul.line { }
a {padding-right:3px; margin:0; cursor:pointer; height:@h; color:@color-normal; background-color: transparent; a {padding-right:3px; margin:0; cursor:pointer; height:@h; color:@color-normal; background-color: transparent;
text-decoration:none; vertical-align:top; display: inline-block; text-decoration:none; vertical-align:top; display: inline-block;
input.rename {height:14px; width:80px; padding:0; margin:0; input.rename {height:14px; width:80px; padding:0; margin:0;
color: @color-bg; background-color: @color-normal; color: @color-bg; background-color: @color-normal;
...@@ -64,11 +64,11 @@ website: http://code.google.com/p/jquerytree/ ...@@ -64,11 +64,11 @@ website: http://code.google.com/p/jquerytree/
span.button {line-height:0; margin:0; padding: 0; width:@w; height:@h; display: inline-block; vertical-align:top; span.button {line-height:0; margin:0; padding: 0; width:@w; height:@h; display: inline-block; vertical-align:top;
border:0px solid; cursor: pointer;outline:none; border:0px solid; cursor: pointer;outline:none;
background-color:transparent; background-repeat:no-repeat; background-attachment: scroll; background-color:transparent; background-repeat:no-repeat; background-attachment: scroll;
&::before{color: @color-normal; font-family: FontAwesome; padding-top:@pad-top;} &::before{color: @color-normal; font-family: FontAwesome; padding-top:@pad-top;}
&.chk { margin:0px; cursor: auto; width: 12px; &.chk { margin:0px; cursor: auto; width: 12px;
display: inline-block;padding-top:@pad-top;padding-left:@pad-left; display: inline-block;padding-top:@pad-top;padding-left:@pad-left;
&.checkbox_false_full::before {content: @fa-square-o;} &.checkbox_false_full::before {content: @fa-square-o;}
&.checkbox_false_full_focus::before {content: @fa-square-o; color:@color-highlight;} &.checkbox_false_full_focus::before {content: @fa-square-o; color:@color-highlight;}
&.checkbox_false_part::before {content: @fa-square-o;color: @color-partial;} &.checkbox_false_part::before {content: @fa-square-o;color: @color-partial;}
...@@ -82,7 +82,7 @@ website: http://code.google.com/p/jquerytree/ ...@@ -82,7 +82,7 @@ website: http://code.google.com/p/jquerytree/
&.checkbox_true_part::before {content: @fa-check-square-o;color: @color-partial} &.checkbox_true_part::before {content: @fa-check-square-o;color: @color-partial}
&.checkbox_true_part_focus::before {content: @fa-check-square-o;color: @color-partfocus;} &.checkbox_true_part_focus::before {content: @fa-check-square-o;color: @color-partfocus;}
&.checkbox_true_disable::before {content: @fa-check-square-o;color: @color-disabled} &.checkbox_true_disable::before {content: @fa-check-square-o;color: @color-disabled}
&.radio_false_full::before {content: @fa-circle-o;} &.radio_false_full::before {content: @fa-circle-o;}
&.radio_false_full_focus::before {content: @fa-circle-o;color: @color-highlight} &.radio_false_full_focus::before {content: @fa-circle-o;color: @color-highlight}
&.radio_false_part::before {content: @fa-circle-o;color: @color-partial} &.radio_false_part::before {content: @fa-circle-o;color: @color-partial}
...@@ -93,17 +93,17 @@ website: http://code.google.com/p/jquerytree/ ...@@ -93,17 +93,17 @@ website: http://code.google.com/p/jquerytree/
&.radio_true_part::before {content: @fa-dot-circle-o;color: @color-partial} &.radio_true_part::before {content: @fa-dot-circle-o;color: @color-partial}
&.radio_true_part_focus::before {content: @fa-dot-circle-o;color: @color-partial;} &.radio_true_part_focus::before {content: @fa-dot-circle-o;color: @color-partial;}
&.radio_true_disable::before {content: @fa-circle-thin;color: @color-disabled} &.radio_true_disable::before {content: @fa-circle-thin;color: @color-disabled}
} }
&.switch {width:@w; height:@h} &.switch {width:@w; height:@h}
&.root_open::before{content: @fa-chevron-down;padding-top:@pad-top;padding-left:@pad-left;display: inline-block;} &.root_open::before{content: @fa-angle-down;padding-top:@pad-top;padding-left:@pad-left;display: inline-block;}
&.root_close::before{content: @fa-chevron-right;padding-top:@pad-top;padding-left:@pad-left;display: inline-block;} &.root_close::before{content: @fa-angle-right;padding-top:@pad-top;padding-left:@pad-left;display: inline-block;}
&.roots_open::before{content: @fa-chevron-down;padding-top:@pad-top;padding-left:@pad-left;display: inline-block;} &.roots_open::before{content: @fa-angle-down;padding-top:@pad-top;padding-left:@pad-left;display: inline-block;}
&.roots_close::before{content: @fa-chevron-right;padding-top:@pad-top;padding-left:@pad-left;display: inline-block;} &.roots_close::before{content: @fa-angle-right;padding-top:@pad-top;padding-left:@pad-left;display: inline-block;}
&.center_open::before{content: @fa-chevron-down;padding-top:@pad-top;padding-left:@pad-left;display: inline-block;} &.center_open::before{content: @fa-angle-down;padding-top:@pad-top;padding-left:@pad-left;display: inline-block;}
&.center_close::before{content: @fa-chevron-right;padding-top:@pad-top;padding-left:@pad-left;display: inline-block;} &.center_close::before{content: @fa-angle-right;padding-top:@pad-top;padding-left:@pad-left;display: inline-block;}
&.bottom_open::before{content: @fa-chevron-down;padding-top:@pad-top;padding-left:@pad-left;display: inline-block;} &.bottom_open::before{content: @fa-angle-down;padding-top:@pad-top;padding-left:@pad-left;display: inline-block;}
&.bottom_close::before{content: @fa-chevron-right;padding-top:@pad-top;padding-left:@pad-left;display: inline-block;} &.bottom_close::before{content: @fa-angle-right;padding-top:@pad-top;padding-left:@pad-left;display: inline-block;}
&.noline_open{} &.noline_open{}
&.noline_close{} &.noline_close{}
&.root_docu{ background:none;} &.root_docu{ background:none;}
...@@ -111,11 +111,15 @@ website: http://code.google.com/p/jquerytree/ ...@@ -111,11 +111,15 @@ website: http://code.google.com/p/jquerytree/
&.center_docu::before{padding-top:@pad-top;padding-left:@pad-left;display: inline-block;color:@color-normal;} &.center_docu::before{padding-top:@pad-top;padding-left:@pad-left;display: inline-block;color:@color-normal;}
&.bottom_docu::before{padding-top:@pad-top;padding-left:@pad-left;display: inline-block;color:@color-normal;} &.bottom_docu::before{padding-top:@pad-top;padding-left:@pad-left;display: inline-block;color:@color-normal;}
&.noline_docu{ background:none;} &.noline_docu{ background:none;}
&.ico_open::before {content: @fa-folder-open;font-family: FontAwesome;padding-top:@pad-top;padding-left:@pad-left;display: inline-block;color:@color-normal;} &.ico_open::before {content: @fa-folder-open;font-family: FontAwesome;padding-top:@pad-top;padding-left:@pad-left;display: inline-block;color:@color-normal;}
&.ico_close::before {content: @fa-folder;font-family: FontAwesome;padding-top:@pad-top;padding-left:@pad-left;display: inline-block;color:@color-normal;} &.ico_close::before {content: @fa-folder;font-family: FontAwesome;padding-top:@pad-top;padding-left:@pad-left;display: inline-block;color:@color-normal;}
&.ico_docu::before{content: @fa-folder-o;font-family: FontAwesome;padding-top:@pad-top;padding-left:@pad-left;display: inline-block;color:@color-normal;} &.ico_docu::before{content: @fa-folder;font-family: FontAwesome;padding-top:@pad-top;padding-left:@pad-left;display: inline-block;color:@color-normal;}
&.file_ico_docu::before{content: @fa-list-alt;font-family: FontAwesome;padding-top:@pad-top;padding-left:@pad-left;display: inline-block;color:@color-normal;}
&.linux_ico_docu::before{content: @fa-linux;font-family: FontAwesome;padding-top:@pad-top;padding-left:@pad-left;display: inline-block;color:@color-normal;}
&.windows_ico_docu::before{content: @fa-windows;font-family: FontAwesome;padding-top:@pad-top;padding-left:@pad-left;display: inline-block;color:@color-normal;}
&.edit {margin-left:4px; margin-right: -1px; vertical-align:top; *vertical-align:middle;padding-top:@pad-top;} &.edit {margin-left:4px; margin-right: -1px; vertical-align:top; *vertical-align:middle;padding-top:@pad-top;}
&.edit::before{content: @fa-pencil-square-o;font-family: FontAwesome;} &.edit::before{content: @fa-pencil-square-o;font-family: FontAwesome;}
......
...@@ -62,7 +62,6 @@ function GetTableDataBox() { ...@@ -62,7 +62,6 @@ function GetTableDataBox() {
} }
} }
for (i in id_list) { for (i in id_list) {
console.log(tabProduct);
tableData.push(GetRowData(tabProduct.rows[id_list[i]])); tableData.push(GetRowData(tabProduct.rows[id_list[i]]));
} }
...@@ -240,6 +239,13 @@ $.fn.serializeObject = function() ...@@ -240,6 +239,13 @@ $.fn.serializeObject = function()
}); });
return o; return o;
}; };
function makeLabel(data) {
return "<label class='detail-key'><b>" + data[0] + ": </b></label>" + data[1] + "</br>"
}
var jumpserver = {}; var jumpserver = {};
jumpserver.checked = false; jumpserver.checked = false;
jumpserver.selected = {}; jumpserver.selected = {};
...@@ -281,7 +287,7 @@ jumpserver.initDataTable = function (options) { ...@@ -281,7 +287,7 @@ jumpserver.initDataTable = function (options) {
buttons: [], buttons: [],
columnDefs: columnDefs, columnDefs: columnDefs,
ajax: { ajax: {
url: options.ajax_url , url: options.ajax_url,
dataSrc: "" dataSrc: ""
}, },
columns: options.columns || [], columns: options.columns || [],
......
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
from __future__ import unicode_literals from __future__ import unicode_literals
import os import os
from django import forms
from django.shortcuts import render from django.shortcuts import render
from django.contrib.auth import login as auth_login, logout as auth_logout from django.contrib.auth import login as auth_login, logout as auth_logout
from django.contrib.auth.mixins import LoginRequiredMixin from django.contrib.auth.mixins import LoginRequiredMixin
...@@ -20,10 +19,9 @@ from django.views.generic.base import TemplateView ...@@ -20,10 +19,9 @@ from django.views.generic.base import TemplateView
from django.views.generic.edit import FormView from django.views.generic.edit import FormView
from formtools.wizard.views import SessionWizardView from formtools.wizard.views import SessionWizardView
from django.conf import settings from django.conf import settings
from django.utils import timezone
from common.utils import get_object_or_none from common.utils import get_object_or_none
from common.mixins import DatetimeSearchMixin from common.mixins import DatetimeSearchMixin, AdminUserRequiredMixin
from ..models import User, LoginLog from ..models import User, LoginLog
from ..utils import send_reset_password_mail from ..utils import send_reset_password_mail
from ..tasks import write_login_log_async from ..tasks import write_login_log_async
...@@ -228,7 +226,7 @@ class UserFirstLoginView(LoginRequiredMixin, SessionWizardView): ...@@ -228,7 +226,7 @@ class UserFirstLoginView(LoginRequiredMixin, SessionWizardView):
return form return form
class LoginLogListView(DatetimeSearchMixin, ListView): class LoginLogListView(AdminUserRequiredMixin, DatetimeSearchMixin, ListView):
template_name = 'users/login_log_list.html' template_name = 'users/login_log_list.html'
model = LoginLog model = LoginLog
paginate_by = settings.DISPLAY_PER_PAGE paginate_by = settings.DISPLAY_PER_PAGE
......
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