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:
Mathieu Pillard 2024-07-31 12:05:31 +02:00 коммит произвёл GitHub
Родитель 66ee580f02
Коммит f9de2f6f3d
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
4 изменённых файлов: 169 добавлений и 11 удалений

Просмотреть файл

@ -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>`).
----------------------------
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
--------------

Просмотреть файл

@ -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
* 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-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/
.. _`#11379`: https://github.com/mozilla/addons-server/issues/11379/

Просмотреть файл

@ -5055,23 +5055,154 @@ class TestAddonViewSetEulaPolicy(TestCase):
response = self.client.get(self.url)
assert response.status_code == 401
def test_policy_none(self):
def test_eula_and_policy_none(self):
response = self.client.get(self.url)
assert response.status_code == 200
data = json.loads(force_str(response.content))
assert data['eula'] is None
assert data['privacy_policy'] is None
assert data == {
'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.privacy_policy = 'My Prïvacy, My Policy'
self.addon.save()
response = self.client.get(self.url)
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 Addôn EULA', 'fr': 'Hoüla'}
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 dutilisation',
},
'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 dutilisation',
},
'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 dutilisation',
},
'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 dutilisation',
},
'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 dutilisation',
},
'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 dutilisation',
}
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 dutilisation'
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 dutilisation',
},
'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):
client_class = APITestClientSessionID

Просмотреть файл

@ -19,7 +19,7 @@ from rest_framework.mixins import (
RetrieveModelMixin,
UpdateModelMixin,
)
from rest_framework.permissions import IsAuthenticated
from rest_framework.permissions import SAFE_METHODS, IsAuthenticated
from rest_framework.response import Response
from rest_framework.settings import api_settings
from rest_framework.views import APIView
@ -344,13 +344,22 @@ class AddonViewSet(
def get_georestrictions(self):
return [perm() for perm in self.georestriction_classes]
@action(detail=True)
def eula_policy(self, request, pk=None):
obj = self.get_object()
serializer = AddonEulaPolicySerializer(
obj, context=self.get_serializer_context()
@action(
detail=True,
methods=['get', 'patch'],
serializer_class=AddonEulaPolicySerializer,
# 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)
def delete_confirm(self, request, *args, **kwargs):