예제 #1
0
    def list_projects(self, request, *args, **kwargs):
        self.check_permissions(request, "list_projects", None)
        url = request.DATA.get('url', None)
        if not url:
            raise exc.WrongArguments(_("The url param is needed"))

        token = self._get_token(request)
        importer = JiraNormalImporter(request.user, url, token)
        agile_importer = JiraAgileImporter(request.user, url, token)
        projects = importer.list_projects()
        boards = agile_importer.list_projects()
        return response.Ok(sorted(projects + boards, key=lambda x: x['name']))
예제 #2
0
    def remove_logo(self, request, *args, **kwargs):
        """
        Remove the logo of a project.
        """
        self.object = get_object_or_404(self.get_queryset(), **kwargs)
        self.check_permissions(request, "remove_logo", self.object)
        self.pre_conditions_on_save(self.object)
        self.object.logo = None
        self.object.save(update_fields=["logo"])

        serializer = self.get_serializer(self.object)
        return response.Ok(serializer.data)
예제 #3
0
    def resend(self, request, pk=None):
        webhooklog = self.get_object()
        self.check_permissions(request, 'resend', webhooklog)
        webhook = webhooklog.webhook
        if webhook.project.blocked_code is not None:
            raise exc.Blocked(_("Blocked element"))

        webhooklog = tasks.resend_webhook(webhook.id, webhook.url, webhook.key,
                                          webhooklog.request_data)

        log = serializers.WebhookLogSerializer(webhooklog)

        return response.Ok(log.data)
예제 #4
0
    def list(self, request):
        if self.request.user.is_anonymous():
            return response.Ok({})

        queryset = models.WebNotification.objects\
            .filter(user=self.request.user)

        if request.GET.get("only_unread", False):
            queryset = queryset.filter(read__isnull=True)

        queryset = queryset.order_by('-read', '-created')

        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_pagination_serializer(page)
            return response.Ok({
                "objects": serializer.data,
                "total": queryset.count()
            })

        serializer = self.get_serializer(queryset, many=True)
        return response.Ok(serializer.data)
예제 #5
0
    def modules(self, request, pk=None):
        project = self.get_object()
        self.check_permissions(request, 'modules', project)
        modules_config = services.get_modules_config(project)

        if request.method == "GET":
            return response.Ok(modules_config.config)

        else:
            self.pre_conditions_on_save(project)
            modules_config.config.update(request.DATA)
            modules_config.save()
            return response.NoContent()
예제 #6
0
    def filters_data(self, request, *args, **kwargs):
        project_id = request.QUERY_PARAMS.get("project", None)
        project = get_object_or_404(Project, id=project_id)

        filter_backends = self.get_filter_backends()
        types_filter_backends = (f for f in filter_backends
                                 if f != filters.IssueTypesFilter)
        statuses_filter_backends = (f for f in filter_backends
                                    if f != filters.StatusesFilter)
        assigned_to_filter_backends = (f for f in filter_backends
                                       if f != filters.AssignedToFilter)
        owners_filter_backends = (f for f in filter_backends
                                  if f != filters.OwnersFilter)
        priorities_filter_backends = (f for f in filter_backends
                                      if f != filters.PrioritiesFilter)
        severities_filter_backends = (f for f in filter_backends
                                      if f != filters.SeveritiesFilter)
        roles_filter_backends = (f for f in filter_backends
                                 if f != filters.RoleFilter)
        tags_filter_backends = (f for f in filter_backends
                                if f != filters.TagsFilter)

        queryset = self.get_queryset()
        querysets = {
            "types":
            self.filter_queryset(queryset,
                                 filter_backends=types_filter_backends),
            "statuses":
            self.filter_queryset(queryset,
                                 filter_backends=statuses_filter_backends),
            "assigned_to":
            self.filter_queryset(queryset,
                                 filter_backends=assigned_to_filter_backends),
            "owners":
            self.filter_queryset(queryset,
                                 filter_backends=owners_filter_backends),
            "priorities":
            self.filter_queryset(queryset,
                                 filter_backends=priorities_filter_backends),
            "severities":
            self.filter_queryset(queryset,
                                 filter_backends=severities_filter_backends),
            "tags":
            self.filter_queryset(queryset,
                                 filter_backends=tags_filter_backends),
            "roles":
            self.filter_queryset(queryset,
                                 filter_backends=roles_filter_backends),
        }
        return response.Ok(services.get_issues_filters_data(
            project, querysets))
예제 #7
0
    def validate(self, request, pk=None):
        application_id = request.DATA.get("application", None)
        auth_code = request.DATA.get("auth_code", None)
        state = request.DATA.get("state", None)
        application_token = get_object_or_404(models.ApplicationToken,
                                              application__id=application_id,
                                              auth_code=auth_code,
                                              state=state)

        application_token.generate_token()
        application_token.save()

        access_token_data = serializers.AccessTokenSerializer(application_token).data
        return response.Ok(access_token_data)
예제 #8
0
    def delete_tag(self, request, pk=None):
        project = self.get_object()
        self.check_permissions(request, "delete_tag", project)
        self._raise_if_blocked(project)

        validator = validators.DeleteTagValidator(data=request.DATA,
                                                  project=project)
        if not validator.is_valid():
            return response.BadRequest(validator.errors)

        data = validator.data
        services.delete_tag(project, data.get("tag"))

        return response.Ok()
예제 #9
0
    def mix_tags(self, request, pk=None):
        project = self.get_object()
        self.check_permissions(request, "mix_tags", project)
        self._raise_if_blocked(project)

        validator = validators.MixTagsValidator(data=request.DATA,
                                                project=project)
        if not validator.is_valid():
            return response.BadRequest(validator.errors)

        data = validator.data
        services.mix_tags(project, data.get("from_tags"), data.get("to_tag"))

        return response.Ok()
예제 #10
0
    def comment_versions(self, request, pk):
        obj = self.get_object()
        history_entry_id = request.QUERY_PARAMS.get('id', None)
        history_entry = services.get_history_queryset_by_model_instance(obj).filter(id=history_entry_id).first()
        if history_entry is None:
            return response.NotFound()

        self.check_permissions(request, 'comment_versions', history_entry)

        if history_entry is None:
            return response.NotFound()

        history_entry.attach_user_info_to_comment_versions()
        return response.Ok(history_entry.comment_versions)
예제 #11
0
    def retrieve(self, request, *args, **kwargs):
        pk = kwargs.get("pk", None)
        resource_id = kwargs.get("resource_id", None)
        resource = get_object_or_404(self.resource_model, pk=resource_id)

        self.check_permissions(request, 'retrieve', resource)

        try:
            self.object = services.get_voters(resource).get(pk=pk)
        except ObjectDoesNotExist:  # or User.DoesNotExist
            return response.NotFound()

        serializer = self.get_serializer(self.object)
        return response.Ok(serializer.data)
예제 #12
0
    def filters_data(self, request, *args, **kwargs):
        project_id = request.QUERY_PARAMS.get("project", None)
        project = get_object_or_404(Project, id=project_id)

        filter_backends = self.get_filter_backends()
        statuses_filter_backends = (
            f for f in filter_backends
            if f != base_filters.UserStoryStatusesFilter)
        assigned_to_filter_backends = (f for f in filter_backends
                                       if f != base_filters.AssignedToFilter)
        assigned_users_filter_backends = (
            f for f in filter_backends
            if f != base_filters.AssignedUsersFilter)
        owners_filter_backends = (f for f in filter_backends
                                  if f != base_filters.OwnersFilter)
        epics_filter_backends = (f for f in filter_backends
                                 if f != filters.EpicFilter)
        roles_filter_backends = (f for f in filter_backends
                                 if f != base_filters.RoleFilter)
        tags_filter_backends = (f for f in filter_backends
                                if f != base_filters.TagsFilter)

        queryset = self.get_queryset()
        querysets = {
            "statuses":
            self.filter_queryset(queryset,
                                 filter_backends=statuses_filter_backends),
            "assigned_to":
            self.filter_queryset(queryset,
                                 filter_backends=assigned_to_filter_backends),
            "assigned_users":
            self.filter_queryset(
                queryset, filter_backends=assigned_users_filter_backends),
            "owners":
            self.filter_queryset(queryset,
                                 filter_backends=owners_filter_backends),
            "tags":
            self.filter_queryset(queryset,
                                 filter_backends=tags_filter_backends),
            "epics":
            self.filter_queryset(queryset,
                                 filter_backends=epics_filter_backends),
            "roles":
            self.filter_queryset(queryset,
                                 filter_backends=roles_filter_backends)
        }

        return response.Ok(
            services.get_userstories_filters_data(project, querysets))
예제 #13
0
    def bulk_update_milestone(self, request, **kwargs):
        validator = validators.UpdateMilestoneBulkValidator(data=request.DATA)
        if not validator.is_valid():
            return response.BadRequest(validator.errors)

        data = validator.data
        project = get_object_or_404(Project, pk=data["project_id"])
        milestone = get_object_or_404(Milestone, pk=data["milestone_id"])

        self.check_permissions(request, "bulk_update_milestone", project)

        ret = services.update_issues_milestone_in_bulk(data["bulk_issues"],
                                                       milestone)

        return response.Ok(ret)
예제 #14
0
    def authorize(self, request, *args, **kwargs):
        self.check_permissions(request, "authorize", None)

        try:
            oauth_data = request.user.auth_data.get(key="pivotal-oauth")
            oauth_token = oauth_data.extra['oauth_token']
            oauth_secret = oauth_data.extra['oauth_secret']
            oauth_verifier = request.DATA.get('code')
            oauth_data.delete()
            pivotal_token = PivotalImporter.get_access_token(
                oauth_token, oauth_secret, oauth_verifier)['oauth_token']
        except Exception as e:
            raise exc.WrongArguments(_("Invalid or expired auth token"))

        return response.Ok({"token": pivotal_token})
예제 #15
0
    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"))
예제 #16
0
    def password_recovery(self, request, pk=None):
        username_or_email = request.DATA.get('username', None)

        self.check_permissions(request, "password_recovery", None)

        if not username_or_email:
            raise exc.WrongArguments(_("Invalid username or email"))

        user = get_user_by_username_or_email(username_or_email)
        user.token = str(uuid.uuid4())
        user.save(update_fields=["token"])

        email = mail_builder.password_recovery(user, {"user": user})
        email.send()

        return response.Ok({"detail": _("Mail sended successful!")})
예제 #17
0
    def list(self, request, **kwargs):
        text = request.QUERY_PARAMS.get('text', "")
        project_id = request.QUERY_PARAMS.get('project', None)

        project = self._get_project(project_id)

        result = {}
        with futures.ThreadPoolExecutor(max_workers=4) as executor:
            futures_list = []
            if user_has_perm(request.user, "view_epics", project):
                epics_future = executor.submit(self._search_epics, project,
                                               text)
                epics_future.result_key = "epics"
                futures_list.append(epics_future)
            if user_has_perm(request.user, "view_us", project):
                uss_future = executor.submit(self._search_user_stories,
                                             project, text)
                uss_future.result_key = "userstories"
                futures_list.append(uss_future)
            if user_has_perm(request.user, "view_tasks", project):
                tasks_future = executor.submit(self._search_tasks, project,
                                               text)
                tasks_future.result_key = "tasks"
                futures_list.append(tasks_future)
            if user_has_perm(request.user, "view_issues", project):
                issues_future = executor.submit(self._search_issues, project,
                                                text)
                issues_future.result_key = "issues"
                futures_list.append(issues_future)
            if user_has_perm(request.user, "view_wiki_pages", project):
                wiki_pages_future = executor.submit(self._search_wiki_pages,
                                                    project, text)
                wiki_pages_future.result_key = "wikipages"
                futures_list.append(wiki_pages_future)

            for future in futures.as_completed(futures_list):
                data = []
                try:
                    data = future.result()
                except Exception as exc:
                    print('%s generated an exception: %s' %
                          (future.result_key, exc))
                finally:
                    result[future.result_key] = data

        result["count"] = sum(map(lambda x: len(x), result.values()))
        return response.Ok(result)
예제 #18
0
    def edit_comment(self, request, pk):
        obj = self.get_object()
        history_entry_id = request.QUERY_PARAMS.get('id', None)
        history_entry = services.get_history_queryset_by_model_instance(obj).filter(id=history_entry_id).first()
        if history_entry is None:
            return response.NotFound()

        obj = services.get_instance_from_key(history_entry.key)
        comment = request.DATA.get("comment", None)

        self.check_permissions(request, 'edit_comment', history_entry)

        if history_entry is None:
            return response.NotFound()

        if comment is None:
            return response.BadRequest({"error": _("comment is required")})

        if history_entry.delete_comment_date or history_entry.delete_comment_user:
            return response.BadRequest({"error": _("deleted comments can't be edited")})

        # comment_versions can be None if there are no historic versions of the comment
        comment_versions = history_entry.comment_versions or []
        comment_versions.append({
            "date": history_entry.created_at,
            "comment": history_entry.comment,
            "comment_html": history_entry.comment_html,
            "user": {
                "id": request.user.pk,
            }
        })

        new_mentions = self._get_new_mentions(obj, history_entry.comment, comment)

        history_entry.edit_comment_date = timezone.now()
        history_entry.comment = comment
        history_entry.comment_html = mdrender(obj.project, comment)
        history_entry.comment_versions = comment_versions
        history_entry.save()

        if new_mentions:
            signal_mentions.send(sender=self.__class__,
                                 user=self.request.user,
                                 obj=obj,
                                 mentions=new_mentions)

        return response.Ok()
예제 #19
0
    def edit_tag(self, request, pk=None):
        project = self.get_object()
        self.check_permissions(request, "edit_tag", project)
        self._raise_if_blocked(project)

        validator = validators.EditTagTagValidator(data=request.DATA,
                                                   project=project)
        if not validator.is_valid():
            return response.BadRequest(validator.errors)

        data = validator.data
        services.edit_tag(project,
                          data.get("from_tag"),
                          to_tag=data.get("to_tag", None),
                          color=data.get("color", None))

        return response.Ok()
예제 #20
0
    def import_project(self, request, *args, **kwargs):
        self.check_permissions(request, "import_project", None)

        token = request.DATA.get('token', None)
        project_id = request.DATA.get('project', None)
        if not project_id:
            raise exc.WrongArguments(_("The project param is needed"))

        template = request.DATA.get('template', "scrum")
        items_type = "user_stories"
        if template == "issues":
            items_type = "issues"
            template = "scrum"

        options = {
            "name":
            request.DATA.get('name', None),
            "description":
            request.DATA.get('description', None),
            "template":
            template,
            "type":
            items_type,
            "users_bindings":
            resolve_users_bindings(request.DATA.get("users_bindings", {})),
            "keep_external_reference":
            request.DATA.get("keep_external_reference", False),
            "is_private":
            request.DATA.get("is_private", False),
        }

        if settings.CELERY_ENABLED:
            task = tasks.import_project.delay(request.user.id, token,
                                              project_id, options)
            return response.Accepted({"task_id": task.id})

        importer = GithubImporter(request.user, token)
        project = importer.import_project(project_id, options)
        project_data = {
            "slug": project.slug,
            "my_permissions": ["view_us"],
            "is_backlog_activated": project.is_backlog_activated,
            "is_kanban_activated": project.is_kanban_activated,
        }

        return response.Ok(project_data)
예제 #21
0
    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"))
예제 #22
0
    def contacts(self, request, *args, **kwargs):
        user = get_object_or_404(models.User, **kwargs)
        self.check_permissions(request, 'contacts', user)

        self.object_list = user_filters.ContactsFilterBackend(
        ).filter_queryset(
            user, request, self.get_queryset(),
            self).extra(select={
                "complete_user_name": "concat(full_name, username)"
            }).order_by("complete_user_name")

        page = self.paginate_queryset(self.object_list)
        if page is not None:
            serializer = self.serializer_class(page.object_list, many=True)
        else:
            serializer = self.serializer_class(self.object_list, many=True)

        return response.Ok(serializer.data)
예제 #23
0
    def render(self, request, **kwargs):
        content = request.DATA.get("content", None)
        project_id = request.DATA.get("project_id", None)

        if not content:
            raise exc.WrongArguments(
                {"content": _("'content' parameter is mandatory")})

        if not project_id:
            raise exc.WrongArguments(
                {"project_id": _("'project_id' parameter is mandatory")})

        project = get_object_or_404(Project, pk=project_id)

        self.check_permissions(request, "render", project)

        data = mdrender(project, content)
        return response.Ok({"data": data})
예제 #24
0
    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})
예제 #25
0
    def auth_url(self, request, *args, **kwargs):
        self.check_permissions(request, "auth_url", None)

        (oauth_token, oauth_secret, url) = PivotalImporter.get_auth_url()

        (auth_data,
         created) = AuthData.objects.get_or_create(user=request.user,
                                                   key="pivotal-oauth",
                                                   defaults={
                                                       "value": "",
                                                       "extra": {},
                                                   })
        auth_data.extra = {
            "oauth_token": oauth_token,
            "oauth_secret": oauth_secret,
        }
        auth_data.save()

        return response.Ok({"url": url})
예제 #26
0
    def delete_comment(self, request, pk):
        obj = self.get_object()
        history_entry_id = request.QUERY_PARAMS.get('id', None)
        history_entry = services.get_history_queryset_by_model_instance(obj).filter(id=history_entry_id).first()
        if history_entry is None:
            return response.NotFound()

        self.check_permissions(request, 'delete_comment', history_entry)

        if history_entry is None:
            return response.NotFound()

        if history_entry.delete_comment_date or history_entry.delete_comment_user:
            return response.BadRequest({"error": _("Comment already deleted")})

        history_entry.delete_comment_date = timezone.now()
        history_entry.delete_comment_user = {"pk": request.user.pk, "name": request.user.get_full_name()}
        history_entry.save()
        return response.Ok()
예제 #27
0
    def undelete_comment(self, request, pk):
        obj = self.get_object()
        history_entry_id = request.QUERY_PARAMS.get('id', None)
        history_entry = services.get_history_queryset_by_model_instance(obj).filter(id=history_entry_id).first()
        if history_entry is None:
            return response.NotFound()

        self.check_permissions(request, 'undelete_comment', history_entry)

        if history_entry is None:
            return response.NotFound()

        if not history_entry.delete_comment_date and not history_entry.delete_comment_user:
            return response.BadRequest({"error": _("Comment not deleted")})

        history_entry.delete_comment_date = None
        history_entry.delete_comment_user = None
        history_entry.save()
        return response.Ok()
예제 #28
0
    def token(self, request, *args, **kwargs):
        if self.request.user.is_anonymous():
            raise exc.NotAuthenticated(_("Authentication required"))

        application = get_object_or_404(models.Application, **kwargs)
        self.check_permissions(request, 'token', request.user)
        try:
            application_token = models.ApplicationToken.objects.get(user=request.user, application=application)
            application_token.update_auth_code()
            application_token.state = request.GET.get("state", None)
            application_token.save()

        except models.ApplicationToken.DoesNotExist:
            application_token = models.ApplicationToken(
                user=request.user,
                application=application
            )

        auth_code_data = serializers.ApplicationTokenSerializer(application_token).data
        return response.Ok(auth_code_data)
예제 #29
0
    def retrieve(self, request, *args, **kwargs):
        qs = self.get_queryset()
        if self.action == "by_slug":
            self.lookup_field = "slug"
            # If we retrieve the project by slug we want to filter by user the
            # permissions and return 404 in case the user don't have access
            flt = filters.get_filter_expression_can_view_projects(
                self.request.user)

            qs = qs.filter(flt)

        self.object = get_object_or_404(qs, **kwargs)

        self.check_permissions(request, 'retrieve', self.object)

        if self.object is None:
            raise Http404

        serializer = self.get_serializer(self.object)
        return response.Ok(serializer.data)
예제 #30
0
    def create(self, request, **kwargs):
        self.check_permissions(request, "create", None)

        data = copy.deepcopy(request.DATA)
        data.update({"full_name": request.user.get_full_name(),
                     "email": request.user.email})

        validator = self.validator_class(data=data)
        if not validator.is_valid():
            return response.BadRequest(validator.errors)

        self.object = validator.save(force_insert=True)

        extra = {
            "HTTP_HOST":  request.META.get("HTTP_HOST", None),
            "HTTP_REFERER": request.META.get("HTTP_REFERER", None),
            "HTTP_USER_AGENT": request.META.get("HTTP_USER_AGENT", None),
        }
        services.send_feedback(self.object, extra, reply_to=[request.user.email])

        return response.Ok(validator.data)