From 91c7dee2f664afc5996af1b23731d16695333f09 Mon Sep 17 00:00:00 2001 From: AlanCoding Date: Thu, 5 May 2016 10:54:06 -0400 Subject: [PATCH 1/2] Add error messages in permission denied cases --- awx/api/serializers.py | 28 ++++++++++++++-------------- awx/api/views.py | 18 +++++++++--------- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/awx/api/serializers.py b/awx/api/serializers.py index d679029057..7c3f607d37 100644 --- a/awx/api/serializers.py +++ b/awx/api/serializers.py @@ -1292,7 +1292,7 @@ class InventorySourceOptionsSerializer(BaseSerializer): return value except yaml.YAMLError: pass - raise serializers.ValidationError('Must be valid JSON or YAML') + raise serializers.ValidationError('Must be valid JSON or YAML.') def validate(self, attrs): # TODO: Validate source, validate source_regions @@ -2426,36 +2426,36 @@ class ScheduleSerializer(BaseSerializer): if not len(match_multiple_dtstart): raise serializers.ValidationError('DTSTART required in rrule. Value should match: DTSTART:YYYYMMDDTHHMMSSZ') if len(match_multiple_dtstart) > 1: - raise serializers.ValidationError('Multiple DTSTART is not supported') + raise serializers.ValidationError('Multiple DTSTART is not supported.') if not len(match_multiple_rrule): - raise serializers.ValidationError('RRULE require in rrule') + raise serializers.ValidationError('RRULE require in rrule.') if len(match_multiple_rrule) > 1: - raise serializers.ValidationError('Multiple RRULE is not supported') + raise serializers.ValidationError('Multiple RRULE is not supported.') if 'interval' not in rrule_value.lower(): - raise serializers.ValidationError('INTERVAL required in rrule') + raise serializers.ValidationError('INTERVAL required in rrule.') if 'tzid' in rrule_value.lower(): - raise serializers.ValidationError('TZID is not supported') + raise serializers.ValidationError('TZID is not supported.') if 'secondly' in rrule_value.lower(): - raise serializers.ValidationError('SECONDLY is not supported') + raise serializers.ValidationError('SECONDLY is not supported.') if re.match(multi_by_month_day, rrule_value): - raise serializers.ValidationError('Multiple BYMONTHDAYs not supported') + raise serializers.ValidationError('Multiple BYMONTHDAYs not supported.') if re.match(multi_by_month, rrule_value): - raise serializers.ValidationError('Multiple BYMONTHs not supported') + raise serializers.ValidationError('Multiple BYMONTHs not supported.') if re.match(by_day_with_numeric_prefix, rrule_value): - raise serializers.ValidationError("BYDAY with numeric prefix not supported") + raise serializers.ValidationError("BYDAY with numeric prefix not supported.") if 'byyearday' in rrule_value.lower(): - raise serializers.ValidationError("BYYEARDAY not supported") + raise serializers.ValidationError("BYYEARDAY not supported.") if 'byweekno' in rrule_value.lower(): - raise serializers.ValidationError("BYWEEKNO not supported") + raise serializers.ValidationError("BYWEEKNO not supported.") if match_count: count_val = match_count.groups()[0].strip().split("=") if int(count_val[1]) > 999: - raise serializers.ValidationError("COUNT > 999 is unsupported") + raise serializers.ValidationError("COUNT > 999 is unsupported.") try: rrule.rrulestr(rrule_value) except Exception: # TODO: Log - raise serializers.ValidationError("rrule parsing failed validation") + raise serializers.ValidationError("rrule parsing failed validation.") return value class ActivityStreamSerializer(BaseSerializer): diff --git a/awx/api/views.py b/awx/api/views.py index aa476f18c6..a54811f2a9 100644 --- a/awx/api/views.py +++ b/awx/api/views.py @@ -925,7 +925,7 @@ class ProjectDetail(RetrieveUpdateDestroyAPIView): obj = self.get_object() can_delete = request.user.can_access(Project, 'delete', obj) if not can_delete: - raise PermissionDenied("Cannot delete project") + raise PermissionDenied("Cannot delete project.") for pu in obj.project_updates.filter(status__in=['new', 'pending', 'waiting', 'running']): pu.cancel() return super(ProjectDetail, self).destroy(request, *args, **kwargs) @@ -1114,7 +1114,7 @@ class UserRolesList(SubListCreateAttachDetachAPIView): return Response(data, status=status.HTTP_400_BAD_REQUEST) if sub_id == self.request.user.admin_role.pk: - raise PermissionDenied('You may not remove your own admin_role') + raise PermissionDenied('You may not remove your own admin_role.') return super(UserRolesList, self).post(request, *args, **kwargs) @@ -1210,13 +1210,13 @@ class UserDetail(RetrieveUpdateDestroyAPIView): if left is not None and right is not None and left != right: changed[field] = (left, right) if changed: - raise PermissionDenied('Cannot change %s' % ', '.join(changed.keys())) + raise PermissionDenied('Cannot change %s.' % ', '.join(changed.keys())) def destroy(self, request, *args, **kwargs): obj = self.get_object() can_delete = request.user.can_access(User, 'delete', obj) if not can_delete: - raise PermissionDenied('Cannot delete user') + raise PermissionDenied('Cannot delete user.') return super(UserDetail, self).destroy(request, *args, **kwargs) class UserAccessList(ResourceAccessList): @@ -1373,7 +1373,7 @@ class InventoryScriptDetail(RetrieveUpdateDestroyAPIView): instance = self.get_object() can_delete = request.user.can_access(self.model, 'delete', instance) if not can_delete: - raise PermissionDenied("Cannot delete inventory script") + raise PermissionDenied("Cannot delete inventory script.") for inv_src in InventorySource.objects.filter(source_script=instance): inv_src.source_script = None inv_src.save() @@ -1957,7 +1957,7 @@ class InventorySourceDetail(RetrieveUpdateAPIView): obj = self.get_object() can_delete = request.user.can_access(InventorySource, 'delete', obj) if not can_delete: - raise PermissionDenied("Cannot delete inventory source") + raise PermissionDenied("Cannot delete inventory source.") for pu in obj.inventory_updates.filter(status__in=['new', 'pending', 'waiting', 'running']): pu.cancel() return super(InventorySourceDetail, self).destroy(request, *args, **kwargs) @@ -2099,7 +2099,7 @@ class JobTemplateDetail(RetrieveUpdateDestroyAPIView): obj = self.get_object() can_delete = request.user.can_access(JobTemplate, 'delete', obj) if not can_delete: - raise PermissionDenied("Cannot delete job template") + raise PermissionDenied("Cannot delete job template.") for pu in obj.jobs.filter(status__in=['new', 'pending', 'waiting', 'running']): pu.cancel() return super(JobTemplateDetail, self).destroy(request, *args, **kwargs) @@ -2482,7 +2482,7 @@ class SystemJobTemplateList(ListAPIView): def get(self, request, *args, **kwargs): if not request.user.is_superuser: - raise PermissionDenied("Superuser privileges needed") + raise PermissionDenied("Superuser privileges needed.") return super(SystemJobTemplateList, self).get(request, *args, **kwargs) class SystemJobTemplateDetail(RetrieveAPIView): @@ -3212,7 +3212,7 @@ class SystemJobList(ListCreateAPIView): def get(self, request, *args, **kwargs): if not request.user.is_superuser: - raise PermissionDenied("Superuser privileges needed") + raise PermissionDenied("Superuser privileges needed.") return super(SystemJobList, self).get(request, *args, **kwargs) From 532583ed274304c334e4aa1acffbdff734389f68 Mon Sep 17 00:00:00 2001 From: AlanCoding Date: Fri, 6 May 2016 11:44:30 -0400 Subject: [PATCH 2/2] add periods throughout access.py --- awx/main/access.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/awx/main/access.py b/awx/main/access.py index 2130997130..dec54c9e6c 100644 --- a/awx/main/access.py +++ b/awx/main/access.py @@ -182,24 +182,24 @@ class BaseAccess(object): validation_info['grace_period_remaining'] = 99999999 if check_expiration and validation_info.get('time_remaining', None) is None: - raise PermissionDenied("license is missing") + raise PermissionDenied("License is missing.") if check_expiration and validation_info.get("grace_period_remaining") <= 0: - raise PermissionDenied("license has expired") + raise PermissionDenied("License has expired.") free_instances = validation_info.get('free_instances', 0) available_instances = validation_info.get('available_instances', 0) if add_host and free_instances == 0: - raise PermissionDenied("license count of %s instances has been reached" % available_instances) + raise PermissionDenied("License count of %s instances has been reached." % available_instances) elif add_host and free_instances < 0: - raise PermissionDenied("license count of %s instances has been exceeded" % available_instances) + raise PermissionDenied("License count of %s instances has been exceeded." % available_instances) elif not add_host and free_instances < 0: - raise PermissionDenied("host count exceeds available instances") + raise PermissionDenied("Host count exceeds available instances.") if feature is not None: if "features" in validation_info and not validation_info["features"].get(feature, False): - raise LicenseForbids("Feature %s is not enabled in the active license" % feature) + raise LicenseForbids("Feature %s is not enabled in the active license." % feature) elif "features" not in validation_info: - raise LicenseForbids("Features not found in active license") + raise LicenseForbids("Features not found in active license.") class UserAccess(BaseAccess): @@ -412,7 +412,7 @@ class HostAccess(BaseAccess): # Prevent moving a host to a different inventory. inventory_pk = get_pk_from_dict(data, 'inventory') if obj and inventory_pk and obj.inventory.pk != inventory_pk: - raise PermissionDenied('Unable to change inventory on a host') + raise PermissionDenied('Unable to change inventory on a host.') # Checks for admin or change permission on inventory, controls whether # the user can edit variable data. return obj and self.user in obj.inventory.update_role @@ -424,7 +424,7 @@ class HostAccess(BaseAccess): return False # Prevent assignments between different inventories. if obj.inventory != sub_obj.inventory: - raise ParseError('Cannot associate two items from different inventories') + raise ParseError('Cannot associate two items from different inventories.') return True def can_delete(self, obj): @@ -458,7 +458,7 @@ class GroupAccess(BaseAccess): # Prevent moving a group to a different inventory. inventory_pk = get_pk_from_dict(data, 'inventory') if obj and inventory_pk and obj.inventory.pk != inventory_pk: - raise PermissionDenied('Unable to change inventory on a group') + raise PermissionDenied('Unable to change inventory on a group.') # Checks for admin or change permission on inventory, controls whether # the user can attach subgroups or edit variable data. return obj and self.user in obj.inventory.update_role @@ -470,7 +470,7 @@ class GroupAccess(BaseAccess): return False # Prevent assignments between different inventories. if obj.inventory != sub_obj.inventory: - raise ParseError('Cannot associate two items from different inventories') + raise ParseError('Cannot associate two items from different inventories.') # Prevent group from being assigned as its own (grand)child. if type(obj) == type(sub_obj): parent_pks = set(obj.all_parents.values_list('pk', flat=True)) @@ -635,7 +635,7 @@ class TeamAccess(BaseAccess): # Prevent moving a team to a different organization. org_pk = get_pk_from_dict(data, 'organization') if obj and org_pk and obj.organization.pk != org_pk: - raise PermissionDenied('Unable to change organization on a team') + raise PermissionDenied('Unable to change organization on a team.') if self.user.is_superuser: return True return self.user in obj.admin_role