def list(self, request, **kwargs): serializer = ResolverSerializer(data=request.QUERY_PARAMS) if not serializer.is_valid(): raise exc.BadRequest(serializer.errors) data = serializer.data project_model = apps.get_model("projects", "Project") project = get_object_or_404(project_model, slug=data["project"]) self.check_permissions(request, "list", project) result = {"project": project.pk} if data["us"] and user_has_perm(request.user, "view_us", project): result["us"] = get_object_or_404(project.user_stories.all(), ref=data["us"]).pk if data["task"] and user_has_perm(request.user, "view_tasks", project): result["task"] = get_object_or_404(project.tasks.all(), ref=data["task"]).pk if data["issue"] and user_has_perm(request.user, "view_issues", project): result["issue"] = get_object_or_404(project.issues.all(), ref=data["issue"]).pk if data["milestone"] and user_has_perm(request.user, "view_milestones", project): result["milestone"] = get_object_or_404(project.milestones.all(), slug=data["milestone"]).pk if data["wikipage"] and user_has_perm(request.user, "view_wiki_pages", project): result["wikipage"] = get_object_or_404(project.wiki_pages.all(), slug=data["wikipage"]).pk return Response(result)
def auth_url(self, request, *args, **kwargs): self.check_permissions(request, "auth_url", None) jira_url = request.QUERY_PARAMS.get('url', None) if not jira_url: raise exc.WrongArguments(_("The url param is needed")) try: (oauth_token, oauth_secret, url) = JiraNormalImporter.get_auth_url( jira_url, settings.IMPORTERS.get('jira', {}).get('consumer_key', None), settings.IMPORTERS.get('jira', {}).get('cert', None), True) except exceptions.InvalidServiceConfiguration: raise exc.BadRequest(_("Invalid Jira server configuration.")) (auth_data, created) = AuthData.objects.get_or_create(user=request.user, key="jira-oauth", defaults={ "value": uuid.uuid4().hex, "extra": {}, }) auth_data.extra = { "oauth_token": oauth_token, "oauth_secret": oauth_secret, "url": jira_url, } auth_data.save() return response.Ok({"url": url})
def _transform_value(value): try: return int(value) except: if value in self._special_values_dict.keys(): return self._special_values_dict[value] raise exc.BadRequest()
def filter_queryset(self, request, queryset, view): query_params = {} if not hasattr(view, "filter_fields"): return queryset for field in view.filter_fields: if isinstance(field, (tuple, list)): param_name, field_name = field else: param_name, field_name = field, field if param_name in request.QUERY_PARAMS: field_data = request.QUERY_PARAMS[param_name] if field_data in self._special_values_dict: query_params[field_name] = self._special_values_dict[ field_data] else: query_params[field_name] = field_data if query_params: try: queryset = queryset.filter(**query_params) except ValueError: raise exc.BadRequest(_("Error in filter params types.")) return queryset
def bulk_update_order(self, request, **kwargs): bulk_data = request.DATA.get(self.bulk_update_param, None) if bulk_data is None: raise exc.BadRequest(_("'{param}' parameter is mandatory".format(param=self.bulk_update_param))) project_id = request.DATA.get('project', None) if project_id is None: raise exc.BadRequest(_("'project' parameter is mandatory")) project = get_object_or_404(Project, id=project_id) self.check_permissions(request, 'bulk_update_order', project) self.__class__.bulk_update_order_action(project, request.user, bulk_data) return response.NoContent(data=None)
def create_default(self, request, **kwargs): context = {"request": request} validator = validators.DueDatesCreationValidator(data=request.DATA, context=context) if not validator.is_valid(): return response.BadRequest(validator.errors) project_id = request.DATA.get('project_id') project = models.Project.objects.get(id=project_id) if project.issue_duedates.all(): raise exc.BadRequest( _("Project does already have issue due dates")) project_template = models.ProjectTemplate.objects.get( id=project.creation_template.id) for issue_duedate in project_template.issue_duedates: models.IssueDueDate.objects.create( name=issue_duedate["name"], by_default=issue_duedate["by_default"], color=issue_duedate["color"], days_to_due=issue_duedate["days_to_due"], order=issue_duedate["order"], project=project) project.save() serializer = self.get_serializer(project.issue_duedates.all(), many=True) return response.Ok(serializer.data)
def destroy(self, request, *args, **kwargs): obj = self.get_object_or_none() self.check_permissions(request, 'destroy', obj) move_to = self.request.QUERY_PARAMS.get('moveTo', None) if move_to is None: total_elements = obj.project.swimlanes.count() # you cannot set swimlane=None if there are more swimlanes available if total_elements > 1: raise exc.BadRequest( _("Cannot set swimlane to None if there are available swimlanes" )) # but if it was the last swimlane, # it can be deleted and all uss have now swimlane=None obj.user_stories.update(swimlane_id=None) else: move_item = get_object_or_404(self.model, id=move_to) # check permisions over moveTo object self.check_permissions(request, 'destroy', move_item) update_order_and_swimlane(obj, move_item) return super().destroy(request, *args, **kwargs)
def filter_queryset(self, request, queryset, view): project_id = None if (hasattr(view, "filter_fields") and "project" in view.filter_fields and "project" in request.QUERY_PARAMS): try: project_id = int(request.QUERY_PARAMS["project"]) except: logger.error("Filtering project diferent value than an integer: {}".format( request.QUERY_PARAMS["project"] )) raise exc.BadRequest(_("'project' must be an integer value.")) qs = queryset if request.user.is_authenticated() and request.user.is_superuser: qs = qs elif request.user.is_authenticated(): membership_model = apps.get_model('projects', 'Membership') memberships_qs = membership_model.objects.filter(user=request.user) if project_id: memberships_qs = memberships_qs.filter(project_id=project_id) memberships_qs = memberships_qs.filter( Q(role__permissions__contains=[self.permission]) | Q(is_admin=True)) projects_list = [membership.project_id for membership in memberships_qs] qs = qs.filter(Q(project_id__in=projects_list) | Q(project__public_permissions__contains=[self.permission])) else: qs = qs.filter(project__anon_permissions__contains=[self.permission]) return super().filter_queryset(request, qs, view)
def register(self, request, **kwargs): type = request.DATA.get("type", None) if type == "public": return self._public_register(request) elif type == "private": return self._private_register(request) raise exc.BadRequest(_("invalid register type"))
def filter_queryset(self, request, queryset, view): project_id = None project = None qs = queryset.filter(is_active=True) if "project" in request.QUERY_PARAMS: try: project_id = int(request.QUERY_PARAMS["project"]) except: logger.error( "Filtering project diferent value than an integer: {}". format(request.QUERY_PARAMS["project"])) raise exc.BadRequest(_("'project' must be an integer value.")) if project_id: Project = apps.get_model("projects", "Project") project = get_object_or_404(Project, pk=project_id) if request.user.is_authenticated() and request.user.is_superuser: qs = qs elif request.user.is_authenticated(): Membership = apps.get_model("projects", "Membership") memberships_qs = Membership.objects.filter(user=request.user) if project_id: memberships_qs = memberships_qs.filter(project_id=project_id) memberships_qs = memberships_qs.filter( Q(role__permissions__contains=[self.permission]) | Q(is_admin=True)) projects_list = [ membership.project_id for membership in memberships_qs ] if project: is_member = project.id in projects_list has_project_public_view_permission = ( "view_project" in project.public_permissions) if not is_member and not has_project_public_view_permission: qs = qs.none() q = Q(memberships__project_id__in=projects_list) | Q( id=request.user.id) # If there is no selected project we want access to users from public projects if not project: q = q | Q(memberships__project__public_permissions__contains=[ self.permission ]) qs = qs.filter(q) else: if project and "view_project" not in project.anon_permissions: qs = qs.none() qs = qs.filter(memberships__project__anon_permissions__contains=[ self.permission ]) return qs.distinct()
def authorize(self, request, *args, **kwargs): self.check_permissions(request, "authorize", None) code = request.DATA.get('code', None) if code is None: raise exc.BadRequest(_("Code param needed")) try: token = GithubImporter.get_access_token( settings.IMPORTERS.get('github', {}).get('client_id', None), settings.IMPORTERS.get('github', {}).get('client_secret', None), code) return response.Ok({"token": token}) except exceptions.InvalidAuthResult: raise exc.BadRequest(_("Invalid auth data")) except exceptions.FailedRequest: raise exc.BadRequest(_("Third party service failing"))
def create(self, *args, **kwargs): key = self.request.DATA.get("key", None) if (key and self.request.user.is_authenticated() and self.request.user.storage_entries.filter(key=key).exists()): raise exc.BadRequest( _("Duplicate key value violates unique constraint. " "Key '{}' already exists.").format(key)) return super().create(*args, **kwargs)
def _get_payload(self, request): try: body = parse_qs(request.body.decode("utf-8"), strict_parsing=True) payload = body["payload"] except (ValueError, KeyError): raise exc.BadRequest(_("The payload is not a valid application/x-www-form-urlencoded")) return payload
def create(self, request, **kwargs): self.check_permissions(request, 'create', None) type = request.DATA.get("type", None) if type == "normal": return self._login(request) elif type == "github": return self._github_login(request) raise exc.BadRequest(_("invalid login type"))
def bulk_update_order(self, request, **kwargs): bulk_data = request.DATA.get(self.bulk_update_param, None) if bulk_data is None: raise exc.BadRequest( _("%s parameter is mandatory") % self.bulk_update_param) project_id = request.DATA.get('project', None) if project_id is None: raise exc.BadRequest(_("project parameter is mandatory")) project = get_object_or_404(models.Project, id=project_id) self.check_permissions(request, 'bulk_update_order', project) self.__class__.bulk_update_order_action(project, request.user, bulk_data) return Response(data=None, status=status.HTTP_204_NO_CONTENT)
def authorize(self, request, *args, **kwargs): self.check_permissions(request, "authorize", None) code = request.DATA.get('code', None) if code is None: raise exc.BadRequest(_("Code param needed")) try: asana_token = AsanaImporter.get_access_token( code, settings.IMPORTERS.get('asana', {}).get('app_id', None), settings.IMPORTERS.get('asana', {}).get('app_secret', None), settings.IMPORTERS.get('asana', {}).get('callback_url', None)) except exceptions.InvalidRequest: raise exc.BadRequest(_('Invalid Asana API request')) except exceptions.FailedRequest: raise exc.BadRequest(_('Failed to make the request to Asana API')) return response.Ok({"token": asana_token})
def bulk_update_order(self, request, **kwargs): bulk_data = request.DATA.get(self.bulk_update_param, None) if bulk_data is None: raise exc.BadRequest( _("%s parameter is mandatory") % self.bulk_update_param) project_id = request.DATA.get('project', None) if project_id is None: raise exc.BadRequest(_("project parameter ir mandatory")) project = get_object_or_404(models.Project, id=project_id) if request.user != project.owner and not has_project_perm( request.user, project, self.bulk_update_perm): raise exc.PermissionDenied( _("You don't have permisions %s.") % self.bulk_update_perm) self.bulk_update_order(project, request.user, bulk_data) return Response(data=None, status=status.HTTP_204_NO_CONTENT)
def create(self, request, **kwargs): self.check_permissions(request, 'create', None) auth_plugins = get_auth_plugins() login_type = request.DATA.get("type", None) if login_type in auth_plugins: data = auth_plugins[login_type]['login_func'](request) return response.Ok(data) raise exc.BadRequest(_("invalid login type"))
def us(self, request, *args, **kwargs): project = self.get_object_or_none() self.check_permissions(request, 'import_item', project) us = services.store.store_user_story(project, request.DATA.copy()) errors = services.store.get_errors() if errors: raise exc.BadRequest(errors) headers = self.get_success_headers(us.data) return response.Created(us.data, headers=headers)
def create(self, request, *args, **kwargs): project = self._get_project(request) if not project: raise exc.BadRequest(_("The project doesn't exist")) if not self._validate_signature(project, request): raise exc.BadRequest(_("Bad signature")) event_name = self._get_event_name(request) payload = self._get_payload(request) event_hook_class = self.event_hook_classes.get(event_name, None) if event_hook_class is not None: event_hook = event_hook_class(project, payload) try: event_hook.process_event() except ActionSyntaxException as e: raise exc.BadRequest(e) return response.NoContent()
def list(self, request, **kwargs): validator = ResolverValidator(data=request.QUERY_PARAMS) if not validator.is_valid(): raise exc.BadRequest(validator.errors) data = validator.data project_model = apps.get_model("projects", "Project") project = get_object_or_404(project_model, slug=data["project"]) self.check_permissions(request, "list", project) result = {"project": project.pk} if data["us"] and user_has_perm(request.user, "view_us", project): result["us"] = get_object_or_404(project.user_stories.all(), ref=data["us"]).pk if data["task"] and user_has_perm(request.user, "view_tasks", project): result["task"] = get_object_or_404(project.tasks.all(), ref=data["task"]).pk if data["issue"] and user_has_perm(request.user, "view_issues", project): result["issue"] = get_object_or_404(project.issues.all(), ref=data["issue"]).pk if data["milestone"] and user_has_perm(request.user, "view_milestones", project): result["milestone"] = get_object_or_404(project.milestones.all(), slug=data["milestone"]).pk if data["wikipage"] and user_has_perm(request.user, "view_wiki_pages", project): result["wikipage"] = get_object_or_404(project.wiki_pages.all(), slug=data["wikipage"]).pk if data["ref"]: ref_found = False # No need to continue once one ref is found if user_has_perm(request.user, "view_us", project): us = project.user_stories.filter(ref=data["ref"]).first() if us: result["us"] = us.pk ref_found = True if ref_found is False and user_has_perm(request.user, "view_tasks", project): task = project.tasks.filter(ref=data["ref"]).first() if task: result["task"] = task.pk ref_found = True if ref_found is False and user_has_perm(request.user, "view_issues", project): issue = project.issues.filter(ref=data["ref"]).first() if issue: result["issue"] = issue.pk return response.Ok(result)
def pre_save(self, obj): user = self.request.user (enough_slots, not_enough_slots_error) = users_service.has_available_slot_for_project(user, project=obj) if not enough_slots: raise exc.BadRequest(not_enough_slots_error) if not obj.id: obj.owner = user obj.template = self.request.QUERY_PARAMS.get('template', None) self._set_base_permissions(obj) super().pre_save(obj)
def milestone(self, request, *args, **kwargs): project = self.get_object_or_none() self.check_permissions(request, "import_item", project) milestone = services.store.store_milestone(project, request.DATA.copy()) errors = services.store.get_errors() if errors: raise exc.BadRequest(errors) data = serializers.MilestoneExportSerializer(milestone.object).data headers = self.get_success_headers(data) return response.Created(data, headers=headers)
def wiki_link(self, request, *args, **kwargs): project = self.get_object_or_none() self.check_permissions(request, 'import_item', project) wiki_link = services.store.store_wiki_link(project, request.DATA.copy()) errors = services.store.get_errors() if errors: raise exc.BadRequest(errors) data = serializers.WikiLinkExportSerializer(wiki_link.object).data headers = self.get_success_headers(data) return response.Created(data, headers=headers)
def create(self, request, **kwargs): self.check_permissions(request, 'create', None) auth_plugins = get_auth_plugins() login_type = request.DATA.get("type", None) invitation_token = request.DATA.get("invitation_token", None) if login_type in auth_plugins: data = auth_plugins[login_type]['login_func'](request) if invitation_token: accept_invitation_by_existing_user(invitation_token, data['id']) return response.Ok(data) raise exc.BadRequest(_("invalid login type"))
def wiki_link(self, request, *args, **kwargs): project = self.get_object_or_none() self.check_permissions(request, 'import_item', project) wiki_link = service.store_wiki_link(project, request.DATA.copy()) errors = service.get_errors() if errors: raise exc.BadRequest(errors) headers = self.get_success_headers(wiki_link.data) return Response(wiki_link.data, status=status.HTTP_201_CREATED, headers=headers)
def filter_queryset(self, request, queryset, view): project_id = None if "project" in request.QUERY_PARAMS: try: project_id = int(request.QUERY_PARAMS["project"]) except ValueError: logger.error("Filtering project different value tpphan an integer: {}".format( request.QUERY_PARAMS["project"])) raise exc.BadRequest(_("'project' must be an integer value.")) if project_id: queryset = queryset.filter(status__project_id=project_id) return super().filter_queryset(request, queryset, view)
def filter_queryset(self, request, queryset, view): query_watchers = self._get_watchers_queryparams(request.QUERY_PARAMS) model = queryset.model if query_watchers: WatchedModel = apps.get_model("notifications", "Watched") watched_type = ContentType.objects.get_for_model(queryset.model) try: watched_ids = WatchedModel.objects.filter(content_type=watched_type, user__id__in=query_watchers).values_list("object_id", flat=True) queryset = queryset.filter(id__in=watched_ids) except ValueError: raise exc.BadRequest(_("Error in filter params types.")) return super().filter_queryset(request, queryset, view)
def pre_save(self, obj): if not obj.id: (enough_slots, not_enough_slots_error ) = users_service.has_available_slot_for_project( self.request.user, project=obj.project, members=1) if not enough_slots: raise exc.BadRequest(not_enough_slots_error) if not obj.token: obj.token = str(uuid.uuid1()) obj.invited_by = self.request.user obj.user = services.find_invited_user(obj.email, default=obj.user) super().pre_save(obj)
def destroy(self, request, *args, **kwargs): # moveTo is needed move_to = self.request.QUERY_PARAMS.get('moveTo', None) if move_to is None: raise exc.BadRequest(_("Query param 'moveTo' is required")) # check permisions over moveTo object move_item = get_object_or_404(self.model, id=move_to) self.check_permissions(request, 'update', move_item) obj = self.get_object_or_none() qs = self.move_on_destroy_related_class.objects.filter( **{self.move_on_destroy_related_field: obj}) # Reorder after moved self.move_on_destroy_reorder_after_moved(move_item, qs) # move related objects to the new one. # (we need to do this befero to prevent some deletes-on-cascade behaivors) qs.update(**{self.move_on_destroy_related_field: move_item}) # change default project value if is needed if getattr(obj.project, self.move_on_destroy_project_default_field) == obj: setattr(obj.project, self.move_on_destroy_project_default_field, move_item) obj.project.save() changed_default_value = True # destroy object res = super().destroy(request, *args, **kwargs) # if the object is not deleted if not isinstance(res, response.NoContent): # Restart status (roolback) if we can't delete the object qs.update(**{self.move_on_destroy_related_field: obj}) # Restart default value if changed_default_value: setattr(obj.project, self.move_on_destroy_project_default_field, obj) obj.project.save() else: if self.move_on_destroy_post_destroy_signal: # throw post delete signal self.move_on_destroy_post_destroy_signal.send(obj.__class__, deleted=obj, moved=move_item) return res