🔥(back) remove collaboration-auth endpoint
We don't need anymore the collaboration-auth endpoint. Every code related to it is removed.
This commit is contained in:
@@ -380,10 +380,7 @@ class DocumentViewSet(
|
||||
9. **Media Auth**: Authorize access to document media.
|
||||
Example: GET /documents/media-auth/
|
||||
|
||||
10. **Collaboration Auth**: Authorize access to the collaboration server for a document.
|
||||
Example: GET /documents/collaboration-auth/
|
||||
|
||||
11. **AI Transform**: Apply a transformation action on a piece of text with AI.
|
||||
10. **AI Transform**: Apply a transformation action on a piece of text with AI.
|
||||
Example: POST /documents/{id}/ai-transform/
|
||||
Expected data:
|
||||
- text (str): The input text.
|
||||
@@ -391,7 +388,7 @@ class DocumentViewSet(
|
||||
Returns: JSON response with the processed text.
|
||||
Throttled by: AIDocumentRateThrottle, AIUserRateThrottle.
|
||||
|
||||
12. **AI Translate**: Translate a piece of text with AI.
|
||||
11. **AI Translate**: Translate a piece of text with AI.
|
||||
Example: POST /documents/{id}/ai-translate/
|
||||
Expected data:
|
||||
- text (str): The input text.
|
||||
@@ -1207,17 +1204,6 @@ class DocumentViewSet(
|
||||
logger.debug("Failed to extract parameters from subrequest URL: %s", exc)
|
||||
raise drf.exceptions.PermissionDenied() from exc
|
||||
|
||||
def _auth_get_document(self, pk):
|
||||
"""
|
||||
Retrieves the document corresponding to the given primary key (pk).
|
||||
Raises PermissionDenied if the document is not found.
|
||||
"""
|
||||
try:
|
||||
return models.Document.objects.get(pk=pk)
|
||||
except models.Document.DoesNotExist as exc:
|
||||
logger.debug("Document with ID '%s' does not exist", pk)
|
||||
raise drf.exceptions.PermissionDenied() from exc
|
||||
|
||||
@drf.decorators.action(detail=False, methods=["get"], url_path="media-auth")
|
||||
def media_auth(self, request, *args, **kwargs):
|
||||
"""
|
||||
@@ -1265,42 +1251,6 @@ class DocumentViewSet(
|
||||
|
||||
return drf.response.Response("authorized", headers=request.headers, status=200)
|
||||
|
||||
@drf.decorators.action(detail=False, methods=["get"], url_path="collaboration-auth")
|
||||
def collaboration_auth(self, request, *args, **kwargs):
|
||||
"""
|
||||
This view is used by an Nginx subrequest to control access to a document's
|
||||
collaboration server.
|
||||
"""
|
||||
parsed_url = self._auth_get_original_url(request)
|
||||
url_params = self._auth_get_url_params(
|
||||
enums.COLLABORATION_WS_URL_PATTERN, parsed_url.query
|
||||
)
|
||||
document = self._auth_get_document(url_params["pk"])
|
||||
|
||||
abilities = document.get_abilities(request.user)
|
||||
if not abilities.get(self.action, False):
|
||||
logger.debug(
|
||||
"User '%s' lacks permission for document '%s'",
|
||||
request.user,
|
||||
document.pk,
|
||||
)
|
||||
raise drf.exceptions.PermissionDenied()
|
||||
|
||||
if not settings.COLLABORATION_SERVER_SECRET:
|
||||
logger.debug("Collaboration server secret is not defined")
|
||||
raise drf.exceptions.PermissionDenied()
|
||||
|
||||
# Add the collaboration server secret token to the headers
|
||||
headers = {
|
||||
"Authorization": settings.COLLABORATION_SERVER_SECRET,
|
||||
"X-Can-Edit": str(abilities["partial_update"]),
|
||||
}
|
||||
|
||||
if request.user.is_authenticated:
|
||||
headers["X-User-Id"] = str(request.user.id)
|
||||
|
||||
return drf.response.Response("authorized", headers=headers, status=200)
|
||||
|
||||
@drf.decorators.action(
|
||||
detail=True,
|
||||
methods=["post"],
|
||||
|
||||
@@ -20,7 +20,6 @@ MEDIA_STORAGE_URL_PATTERN = re.compile(
|
||||
MEDIA_STORAGE_URL_EXTRACT = re.compile(
|
||||
f"{settings.MEDIA_URL:s}({UUID_REGEX}/{ATTACHMENTS_FOLDER}/{UUID_REGEX}{FILE_EXT_REGEX})"
|
||||
)
|
||||
COLLABORATION_WS_URL_PATTERN = re.compile(rf"(?:^|&)room=(?P<pk>{UUID_REGEX})(?:&|$)")
|
||||
|
||||
|
||||
# In Django's code base, `LANGUAGES` is set by default with all supported languages.
|
||||
|
||||
@@ -1,185 +0,0 @@
|
||||
"""
|
||||
Test collaboration websocket access API endpoint for users in impress's core app.
|
||||
"""
|
||||
|
||||
from uuid import uuid4
|
||||
|
||||
from django.test import override_settings
|
||||
|
||||
import pytest
|
||||
from rest_framework.test import APIClient
|
||||
|
||||
from core import factories, models
|
||||
from core.tests.conftest import TEAM, USER, VIA
|
||||
|
||||
pytestmark = pytest.mark.django_db
|
||||
|
||||
|
||||
def test_api_documents_collaboration_auth_unkown_document():
|
||||
"""
|
||||
Trying to connect to the collaboration server on a document ID that does not exist
|
||||
should not have the side effect to create it (no regression test).
|
||||
"""
|
||||
original_url = f"http://localhost/collaboration/ws/?room={uuid4()!s}"
|
||||
|
||||
response = APIClient().get(
|
||||
"/api/v1.0/documents/collaboration-auth/", HTTP_X_ORIGINAL_URL=original_url
|
||||
)
|
||||
|
||||
assert response.status_code == 403
|
||||
assert models.Document.objects.exists() is False
|
||||
|
||||
|
||||
def test_api_documents_collaboration_auth_original_url_not_matching():
|
||||
"""
|
||||
Trying to authenticate on the collaboration server with an invalid
|
||||
original url should return a 403.
|
||||
"""
|
||||
document = factories.DocumentFactory(link_reach="public")
|
||||
|
||||
response = APIClient().get(
|
||||
"/api/v1.0/documents/collaboration-auth/",
|
||||
HTTP_X_ORIGINAL_URL=f"http://localhost/ws/?invalid={document.pk}",
|
||||
)
|
||||
|
||||
assert response.status_code == 403
|
||||
assert "Authorization" not in response
|
||||
assert "X-Can-Edit" not in response
|
||||
assert "X-User-Id" not in response
|
||||
|
||||
|
||||
def test_api_documents_collaboration_auth_secret_not_defined(settings):
|
||||
"""
|
||||
Trying to authenticate on the collaboration server when the secret is not defined
|
||||
should return a 403.
|
||||
"""
|
||||
settings.COLLABORATION_SERVER_SECRET = None
|
||||
|
||||
document = factories.DocumentFactory(link_reach="public")
|
||||
|
||||
response = APIClient().get(
|
||||
"/api/v1.0/documents/collaboration-auth/",
|
||||
HTTP_X_ORIGINAL_URL=f"http://localhost/ws/?room={document.pk}",
|
||||
)
|
||||
|
||||
assert response.status_code == 403
|
||||
assert "Authorization" not in response
|
||||
assert "X-Can-Edit" not in response
|
||||
assert "X-User-Id" not in response
|
||||
|
||||
|
||||
@override_settings(COLLABORATION_SERVER_SECRET="123")
|
||||
@pytest.mark.parametrize("reach", ["authenticated", "restricted"])
|
||||
def test_api_documents_collaboration_auth_anonymous_authenticated_or_restricted(reach):
|
||||
"""
|
||||
Anonymous users should not be allowed to connect to the collaboration server for a document
|
||||
with link reach set to authenticated or restricted.
|
||||
"""
|
||||
document = factories.DocumentFactory(link_reach=reach)
|
||||
|
||||
response = APIClient().get(
|
||||
"/api/v1.0/documents/collaboration-auth/",
|
||||
HTTP_X_ORIGINAL_URL=f"http://localhost/ws/?room={document.pk}",
|
||||
)
|
||||
|
||||
assert response.status_code == 403
|
||||
assert "Authorization" not in response
|
||||
assert "X-Can-Edit" not in response
|
||||
assert "X-User-Id" not in response
|
||||
|
||||
|
||||
@override_settings(COLLABORATION_SERVER_SECRET="123")
|
||||
def test_api_documents_collaboration_auth_anonymous_public():
|
||||
"""
|
||||
Anonymous users should be able to connect to the collaboration server for a public document.
|
||||
"""
|
||||
document = factories.DocumentFactory(link_reach="public")
|
||||
|
||||
response = APIClient().get(
|
||||
"/api/v1.0/documents/collaboration-auth/",
|
||||
HTTP_X_ORIGINAL_URL=f"http://localhost/ws/?room={document.pk}",
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
assert response["Authorization"] == "123"
|
||||
assert response["X-Can-Edit"] == str(document.link_role == "editor")
|
||||
assert "X-User-Id" not in response
|
||||
|
||||
|
||||
@override_settings(COLLABORATION_SERVER_SECRET="123")
|
||||
@pytest.mark.parametrize("reach", ["public", "authenticated"])
|
||||
def test_api_documents_collaboration_auth_authenticated_public_or_authenticated(reach):
|
||||
"""
|
||||
Authenticated users who are not related to a document should be able to connect to the
|
||||
collaboration server if this document's link reach is set to public or authenticated.
|
||||
"""
|
||||
user = factories.UserFactory()
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
|
||||
document = factories.DocumentFactory(link_reach=reach)
|
||||
|
||||
response = client.get(
|
||||
"/api/v1.0/documents/collaboration-auth/",
|
||||
HTTP_X_ORIGINAL_URL=f"http://localhost/ws/?room={document.pk}",
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
assert response["Authorization"] == "123"
|
||||
assert response["X-Can-Edit"] == str(document.link_role == "editor")
|
||||
assert response["X-User-Id"] == str(user.id)
|
||||
|
||||
|
||||
@override_settings(COLLABORATION_SERVER_SECRET="123")
|
||||
def test_api_documents_collaboration_auth_authenticated_restricted():
|
||||
"""
|
||||
Authenticated users who are not related to a document should not be allowed to connect to the
|
||||
collaboration server if this document's link reach is set to restricted.
|
||||
"""
|
||||
user = factories.UserFactory()
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
|
||||
document = factories.DocumentFactory(link_reach="restricted")
|
||||
|
||||
response = client.get(
|
||||
"/api/v1.0/documents/collaboration-auth/",
|
||||
HTTP_X_ORIGINAL_URL=f"http://localhost/ws/?room={document.pk}",
|
||||
)
|
||||
|
||||
assert response.status_code == 403
|
||||
assert "Authorization" not in response
|
||||
assert "X-Can-Edit" not in response
|
||||
assert "X-User-Id" not in response
|
||||
|
||||
|
||||
@override_settings(COLLABORATION_SERVER_SECRET="123")
|
||||
@pytest.mark.parametrize("role", models.RoleChoices.values)
|
||||
@pytest.mark.parametrize("via", VIA)
|
||||
def test_api_documents_collaboration_auth_related(via, role, mock_user_teams):
|
||||
"""
|
||||
Users who have a specific access to a document, whatever the role, should be able to
|
||||
connect to the collaboration server for this document.
|
||||
"""
|
||||
user = factories.UserFactory()
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
|
||||
document = factories.DocumentFactory(link_reach="restricted")
|
||||
if via == USER:
|
||||
factories.UserDocumentAccessFactory(document=document, user=user, role=role)
|
||||
elif via == TEAM:
|
||||
mock_user_teams.return_value = ["lasuite", "unknown"]
|
||||
factories.TeamDocumentAccessFactory(
|
||||
document=document, team="lasuite", role=role
|
||||
)
|
||||
|
||||
response = client.get(
|
||||
"/api/v1.0/documents/collaboration-auth/",
|
||||
HTTP_X_ORIGINAL_URL=f"http://localhost/ws/?room={document.pk}",
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
assert response["Authorization"] == "123"
|
||||
assert response["X-Can-Edit"] == str(role != "reader")
|
||||
assert response["X-User-Id"] == str(user.id)
|
||||
@@ -75,15 +75,11 @@ ingressCollaborationWS:
|
||||
## @param ingressCollaborationWS.customBackends Add custom backends to ingress
|
||||
customBackends: []
|
||||
|
||||
## @param ingressCollaborationWS.annotations.nginx.ingress.kubernetes.io/auth-response-headers
|
||||
## @param ingressCollaborationWS.annotations.nginx.ingress.kubernetes.io/auth-url
|
||||
## @param ingressCollaborationWS.annotations.nginx.ingress.kubernetes.io/enable-websocket
|
||||
## @param ingressCollaborationWS.annotations.nginx.ingress.kubernetes.io/proxy-read-timeout
|
||||
## @param ingressCollaborationWS.annotations.nginx.ingress.kubernetes.io/proxy-send-timeout
|
||||
## @param ingressCollaborationWS.annotations.nginx.ingress.kubernetes.io/upstream-hash-by
|
||||
annotations:
|
||||
nginx.ingress.kubernetes.io/auth-response-headers: "Authorization, X-Can-Edit, X-User-Id"
|
||||
nginx.ingress.kubernetes.io/auth-url: https://impress.example.com/api/v1.0/documents/collaboration-auth/
|
||||
nginx.ingress.kubernetes.io/enable-websocket: "true"
|
||||
nginx.ingress.kubernetes.io/proxy-read-timeout: "86400"
|
||||
nginx.ingress.kubernetes.io/proxy-send-timeout: "86400"
|
||||
|
||||
Reference in New Issue
Block a user