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
# such that the transaction does not commit.
if not self.__class__.parent_model.can_user_attach(request.user, main, obj, self.__class__.relationship):
raise PermissionDenied()
if self.__class__.parent_model != User:
if not self.__class__.parent_model.can_user_attach(request.user, main, obj, self.__class__.relationship):
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)

View File

@@ -126,6 +126,13 @@ class UserHelper(object):
matching_orgs = obj.organizations.filter(admins__in = [user]).count()
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):
'''
@@ -524,6 +531,20 @@ class Credential(CommonModel):
ssh_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):
'''

View File

@@ -146,7 +146,7 @@ class CredentialSerializer(BaseSerializer):
model = Credential
fields = (
'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'
)

View File

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

View File

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

View File

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

View File

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