Skip to content

Commit

Permalink
Merge 1802e27 into f1988b5
Browse files Browse the repository at this point in the history
  • Loading branch information
mldzs committed Mar 24, 2021
2 parents f1988b5 + 1802e27 commit 2b89a8a
Show file tree
Hide file tree
Showing 17 changed files with 981 additions and 4 deletions.
2 changes: 1 addition & 1 deletion bothub/api/grpc/organization/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
OrgCreateProtoSerializer,
OrgUpdateProtoSerializer,
)
from bothub.authentication.models import User, RepositoryOwner
from bothub.authentication.models import User
from bothub.common.models import Organization, OrganizationAuthorization


Expand Down
Empty file.
70 changes: 70 additions & 0 deletions bothub/api/v2/knowledge_base/filters.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
from django.utils.translation import ugettext_lazy as _
from django.core.exceptions import ValidationError as DjangoValidationError
from django_filters import rest_framework as filters
from rest_framework.exceptions import PermissionDenied, NotFound

from bothub.common.models import QAKnowledgeBase, Repository, QAContext


class QAKnowledgeBaseFilter(filters.FilterSet):
class Meta:
model = QAKnowledgeBase
fields = ["title", "created_at", "repository_uuid"]

repository_uuid = filters.CharFilter(
field_name="repository_uuid",
method="filter_repository_uuid",
required=True,
help_text=_("Repository's UUID"),
)

def filter_repository_uuid(self, queryset, name, value):
request = self.request
try:
repository = Repository.objects.get(uuid=value)
authorization = repository.get_user_authorization(request.user)

if not authorization.can_read:
raise PermissionDenied()

return queryset.filter(repository=repository)
except Repository.DoesNotExist:
raise NotFound(_("Repository {} does not exist").format(value))
except DjangoValidationError:
raise NotFound(_("Invalid repository_uuid"))


class QAContextFilter(filters.FilterSet):
class Meta:
model = QAContext
fields = [
"text",
"language",
"created_at",
"repository_uuid",
"knowledge_base_id",
]

knowledge_base_id = filters.CharFilter(field_name="knowledge_base__id")

repository_uuid = filters.CharFilter(
field_name="repository_uuid",
method="filter_repository_uuid",
required=True,
help_text=_("Repository's UUID"),
)

def filter_repository_uuid(self, queryset, name, value):
request = self.request
try:
repository = Repository.objects.get(uuid=value)
authorization = repository.get_user_authorization(request.user)

if not authorization.can_read:
raise PermissionDenied()

return queryset.filter(knowledge_base__repository=repository)
except Repository.DoesNotExist:
raise NotFound(_("Repository {} does not exist").format(value))
except DjangoValidationError:
raise NotFound(_("Invalid repository_uuid"))
22 changes: 22 additions & 0 deletions bothub/api/v2/knowledge_base/permissions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from rest_framework import permissions

from bothub.api.v2 import READ_METHODS


class QAKnowledgeBasePermission(permissions.BasePermission):
def has_object_permission(self, request, view, obj):
authorization = obj.repository.get_user_authorization(request.user)
if request.method in READ_METHODS:
return authorization.can_read
return authorization.can_contribute


class QAContextPermission(permissions.BasePermission):
def has_object_permission(self, request, view, obj):
authorization = obj.knowledge_base.repository.get_user_authorization(
request.user
)
if request.method in READ_METHODS:
return authorization.can_read

return authorization.can_contribute
25 changes: 25 additions & 0 deletions bothub/api/v2/knowledge_base/serializers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
from rest_framework import serializers

from bothub.common import languages
from bothub.common.models import Repository, QAKnowledgeBase, QAContext


class QAKnowledgeBaseSerializer(serializers.ModelSerializer):
class Meta:
model = QAKnowledgeBase
fields = ["id", "repository", "title"]
read_only_fields = ["created_at", "last_update"]

repository = serializers.PrimaryKeyRelatedField(queryset=Repository.objects)


class QAContextSerializer(serializers.ModelSerializer):
class Meta:
model = QAContext
fields = ["id", "text", "language", "knowledge_base"]
read_only_fields = ["created_at", "last_update"]

knowledge_base = serializers.PrimaryKeyRelatedField(
queryset=QAKnowledgeBase.objects
)
language = serializers.ChoiceField(languages.LANGUAGE_CHOICES, required=True)
35 changes: 35 additions & 0 deletions bothub/api/v2/knowledge_base/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
from rest_framework import mixins, permissions
from rest_framework.viewsets import GenericViewSet

from .filters import QAKnowledgeBaseFilter, QAContextFilter
from .permissions import QAKnowledgeBasePermission, QAContextPermission
from .serializers import QAKnowledgeBaseSerializer, QAContextSerializer
from bothub.common.models import QAKnowledgeBase, QAContext


class QAKnowledgeBaseViewSet(
mixins.ListModelMixin,
mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
mixins.DestroyModelMixin,
mixins.UpdateModelMixin,
GenericViewSet,
):
queryset = QAKnowledgeBase.objects.all()
serializer_class = QAKnowledgeBaseSerializer
filter_class = QAKnowledgeBaseFilter
permission_classes = [permissions.IsAuthenticated, QAKnowledgeBasePermission]


class QAContextViewSet(
mixins.ListModelMixin,
mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
mixins.DestroyModelMixin,
mixins.UpdateModelMixin,
GenericViewSet,
):
queryset = QAContext.objects.all()
serializer_class = QAContextSerializer
filter_class = QAContextFilter
permission_classes = [permissions.IsAuthenticated, QAContextPermission]
35 changes: 35 additions & 0 deletions bothub/api/v2/nlp/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -593,3 +593,38 @@ class RepositoryNLPLogsViewSet(mixins.CreateModelMixin, GenericViewSet):
serializer_class = RepositoryNLPLogSerializer
permission_classes = [AllowAny]
authentication_classes = [NLPAuthentication]


class RepositoryAuthorizationKnowledgeBaseViewSet(
mixins.RetrieveModelMixin, GenericViewSet
):
queryset = RepositoryAuthorization.objects
serializer_class = NLPSerializer
permission_classes = [AllowAny]
authentication_classes = [NLPAuthentication]

def retrieve(self, request, *args, **kwargs):
check_auth(request)
repository_authorization = self.get_object()

if not repository_authorization.can_contribute:
raise PermissionDenied()

repository = repository_authorization.repository

knowledge_base_pk = request.query_params.get("knowledge_base_id")
language = request.query_params.get("language")

knowledge_base = get_object_or_404(
repository.knowledge_bases.all(), pk=knowledge_base_pk
)

context = get_object_or_404(knowledge_base.contexts.all(), language=language)

return Response(
{
"knowledge_base_id": knowledge_base.pk,
"text": context.text,
"language": context.language,
}
)
7 changes: 6 additions & 1 deletion bothub/api/v2/repository/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -1016,7 +1016,12 @@ def create(self, validated_data):
if not owner.is_organization:
raise ValidationError(_("It's necessary to pass an organization."))

validated_data.update({"slug": utils.unique_slug_generator(validated_data)})
validated_data.update(
{
"slug": utils.unique_slug_generator(validated_data),
"owner": owner
}
)

repository = super().create(validated_data)

Expand Down
13 changes: 12 additions & 1 deletion bothub/api/v2/routers.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from bothub.api.v2.versionning.views import RepositoryVersionViewSet
from .groups.views import RepositoryEntityGroupViewSet
from .knowledge_base.views import QAKnowledgeBaseViewSet, QAContextViewSet
from .organization.views import (
OrganizationViewSet,
OrganizationProfileViewSet,
Expand Down Expand Up @@ -30,7 +31,11 @@
from .repository.views import RepositoryAuthorizationViewSet
from .repository.views import RepositoryAuthorizationRequestsViewSet
from .repository.views import RepositoryExampleViewSet
from .nlp.views import RepositoryAuthorizationTrainViewSet, RepositoryNLPLogsViewSet
from .nlp.views import (
RepositoryAuthorizationTrainViewSet,
RepositoryNLPLogsViewSet,
RepositoryAuthorizationKnowledgeBaseViewSet,
)
from .nlp.views import RepositoryAuthorizationParseViewSet
from .nlp.views import RepositoryAuthorizationInfoViewSet
from .nlp.views import RepositoryAuthorizationEvaluateViewSet
Expand Down Expand Up @@ -172,6 +177,8 @@ def get_lookup_regex(self, viewset, lookup_prefix=""):
router.register("repository/log", RepositoryNLPLogViewSet)
router.register("repository/entities", RepositoryEntitiesViewSet)
router.register("repository/task-queue", RepositoryTaskQueueViewSet)
router.register("repository/qa/knowledge-base", QAKnowledgeBaseViewSet)
router.register("repository/qa/context", QAContextViewSet)
router.register("repository/upload-rasa-file", RasaUploadViewSet)
router.register("repository/entity/group", RepositoryEntityGroupViewSet)
router.register("repository/repository-migrate", RepositoryMigrateViewSet)
Expand All @@ -189,6 +196,10 @@ def get_lookup_regex(self, viewset, lookup_prefix=""):
router.register(
"repository/nlp/update_interpreters", RepositoryUpdateInterpretersViewSet
)
router.register(
"repository/nlp/authorization/knowledge-base",
RepositoryAuthorizationKnowledgeBaseViewSet,
)
router.register("repository/nlp/log", RepositoryNLPLogsViewSet)
router.register("account/login", LoginViewSet)
router.register("account/register", RegisterUserViewSet)
Expand Down
Loading

0 comments on commit 2b89a8a

Please sign in to comment.