Allow EULA/Privacy policy to be edited through the API (#22522)
* Allow EULA/Privacy policy to be edited through the API
This commit is contained in:
Родитель
66ee580f02
Коммит
f9de2f6f3d
|
@ -894,6 +894,23 @@ This endpoint allows you to fetch an add-on EULA and privacy policy.
|
||||||
:>json object|null privacy_policy: The text of the Privacy Policy, if present (See :ref:`translated fields <api-overview-translations>`).
|
:>json object|null privacy_policy: The text of the Privacy Policy, if present (See :ref:`translated fields <api-overview-translations>`).
|
||||||
|
|
||||||
|
|
||||||
|
----------------------------
|
||||||
|
EULA and Privacy Policy Edit
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
.. _addon-eula-policy-edit:
|
||||||
|
|
||||||
|
This endpoint allows an add-on's EULA and privacy policy to be edited.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
This API requires :doc:`authentication <auth>`, and for the user to be an author of the add-on.
|
||||||
|
|
||||||
|
.. http:patch:: /api/v5/addons/addon/(int:id|string:slug|string:guid)/eula_policy/
|
||||||
|
|
||||||
|
:<json object|null eula: The EULA text (See :ref:`translated fields <api-overview-translations>`).
|
||||||
|
:<json object|null privacy_policy: The privacy policy text (See :ref:`translated fields <api-overview-translations>`).
|
||||||
|
|
||||||
|
|
||||||
--------------
|
--------------
|
||||||
Language Tools
|
Language Tools
|
||||||
--------------
|
--------------
|
||||||
|
|
|
@ -471,6 +471,7 @@ These are `v5` specific changes - `v4` changes apply also.
|
||||||
* 2023-12-07: added ``lang`` parameter to all /abuse/report/ endpoints. https://github.com/mozilla/addons-server/issues/21529
|
* 2023-12-07: added ``lang`` parameter to all /abuse/report/ endpoints. https://github.com/mozilla/addons-server/issues/21529
|
||||||
* 2024-06-20: added ``illegal_category`` parameter to all /abuse/report/ endpoints. https://github.com/mozilla/addons/issues/14870
|
* 2024-06-20: added ``illegal_category`` parameter to all /abuse/report/ endpoints. https://github.com/mozilla/addons/issues/14870
|
||||||
* 2024-06-20: added ``illegal_subcategory`` parameter to all /abuse/report/ endpoints. https://github.com/mozilla/addons/issues/14875
|
* 2024-06-20: added ``illegal_subcategory`` parameter to all /abuse/report/ endpoints. https://github.com/mozilla/addons/issues/14875
|
||||||
|
* 2024-08-08: added support for writing to add-on eula_policy endpoint. https://github.com/mozilla/addons/issues/14927
|
||||||
|
|
||||||
.. _`#11380`: https://github.com/mozilla/addons-server/issues/11380/
|
.. _`#11380`: https://github.com/mozilla/addons-server/issues/11380/
|
||||||
.. _`#11379`: https://github.com/mozilla/addons-server/issues/11379/
|
.. _`#11379`: https://github.com/mozilla/addons-server/issues/11379/
|
||||||
|
|
|
@ -5055,23 +5055,154 @@ class TestAddonViewSetEulaPolicy(TestCase):
|
||||||
response = self.client.get(self.url)
|
response = self.client.get(self.url)
|
||||||
assert response.status_code == 401
|
assert response.status_code == 401
|
||||||
|
|
||||||
def test_policy_none(self):
|
def test_eula_and_policy_none(self):
|
||||||
response = self.client.get(self.url)
|
response = self.client.get(self.url)
|
||||||
assert response.status_code == 200
|
assert response.status_code == 200
|
||||||
data = json.loads(force_str(response.content))
|
data = json.loads(force_str(response.content))
|
||||||
assert data['eula'] is None
|
assert data == {
|
||||||
assert data['privacy_policy'] is None
|
'eula': None,
|
||||||
|
'privacy_policy': None,
|
||||||
|
}
|
||||||
|
|
||||||
def test_policy(self):
|
def test_eula_and_policy(self):
|
||||||
self.addon.eula = {'en-US': 'My Addôn EULA', 'fr': 'Hoüla'}
|
self.addon.eula = {'en-US': 'My Addôn EULA', 'fr': 'Hoüla'}
|
||||||
self.addon.privacy_policy = 'My Prïvacy, My Policy'
|
self.addon.privacy_policy = 'My Prïvacy, My Policy'
|
||||||
self.addon.save()
|
self.addon.save()
|
||||||
response = self.client.get(self.url)
|
response = self.client.get(self.url)
|
||||||
assert response.status_code == 200
|
assert response.status_code == 200
|
||||||
data = json.loads(force_str(response.content))
|
data = json.loads(force_str(response.content))
|
||||||
|
assert list(data.keys()) == ['eula', 'privacy_policy']
|
||||||
assert data['eula'] == {'en-US': 'My Addôn EULA', 'fr': 'Hoüla'}
|
assert data['eula'] == {'en-US': 'My Addôn EULA', 'fr': 'Hoüla'}
|
||||||
assert data['privacy_policy'] == {'en-US': 'My Prïvacy, My Policy'}
|
assert data['privacy_policy'] == {'en-US': 'My Prïvacy, My Policy'}
|
||||||
|
|
||||||
|
def test_update_non_author(self):
|
||||||
|
user = UserProfile.objects.create(username='user')
|
||||||
|
self.client.login_api(user)
|
||||||
|
response = self.client.patch(
|
||||||
|
self.url,
|
||||||
|
{
|
||||||
|
'eula': {
|
||||||
|
'en-US': 'My Updated Add-on EULA in English',
|
||||||
|
'fr': 'Mes Conditions générales d’utilisation',
|
||||||
|
},
|
||||||
|
'privacy_policy': {
|
||||||
|
'en-US': 'My privacy policy',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
assert response.status_code == 403
|
||||||
|
|
||||||
|
response = self.client.put(
|
||||||
|
self.url,
|
||||||
|
{
|
||||||
|
'eula': {
|
||||||
|
'en-US': 'My Updated Add-on EULA in English',
|
||||||
|
'fr': 'Mes Conditions générales d’utilisation',
|
||||||
|
},
|
||||||
|
'privacy_policy': {
|
||||||
|
'en-US': 'My privacy policy',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
assert response.status_code == 405
|
||||||
|
|
||||||
|
def test_update_anonymous(self):
|
||||||
|
response = self.client.patch(
|
||||||
|
self.url,
|
||||||
|
{
|
||||||
|
'eula': {
|
||||||
|
'en-US': 'My Updated Add-on EULA in English',
|
||||||
|
'fr': 'Mes Conditions générales d’utilisation',
|
||||||
|
},
|
||||||
|
'privacy_policy': {
|
||||||
|
'en-US': 'My privacy policy',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
assert response.status_code == 401
|
||||||
|
|
||||||
|
response = self.client.put(
|
||||||
|
self.url,
|
||||||
|
{
|
||||||
|
'eula': {
|
||||||
|
'en-US': 'My Updated Add-on EULA in English',
|
||||||
|
'fr': 'Mes Conditions générales d’utilisation',
|
||||||
|
},
|
||||||
|
'privacy_policy': {
|
||||||
|
'en-US': 'My privacy policy',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
assert response.status_code == 401
|
||||||
|
|
||||||
|
def test_update(self):
|
||||||
|
user = UserProfile.objects.create(username='user')
|
||||||
|
AddonUser.objects.create(user=user, addon=self.addon)
|
||||||
|
self.client.login_api(user)
|
||||||
|
response = self.client.patch(
|
||||||
|
self.url,
|
||||||
|
{
|
||||||
|
'eula': {
|
||||||
|
'en-US': 'My Updated Add-on EULA in English',
|
||||||
|
'fr': 'Mes Conditions générales d’utilisation',
|
||||||
|
},
|
||||||
|
'privacy_policy': {
|
||||||
|
'en-US': 'My privacy policy',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
assert response.status_code == 200
|
||||||
|
data = json.loads(force_str(response.content))
|
||||||
|
assert list(data.keys()) == ['eula', 'privacy_policy']
|
||||||
|
assert data['eula'] == {
|
||||||
|
'en-US': 'My Updated Add-on EULA in English',
|
||||||
|
'fr': 'Mes Conditions générales d’utilisation',
|
||||||
|
}
|
||||||
|
assert data['privacy_policy'] == {
|
||||||
|
'en-US': 'My privacy policy',
|
||||||
|
}
|
||||||
|
self.addon.reload()
|
||||||
|
assert str(self.addon.eula) == 'My Updated Add-on EULA in English'
|
||||||
|
assert str(self.addon.privacy_policy) == 'My privacy policy'
|
||||||
|
with self.activate('fr'):
|
||||||
|
self.addon = Addon.objects.get(pk=self.addon.pk)
|
||||||
|
assert str(self.addon.eula) == 'Mes Conditions générales d’utilisation'
|
||||||
|
assert str(self.addon.privacy_policy) == 'My privacy policy'
|
||||||
|
|
||||||
|
def test_update_put(self):
|
||||||
|
user = UserProfile.objects.create(username='user')
|
||||||
|
AddonUser.objects.create(user=user, addon=self.addon)
|
||||||
|
self.client.login_api(user)
|
||||||
|
response = self.client.put(
|
||||||
|
self.url,
|
||||||
|
{
|
||||||
|
'eula': {
|
||||||
|
'en-US': 'My Updated Add-on EULA in English',
|
||||||
|
'fr': 'Mes Conditions générales d’utilisation',
|
||||||
|
},
|
||||||
|
'privacy_policy': {
|
||||||
|
'en-US': 'My privacy policy',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
assert response.status_code == 405
|
||||||
|
|
||||||
|
def test_update_something_else(self):
|
||||||
|
assert self.addon.summary
|
||||||
|
original_summary = self.addon.summary
|
||||||
|
user = UserProfile.objects.create(username='user')
|
||||||
|
AddonUser.objects.create(user=user, addon=self.addon)
|
||||||
|
self.client.login_api(user)
|
||||||
|
response = self.client.patch(
|
||||||
|
self.url,
|
||||||
|
{'summary': 'attempting to change the summary via wrong endpoint'},
|
||||||
|
)
|
||||||
|
assert response.status_code == 200 # We ignore unknown fields
|
||||||
|
data = json.loads(force_str(response.content))
|
||||||
|
assert data == {'eula': None, 'privacy_policy': None}
|
||||||
|
self.addon.reload()
|
||||||
|
assert self.addon.summary == original_summary
|
||||||
|
|
||||||
|
|
||||||
class TestAddonSearchView(ESTestCase):
|
class TestAddonSearchView(ESTestCase):
|
||||||
client_class = APITestClientSessionID
|
client_class = APITestClientSessionID
|
||||||
|
|
|
@ -19,7 +19,7 @@ from rest_framework.mixins import (
|
||||||
RetrieveModelMixin,
|
RetrieveModelMixin,
|
||||||
UpdateModelMixin,
|
UpdateModelMixin,
|
||||||
)
|
)
|
||||||
from rest_framework.permissions import IsAuthenticated
|
from rest_framework.permissions import SAFE_METHODS, IsAuthenticated
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
from rest_framework.settings import api_settings
|
from rest_framework.settings import api_settings
|
||||||
from rest_framework.views import APIView
|
from rest_framework.views import APIView
|
||||||
|
@ -344,13 +344,22 @@ class AddonViewSet(
|
||||||
def get_georestrictions(self):
|
def get_georestrictions(self):
|
||||||
return [perm() for perm in self.georestriction_classes]
|
return [perm() for perm in self.georestriction_classes]
|
||||||
|
|
||||||
@action(detail=True)
|
@action(
|
||||||
def eula_policy(self, request, pk=None):
|
detail=True,
|
||||||
obj = self.get_object()
|
methods=['get', 'patch'],
|
||||||
serializer = AddonEulaPolicySerializer(
|
serializer_class=AddonEulaPolicySerializer,
|
||||||
obj, context=self.get_serializer_context()
|
# For this action, developers use the same serializer - it only
|
||||||
|
# contains eula/privacy policy.
|
||||||
|
serializer_class_for_developers=AddonEulaPolicySerializer,
|
||||||
)
|
)
|
||||||
return Response(serializer.data)
|
def eula_policy(self, request, pk=None):
|
||||||
|
kwargs = {}
|
||||||
|
if request.method in SAFE_METHODS:
|
||||||
|
method = self.retrieve
|
||||||
|
else:
|
||||||
|
kwargs['partial'] = True
|
||||||
|
method = self.update
|
||||||
|
return method(request, **kwargs)
|
||||||
|
|
||||||
@action(detail=True)
|
@action(detail=True)
|
||||||
def delete_confirm(self, request, *args, **kwargs):
|
def delete_confirm(self, request, *args, **kwargs):
|
||||||
|
|
Загрузка…
Ссылка в новой задаче