diff --git a/apps/assets/api.py b/apps/assets/api.py index 2aa8c564c..05ca46331 100644 --- a/apps/assets/api.py +++ b/apps/assets/api.py @@ -1,33 +1,16 @@ # ~*~ coding: utf-8 ~*~ -from rest_framework import serializers -from rest_framework import viewsets, serializers, generics +from rest_framework import viewsets, generics, mixins from rest_framework.response import Response from rest_framework.views import APIView from rest_framework_bulk import BulkListSerializer, BulkSerializerMixin, ListBulkCreateUpdateDestroyAPIView +from django.shortcuts import get_object_or_404 from common.mixins import BulkDeleteApiMixin from common.utils import get_object_or_none, signer from .hands import IsSuperUserOrTerminalUser, IsSuperUser -from .models import AssetGroup, Asset, IDC, SystemUser -from .serializers import AssetBulkUpdateSerializer - - -class AssetGroupSerializer(serializers.ModelSerializer): - class Meta: - model = AssetGroup - - -class AssetSerializer(serializers.ModelSerializer): - class Meta: - model = Asset - # fields = ('id', 'title', 'code', 'linenos', 'language', 'style') - - -class IDCSerializer(serializers.ModelSerializer): - class Meta: - model = IDC - # fields = ('id', 'title', 'code', 'linenos', 'language', 'style') +from .models import AssetGroup, Asset, IDC, SystemUser, AdminUser +from . import serializers class AssetGroupViewSet(viewsets.ModelViewSet): @@ -35,26 +18,50 @@ class AssetGroupViewSet(viewsets.ModelViewSet): some other comment """ queryset = AssetGroup.objects.all() - serializer_class = AssetGroupSerializer + serializer_class = serializers.AssetGroupSerializer class AssetViewSet(viewsets.ModelViewSet): """API endpoint that allows Asset to be viewed or edited.""" queryset = Asset.objects.all() - serializer_class = AssetSerializer + serializer_class = serializers.AssetSerializer -class IDCViewSet(viewsets.ReadOnlyModelViewSet): +class IDCViewSet(viewsets.ModelViewSet): """API endpoint that allows IDC to be viewed or edited.""" queryset = IDC.objects.all() - serializer_class = IDCSerializer + serializer_class = serializers.IDCSerializer permission_classes = (IsSuperUser,) +class AdminUserViewSet(viewsets.ModelViewSet): + queryset = AdminUser.objects.all() + serializer_class = serializers.AdminUserSerializer + permission_classes = (IsSuperUser,) + + +class SystemUserViewSet(viewsets.ModelViewSet): + queryset = SystemUser.objects.all() + serializer_class = serializers.SystemUserSerializer + permission_classes = (IsSuperUser,) + + +class IDCAssetsApi(generics.ListAPIView): + model = IDC + serializer_class = serializers.AssetSerializer + + def get(self, request, *args, **kwargs): + filter_kwargs = {self.lookup_field: self.kwargs[self.lookup_field]} + self.object = get_object_or_404(self.model, **filter_kwargs) + return super(IDCAssetsApi, self).get(request, *args, **kwargs) + + def get_queryset(self): + return self.object.assets.all() + class AssetListUpdateApi(BulkDeleteApiMixin, ListBulkCreateUpdateDestroyAPIView): queryset = Asset.objects.all() - serializer_class = AssetBulkUpdateSerializer + serializer_class = serializers.AssetBulkUpdateSerializer permission_classes = (IsSuperUser,) diff --git a/apps/assets/models.py b/apps/assets/models.py index 1103d0b4c..fdb298e3c 100644 --- a/apps/assets/models.py +++ b/apps/assets/models.py @@ -329,6 +329,7 @@ class Asset(models.Model): def __unicode__(self): return '%(ip)s:%(port)s' % {'ip': self.ip, 'port': self.port} + @property def is_valid(self): warning = '' if not self.is_active: diff --git a/apps/assets/serializers.py b/apps/assets/serializers.py index f5b53fb68..cc00144ec 100644 --- a/apps/assets/serializers.py +++ b/apps/assets/serializers.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- from django.utils.translation import ugettext_lazy as _ from rest_framework import viewsets, serializers,generics -from .models import AssetGroup, Asset, IDC, AssetExtend +from .models import AssetGroup, Asset, IDC, AssetExtend, AdminUser, SystemUser from common.mixins import BulkDeleteApiMixin from rest_framework_bulk import BulkListSerializer, BulkSerializerMixin @@ -14,11 +14,47 @@ class AssetBulkUpdateSerializer(BulkSerializerMixin, serializers.ModelSerializer class Meta(object): model = Asset list_serializer_class = BulkListSerializer - fields = ['id', 'port', 'idc'] + fields = ('id', 'port', 'idc') # def get_group_display(self, obj): # return " ".join([group.name for group in obj.groups.all()]) # # def get_active_display(self, obj): # # TODO: user ative state - # return not (obj.is_expired and obj.is_active) \ No newline at end of file + # return not (obj.is_expired and obj.is_active) + + +class AssetGroupSerializer(serializers.ModelSerializer): + class Meta: + model = AssetGroup + + +class AssetSerializer(serializers.ModelSerializer): + class Meta: + model = Asset + + +class AdminUserSerializer(serializers.ModelSerializer): + class Meta: + model = AdminUser + + +class SystemUserSerializer(serializers.ModelSerializer): + class Meta: + model = SystemUser + + +class IDCSerializer(serializers.ModelSerializer): + assets_amount = serializers.SerializerMethodField() + + class Meta: + model = IDC + + @staticmethod + def get_assets_amount(obj): + return obj.assets.count() + + def get_field_names(self, declared_fields, info): + fields = super(IDCSerializer, self).get_field_names(declared_fields, info) + fields.append('assets_amount') + return fields diff --git a/apps/assets/templates/assets/admin_user_list.html b/apps/assets/templates/assets/admin_user_list.html index ed41a5cfe..e204b2e15 100644 --- a/apps/assets/templates/assets/admin_user_list.html +++ b/apps/assets/templates/assets/admin_user_list.html @@ -1,41 +1,118 @@ {% extends '_base_list.html' %} -{% load i18n %} -{% load common_tags %} -{% block content_left_head %} - {% trans "Create admin user" %} +{#{% load i18n %}#} +{#{% load common_tags %}#} +{#{% block content_left_head %}#} +{# {% trans "Create admin user" %} #} +{#{% endblock %}#} +{##} +{#{% block table_head %}#} +{# {% trans 'ID' %}#} +{# {% trans 'Name' %}#} +{# {% trans 'Username' %}#} +{# {% trans 'Asset num' %}#} +{# {% trans 'Lost connection' %}#} +{# {% trans 'Comment' %}#} +{# #} +{#{% endblock %}#} +{##} +{#{% block table_body %}#} +{# {% for admin_user in admin_user_list %}#} +{# #} +{# {{ admin_user.id }}#} +{# #} +{# #} +{# {{ admin_user.name }}#} +{# #} +{# #} +{# {{ admin_user.username }}#} +{# {{ admin_user.assets.count }}#} +{# {{ admin_user.assets.count }}#} +{# {{ admin_user.comment|truncatewords:8 }}#} +{# #} +{# #} +{# {% trans 'Script' %}#} +{# #} +{# {% trans 'Refresh' %}#} +{# {% trans 'Update' %}#} +{# {% trans 'Delete' %}#} +{# #} +{# #} +{# {% endfor %}#} +{#{% endblock %}#} +{% extends '_base_list.html' %} +{% load i18n static %} +{% block custom_head_css_js %} +{{ block.super }} + +{% endblock %} +{% block table_search %}{% endblock %} +{% block table_container %} +
+ {% trans "Create IDC" %} +
+ + + + + + + + + + + + + + +
+ + {% trans 'Name' %}{% trans 'Username' %}{% trans 'Asset num' %}{% trans 'Lost connection' %}{% trans 'Comment' %}
+{% endblock %} +{% block content_bottom_left %}{% endblock %} +{% block custom_foot_js %} + {% endblock %} -{% block table_head %} - {% trans 'ID' %} - {% trans 'Name' %} - {% trans 'Username' %} - {% trans 'Asset num' %} - {% trans 'Lost connection' %} - {% trans 'Comment' %} - -{% endblock %} -{% block table_body %} - {% for admin_user in admin_user_list %} - - {{ admin_user.id }} - - - {{ admin_user.name }} - - - {{ admin_user.username }} - {{ admin_user.assets.count }} - {{ admin_user.assets.count }} - {{ admin_user.comment|truncatewords:8 }} - - - {% trans 'Script' %} - - {% trans 'Refresh' %} - {% trans 'Update' %} - {% trans 'Delete' %} - - - {% endfor %} -{% endblock %} + diff --git a/apps/assets/templates/assets/asset_list.html b/apps/assets/templates/assets/asset_list.html index cf2fa8e90..d8229855a 100644 --- a/apps/assets/templates/assets/asset_list.html +++ b/apps/assets/templates/assets/asset_list.html @@ -7,19 +7,19 @@ {% endblock %} {% block content_left_head %}{% endblock %} @@ -80,7 +80,8 @@ div.dataTables_wrapper div.dataTables_filter, {% trans 'Update' %} - {% trans 'Delete' %} + + {% trans 'Delete' %} {% endfor %} @@ -190,7 +191,7 @@ div.dataTables_wrapper div.dataTables_filter, }else{ $(this).addClass('selected'); this.children[0].children[0].checked=1; - }; + } }); $('#btn_bulk_update').on('click',function(){ @@ -201,7 +202,7 @@ div.dataTables_wrapper div.dataTables_filter, for(var i=0;i
{% csrf_token %} -

Are you sure you want to delete "{{ object.name }}"?

+

{% trans 'Are you sure delete' %} {{ object.name }} ?

diff --git a/apps/assets/templates/assets/idc_assets.html b/apps/assets/templates/assets/idc_assets.html new file mode 100644 index 000000000..0afd1fa0c --- /dev/null +++ b/apps/assets/templates/assets/idc_assets.html @@ -0,0 +1,138 @@ +{% extends 'base.html' %} +{% load common_tags %} +{% load users_tags %} +{% load static %} +{% load i18n %} + +{% block custom_head_css_js %} + + + +{% endblock %} +{% block content %} +
+
+
+
+ +
+
+
+
+ {% trans 'IDC assets' %} {{ idc.name }} +
+ + + + + + + + + + +
+
+
+ + + + + + + + + + + + + +
+ + {% trans 'Hostname' %}{% trans 'IP' %}{% trans 'Port' %}{% trans 'Type' %}{% trans 'Valid' %}
+
+
+
+
+
+
+ {% trans 'Attach to assets ' %} +
+
+ + + + + + + + + + + +
+ +
+ +
+
+
+
+
+
+
+
+
+ +{% endblock %} +{% block custom_foot_js %} + +{% endblock %} \ No newline at end of file diff --git a/apps/assets/templates/assets/idc_detail.html b/apps/assets/templates/assets/idc_detail.html new file mode 100644 index 000000000..dc3143213 --- /dev/null +++ b/apps/assets/templates/assets/idc_detail.html @@ -0,0 +1,138 @@ +{% extends 'base.html' %} +{% load common_tags %} +{% load users_tags %} +{% load static %} +{% load i18n %} + +{% block custom_head_css_js %} + + +{% endblock %} +{% block content %} +
+
+
+
+ +
+
+
+
+ {{ idc.name }} +
+ + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
{% trans 'Name' %}:{{ idc.name }}
{% trans 'Bandwidth' %}:{{ idc.bandwidth }}
{% trans 'Contact' %}:{{ idc.contact }}
{% trans 'Phone' %}:{{ idc.phone }}
{% trans 'Address' %}:{{ idc.address }}
{% trans 'Intranet' %}:{{ idc.Intranet }}
{% trans 'Extranet' %}:{{ idc.extranet }}
{% trans 'Operator' %}:{{ idc.operator }}
{% trans 'Date created' %}:{{ system_user.date_created }}
{% trans 'Created by' %}:{{ asset_group.created_by }}
{% trans 'Comment' %}:{{ system_user.comment }}
+
+
+
+
+
+
+
+
+ + +{% endblock %} +{% block custom_foot_js %} + +{% endblock %} \ No newline at end of file diff --git a/apps/assets/templates/assets/idc_list.html b/apps/assets/templates/assets/idc_list.html index 810b2a102..e7bb236ca 100644 --- a/apps/assets/templates/assets/idc_list.html +++ b/apps/assets/templates/assets/idc_list.html @@ -1,43 +1,77 @@ {% extends '_base_list.html' %} -{% load i18n %} -{% load common_tags %} -{% block content_left_head %} - {% trans "Create IDC" %} -{% endblock %} +{% load i18n static %} +{% block custom_head_css_js %} +{{ block.super }} + {% endblock %} - -{% block table_body %} - {% for idc in idc_list %} - - - - - {{ idc.name }} - {{ idc.assets.count }} -{# {{ idc.bandwidth }}#} - {{ idc.contact }} - {{ idc.phone }} -{# {{ idc.address }}#} - - {% trans 'Update' %} - {% trans 'Delete' %} - - - {% endfor %} +{% block table_search %}{% endblock %} +{% block table_container %} +
+ {% trans "Create IDC" %} +
+ + + + + + + + + + + + + + +
+ + {% trans 'Name' %}{% trans 'Asset num' %}{% trans 'Contact' %}{% trans 'Phone' %}{% trans 'Operator' %}{% trans 'Action' %}
{% endblock %} +{% block content_bottom_left %}{% endblock %} {% block custom_foot_js %} {% endblock %} + + diff --git a/apps/assets/urls.py b/apps/assets/urls.py index 825b3e4ab..01c431ec3 100644 --- a/apps/assets/urls.py +++ b/apps/assets/urls.py @@ -2,14 +2,8 @@ from django.conf.urls import url, include import views import api -# from .api import ( -# AssetGroupViewSet, AssetViewSet, IDCViewSet -# ) -# from rest_framework import routers -# router = routers.DefaultRouter() -# router.register(r'assetgroup', AssetGroupViewSet) -# router.register(r'asset', AssetViewSet) -# router.register(r'idc', IDCViewSet) +from rest_framework import routers + app_name = 'assets' urlpatterns = [ @@ -43,6 +37,7 @@ urlpatterns = [ url(r'^idc/(?P[0-9]+)$', views.IDCDetailView.as_view(), name='idc-detail'), url(r'^idc/(?P[0-9]+)/update', views.IDCUpdateView.as_view(), name='idc-update'), url(r'^idc/(?P[0-9]+)/delete$', views.IDCDeleteView.as_view(), name='idc-delete'), + url(r'^idc/(?P[0-9]+)/assets$', views.IDCAssetsView.as_view(), name='idc-assets'), # Resource admin user url url(r'^admin-user$', views.AdminUserListView.as_view(), name='admin-user-list'), @@ -63,10 +58,49 @@ urlpatterns = [ ] +# router = routers.DefaultRouter() +# router.register(r'v1/asset-groups/', api.AssetGroupViewSet) +# router.register(r'v1/assets/', api.AssetViewSet) +# router.register(r'v1/idc/', api.IDCViewSet) + +asset_list_view = api.AssetViewSet.as_view({ + 'get': 'list', + 'post': 'create' +}) + +asset_detail_view = api.AssetViewSet.as_view({ + 'get': 'retrieve', + 'put': 'update', + 'patch': 'partial_update', + 'delete': 'destroy', +}) + +idc_list_view = api.IDCViewSet.as_view({ + 'get': 'list', + 'post': 'create', +}) + +idc_detail_view = api.IDCViewSet.as_view({ + 'get': 'retrieve', + 'put': 'update', + 'patch': 'partial_update', + 'delete': 'destroy', +}) + +admin_user_list_view = api.AdminUserViewSet.as_view({ + 'get': 'list', + 'post': 'create', +}) + urlpatterns += [ - url(r'^v1/assets/$', api.AssetViewSet.as_view({'get':'list'}), name='assets-list-api'), + url(r'^v1/assets/$', asset_list_view, name='asset-list-create-api'), + url(r'^v1/assets/(?P[0-9]+)/$', asset_detail_view, name='asset-detail-update-delete-api'), url(r'^v1/assets_bulk/$', api.AssetListUpdateApi.as_view(), name='asset-bulk-update-api'), - url(r'^v1/idc/$', api.IDCViewSet.as_view({'get':'list'}), name='idc-list-json'), + url(r'^v1/idc/$', idc_list_view, name='idc-list-create-api'), + url(r'^v1/idc/(?P[0-9]+)/$', idc_detail_view, name='idc-detail-update-delete-api'), + url(r'^v1/idc/(?P[0-9]+)/assets/$', api.IDCAssetsApi.as_view(), name='idc-assets-api'), + url(r'^v1/admin-user/$', idc_list_view, name='idc-list-create-api'), + url(r'^v1/idc/(?P[0-9]+)/$', idc_detail_view, name='idc-detail-update-delete-api'), url(r'^v1/system-user/auth/', api.SystemUserAuthApi.as_view(), name='system-user-auth'), ] diff --git a/apps/assets/views.py b/apps/assets/views.py index f15612de8..837dc3fed 100644 --- a/apps/assets/views.py +++ b/apps/assets/views.py @@ -30,14 +30,14 @@ class AssetListView(AdminUserRequiredMixin, ListView): @staticmethod def sorted_by_valid_and_ip(asset): ip_list = int_seq(asset.ip.split('.')) - ip_list.insert(0, asset.is_valid()[0]) + ip_list.insert(0, asset.is_valid[0]) return ip_list def get_context_data(self, **kwargs): context = { 'app': 'Assets', 'action': 'asset list', - 'tag_list': [(i.id,i.name,i.asset_set.all().count())for i in Tag.objects.all().order_by('name')] + 'tag_list': [(i.id, i.name, i.asset_set.all().count())for i in Tag.objects.all().order_by('name')] } kwargs.update(context) @@ -341,33 +341,33 @@ class AssetGroupDeleteView(AdminUserRequiredMixin, DeleteView): success_url = reverse_lazy('assets:asset-group-list') -class IDCListView(AdminUserRequiredMixin, ListView): - model = IDC - paginate_by = settings.CONFIG.DISPLAY_PER_PAGE - context_object_name = 'idc_list' +class IDCListView(AdminUserRequiredMixin, TemplateView): + # model = IDC + # paginate_by = settings.CONFIG.DISPLAY_PER_PAGE + # context_object_name = 'idc_list' template_name = 'assets/idc_list.html' def get_context_data(self, **kwargs): context = { 'app': _('Assets'), 'action': _('IDC list'), - 'keyword': self.request.GET.get('keyword', '') + # 'keyword': self.request.GET.get('keyword', '') } kwargs.update(context) return super(IDCListView, self).get_context_data(**kwargs) - def get_queryset(self): - self.queryset = super(IDCListView, self).get_queryset() - self.keyword = keyword = self.request.GET.get('keyword', '') - self.sort = sort = self.request.GET.get('sort', '-date_created') - - if keyword: - self.queryset = self.queryset.filter(Q(name__icontains=keyword) | - Q(comment__icontains=keyword)) - - if sort: - self.queryset = self.queryset.order_by(sort) - return self.queryset + # def get_queryset(self): + # self.queryset = super(IDCListView, self).get_queryset() + # self.keyword = keyword = self.request.GET.get('keyword', '') + # self.sort = sort = self.request.GET.get('sort', '-date_created') + # + # if keyword: + # self.queryset = self.queryset.filter(Q(name__icontains=keyword) | + # Q(comment__icontains=keyword)) + # + # if sort: + # self.queryset = self.queryset.order_by(sort) + # return self.queryset class IDCCreateView(AdminUserRequiredMixin, CreateView): @@ -414,7 +414,15 @@ class IDCUpdateView(AdminUserRequiredMixin, UpdateView): class IDCDetailView(AdminUserRequiredMixin, DetailView): - pass + model = IDC + template_name = 'assets/idc_detail.html' + context_object_name = 'idc' + + +class IDCAssetsView(AdminUserRequiredMixin, DetailView): + model = IDC + template_name = 'assets/idc_assets.html' + context_object_name = 'idc' class IDCDeleteView(AdminUserRequiredMixin, DeleteView): diff --git a/apps/common/templates/common/flash_message_standalone.html b/apps/templates/flash_message_standalone.html similarity index 100% rename from apps/common/templates/common/flash_message_standalone.html rename to apps/templates/flash_message_standalone.html diff --git a/apps/users/models.py b/apps/users/models.py index 8187eb916..531c8f402 100644 --- a/apps/users/models.py +++ b/apps/users/models.py @@ -234,7 +234,7 @@ class User(AbstractUser): user.groups.add(UserGroup.initial()) def delete(self): - if self.pk == 1: + if self.pk == 1 or self.username == 'admin': return return super(User, self).delete() diff --git a/apps/users/templates/users/user_list.html b/apps/users/templates/users/user_list.html index b50d5b24b..da124adfb 100644 --- a/apps/users/templates/users/user_list.html +++ b/apps/users/templates/users/user_list.html @@ -79,7 +79,7 @@ $(document).ready(function(){ {targets: 7, createdCell: function (td, cellData, rowData) { var update_btn = '{% trans "Update" %}'.replace('99991937', cellData); var del_btn = '{% trans "Delete" %}'.replace('99991937', cellData); - if (rowData.id === 1) { + if (rowData.id === 1 || rowData.username == "admin") { $(td).html(update_btn) } else { $(td).html(update_btn + del_btn)