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:
parent
7283ba180a
commit
10c16a0bf6
1
setup.py
1
setup.py
|
@ -103,6 +103,7 @@ setup(
|
||||||
'django-haystack<2.8',
|
'django-haystack<2.8',
|
||||||
'django-reversion>=2.0',
|
'django-reversion>=2.0',
|
||||||
'django-taggit',
|
'django-taggit',
|
||||||
|
'djangorestframework>=3.3, <3.7',
|
||||||
'requests',
|
'requests',
|
||||||
'whoosh',
|
'whoosh',
|
||||||
'XStatic-Select2',
|
'XStatic-Select2',
|
||||||
|
|
|
@ -18,6 +18,8 @@ import json
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
from django.contrib.auth.models import User
|
||||||
|
|
||||||
from httmock import urlmatch, HTTMock
|
from httmock import urlmatch, HTTMock
|
||||||
|
|
||||||
|
|
||||||
|
@ -153,7 +155,7 @@ def test_utils(maarch):
|
||||||
PDF_MOCK = '%PDF-1.4 ...'
|
PDF_MOCK = '%PDF-1.4 ...'
|
||||||
|
|
||||||
|
|
||||||
def test_feed(app, maarch, wcs, user):
|
def test_feed(settings, app, maarch, wcs, user):
|
||||||
import base64
|
import base64
|
||||||
from django.core.management import call_command
|
from django.core.management import call_command
|
||||||
from django.contrib.contenttypes.models import ContentType
|
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():
|
def test_command_is_noop():
|
||||||
from django.core.management import call_command
|
from django.core.management import call_command
|
||||||
|
|
|
@ -51,6 +51,7 @@ INSTALLED_APPS = (
|
||||||
'welco.contacts',
|
'welco.contacts',
|
||||||
'gadjo',
|
'gadjo',
|
||||||
'xstatic.pkg.select2',
|
'xstatic.pkg.select2',
|
||||||
|
'rest_framework',
|
||||||
)
|
)
|
||||||
|
|
||||||
MIDDLEWARE_CLASSES = (
|
MIDDLEWARE_CLASSES = (
|
||||||
|
@ -227,6 +228,9 @@ PHONE_AUTOTAKE_MELLON_USERNAME = False
|
||||||
# ex: FLAVOURS = ['alfortville']
|
# ex: FLAVOURS = ['alfortville']
|
||||||
FLAVOURS = []
|
FLAVOURS = []
|
||||||
|
|
||||||
|
REST_FRAMEWORK = {}
|
||||||
|
REST_FRAMEWORK['DEFAULT_AUTHENTICATION_CLASSES'] = ['rest_framework.authentication.BasicAuthentication']
|
||||||
|
|
||||||
local_settings_file = os.environ.get('WELCO_SETTINGS_FILE',
|
local_settings_file = os.environ.get('WELCO_SETTINGS_FILE',
|
||||||
os.path.join(os.path.dirname(__file__), 'local_settings.py'))
|
os.path.join(os.path.dirname(__file__), 'local_settings.py'))
|
||||||
if os.path.exists(local_settings_file):
|
if os.path.exists(local_settings_file):
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
from django.conf.urls import url
|
from django.conf.urls import url
|
||||||
|
|
||||||
from .views import (viewer, feeder, qualification_save, edit_note, note,
|
from .views import (viewer, feeder, qualification_save, edit_note, note,
|
||||||
reject, mail_count)
|
reject, mail_count, mail_response)
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url('viewer/$', viewer, name='mail-viewer'),
|
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/edit-note/$', edit_note, name='mail-edit-note'),
|
||||||
url(r'^ajax/mail/note/(?P<pk>\w+)$', note, name='mail-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'^ajax/count/mail/$', mail_count, name='mail-count'),
|
||||||
|
url(r'^api/mail/response/$', mail_response, name='mail-api-response'),
|
||||||
]
|
]
|
||||||
|
|
|
@ -16,18 +16,19 @@
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
|
||||||
from .maarch import MaarchCourrier
|
from .maarch import MaarchCourrier, MaarchError
|
||||||
|
|
||||||
|
|
||||||
class WelcoMaarchCourrier(MaarchCourrier):
|
class WelcoMaarchCourrier(MaarchCourrier):
|
||||||
def __init__(self, url, username, password, grc_status,
|
def __init__(self, url, username, password, grc_status,
|
||||||
grc_received_status, grc_send_status, grc_refused_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)
|
super(WelcoMaarchCourrier, self).__init__(url, username, password)
|
||||||
self.grc_status = grc_status
|
self.grc_status = grc_status
|
||||||
self.grc_received_status = grc_received_status
|
self.grc_received_status = grc_received_status
|
||||||
self.grc_send_status = grc_send_status
|
self.grc_send_status = grc_send_status
|
||||||
self.grc_refused_status = grc_refused_status
|
self.grc_refused_status = grc_refused_status
|
||||||
|
self.grc_response_status = grc_response_status
|
||||||
self.batch_size = batch_size
|
self.batch_size = batch_size
|
||||||
|
|
||||||
def get_mails(self):
|
def get_mails(self):
|
||||||
|
@ -53,6 +54,10 @@ class WelcoMaarchCourrier(MaarchCourrier):
|
||||||
mail = self.Courrier(self, pk=mail_pk)
|
mail = self.Courrier(self, pk=mail_pk)
|
||||||
self.update_status([mail], self.grc_refused_status)
|
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():
|
def get_maarch():
|
||||||
config = getattr(settings, 'MAARCH_FEED', {})
|
config = getattr(settings, 'MAARCH_FEED', {})
|
||||||
|
@ -68,5 +73,6 @@ def get_maarch():
|
||||||
grc_status=config.get('STATUS_GRC', 'GRC'),
|
grc_status=config.get('STATUS_GRC', 'GRC'),
|
||||||
grc_received_status=config.get('STATUS_RECEIVED', 'GRC_TRT'),
|
grc_received_status=config.get('STATUS_RECEIVED', 'GRC_TRT'),
|
||||||
grc_send_status=config.get('STATUS_SEND', 'GRCSENT'),
|
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'))
|
||||||
|
|
||||||
|
|
|
@ -29,11 +29,15 @@ from django.views.decorators.csrf import csrf_exempt
|
||||||
from django.views.generic import TemplateView
|
from django.views.generic import TemplateView
|
||||||
from django.db.transaction import atomic
|
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 welco.utils import response_for_json
|
||||||
|
|
||||||
from .models import Mail
|
from .models import Mail
|
||||||
from .forms import MailQualificationForm
|
from .forms import MailQualificationForm
|
||||||
from .utils import get_maarch
|
from .utils import get_maarch, MaarchError
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
@ -149,3 +153,43 @@ def reject(request, *args, **kwargs):
|
||||||
def mail_count(request, *args, **kwargs):
|
def mail_count(request, *args, **kwargs):
|
||||||
count = Mail.objects.exclude(status__startswith='done-').count()
|
count = Mail.objects.exclude(status__startswith='done-').count()
|
||||||
return response_for_json(request, {'count': 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()
|
||||||
|
|
Loading…
Reference in New Issue