Refactor day: Use taiga.base.response instead rest_framework.response

remotes/origin/enhancement/email-actions
David Barragán Merino 2015-02-10 18:24:24 +01:00
parent 5196f1c25d
commit 60ab6127aa
27 changed files with 170 additions and 200 deletions

View File

@ -20,13 +20,13 @@ from enum import Enum
from django.utils.translation import ugettext_lazy as _
from django.conf import settings
from rest_framework.response import Response
from rest_framework import status
from rest_framework import serializers
from taiga.base.api import viewsets
from taiga.base.decorators import list_route
from taiga.base import exceptions as exc
from taiga.base import response
from taiga.users.services import get_and_validate_user
from .serializers import PublicRegisterSerializer
@ -108,7 +108,7 @@ class AuthViewSet(viewsets.ViewSet):
raise exc.BadRequest(e.detail)
data = make_auth_response_data(user)
return Response(data, status=status.HTTP_201_CREATED)
return response.Created(data)
def _private_register(self, request):
register_type = parse_register_type(request.DATA)
@ -121,7 +121,7 @@ class AuthViewSet(viewsets.ViewSet):
user = private_register_for_new_user(**data)
data = make_auth_response_data(user)
return Response(data, status=status.HTTP_201_CREATED)
return response.Created(data)
@list_route(methods=["POST"])
def register(self, request, **kwargs):
@ -134,7 +134,6 @@ class AuthViewSet(viewsets.ViewSet):
return self._private_register(request)
raise exc.BadRequest(_("invalid register type"))
# Login view: /api/v1/auth
def create(self, request, **kwargs):
self.check_permissions(request, 'create', None)

View File

@ -29,12 +29,10 @@ from django.db import transaction as tx
from django.db import IntegrityError
from django.utils.translation import ugettext as _
from rest_framework.response import Response
from rest_framework import status
from djmail.template_mail import MagicMailBuilder, InlineCSSTemplateMail
from taiga.base import exceptions as exc
from taiga.base import response
from taiga.users.serializers import UserSerializer
from taiga.users.services import get_and_validate_user
from taiga.base.utils.slug import slugify_uniquely
@ -203,7 +201,7 @@ def normal_login_func(request):
user = get_and_validate_user(username=username, password=password)
data = make_auth_response_data(user)
return Response(data, status=status.HTTP_200_OK)
return response.Ok(data)
register_auth_plugin("normal", normal_login_func);

View File

@ -23,9 +23,7 @@ from django.core.exceptions import ValidationError
from django.http import Http404
from django.db import transaction as tx
from rest_framework import status
from rest_framework.response import Response
from rest_framework.request import clone_request
from taiga.base import response
from rest_framework.settings import api_settings
from .utils import get_object_or_404
@ -73,10 +71,9 @@ class CreateModelMixin(object):
self.object = serializer.save(force_insert=True)
self.post_save(self.object, created=True)
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED,
headers=headers)
return response.Created(serializer.data, headers=headers)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
return response.BadRequest(serializer.errors)
def get_success_headers(self, data):
try:
@ -114,7 +111,7 @@ class ListModelMixin(object):
else:
serializer = self.get_serializer(self.object_list, many=True)
return Response(serializer.data)
return response.Ok(serializer.data)
class RetrieveModelMixin(object):
@ -130,7 +127,7 @@ class RetrieveModelMixin(object):
raise Http404
serializer = self.get_serializer(self.object)
return Response(serializer.data)
return response.Ok(serializer.data)
class UpdateModelMixin(object):
@ -149,7 +146,7 @@ class UpdateModelMixin(object):
files=request.FILES, partial=partial)
if not serializer.is_valid():
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
return response.BadRequest(serializer.errors)
# Hooks
try:
@ -158,16 +155,16 @@ class UpdateModelMixin(object):
except ValidationError as err:
# full_clean on model instance may be called in pre_save,
# so we have to handle eventual errors.
return Response(err.message_dict, status=status.HTTP_400_BAD_REQUEST)
return response.BadRequest(err.message_dict)
if self.object is None:
self.object = serializer.save(force_insert=True)
self.post_save(self.object, created=True)
return Response(serializer.data, status=status.HTTP_201_CREATED)
return response.Created(serializer.data)
self.object = serializer.save(force_update=True)
self.post_save(self.object, created=False)
return Response(serializer.data, status=status.HTTP_200_OK)
return response.Ok(serializer.data)
def partial_update(self, request, *args, **kwargs):
kwargs['partial'] = True
@ -216,4 +213,4 @@ class DestroyModelMixin(object):
self.pre_conditions_on_delete(obj)
obj.delete()
self.post_delete(obj)
return Response(status=status.HTTP_204_NO_CONTENT)
return response.NoContent()

View File

@ -27,10 +27,13 @@ from django.views.decorators.csrf import csrf_exempt
from rest_framework import status, exceptions
from rest_framework.compat import smart_text, HttpResponseBase, View
from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.settings import api_settings
from rest_framework.utils import formatting
from taiga.base.response import Response
from taiga.base.response import Ok
from taiga.base.response import NotFound
from taiga.base.response import Forbidden
from taiga.base.utils.iterators import as_tuple
from django.conf import settings
@ -89,12 +92,10 @@ def exception_handler(exc):
headers=headers)
elif isinstance(exc, Http404):
return Response({'detail': 'Not found'},
status=status.HTTP_404_NOT_FOUND)
return NotFound({'detail': 'Not found'})
elif isinstance(exc, PermissionDenied):
return Response({'detail': 'Permission denied'},
status=status.HTTP_403_FORBIDDEN)
return Forbidden({'detail': 'Permission denied'})
# Note: Unhandled exceptions will raise a 500 error.
return None
@ -425,7 +426,7 @@ class APIView(View):
We may as well implement this as Django will otherwise provide
a less useful default implementation.
"""
return Response(self.metadata(request), status=status.HTTP_200_OK)
return Ok(self.metadata(request))
def metadata(self, request):
"""

View File

@ -14,17 +14,16 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from rest_framework import exceptions
from rest_framework import status
from rest_framework.response import Response
from django.core.exceptions import PermissionDenied as DjangoPermissionDenied
from django.utils.encoding import force_text
from django.utils.translation import ugettext_lazy as _
from django.http import Http404
from .utils.json import to_json
from taiga.base import response
from taiga.base.utils.json import to_json
class BaseException(exceptions.APIException):
@ -129,15 +128,13 @@ def exception_handler(exc):
headers["X-Throttle-Wait-Seconds"] = "%d" % exc.wait
detail = format_exception(exc)
return Response(detail, status=exc.status_code, headers=headers)
return response.Response(detail, status=exc.status_code, headers=headers)
elif isinstance(exc, Http404):
return Response({'_error_message': str(exc)},
status=status.HTTP_404_NOT_FOUND)
return response.NotFound({'_error_message': str(exc)})
elif isinstance(exc, DjangoPermissionDenied):
return Response({"_error_message": str(exc)},
status=status.HTTP_403_FORBIDDEN)
return response.Forbidden({"_error_message": str(exc)})
# Note: Unhandled exceptions will raise a 500 error.
return None

View File

@ -23,7 +23,7 @@ from django.core.exceptions import ImproperlyConfigured
from django.core.urlresolvers import NoReverseMatch
from rest_framework import views
from rest_framework.response import Response
from taiga.base import response
from rest_framework.reverse import reverse
from rest_framework.urlpatterns import format_suffix_patterns
@ -292,7 +292,7 @@ class DRFDefaultRouter(SimpleRouter):
except NoReverseMatch:
# Support resources that are prefixed by a parametrized url
ret[key] = request.build_absolute_uri() + key
return Response(ret)
return response.Response(ret)
return APIRoot.as_view()

View File

@ -18,10 +18,6 @@ import json
import codecs
import uuid
from rest_framework.response import Response
from rest_framework.decorators import throttle_classes
from rest_framework import status
from django.utils.decorators import method_decorator
from django.utils.translation import ugettext_lazy as _
from django.db.transaction import atomic
@ -30,10 +26,13 @@ from django.conf import settings
from django.core.files.storage import default_storage
from django.core.files.base import ContentFile
from taiga.base.api.mixins import CreateModelMixin
from taiga.base.api.viewsets import GenericViewSet
from rest_framework.decorators import throttle_classes
from taiga.base.decorators import detail_route, list_route
from taiga.base import exceptions as exc
from taiga.base import response
from taiga.base.api.mixins import CreateModelMixin
from taiga.base.api.viewsets import GenericViewSet
from taiga.projects.models import Project, Membership
from taiga.projects.issues.models import Issue
from taiga.projects.serializers import ProjectSerializer
@ -65,8 +64,9 @@ class ProjectExporterViewSet(mixins.ImportThrottlingPolicyMixin, GenericViewSet)
if settings.CELERY_ENABLED:
task = tasks.dump_project.delay(request.user, project)
tasks.delete_project_dump.apply_async((project.pk, project.slug), countdown=settings.EXPORTS_TTL)
return Response({"export_id": task.id}, status=status.HTTP_202_ACCEPTED)
tasks.delete_project_dump.apply_async((project.pk, project.slug),
countdown=settings.EXPORTS_TTL)
return response.Accepted({"export_id": task.id})
path = "exports/{}/{}-{}.json".format(project.pk, project.slug, uuid.uuid4().hex)
content = ContentFile(ExportRenderer().render(service.project_to_dict(project),
@ -76,7 +76,7 @@ class ProjectExporterViewSet(mixins.ImportThrottlingPolicyMixin, GenericViewSet)
response_data = {
"url": default_storage.url(path)
}
return Response(response_data, status=status.HTTP_200_OK)
return response.Ok(response_data)
class ProjectImporterViewSet(mixins.ImportThrottlingPolicyMixin, CreateModelMixin, GenericViewSet):
@ -152,7 +152,7 @@ class ProjectImporterViewSet(mixins.ImportThrottlingPolicyMixin, CreateModelMixi
response_data = project_serialized.data
response_data['id'] = project_serialized.object.id
headers = self.get_success_headers(response_data)
return Response(response_data, status=status.HTTP_201_CREATED, headers=headers)
return response.Created(response_data, headers=headers)
@list_route(methods=["POST"])
@method_decorator(atomic)
@ -181,11 +181,11 @@ class ProjectImporterViewSet(mixins.ImportThrottlingPolicyMixin, CreateModelMixi
if settings.CELERY_ENABLED:
task = tasks.load_project_dump.delay(request.user, dump)
return Response({"import_id": task.id}, status=status.HTTP_202_ACCEPTED)
return response.Accepted({"import_id": task.id})
project = dump_service.dict_to_project(dump, request.user.email)
response_data = ProjectSerializer(project).data
return Response(response_data, status=status.HTTP_201_CREATED)
return response.Created(response_data)
@detail_route(methods=['post'])
@ -204,7 +204,7 @@ class ProjectImporterViewSet(mixins.ImportThrottlingPolicyMixin, CreateModelMixi
raise exc.BadRequest(errors)
headers = self.get_success_headers(issue.data)
return Response(issue.data, status=status.HTTP_201_CREATED, headers=headers)
return response.Created(issue.data, headers=headers)
@detail_route(methods=['post'])
@method_decorator(atomic)
@ -219,7 +219,7 @@ class ProjectImporterViewSet(mixins.ImportThrottlingPolicyMixin, CreateModelMixi
raise exc.BadRequest(errors)
headers = self.get_success_headers(task.data)
return Response(task.data, status=status.HTTP_201_CREATED, headers=headers)
return response.Created(task.data, headers=headers)
@detail_route(methods=['post'])
@method_decorator(atomic)
@ -234,7 +234,7 @@ class ProjectImporterViewSet(mixins.ImportThrottlingPolicyMixin, CreateModelMixi
raise exc.BadRequest(errors)
headers = self.get_success_headers(us.data)
return Response(us.data, status=status.HTTP_201_CREATED, headers=headers)
return response.Created(us.data, headers=headers)
@detail_route(methods=['post'])
@method_decorator(atomic)
@ -249,7 +249,7 @@ class ProjectImporterViewSet(mixins.ImportThrottlingPolicyMixin, CreateModelMixi
raise exc.BadRequest(errors)
headers = self.get_success_headers(milestone.data)
return Response(milestone.data, status=status.HTTP_201_CREATED, headers=headers)
return response.Created(milestone.data, headers=headers)
@detail_route(methods=['post'])
@method_decorator(atomic)
@ -264,7 +264,7 @@ class ProjectImporterViewSet(mixins.ImportThrottlingPolicyMixin, CreateModelMixi
raise exc.BadRequest(errors)
headers = self.get_success_headers(wiki_page.data)
return Response(wiki_page.data, status=status.HTTP_201_CREATED, headers=headers)
return response.Created(wiki_page.data, headers=headers)
@detail_route(methods=['post'])
@method_decorator(atomic)
@ -279,4 +279,4 @@ class ProjectImporterViewSet(mixins.ImportThrottlingPolicyMixin, CreateModelMixi
raise exc.BadRequest(errors)
headers = self.get_success_headers(wiki_link.data)
return Response(wiki_link.data, status=status.HTTP_201_CREATED, headers=headers)
return response.Created(wiki_link.data, headers=headers)

View File

@ -14,11 +14,11 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from rest_framework.response import Response
from django.utils.translation import ugettext_lazy as _
from taiga.base.api.viewsets import GenericViewSet
from taiga.base import exceptions as exc
from taiga.base import response
from taiga.base.api.viewsets import GenericViewSet
from taiga.base.utils import json
from taiga.projects.models import Project
@ -75,4 +75,4 @@ class BaseWebhookApiViewSet(GenericViewSet):
except ActionSyntaxException as e:
raise exc.BadRequest(e)
return Response({})
return response.NoContent()

View File

@ -14,18 +14,14 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from rest_framework.response import Response
from django.utils.translation import ugettext_lazy as _
from django.conf import settings
from taiga.base.api.viewsets import GenericViewSet
from taiga.base import exceptions as exc
from taiga.base.utils import json
from taiga.projects.models import Project
from taiga.hooks.api import BaseWebhookApiViewSet
from . import event_hooks
from ..exceptions import ActionSyntaxException
from urllib.parse import parse_qs
from ipware.ip import get_real_ip
@ -61,7 +57,9 @@ class BitBucketViewSet(BaseWebhookApiViewSet):
if not project_secret:
return False
valid_origin_ips = project.modules_config.config.get("bitbucket", {}).get("valid_origin_ips", settings.BITBUCKET_VALID_ORIGIN_IPS)
bitbucket_config = project.modules_config.config.get("bitbucket", {})
valid_origin_ips = bitbucket_config.get("valid_origin_ips",
settings.BITBUCKET_VALID_ORIGIN_IPS)
origin_ip = get_real_ip(request)
if valid_origin_ips and (not origin_ip or not origin_ip in valid_origin_ips):
return False

View File

@ -14,13 +14,6 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from rest_framework.response import Response
from django.utils.translation import ugettext_lazy as _
from taiga.base.api.viewsets import GenericViewSet
from taiga.base import exceptions as exc
from taiga.base.utils import json
from taiga.projects.models import Project
from taiga.hooks.api import BaseWebhookApiViewSet
from . import event_hooks
@ -51,7 +44,8 @@ class GitHubViewSet(BaseWebhookApiViewSet):
if project.modules_config.config is None:
return False
secret = bytes(project.modules_config.config.get("github", {}).get("secret", "").encode("utf-8"))
secret = project.modules_config.config.get("github", {}).get("secret", "")
secret = bytes(secret.encode("utf-8"))
mac = hmac.new(secret, msg=request.body,digestmod=hashlib.sha1)
return hmac.compare_digest(mac.hexdigest(), signature)

View File

@ -14,20 +14,18 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from rest_framework.response import Response
from django.utils.translation import ugettext_lazy as _
from django.conf import settings
from taiga.base.api.viewsets import GenericViewSet
from taiga.base import exceptions as exc
from ipware.ip import get_real_ip
from taiga.base.utils import json
from taiga.projects.models import Project
from taiga.hooks.api import BaseWebhookApiViewSet
from . import event_hooks
from ipware.ip import get_real_ip
class GitLabViewSet(BaseWebhookApiViewSet):
event_hook_classes = {
@ -51,7 +49,8 @@ class GitLabViewSet(BaseWebhookApiViewSet):
if not project_secret:
return False
valid_origin_ips = project.modules_config.config.get("gitlab", {}).get("valid_origin_ips", settings.GITLAB_VALID_ORIGIN_IPS)
gitlab_config = project.modules_config.config.get("gitlab", {})
valid_origin_ips = gitlab_config.get("valid_origin_ips", settings.GITLAB_VALID_ORIGIN_IPS)
origin_ip = get_real_ip(request)
if valid_origin_ips and (not origin_ip or origin_ip not in valid_origin_ips):
return False

View File

@ -74,7 +74,7 @@ class ProjectViewSet(ModelCrudViewSet):
modules_config = services.get_modules_config(project)
if request.method == "GET":
return response.Ok(data=modules_config.config)
return response.Ok(modules_config.config)
else:
modules_config.config.update(request.DATA)
@ -85,31 +85,31 @@ class ProjectViewSet(ModelCrudViewSet):
def stats(self, request, pk=None):
project = self.get_object()
self.check_permissions(request, "stats", project)
return response.Ok(data=services.get_stats_for_project(project))
return response.Ok(services.get_stats_for_project(project))
@detail_route(methods=["GET"])
def member_stats(self, request, pk=None):
project = self.get_object()
self.check_permissions(request, "member_stats", project)
return response.Ok(data=services.get_member_stats_for_project(project))
return response.Ok(services.get_member_stats_for_project(project))
@detail_route(methods=["GET"])
def issues_stats(self, request, pk=None):
project = self.get_object()
self.check_permissions(request, "issues_stats", project)
return response.Ok(data=services.get_stats_for_project_issues(project))
return response.Ok(services.get_stats_for_project_issues(project))
@detail_route(methods=["GET"])
def issue_filters_data(self, request, pk=None):
project = self.get_object()
self.check_permissions(request, "issues_filters_data", project)
return response.Ok(data=services.get_issues_filters_data(project))
return response.Ok(services.get_issues_filters_data(project))
@detail_route(methods=["GET"])
def tags_colors(self, request, pk=None):
project = self.get_object()
self.check_permissions(request, "tags_colors", project)
return response.Ok(data=dict(project.tags_colors))
return response.Ok(dict(project.tags_colors))
@detail_route(methods=["POST"])
def star(self, request, pk=None):
@ -132,7 +132,7 @@ class ProjectViewSet(ModelCrudViewSet):
voters = votes_service.get_voters(project)
voters_data = votes_serializers.VoterSerializer(voters, many=True)
return response.Ok(data=voters_data.data)
return response.Ok(voters_data.data)
@detail_route(methods=["POST"])
def create_template(self, request, **kwargs):
@ -359,7 +359,7 @@ class MembershipViewSet(ModelCrudViewSet):
return response.BadRequest(err.message_dict)
members_serialized = self.serializer_class(members, many=True)
return response.Ok(data=members_serialized.data)
return response.Ok(members_serialized.data)
@detail_route(methods=["POST"])
def resend_invitation(self, request, **kwargs):

View File

@ -21,14 +21,15 @@ import mimetypes
mimetypes.init()
from django.contrib.contenttypes.models import ContentType
from taiga.base.api.utils import get_object_or_404
from django.conf import settings
from django import http
from taiga.base.api import ModelCrudViewSet
from taiga.base.api import generics
from taiga.base import filters
from taiga.base import exceptions as exc
from taiga.base.api import generics
from taiga.base.api import ModelCrudViewSet
from taiga.base.api.utils import get_object_or_404
from taiga.users.models import User
from taiga.projects.notifications.mixins import WatchedResourceMixin

View File

@ -17,12 +17,10 @@
from django.contrib.contenttypes.models import ContentType
from django.utils import timezone
from rest_framework.response import Response
from rest_framework import status
from taiga.base.api.utils import get_object_or_404
from taiga.base import response
from taiga.base.decorators import detail_route
from taiga.base.api import ReadOnlyListViewSet
from taiga.base.api.utils import get_object_or_404
from . import permissions
from . import serializers
@ -54,7 +52,7 @@ class HistoryViewSet(ReadOnlyListViewSet):
else:
serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)
return response.Ok(serializer.data)
@detail_route(methods=['post'])
def delete_comment(self, request, pk):
@ -65,15 +63,15 @@ class HistoryViewSet(ReadOnlyListViewSet):
self.check_permissions(request, 'delete_comment', comment)
if comment is None:
return Response(status=status.HTTP_404_NOT_FOUND)
return response.NotFound()
if comment.delete_comment_date or comment.delete_comment_user:
return Response({"error": "Comment already deleted"}, status=status.HTTP_400_BAD_REQUEST)
return response.BadRequest({"error": "Comment already deleted"})
comment.delete_comment_date = timezone.now()
comment.delete_comment_user = {"pk": request.user.pk, "name": request.user.get_full_name()}
comment.save()
return Response(status=status.HTTP_200_OK)
return response.Ok()
@detail_route(methods=['post'])
def undelete_comment(self, request, pk):
@ -84,20 +82,20 @@ class HistoryViewSet(ReadOnlyListViewSet):
self.check_permissions(request, 'undelete_comment', comment)
if comment is None:
return Response(status=status.HTTP_404_NOT_FOUND)
return response.NotFound()
if not comment.delete_comment_date and not comment.delete_comment_user:
return Response({"error": "Comment not deleted"}, status=status.HTTP_400_BAD_REQUEST)
return response.BadRequest({"error": "Comment not deleted"})
comment.delete_comment_date = None
comment.delete_comment_user = None
comment.save()
return Response(status=status.HTTP_200_OK)
return response.Ok()
# Just for restframework! Because it raises
# 404 on main api root if this method not exists.
def list(self, request):
return Response({})
return response.NotFound()
def retrieve(self, request, pk):
obj = self.get_object()

View File

@ -18,14 +18,12 @@ from django.utils.translation import ugettext_lazy as _
from django.db.models import Q
from django.http import Http404
from rest_framework.response import Response
from rest_framework import status
from taiga.base.api.utils import get_object_or_404
from taiga.base import filters, response
from taiga.base import filters
from taiga.base import exceptions as exc
from taiga.base import response
from taiga.base.decorators import detail_route, list_route
from taiga.base.api import ModelCrudViewSet, ModelListViewSet
from taiga.base.api.utils import get_object_or_404
from taiga.base import tags
from taiga.users.models import User
@ -139,19 +137,24 @@ class IssueViewSet(OCCResourceMixin, HistoryResourceMixin, WatchedResourceMixin,
super().pre_conditions_on_save(obj)
if obj.milestone and obj.milestone.project != obj.project:
raise exc.PermissionDenied(_("You don't have permissions to set this milestone to this issue."))
raise exc.PermissionDenied(_("You don't have permissions to set this sprint "
"to this issue."))
if obj.status and obj.status.project != obj.project:
raise exc.PermissionDenied(_("You don't have permissions to set this status to this issue."))
raise exc.PermissionDenied(_("You don't have permissions to set this status "
"to this issue."))
if obj.severity and obj.severity.project != obj.project:
raise exc.PermissionDenied(_("You don't have permissions to set this severity to this issue."))
raise exc.PermissionDenied(_("You don't have permissions to set this severity "
"to this issue."))
if obj.priority and obj.priority.project != obj.project:
raise exc.PermissionDenied(_("You don't have permissions to set this priority to this issue."))
raise exc.PermissionDenied(_("You don't have permissions to set this priority "
"to this issue."))
if obj.type and obj.type.project != obj.project:
raise exc.PermissionDenied(_("You don't have permissions to set this type to this issue."))
raise exc.PermissionDenied(_("You don't have permissions to set this type "
"to this issue."))
@list_route(methods=["GET"])
def by_ref(self, request):
@ -185,7 +188,7 @@ class IssueViewSet(OCCResourceMixin, HistoryResourceMixin, WatchedResourceMixin,
self.check_permissions(request, 'upvote', issue)
votes_service.add_vote(issue, user=request.user)
return Response(status=status.HTTP_200_OK)
return response.Ok()
@detail_route(methods=['post'])
def downvote(self, request, pk=None):
@ -194,7 +197,7 @@ class IssueViewSet(OCCResourceMixin, HistoryResourceMixin, WatchedResourceMixin,
self.check_permissions(request, 'downvote', issue)
votes_service.remove_vote(issue, user=request.user)
return Response(status=status.HTTP_200_OK)
return response.Ok()
class VotersViewSet(ModelListViewSet):
@ -215,7 +218,7 @@ class VotersViewSet(ModelListViewSet):
raise Http404
serializer = self.get_serializer(self.object)
return Response(serializer.data)
return response.Ok(serializer.data)
def list(self, request, *args, **kwargs):
issue_id = kwargs.get("issue_id", None)

View File

@ -14,16 +14,11 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from django.utils.translation import ugettext_lazy as _
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from taiga.base.api.utils import get_object_or_404
from taiga.base import filters
from taiga.base import exceptions as exc
from taiga.base import response
from taiga.base.decorators import detail_route
from taiga.base.api import ModelCrudViewSet
from taiga.base.api.utils import get_object_or_404
from taiga.projects.notifications.mixins import WatchedResourceMixin
from taiga.projects.history.mixins import HistoryResourceMixin
@ -97,4 +92,4 @@ class MilestoneViewSet(HistoryResourceMixin, WatchedResourceMixin, ModelCrudView
current_date = current_date + datetime.timedelta(days=1)
optimal_points -= optimal_points_per_day
return Response(milestone_stats)
return response.Ok(milestone_stats)

View File

@ -14,20 +14,10 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from django.utils.translation import ugettext_lazy as _
from django.db.models import Q
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from taiga.base.api.utils import get_object_or_404
from taiga.base import filters
from taiga.base import exceptions as exc
from taiga.base.decorators import detail_route
from taiga.base.api import ModelCrudViewSet
from taiga.projects.models import Project
from taiga.projects.notifications.choices import NotifyLevel
from . import serializers

View File

@ -16,14 +16,13 @@
from django.apps import apps
from rest_framework.response import Response
from taiga.base.api.utils import get_object_or_404
from taiga.base import exceptions as exc
from taiga.base import response
from taiga.base.api import viewsets
from .serializers import ResolverSerializer
from taiga.base.api.utils import get_object_or_404
from taiga.permissions.service import user_has_perm
from .serializers import ResolverSerializer
from . import permissions
@ -42,19 +41,22 @@ class ResolverViewSet(viewsets.ViewSet):
self.check_permissions(request, "list", project)
result = {
"project": project.pk
}
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
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
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
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
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
result["wikipage"] = get_object_or_404(project.wiki_pages.all(),
slug=data["wikipage"]).pk
return Response(result)
return response.Ok(result)

View File

@ -16,19 +16,19 @@
from contextlib import suppress
from rest_framework import status
from django.apps import apps
from django.db import transaction
from django.utils.translation import ugettext as _
from django.core.exceptions import ObjectDoesNotExist
from rest_framework.response import Response
from rest_framework import status
from taiga.base.api.utils import get_object_or_404
from taiga.base import filters, response
from taiga.base import filters
from taiga.base import exceptions as exc
from taiga.base import response
from taiga.base.decorators import list_route
from taiga.base.api import ModelCrudViewSet
from taiga.base.api.utils import get_object_or_404
from taiga.projects.notifications.mixins import WatchedResourceMixin
from taiga.projects.history.mixins import HistoryResourceMixin

View File

@ -17,13 +17,12 @@
from django.utils.translation import ugettext_lazy as _
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework import status
from taiga.base.api.utils import get_object_or_404
from taiga.base import filters
from taiga.base import exceptions as exc
from taiga.base import response
from taiga.base.api import ModelCrudViewSet
from taiga.base.api.utils import get_object_or_404
from taiga.base.decorators import list_route
from taiga.projects.models import Project
from taiga.mdrender.service import render as mdrender
@ -58,17 +57,17 @@ class WikiViewSet(OCCResourceMixin, HistoryResourceMixin, WatchedResourceMixin,
project_id = request.DATA.get("project_id", None)
if not content:
raise exc.WrongArguments({"content": "No content parameter"})
raise exc.WrongArguments({"content": _("No content parameter")})
if not project_id:
raise exc.WrongArguments({"project_id": "No project_id parameter"})
raise exc.WrongArguments({"project_id": _("No project_id parameter")})
project = get_object_or_404(Project, pk=project_id)
self.check_permissions(request, "render", project)
data = mdrender(project, content)
return Response({"data": data})
return response.Ok({"data": data})
def pre_save(self, obj):
if not obj.owner:

View File

@ -16,10 +16,9 @@
from django.apps import apps
from rest_framework.response import Response
from rest_framework import viewsets
from taiga.base import exceptions as excp
from taiga.base import response
from taiga.base.api.utils import get_object_or_404
from taiga.projects.userstories.serializers import UserStorySerializer
from taiga.projects.tasks.serializers import TaskSerializer
@ -48,7 +47,7 @@ class SearchViewSet(viewsets.ViewSet):
result["wikipages"] = self._search_wiki_pages(project, text)
result["count"] = sum(map(lambda x: len(x), result.values()))
return Response(result)
return response.Ok(result)
def _get_project(self, project_id):
project_model = apps.get_model("projects", "Project")

View File

@ -16,8 +16,7 @@
from django.contrib.contenttypes.models import ContentType
from rest_framework.response import Response
from taiga.base import response
from taiga.base.api.utils import get_object_or_404
from taiga.base.api import GenericViewSet
@ -52,12 +51,12 @@ class TimelineViewSet(GenericViewSet):
else:
serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)
return response.Ok(serializer.data)
# Just for restframework! Because it raises
# 404 on main api root if this method not exists.
def list(self, request):
return Response({})
return response.NotFound()
def retrieve(self, request, pk):
obj = self.get_object()

View File

@ -23,25 +23,23 @@ from django.core.validators import validate_email
from django.core.exceptions import ValidationError
from django.conf import settings
from easy_thumbnails.source_generators import pil_image
from rest_framework.response import Response
from rest_framework import status
from djmail.template_mail import MagicMailBuilder
from djmail.template_mail import InlineCSSTemplateMail
from taiga.base import exceptions as exc
from taiga.base import filters
from taiga.base import response
from taiga.auth.tokens import get_user_for_token
from taiga.base.decorators import list_route
from taiga.base.decorators import detail_route
from taiga.base import exceptions as exc
from taiga.base import filters
from taiga.base.api import ModelCrudViewSet
from taiga.base.api.utils import get_object_or_404
from taiga.base.filters import MembersFilterBackend
from taiga.projects.votes import services as votes_service
from taiga.projects.serializers import StarredSerializer
from easy_thumbnails.source_generators import pil_image
from djmail.template_mail import MagicMailBuilder
from djmail.template_mail import InlineCSSTemplateMail
from . import models
from . import serializers
from . import permissions
@ -71,7 +69,7 @@ class UsersViewSet(ModelCrudViewSet):
else:
serializer = self.get_serializer(self.object_list, many=True)
return Response(serializer.data)
return response.Ok(serializer.data)
@list_route(methods=["POST"])
def password_recovery(self, request, pk=None):
@ -96,7 +94,7 @@ class UsersViewSet(ModelCrudViewSet):
email = mbuilder.password_recovery(user.email, {"user": user})
email.send()
return Response({"detail": _("Mail sended successful!"),
return response.Ok({"detail": _("Mail sended successful!"),
"email": user.email})
@list_route(methods=["POST"])
@ -120,7 +118,7 @@ class UsersViewSet(ModelCrudViewSet):
user.token = None
user.save(update_fields=["password", "token"])
return Response(status=status.HTTP_204_NO_CONTENT)
return response.NoContent()
@list_route(methods=["POST"])
def change_password(self, request, pk=None):
@ -148,7 +146,7 @@ class UsersViewSet(ModelCrudViewSet):
request.user.set_password(password)
request.user.save(update_fields=["password"])
return Response(status=status.HTTP_204_NO_CONTENT)
return response.NoContent()
@list_route(methods=["POST"])
def change_avatar(self, request):
@ -171,7 +169,7 @@ class UsersViewSet(ModelCrudViewSet):
request.user.save(update_fields=["photo"])
user_data = serializers.UserSerializer(request.user).data
return Response(user_data, status=status.HTTP_200_OK)
return response.Ok(user_data)
@list_route(methods=["POST"])
def remove_avatar(self, request):
@ -182,7 +180,7 @@ class UsersViewSet(ModelCrudViewSet):
request.user.photo = None
request.user.save(update_fields=["photo"])
user_data = serializers.UserSerializer(request.user).data
return Response(user_data, status=status.HTTP_200_OK)
return response.Ok(user_data)
@detail_route(methods=["GET"])
def starred(self, request, pk=None):
@ -191,7 +189,7 @@ class UsersViewSet(ModelCrudViewSet):
stars = votes_service.get_voted(user.pk, model=apps.get_model('projects', 'Project'))
stars_data = StarredSerializer(stars, many=True)
return Response(stars_data.data)
return response.Ok(stars_data.data)
#TODO: commit_on_success
def partial_update(self, request, *args, **kwargs):
@ -254,7 +252,7 @@ class UsersViewSet(ModelCrudViewSet):
user.email_token = None
user.save(update_fields=["email", "new_email", "email_token"])
return Response(status=status.HTTP_204_NO_CONTENT)
return response.NoContent()
@list_route(methods=["GET"])
def me(self, request, pk=None):
@ -263,7 +261,7 @@ class UsersViewSet(ModelCrudViewSet):
"""
self.check_permissions(request, "me", None)
user_data = serializers.UserSerializer(request.user).data
return Response(user_data, status=status.HTTP_200_OK)
return response.Ok(user_data)
@list_route(methods=["POST"])
def cancel(self, request, pk=None):
@ -286,7 +284,7 @@ class UsersViewSet(ModelCrudViewSet):
raise exc.WrongArguments(_("Invalid, are you sure the token is correct?"))
user.cancel()
return Response(status=status.HTTP_204_NO_CONTENT)
return response.NoContent()
def destroy(self, request, pk=None):
user = self.get_object()
@ -295,7 +293,7 @@ class UsersViewSet(ModelCrudViewSet):
request_data = stream is not None and stream.GET or None
user_cancel_account_signal.send(sender=user.__class__, user=user, request_data=request_data)
user.cancel()
return Response(status=status.HTTP_204_NO_CONTENT)
return response.NoContent()
######################################################

View File

@ -16,10 +16,11 @@
import json
from rest_framework.response import Response
from taiga.base import filters
from taiga.base.api import ModelCrudViewSet, ModelListViewSet
from taiga.base import response
from taiga.base.api import ModelCrudViewSet
from taiga.base.api import ModelListViewSet
from taiga.base.api.utils import get_object_or_404
from taiga.base.decorators import detail_route
@ -44,7 +45,8 @@ class WebhookViewSet(ModelCrudViewSet):
webhooklog = tasks.test_webhook(webhook.id, webhook.url, webhook.key)
log = serializers.WebhookLogSerializer(webhooklog)
return Response(log.data)
return response.Ok(log.data)
class WebhookLogViewSet(ModelListViewSet):
model = models.WebhookLog
@ -60,7 +62,9 @@ class WebhookLogViewSet(ModelListViewSet):
webhook = webhooklog.webhook
webhooklog = tasks.resend_webhook(webhook.id, webhook.url, webhook.key, webhooklog.request_data)
webhooklog = tasks.resend_webhook(webhook.id, webhook.url, webhook.key,
webhooklog.request_data)
log = serializers.WebhookLogSerializer(webhooklog)
return Response(log.data)
return response.Ok(log.data)

View File

@ -55,7 +55,7 @@ def test_ok_signature(client):
urllib.parse.urlencode(data, True),
content_type="application/x-www-form-urlencoded",
REMOTE_ADDR=settings.BITBUCKET_VALID_ORIGIN_IPS[0])
assert response.status_code == 200
assert response.status_code == 204
def test_invalid_ip(client):
project=f.ProjectFactory()
@ -91,7 +91,7 @@ def test_not_ip_filter(client):
urllib.parse.urlencode(data, True),
content_type="application/x-www-form-urlencoded",
REMOTE_ADDR="111.111.111.112")
assert response.status_code == 200
assert response.status_code == 204
def test_push_event_detected(client):
@ -108,7 +108,7 @@ def test_push_event_detected(client):
assert process_event_mock.call_count == 1
assert response.status_code == 200
assert response.status_code == 204
def test_push_event_issue_processing(client):

View File

@ -50,7 +50,7 @@ def test_ok_signature(client):
HTTP_X_HUB_SIGNATURE="sha1=3c8e83fdaa266f81c036ea0b71e98eb5e054581a",
content_type="application/json")
assert response.status_code == 200
assert response.status_code == 204
def test_push_event_detected(client):
@ -70,7 +70,7 @@ def test_push_event_detected(client):
assert process_event_mock.call_count == 1
assert response.status_code == 200
assert response.status_code == 204
def test_push_event_issue_processing(client):

View File

@ -55,7 +55,7 @@ def test_ok_signature(client):
content_type="application/json",
REMOTE_ADDR="111.111.111.111")
assert response.status_code == 200
assert response.status_code == 204
def test_invalid_ip(client):
@ -95,7 +95,7 @@ def test_not_ip_filter(client):
content_type="application/json",
REMOTE_ADDR="111.111.111.111")
assert response.status_code == 200
assert response.status_code == 204
def test_push_event_detected(client):
@ -115,7 +115,7 @@ def test_push_event_detected(client):
assert process_event_mock.call_count == 1
assert response.status_code == 200
assert response.status_code == 204
def test_push_event_issue_processing(client):
@ -340,7 +340,6 @@ def test_issues_event_bad_issue(client):
assert len(mail.outbox) == 0
def test_api_get_project_modules(client):
project = f.create_project()
membership = f.MembershipFactory(project=project, user=project.owner, is_owner=True)