diff --git a/lib/main/serializers.py b/lib/main/serializers.py index b57c09447f..80c8d51fb9 100644 --- a/lib/main/serializers.py +++ b/lib/main/serializers.py @@ -1,15 +1,38 @@ from django.contrib.auth.models import User as DjangoUser from lib.main.models import User, Organization, Project from rest_framework import serializers, pagination - -# FIXME: add all fields here -# FIXME: make proper fields read only -# FIXME: add URLs for sub resources like /organizations/2/projects/ +from django.core.urlresolvers import reverse +import lib.urls class OrganizationSerializer(serializers.ModelSerializer): - url = serializers.CharField(source='get_absolute_url', read_only=True) + # add the URL and related resources + url = serializers.CharField(source='get_absolute_url', read_only=True) + related = serializers.SerializerMethodField('get_related') + + # make certain fields read only + creation_date = serializers.DateTimeField(read_only=True) + active = serializers.BooleanField(read_only=True) class Meta: + model = Organization - fields = ('url', 'id', 'name', 'description') + + # whitelist the fields we want to show + fields = ('url', 'id', 'name', 'description', 'creation_date', 'related') + + def get_related(self, obj): + ''' related resource URLs ''' + + return dict( + audit_trail = reverse(lib.urls.views_OrganizationsAuditTrailList, args=(obj.pk,)), + projects = reverse(lib.urls.views_OrganizationsProjectsList, args=(obj.pk,)), + users = reverse(lib.urls.views_OrganizationsUsersList, args=(obj.pk,)), + admins = reverse(lib.urls.views_OrganizationsAdminsList, args=(obj.pk,)), + tags = reverse(lib.urls.views_OrganizationsTagsList, args=(obj.pk,)) + ) + + + + + diff --git a/lib/main/tests.py b/lib/main/tests.py index cc78d7732d..fa103a5d44 100644 --- a/lib/main/tests.py +++ b/lib/main/tests.py @@ -143,7 +143,12 @@ class OrganizationsTest(BaseTest): # superuser credentials == 200, full list data = self.get(self.collection(), expect=200, auth=self.get_super_credentials()) self.check_pagination_and_size(data, 10, previous=None, next=None) - [self.assertTrue(key in data['results'][0]) for key in ['name', 'description', 'url' ]] + [self.assertTrue(key in data['results'][0]) for key in ['name', 'description', 'url', 'creation_date', 'id' ]] + + # check that the related URL functionality works + related = data['results'][0]['related'] + for x in [ 'audit_trail', 'projects', 'users', 'admins', 'tags' ]: + self.assertTrue(x in related and related[x].endswith("/%s/" % x), "looking for %s in related" % x) # normal credentials == 200, get only organizations that I am actually added to (there are 2) data = self.get(self.collection(), expect=200, auth=self.get_normal_credentials()) @@ -180,13 +185,18 @@ class OrganizationsTest(BaseTest): def test_get_item_subobjects_projects(self): pass - def test_get_item_subobjects_users(self): pass def test_get_item_subobjects_admins(self): pass + def test_get_item_subobjects_tags(self): + pass + + def test_get_item_subobjects_audit_trail(self): + pass + def test_post_item(self): new_org = dict(name='magic test org', description='8675309') @@ -215,6 +225,12 @@ class OrganizationsTest(BaseTest): def test_post_item_subobjects_admins(self): pass + def test_post_item_subobjects_tags(self): + pass + + def test_post_item_subobjects_audit_trail(self): + pass + def test_put_item(self): # first get some urls and data to put back to them diff --git a/lib/main/views.py b/lib/main/views.py index 40a7c89b78..1085c12573 100644 --- a/lib/main/views.py +++ b/lib/main/views.py @@ -11,6 +11,8 @@ from rest_framework import permissions import exceptions import datetime +# FIXME: machinery for auto-adding audit trail logs to all CREATE/EDITS + class BaseList(generics.ListCreateAPIView): def list_permissions_check(self, request, obj=None): @@ -61,6 +63,7 @@ class OrganizationsDetail(BaseDetail): permission_classes = (CustomRbac,) + # FIXME: use this for the audit trail hook, ideally in base class. #def pre_save(self, obj): # obj.owner = self.request.user @@ -77,3 +80,23 @@ class OrganizationsDetail(BaseDetail): def delete_permissions_check(self, request, obj): return request.user.application_user in obj.admins.all() +class OrganizationsAuditTrailList(BaseList): + # FIXME: implementation and tests + pass + +class OrganizationsUsersList(BaseList): + # FIXME: implementation and tests + pass + +class OrganizationsAdminsList(BaseList): + # FIXME: implementation and tests + pass + +class OrganizationsProjectsList(BaseList): + # FIXME: implementation and tests + pass + +class OrganizationsTagsList(BaseList): + pass + + diff --git a/lib/urls.py b/lib/urls.py index 3e055d24db..d19c305cc6 100644 --- a/lib/urls.py +++ b/lib/urls.py @@ -2,13 +2,43 @@ from django.conf import settings from django.conf.urls import * import lib.main.views as views -views_OrganizationsList = views.OrganizationsList.as_view() -views_OrganizationsDetail = views.OrganizationsDetail.as_view() +# organizations service +views_OrganizationsList = views.OrganizationsList.as_view() +views_OrganizationsDetail = views.OrganizationsDetail.as_view() +views_OrganizationsAuditTrailList = views.OrganizationsAuditTrailList.as_view() +views_OrganizationsUsersList = views.OrganizationsUsersList.as_view() +views_OrganizationsAdminsList = views.OrganizationsAdminsList.as_view() +views_OrganizationsProjectsList = views.OrganizationsProjectsList.as_view() +views_OrganizationsTagsList = views.OrganizationsTagsList.as_view() + urlpatterns = patterns('', url(r'', include('lib.web.urls')), - url(r'^api/v1/organizations/$', views_OrganizationsList), - url(r'^api/v1/organizations/(?P[0-9]+)/$', views_OrganizationsDetail), + + # organizations service + url(r'^api/v1/organizations/$', views_OrganizationsList), + url(r'^api/v1/organizations/(?P[0-9]+)/$', views_OrganizationsDetail), + url(r'^api/v1/organizations/(?P[0-9]+)/audit_trail/$', views_OrganizationsAuditTrailList), + url(r'^api/v1/organizations/(?P[0-9]+)/users/$', views_OrganizationsUsersList), + url(r'^api/v1/organizations/(?P[0-9]+)/admins/$', views_OrganizationsAdminsList), + url(r'^api/v1/organizations/(?P[0-9]+)/projects/$', views_OrganizationsProjectsList), + url(r'^api/v1/organizations/(?P[0-9]+)/tags/$', views_OrganizationsTagsList), + + # FIXME: implement: + + # users service + # projects service + # audit trail service + # team service + # inventory service + # group service + # host service + # inventory variable service + # log data services + # events services + # jobs services + # tags service + ) if 'django.contrib.admin' in settings.INSTALLED_APPS: