maarch: add a webservice for sending a mail response (#27814)

POST /api/mail/response/

   {"mail_id": 1234, "content": "response text content"}
This commit is contained in:
Benjamin Dauvergne 2018-11-07 13:49:31 +01:00
parent 7283ba180a
commit 10c16a0bf6
6 changed files with 102 additions and 6 deletions

View File

@ -103,6 +103,7 @@ setup(
'django-haystack<2.8',
'django-reversion>=2.0',
'django-taggit',
'djangorestframework>=3.3, <3.7',
'requests',
'whoosh',
'XStatic-Select2',

View File

@ -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

View File

@ -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):

View File

@ -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'),
]

View File

@ -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'))

View File

@ -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()