From 775ae688f82df6d352e42de3b12e0abdf251f773 Mon Sep 17 00:00:00 2001 From: Chris Church Date: Fri, 28 Jun 2013 22:25:04 -0400 Subject: [PATCH] Added validation to prevent setting an invalid project local_path via the API. --- awx/main/serializers.py | 9 +++++++++ awx/main/tests/projects.py | 30 ++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/awx/main/serializers.py b/awx/main/serializers.py index 38e8e565c1..dbb399ed1f 100644 --- a/awx/main/serializers.py +++ b/awx/main/serializers.py @@ -119,6 +119,15 @@ class ProjectSerializer(BaseSerializer): )) return res + def validate_local_path(self, attrs, source): + # Don't allow assigning a local_path used by another project. + valid_local_paths = Project.get_local_path_choices() + if self.object: + valid_local_paths.append(self.object.local_path) + if attrs[source] not in valid_local_paths: + raise serializers.ValidationError('Invalid path choice') + return attrs + class ProjectPlaybooksSerializer(ProjectSerializer): class Meta: diff --git a/awx/main/tests/projects.py b/awx/main/tests/projects.py index 4f61acb6e6..78605e202c 100644 --- a/awx/main/tests/projects.py +++ b/awx/main/tests/projects.py @@ -3,6 +3,8 @@ import datetime import json +import os +import tempfile from django.conf import settings from django.contrib.auth.models import User as DjangoUser @@ -200,6 +202,34 @@ class ProjectsTest(BaseTest): results = self.get(projects, expect=200, auth=self.get_nobody_credentials()) self.assertEquals(results['count'], 0) + # can add projects (super user) + project_dir = tempfile.mkdtemp(dir=settings.PROJECTS_ROOT) + self._temp_project_dirs.append(project_dir) + project_data = { + 'name': 'My Test Project', + 'description': 'Does amazing things', + 'local_path': os.path.basename(project_dir), + } + response = self.post(projects, project_data, expect=201, + auth=self.get_super_credentials()) + + # can edit project using same local path. + project_detail = reverse('main:project_detail', args=(response['id'],)) + project_data = self.get(project_detail, expect=200, + auth=self.get_super_credentials()) + response = self.put(project_detail, project_data, expect=200, + auth=self.get_super_credentials()) + + # cannot update using local_path from another project. + project_data['local_path'] = self.projects[2].local_path + response = self.put(project_detail, project_data, expect=400, + auth=self.get_super_credentials()) + + # cannot update using a path that doesn't exist. + project_data['local_path'] = 'my_secret_invisible_project_path' + response = self.put(project_detail, project_data, expect=400, + auth=self.get_super_credentials()) + # ===================================================================== # PROJECTS - ACCESS project = reverse('main:project_detail', args=(self.projects[3].pk,))