mirror of
https://github.com/ansible/awx.git
synced 2026-01-09 23:12:08 -03:30
Add related resources from a user object, as a rapid way to list what organizations or projects they belong to.
This commit is contained in:
parent
1ae2e69e8a
commit
18eaec143c
@ -316,7 +316,7 @@ class Team(CommonModel):
|
||||
|
||||
projects = models.ManyToManyField('Project', blank=True, related_name='teams')
|
||||
users = models.ManyToManyField('auth.User', blank=True, related_name='teams')
|
||||
organization = models.ManyToManyField('Organization', related_name='teams')
|
||||
organizations = models.ManyToManyField('Organization', related_name='teams')
|
||||
|
||||
class Project(CommonModel):
|
||||
'''
|
||||
|
||||
@ -78,6 +78,21 @@ class ProjectSerializer(BaseSerializer):
|
||||
# FIXME: add related resources: inventories
|
||||
return dict()
|
||||
|
||||
class TeamSerializer(BaseSerializer):
|
||||
|
||||
# add the URL and related resources
|
||||
url = serializers.CharField(source='get_absolute_url', read_only=True)
|
||||
related = serializers.SerializerMethodField('get_related')
|
||||
|
||||
class Meta:
|
||||
model = Team
|
||||
fields = ('url', 'id', 'related', 'name', 'description', 'creation_date')
|
||||
|
||||
def get_related(self, obj):
|
||||
# FIXME: add related resources: projects, users, organizations
|
||||
return dict()
|
||||
|
||||
|
||||
class UserSerializer(BaseSerializer):
|
||||
|
||||
# add the URL and related resources
|
||||
@ -89,8 +104,12 @@ class UserSerializer(BaseSerializer):
|
||||
fields = ('url', 'id', 'username', 'first_name', 'last_name', 'email', 'is_active', 'is_superuser', 'related')
|
||||
|
||||
def get_related(self, obj):
|
||||
# FIXME: add related lookups?
|
||||
return dict()
|
||||
return dict(
|
||||
teams = reverse(lib.urls.views_UsersTeamsList, args=(obj.pk,)),
|
||||
organizations = reverse(lib.urls.views_UsersOrganizationsList, args=(obj.pk,)),
|
||||
admin_of_organizations = reverse(lib.urls.views_UsersAdminOrganizationsList, args=(obj.pk,)),
|
||||
)
|
||||
|
||||
|
||||
def get_absolute_url_override(self, obj):
|
||||
import lib.urls
|
||||
|
||||
@ -25,6 +25,7 @@ class UsersTest(BaseTest):
|
||||
self.organizations = self.make_organizations(self.super_django_user, 1)
|
||||
self.organizations[0].admins.add(self.normal_django_user)
|
||||
self.organizations[0].users.add(self.other_django_user)
|
||||
self.organizations[0].users.add(self.normal_django_user)
|
||||
|
||||
def test_only_super_user_or_org_admin_can_add_users(self):
|
||||
url = '/api/v1/users/'
|
||||
@ -153,11 +154,47 @@ class UsersTest(BaseTest):
|
||||
self.assertEquals(data['results'][0]['username'], 'admin')
|
||||
self.assertEquals(data['count'], 1)
|
||||
|
||||
# TODO:
|
||||
# possibly nice to have, some quick lookup functions that are not postable:
|
||||
# /users/2/organizations
|
||||
# /users/2/projects
|
||||
# /users/2/teams
|
||||
|
||||
def test_user_related_resources(self):
|
||||
|
||||
# organizations the user is a member of, should be 1
|
||||
url = '/api/v1/users/2/organizations/'
|
||||
data = self.get(url, expect=200, auth=self.get_normal_credentials())
|
||||
self.assertEquals(data['count'], 1)
|
||||
# also accessible via superuser
|
||||
data = self.get(url, expect=200, auth=self.get_super_credentials())
|
||||
self.assertEquals(data['count'], 1)
|
||||
# but not by other user
|
||||
data = self.get(url, expect=403, auth=self.get_other_credentials())
|
||||
|
||||
# organizations the user is an admin of, should be 1
|
||||
url = '/api/v1/users/2/admin_of_organizations/'
|
||||
data = self.get(url, expect=200, auth=self.get_normal_credentials())
|
||||
self.assertEquals(data['count'], 1)
|
||||
# also accessible via superuser
|
||||
data = self.get(url, expect=200, auth=self.get_super_credentials())
|
||||
self.assertEquals(data['count'], 1)
|
||||
# but not by other user
|
||||
data = self.get(url, expect=403, auth=self.get_other_credentials())
|
||||
|
||||
# teams the user is on, should be 0
|
||||
url = '/api/v1/users/2/teams/'
|
||||
data = self.get(url, expect=200, auth=self.get_normal_credentials())
|
||||
self.assertEquals(data['count'], 0)
|
||||
# also accessible via superuser
|
||||
data = self.get(url, expect=200, auth=self.get_super_credentials())
|
||||
self.assertEquals(data['count'], 0)
|
||||
# but not by other user
|
||||
data = self.get(url, expect=403, auth=self.get_other_credentials())
|
||||
|
||||
# verify org admin can still read other user data too
|
||||
url = '/api/v1/users/3/organizations/'
|
||||
data = self.get(url, expect=200, auth=self.get_normal_credentials())
|
||||
self.assertEquals(data['count'], 1)
|
||||
url = '/api/v1/users/3/admin_of_organizations/'
|
||||
data = self.get(url, expect=200, auth=self.get_normal_credentials())
|
||||
self.assertEquals(data['count'], 0)
|
||||
url = '/api/v1/users/3/teams/'
|
||||
data = self.get(url, expect=200, auth=self.get_normal_credentials())
|
||||
self.assertEquals(data['count'], 0)
|
||||
|
||||
|
||||
|
||||
@ -193,6 +193,51 @@ class UsersMeList(BaseList):
|
||||
''' a quick way to find my user record '''
|
||||
return User.objects.filter(pk=self.request.user.pk)
|
||||
|
||||
class UsersTeamsList(BaseSubList):
|
||||
|
||||
model = Team
|
||||
serializer_class = TeamSerializer
|
||||
permission_classes = (CustomRbac,)
|
||||
parent_model = User
|
||||
relationship = 'teams'
|
||||
postable = False
|
||||
|
||||
def _get_queryset(self):
|
||||
user = User.objects.get(pk=self.kwargs['pk'])
|
||||
if not UserHelper.can_user_administrate(self.request.user, user):
|
||||
raise PermissionDenied()
|
||||
return Team.objects.filter(users__in = [ user ])
|
||||
|
||||
class UsersOrganizationsList(BaseSubList):
|
||||
|
||||
model = Organization
|
||||
serializer_class = OrganizationSerializer
|
||||
permission_classes = (CustomRbac,)
|
||||
parent_model = User
|
||||
relationship = 'organizations'
|
||||
postable = False
|
||||
|
||||
def _get_queryset(self):
|
||||
user = User.objects.get(pk=self.kwargs['pk'])
|
||||
if not UserHelper.can_user_administrate(self.request.user, user):
|
||||
raise PermissionDenied()
|
||||
return Organization.objects.filter(users__in = [ user ])
|
||||
|
||||
class UsersAdminOrganizationsList(BaseSubList):
|
||||
|
||||
model = Organization
|
||||
serializer_class = OrganizationSerializer
|
||||
permission_classes = (CustomRbac,)
|
||||
parent_model = User
|
||||
relationship = 'admin_of_organizations'
|
||||
postable = False
|
||||
|
||||
def _get_queryset(self):
|
||||
user = User.objects.get(pk=self.kwargs['pk'])
|
||||
if not UserHelper.can_user_administrate(self.request.user, user):
|
||||
raise PermissionDenied()
|
||||
return Organization.objects.filter(admins__in = [ user ])
|
||||
|
||||
class UsersDetail(BaseDetail):
|
||||
|
||||
model = User
|
||||
|
||||
34
lib/urls.py
34
lib/urls.py
@ -20,18 +20,23 @@ from django.conf.urls import *
|
||||
import lib.main.views as views
|
||||
|
||||
# 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()
|
||||
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()
|
||||
|
||||
# users service
|
||||
views_UsersList = views.UsersList.as_view()
|
||||
views_UsersDetail = views.UsersDetail.as_view()
|
||||
views_UsersMeList = views.UsersMeList.as_view()
|
||||
views_UsersList = views.UsersList.as_view()
|
||||
views_UsersDetail = views.UsersDetail.as_view()
|
||||
views_UsersMeList = views.UsersMeList.as_view()
|
||||
views_UsersTeamsList = views.UsersTeamsList.as_view()
|
||||
views_UsersOrganizationsList = views.UsersOrganizationsList.as_view()
|
||||
views_UsersAdminOrganizationsList = views.UsersAdminOrganizationsList.as_view()
|
||||
|
||||
|
||||
|
||||
# projects service
|
||||
views_ProjectsDetail = views.OrganizationsDetail.as_view()
|
||||
@ -69,9 +74,12 @@ urlpatterns = patterns('',
|
||||
url(r'^api/v1/organizations/(?P<pk>[0-9]+)/tags/$', views_OrganizationsTagsList),
|
||||
|
||||
# users service
|
||||
url(r'^api/v1/users/$', views_UsersList),
|
||||
url(r'^api/v1/users/(?P<pk>[0-9]+)/$', views_UsersDetail),
|
||||
url(r'^api/v1/me/$', views_UsersMeList),
|
||||
url(r'^api/v1/users/$', views_UsersList),
|
||||
url(r'^api/v1/users/(?P<pk>[0-9]+)/$', views_UsersDetail),
|
||||
url(r'^api/v1/me/$', views_UsersMeList),
|
||||
url(r'^api/v1/users/(?P<pk>[0-9]+)/teams/$', views_UsersTeamsList),
|
||||
url(r'^api/v1/users/(?P<pk>[0-9]+)/organizations/$', views_UsersOrganizationsList),
|
||||
url(r'^api/v1/users/(?P<pk>[0-9]+)/admin_of_organizations/$', views_UsersAdminOrganizationsList),
|
||||
|
||||
# projects service
|
||||
url(r'^api/v1/projects/(?P<pk>[0-9]+)/$', views_ProjectsDetail),
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user