Working on surfacing credentials via REST.

This commit is contained in:
Michael DeHaan
2013-04-02 14:59:58 -04:00
parent 37cdd31b79
commit b20a29b458
7 changed files with 97 additions and 59 deletions

View File

@@ -124,8 +124,13 @@ class BaseSubList(BaseList):
# now make sure we could have already attached the two together. If we could not have, raise an exception # now make sure we could have already attached the two together. If we could not have, raise an exception
# such that the transaction does not commit. # such that the transaction does not commit.
if self.__class__.parent_model != User:
if not self.__class__.parent_model.can_user_attach(request.user, main, obj, self.__class__.relationship): if not self.__class__.parent_model.can_user_attach(request.user, main, obj, self.__class__.relationship):
raise PermissionDenied() raise PermissionDenied()
else:
# FIXME: should generalize this
if not UserHelper.can_user_attach(request.user, main, obj, self.__class__.relationship):
raise PermissionDenied()
return Response(status=status.HTTP_201_CREATED, data=ser.data) return Response(status=status.HTTP_201_CREATED, data=ser.data)

View File

@@ -126,6 +126,13 @@ class UserHelper(object):
matching_orgs = obj.organizations.filter(admins__in = [user]).count() matching_orgs = obj.organizations.filter(admins__in = [user]).count()
return matching_orgs return matching_orgs
@classmethod
def can_user_attach(cls, user, obj, sub_obj, relationship_type):
if type(sub_obj) != User:
if not sub_obj.can_user_read(user, sub_obj):
return False
rc = cls.can_user_administrate(user, obj)
return rc
class PrimordialModel(models.Model): class PrimordialModel(models.Model):
''' '''
@@ -524,6 +531,20 @@ class Credential(CommonModel):
ssh_password = models.CharField(blank=True, default='', max_length=1024) ssh_password = models.CharField(blank=True, default='', max_length=1024)
sudo_password = models.CharField(blank=True, default='', max_length=1024) sudo_password = models.CharField(blank=True, default='', max_length=1024)
@classmethod
def can_user_read(cls, user, obj):
''' a user can be read if they are on the same team or can be administrated '''
if user.is_superuser:
return True
if user == obj.user:
return True
if Organizations.filter(admins__in = [ user ], users__in = [ obj.user ]).count():
return True
return False
def get_absolute_url(self):
import lib.urls
return reverse(lib.urls.views_CredentialsDetail, args=(self.pk,))
class Team(CommonModel): class Team(CommonModel):
''' '''

View File

@@ -146,7 +146,7 @@ class CredentialSerializer(BaseSerializer):
model = Credential model = Credential
fields = ( fields = (
'url', 'id', 'related', 'name', 'description', 'creation_date', 'url', 'id', 'related', 'name', 'description', 'creation_date',
'ssh_key_path', 'ssh_key_data', 'ssh_key_unlock', 'ssh_password', 'sudo_password', 'default_username', 'ssh_key_data', 'ssh_key_unlock', 'ssh_password', 'sudo_password',
'user', 'team' 'user', 'team'
) )

View File

@@ -285,7 +285,7 @@ class ProjectsTest(BaseTest):
new_credentials = dict( new_credentials = dict(
name = 'credential', name = 'credential',
project = Project.objects.all()[0].pk, project = Project.objects.all()[0].pk,
ssh_key_path = 'foo', default_username = 'foo',
ssh_key_data = 'bar', ssh_key_data = 'bar',
ssh_key_unlock = 'baz', ssh_key_unlock = 'baz',
ssh_password = 'narf', ssh_password = 'narf',

View File

@@ -88,8 +88,12 @@ class RunLaunchJobTest(BaseCeleryTest):
launch_job_status = self.launch_job.start() launch_job_status = self.launch_job.start()
self.assertEqual(launch_job_status.status, 'pending') self.assertEqual(launch_job_status.status, 'pending')
launch_job_status = LaunchJobStatus.objects.get(pk=launch_job_status.pk) launch_job_status = LaunchJobStatus.objects.get(pk=launch_job_status.pk)
#print 'stdout:', launch_job_status.result_stdout print 'stdout:', launch_job_status.result_stdout
#print 'stderr:', launch_job_status.result_stderr print 'stderr:', launch_job_status.result_stderr
print launch_job_status.status
print settings.DATABASES
self.assertEqual(launch_job_status.status, 'successful') self.assertEqual(launch_job_status.status, 'successful')
self.assertTrue(launch_job_status.result_stdout) self.assertTrue(launch_job_status.result_stdout)
launch_job_status_events = launch_job_status.launch_job_status_events.all() launch_job_status_events = launch_job_status.launch_job_status_events.all()

View File

@@ -400,6 +400,13 @@ class UsersDetail(BaseDetail):
obj.save() obj.save()
request.DATA.pop('password') request.DATA.pop('password')
class CredentialsDetail(BaseDetail):
model = Credential
serializer_class = CredentialSerializer
permission_classes = (CustomRbac,)
class InventoryList(BaseList): class InventoryList(BaseList):
model = Inventory model = Inventory

View File

@@ -80,6 +80,9 @@ views_VariableDetail = views.VariableDetail.as_view()
# tags service # tags service
views_TagsDetail = views.TagsDetail.as_view() views_TagsDetail = views.TagsDetail.as_view()
# credentials service
views_CredentialsDetail = views.CredentialsDetail.as_view()
urlpatterns = patterns('', urlpatterns = patterns('',
@@ -155,9 +158,7 @@ urlpatterns = patterns('',
# ... and tag relations on all resources # ... and tag relations on all resources
# credentials services # credentials services
# ... users url(r'^api/v1/credentials/(?P<pk>[0-9]+)/$', views_CredentialsDetail),
# ... teams
# ... projects (?)
# permissions services # permissions services
# ... users # ... users