summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Dauvergne <bdauvergne@entrouvert.com>2018-11-07 12:49:31 (GMT)
committerBenjamin Dauvergne <bdauvergne@entrouvert.com>2018-11-16 14:32:16 (GMT)
commit10c16a0bf6c7bce032e1446a2d55ba5b80118fb2 (patch)
tree5b8a8f507615f0da16d2d32fe4cab81029f5d386
parent7283ba180acbbd6a91592246d8f33e3ac380281a (diff)
downloadwelco-0.64.zip
welco-0.64.tar.gz
welco-0.64.tar.bz2
maarch: add a webservice for sending a mail response (#27814)v0.64
POST /api/mail/response/ {"mail_id": 1234, "content": "response text content"}
-rw-r--r--setup.py1
-rw-r--r--tests/test_source_maarch.py42
-rw-r--r--welco/settings.py4
-rw-r--r--welco/sources/mail/urls.py3
-rw-r--r--welco/sources/mail/utils.py12
-rw-r--r--welco/sources/mail/views.py46
6 files changed, 102 insertions, 6 deletions
diff --git a/setup.py b/setup.py
index e5e6b92..bdf3a32 100644
--- a/setup.py
+++ b/setup.py
@@ -103,6 +103,7 @@ setup(
'django-haystack<2.8',
'django-reversion>=2.0',
'django-taggit',
+ 'djangorestframework>=3.3, <3.7',
'requests',
'whoosh',
'XStatic-Select2',
diff --git a/tests/test_source_maarch.py b/tests/test_source_maarch.py
index 2d2dcdf..d01c924 100644
--- a/tests/test_source_maarch.py
+++ b/tests/test_source_maarch.py
@@ -18,6 +18,8 @@ import json
import pytest
+from django.contrib.auth.models import User
+
from httmock import urlmatch, HTTMock
@@ -153,7 +155,7 @@ def test_utils(maarch):
PDF_MOCK = '%PDF-1.4 ...'
-def test_feed(app, maarch, wcs, user):
+def test_feed(settings, app, maarch, wcs, user):
import base64
from django.core.management import call_command
from django.contrib.contenttypes.models import ContentType
@@ -241,6 +243,44 @@ def test_feed(app, maarch, wcs, user):
]
}
+ # verify we can answer
+ maarch.clear()
+ app.set_user(None)
+ user = User.objects.create(username='test')
+ user.set_password('test')
+ user.save()
+ # verify authentication error
+ response = app.post_json('/api/mail/response/', params={}, status=401)
+ app.authorization = ('Basic', ('test', 'test'))
+ # verify serializer error
+ response = app.post_json('/api/mail/response/', params={}, status=400)
+ assert response.json['err'] == 1
+ # verify error when maarch feed is not configured
+ settings.MAARCH_FEED['ENABLE'] = False
+ response = app.post_json('/api/mail/response/',
+ params={'mail_id': 'maarch-1', 'content': 'coucou'},
+ status=200)
+ assert response.json['err'] == 1
+ assert response.json['err_desc'] == 'maarch is unconfigured'
+ settings.MAARCH_FEED['ENABLE'] = True
+ # verify error when mail_id is unknown
+ response = app.post_json('/api/mail/response/',
+ params={'mail_id': 'maarch-231', 'content': 'coucou'},
+ status=404)
+ assert response.json['err'] == 1
+
+ # successfull call
+ maarch.responses.append({})
+ with maarch.ctx_manager:
+ response = app.post_json('/api/mail/response/',
+ params={'mail_id': 'maarch-1', 'content': 'coucou'},
+ status=200)
+ assert maarch.requests[0][3] == {
+ 'historyMessage': 'coucou',
+ 'resId': [1],
+ 'status': 'GRC_RESPONSE',
+ }
+
def test_command_is_noop():
from django.core.management import call_command
diff --git a/welco/settings.py b/welco/settings.py
index aaa5f23..28d427a 100644
--- a/welco/settings.py
+++ b/welco/settings.py
@@ -51,6 +51,7 @@ INSTALLED_APPS = (
'welco.contacts',
'gadjo',
'xstatic.pkg.select2',
+ 'rest_framework',
)
MIDDLEWARE_CLASSES = (
@@ -227,6 +228,9 @@ PHONE_AUTOTAKE_MELLON_USERNAME = False
# ex: FLAVOURS = ['alfortville']
FLAVOURS = []
+REST_FRAMEWORK = {}
+REST_FRAMEWORK['DEFAULT_AUTHENTICATION_CLASSES'] = ['rest_framework.authentication.BasicAuthentication']
+
local_settings_file = os.environ.get('WELCO_SETTINGS_FILE',
os.path.join(os.path.dirname(__file__), 'local_settings.py'))
if os.path.exists(local_settings_file):
diff --git a/welco/sources/mail/urls.py b/welco/sources/mail/urls.py
index d37bb82..272c250 100644
--- a/welco/sources/mail/urls.py
+++ b/welco/sources/mail/urls.py
@@ -17,7 +17,7 @@
from django.conf.urls import url
from .views import (viewer, feeder, qualification_save, edit_note, note,
- reject, mail_count)
+ reject, mail_count, mail_response)
urlpatterns = [
url('viewer/$', viewer, name='mail-viewer'),
@@ -27,4 +27,5 @@ urlpatterns = [
url(r'^ajax/mail/edit-note/$', edit_note, name='mail-edit-note'),
url(r'^ajax/mail/note/(?P<pk>\w+)$', note, name='mail-note'),
url(r'^ajax/count/mail/$', mail_count, name='mail-count'),
+ url(r'^api/mail/response/$', mail_response, name='mail-api-response'),
]
diff --git a/welco/sources/mail/utils.py b/welco/sources/mail/utils.py
index 6c59add..babb71a 100644
--- a/welco/sources/mail/utils.py
+++ b/welco/sources/mail/utils.py
@@ -16,18 +16,19 @@
from django.conf import settings
-from .maarch import MaarchCourrier
+from .maarch import MaarchCourrier, MaarchError
class WelcoMaarchCourrier(MaarchCourrier):
def __init__(self, url, username, password, grc_status,
grc_received_status, grc_send_status, grc_refused_status,
- batch_size=10):
+ grc_response_status, batch_size=10):
super(WelcoMaarchCourrier, self).__init__(url, username, password)
self.grc_status = grc_status
self.grc_received_status = grc_received_status
self.grc_send_status = grc_send_status
self.grc_refused_status = grc_refused_status
+ self.grc_response_status = grc_response_status
self.batch_size = batch_size
def get_mails(self):
@@ -53,6 +54,10 @@ class WelcoMaarchCourrier(MaarchCourrier):
mail = self.Courrier(self, pk=mail_pk)
self.update_status([mail], self.grc_refused_status)
+ def set_grc_response_status(self, mail_pk, history_message):
+ mail = self.Courrier(self, pk=mail_pk)
+ self.update_status([mail], self.grc_response_status, history_message)
+
def get_maarch():
config = getattr(settings, 'MAARCH_FEED', {})
@@ -68,5 +73,6 @@ def get_maarch():
grc_status=config.get('STATUS_GRC', 'GRC'),
grc_received_status=config.get('STATUS_RECEIVED', 'GRC_TRT'),
grc_send_status=config.get('STATUS_SEND', 'GRCSENT'),
- grc_refused_status=config.get('STATUS_REFUSED', 'GRCREFUSED'))
+ grc_refused_status=config.get('STATUS_REFUSED', 'GRCREFUSED'),
+ grc_response_status=config.get('STATUS_REFUSED', 'GRC_RESPONSE'))
diff --git a/welco/sources/mail/views.py b/welco/sources/mail/views.py
index d162019..8a7b1fb 100644
--- a/welco/sources/mail/views.py
+++ b/welco/sources/mail/views.py
@@ -29,11 +29,15 @@ from django.views.decorators.csrf import csrf_exempt
from django.views.generic import TemplateView
from django.db.transaction import atomic
+from rest_framework import authentication, serializers, permissions, status
+from rest_framework.generics import GenericAPIView
+from rest_framework.response import Response
+
from welco.utils import response_for_json
from .models import Mail
from .forms import MailQualificationForm
-from .utils import get_maarch
+from .utils import get_maarch, MaarchError
logger = logging.getLogger(__name__)
@@ -149,3 +153,43 @@ def reject(request, *args, **kwargs):
def mail_count(request, *args, **kwargs):
count = Mail.objects.exclude(status__startswith='done-').count()
return response_for_json(request, {'count': count})
+
+
+class NotificationSerializer(serializers.Serializer):
+ mail_id = serializers.CharField()
+ content = serializers.CharField()
+
+
+class MailResponseAPIView(GenericAPIView):
+ permission_classes = (permissions.IsAuthenticated,)
+ serializer_class = NotificationSerializer
+
+ def post(self, request, *args, **kwargs):
+ serializer = self.get_serializer(data=request.data)
+ if not serializer.is_valid():
+ response = {'err': 1, 'err_desc': serializer.errors}
+ return Response(response, status.HTTP_400_BAD_REQUEST)
+ mail_id = serializer.validated_data['mail_id']
+ content = serializer.validated_data['content']
+ # for now, we only support maarch
+ if not mail_id.startswith('maarch-'):
+ response = {'err': 1, 'err_desc': 'only maarch is supported'}
+ return Response(response)
+ mail = Mail.objects.filter(external_id=mail_id).first()
+ if not mail:
+ response = {'err': 1, 'err_desc': 'unknown mail_id'}
+ return Response(response, status.HTTP_404_NOT_FOUND)
+ return self.maarch_response(mail, content)
+
+ def maarch_response(self, mail, content):
+ maarch = get_maarch()
+ if not maarch:
+ return Response({'err': 1, 'err_desc': 'maarch is unconfigured'})
+ mail_pk = int(mail.external_id.split('-', 1)[1])
+ try:
+ maarch.set_grc_response_status(mail_pk, content)
+ except MaarchError as e:
+ return Response({'err': 1, 'err_desc': str(e)})
+ return Response({'err': 0})
+
+mail_response = MailResponseAPIView.as_view()