0002-remove-contrib.seisin_by_email-43487.patch
passerelle/contrib/seisin_by_email/README | ||
---|---|---|
1 |
Connect Publik with INES : sendSeisinByEmail |
|
2 |
============================================ |
|
3 | ||
4 |
How to use |
|
5 |
---------- |
|
6 | ||
7 |
1) Install python-suds |
|
8 | ||
9 |
2) Add to your settings.py |
|
10 | ||
11 |
# local_settings.py: |
|
12 |
INSTALLED_APPS += ('passerelle.contrib.seisin_by_email',) |
passerelle/contrib/seisin_by_email/migrations/0001_initial.py | ||
---|---|---|
1 |
# -*- coding: utf-8 -*- |
|
2 |
from __future__ import unicode_literals |
|
3 | ||
4 |
from django.db import models, migrations |
|
5 | ||
6 | ||
7 |
class Migration(migrations.Migration): |
|
8 | ||
9 |
dependencies = [ |
|
10 |
('base', '0001_initial'), |
|
11 |
] |
|
12 | ||
13 |
operations = [ |
|
14 |
migrations.CreateModel( |
|
15 |
name='SeisinByEmailManagement', |
|
16 |
fields=[ |
|
17 |
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), |
|
18 |
('title', models.CharField(verbose_name='Title', max_length=50)), |
|
19 |
('slug', models.SlugField(verbose_name='Identifier', unique=True)), |
|
20 |
('description', models.TextField(verbose_name='Description')), |
|
21 |
('wsdl_url', models.CharField(help_text='Seisin-by-Email WSDL URL', max_length=128, verbose_name='WSDL URL')), |
|
22 |
('verify_cert', models.BooleanField(default=True, verbose_name='Check HTTPS Certificate validity')), |
|
23 |
('username', models.CharField(max_length=128, verbose_name='Username', blank=True)), |
|
24 |
('password', models.CharField(max_length=128, verbose_name='Password', blank=True)), |
|
25 |
('keystore', models.FileField(help_text='Certificate and private key in PEM format', upload_to=b'seisin-by-email', null=True, verbose_name='Keystore', blank=True)), |
|
26 |
('users', models.ManyToManyField(to='base.ApiUser', related_name='_seisinbyemailmanagement_users_+', related_query_name='+', blank=True)), |
|
27 |
], |
|
28 |
options={ |
|
29 |
'verbose_name': 'Seisin-by-Email', |
|
30 |
}, |
|
31 |
bases=(models.Model,), |
|
32 |
), |
|
33 |
] |
passerelle/contrib/seisin_by_email/migrations/0002_auto_20151007_0744.py | ||
---|---|---|
1 |
# -*- coding: utf-8 -*- |
|
2 |
from __future__ import unicode_literals |
|
3 | ||
4 |
from django.db import models, migrations |
|
5 | ||
6 | ||
7 |
class Migration(migrations.Migration): |
|
8 | ||
9 |
dependencies = [ |
|
10 |
('seisin_by_email', '0001_initial'), |
|
11 |
] |
|
12 | ||
13 |
operations = [ |
|
14 |
migrations.AlterModelOptions( |
|
15 |
name='seisinbyemailmanagement', |
|
16 |
options={'verbose_name': 'Seisin by Email'}, |
|
17 |
), |
|
18 |
] |
passerelle/contrib/seisin_by_email/migrations/0003_seisinbyemailmanagement_log_level.py | ||
---|---|---|
1 |
# -*- coding: utf-8 -*- |
|
2 |
from __future__ import unicode_literals |
|
3 | ||
4 |
from django.db import models, migrations |
|
5 | ||
6 | ||
7 |
class Migration(migrations.Migration): |
|
8 | ||
9 |
dependencies = [ |
|
10 |
('seisin_by_email', '0002_auto_20151007_0744'), |
|
11 |
] |
|
12 | ||
13 |
operations = [ |
|
14 |
migrations.AddField( |
|
15 |
model_name='seisinbyemailmanagement', |
|
16 |
name='log_level', |
|
17 |
field=models.CharField(default=b'NOTSET', max_length=10, verbose_name='Log Level', choices=[(b'NOTSET', b'NOTSET'), (b'DEBUG', b'DEBUG'), (b'INFO', b'INFO'), (b'WARNING', b'WARNING'), (b'ERROR', b'ERROR'), (b'CRITICAL', b'CRITICAL')]), |
|
18 |
preserve_default=True, |
|
19 |
), |
|
20 |
] |
passerelle/contrib/seisin_by_email/migrations/0004_auto_20170920_0951.py | ||
---|---|---|
1 |
# -*- coding: utf-8 -*- |
|
2 |
from __future__ import unicode_literals |
|
3 | ||
4 |
from django.db import migrations, models |
|
5 | ||
6 | ||
7 |
class Migration(migrations.Migration): |
|
8 | ||
9 |
dependencies = [ |
|
10 |
('seisin_by_email', '0003_seisinbyemailmanagement_log_level'), |
|
11 |
] |
|
12 | ||
13 |
operations = [ |
|
14 |
migrations.AlterField( |
|
15 |
model_name='seisinbyemailmanagement', |
|
16 |
name='slug', |
|
17 |
field=models.SlugField(verbose_name='Identifier', unique=True), |
|
18 |
), |
|
19 |
] |
passerelle/contrib/seisin_by_email/migrations/0005_remove_seisinbyemailmanagement_log_level.py | ||
---|---|---|
1 |
# -*- coding: utf-8 -*- |
|
2 |
# Generated by Django 1.11.12 on 2018-11-19 13:47 |
|
3 |
from __future__ import unicode_literals |
|
4 | ||
5 |
from django.db import migrations |
|
6 | ||
7 | ||
8 |
class Migration(migrations.Migration): |
|
9 | ||
10 |
dependencies = [ |
|
11 |
('seisin_by_email', '0004_auto_20170920_0951'), |
|
12 |
] |
|
13 | ||
14 |
operations = [ |
|
15 |
migrations.RemoveField( |
|
16 |
model_name='seisinbyemailmanagement', |
|
17 |
name='log_level', |
|
18 |
), |
|
19 |
] |
passerelle/contrib/seisin_by_email/models.py | ||
---|---|---|
1 |
# passerelle - uniform access to multiple data sources and services |
|
2 |
# Copyright (C) 2015 Entr'ouvert |
|
3 |
# |
|
4 |
# This program is free software: you can redistribute it and/or modify it |
|
5 |
# under the terms of the GNU Affero General Public License as published |
|
6 |
# by the Free Software Foundation, either version 3 of the License, or |
|
7 |
# (at your option) any later version. |
|
8 |
# |
|
9 |
# This program is distributed in the hope that it will be useful, |
|
10 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 |
# GNU Affero General Public License for more details. |
|
13 |
# |
|
14 |
# You should have received a copy of the GNU Affero General Public License |
|
15 |
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
16 | ||
17 |
from django.core.urlresolvers import reverse |
|
18 |
from django.db import models |
|
19 |
from django.utils.translation import ugettext_lazy as _ |
|
20 | ||
21 |
from passerelle.base.models import BaseResource |
|
22 | ||
23 |
class SeisinByEmailManagement(BaseResource): |
|
24 |
wsdl_url = models.CharField(max_length=128, blank=False, |
|
25 |
verbose_name=_('WSDL URL'), |
|
26 |
help_text=_('Seisin-by-Email WSDL URL')) |
|
27 |
verify_cert = models.BooleanField(default=True, |
|
28 |
verbose_name=_('Check HTTPS Certificate validity')) |
|
29 |
username = models.CharField(max_length=128, blank=True, |
|
30 |
verbose_name=_('Username')) |
|
31 |
password = models.CharField(max_length=128, blank=True, |
|
32 |
verbose_name=_('Password')) |
|
33 |
keystore = models.FileField(upload_to='seisin-by-email', null=True, blank=True, |
|
34 |
verbose_name=_('Keystore'), |
|
35 |
help_text=_('Certificate and private key in PEM format')) |
|
36 | ||
37 |
category = _('Business Process Connectors') |
|
38 | ||
39 |
class Meta: |
|
40 |
verbose_name = _('Seisin by Email') |
|
41 | ||
42 |
@classmethod |
|
43 |
def get_verbose_name(cls): |
|
44 |
return cls._meta.verbose_name |
passerelle/contrib/seisin_by_email/soap.py | ||
---|---|---|
1 |
# passerelle - uniform access to multiple data sources and services |
|
2 |
# Copyright (C) 2015 Entr'ouvert |
|
3 |
# |
|
4 |
# This program is free software: you can redistribute it and/or modify it |
|
5 |
# under the terms of the GNU Affero General Public License as published |
|
6 |
# by the Free Software Foundation, either version 3 of the License, or |
|
7 |
# (at your option) any later version. |
|
8 |
# |
|
9 |
# This program is distributed in the hope that it will be useful, |
|
10 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 |
# GNU Affero General Public License for more details. |
|
13 |
# |
|
14 |
# You should have received a copy of the GNU Affero General Public License |
|
15 |
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
16 | ||
17 |
# borrowed from https://pypi.python.org/pypi/suds_requests |
|
18 |
# and https://docs.oracle.com/cd/E50245_01/E50253/html/vmprg-soap-example-authentication-python.html |
|
19 | ||
20 |
import requests |
|
21 | ||
22 |
from django.conf import settings |
|
23 |
from django.utils.six import StringIO |
|
24 |
from suds.transport.http import HttpAuthenticated |
|
25 |
from suds.transport import Reply |
|
26 |
from suds.client import Client |
|
27 | ||
28 | ||
29 |
class Transport(HttpAuthenticated): |
|
30 |
def __init__(self, model, **kwargs): |
|
31 |
self.model = model |
|
32 |
HttpAuthenticated.__init__(self, **kwargs) # oldstyle class... |
|
33 | ||
34 |
def get_requests_kwargs(self): |
|
35 |
kwargs = {} |
|
36 |
if self.model.username: |
|
37 |
kwargs['auth'] = (self.model.username, self.model.password) |
|
38 |
if self.model.keystore: |
|
39 |
kwargs['cert'] = (self.model.keystore.path, self.model.keystore.path) |
|
40 |
if not self.model.verify_cert: |
|
41 |
kwargs['verify'] = False |
|
42 |
if getattr(settings, 'REQUESTS_PROXIES', None): |
|
43 |
kwargs['proxies'] = settings.REQUESTS_PROXIES |
|
44 |
return kwargs |
|
45 | ||
46 |
def open(self, request): |
|
47 |
resp = requests.get(request.url, headers=request.headers, |
|
48 |
**self.get_requests_kwargs()) |
|
49 |
return StringIO(resp.content) |
|
50 | ||
51 |
def send(self, request): |
|
52 |
self.addcredentials(request) |
|
53 |
resp = requests.post(request.url, data=request.message, |
|
54 |
headers=request.headers, **self.get_requests_kwargs()) |
|
55 |
result = Reply(resp.status_code, resp.headers, resp.content) |
|
56 |
return result |
|
57 | ||
58 | ||
59 |
def get_client(model): |
|
60 |
transport = Transport(model) |
|
61 |
return Client(model.wsdl_url, transport=transport, cache=None) |
passerelle/contrib/seisin_by_email/templates/passerelle/contrib/seisin_by_email/detail.html | ||
---|---|---|
1 |
{% extends "passerelle/manage/service_view.html" %} |
|
2 |
{% load i18n passerelle %} |
|
3 | ||
4 |
{% block description %} |
|
5 |
{% endblock %} |
|
6 | ||
7 |
{% block endpoints %} |
|
8 |
<ul> |
|
9 |
<li>{% trans 'Check WSDL availability:' %} <a href="{% url 'seisin-by-email-ping' slug=object.slug %}" |
|
10 |
>{{ site_base_uri }}{% url 'seisin-by-email-ping' slug=object.slug %}</a>[?debug]</li> |
|
11 |
<li>{% trans 'Send a resource by email:' %} POST <a href="{% url 'seisin-by-email-resource' slug=object.slug %}" |
|
12 |
>{{ site_base_uri }}{% url 'seisin-by-email-resource' slug=object.slug %}</a> (payload: JSON w.c.s. formdata)</li> |
|
13 |
</ul> |
|
14 |
{% endblock %} |
|
15 | ||
16 |
{% block security %} |
|
17 |
<p> |
|
18 |
{% trans 'Access is limited to the following API users:' %} |
|
19 |
</p> |
|
20 |
{% access_rights_table resource=object permission='can_access' %} |
|
21 |
{% endblock %} |
passerelle/contrib/seisin_by_email/urls.py | ||
---|---|---|
1 |
# passerelle - uniform access to multiple data sources and services |
|
2 |
# Copyright (C) 2015 Entr'ouvert |
|
3 |
# |
|
4 |
# This program is free software: you can redistribute it and/or modify it |
|
5 |
# under the terms of the GNU Affero General Public License as published |
|
6 |
# by the Free Software Foundation, either version 3 of the License, or |
|
7 |
# (at your option) any later version. |
|
8 |
# |
|
9 |
# This program is distributed in the hope that it will be useful, |
|
10 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 |
# GNU Affero General Public License for more details. |
|
13 |
# |
|
14 |
# You should have received a copy of the GNU Affero General Public License |
|
15 |
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
16 | ||
17 |
from django.conf.urls import include, url |
|
18 | ||
19 |
from .views import * |
|
20 | ||
21 |
urlpatterns = [ |
|
22 |
url(r'^(?P<slug>[\w,-]+)/$', SeisinByEmailManagementDetailView.as_view(), |
|
23 |
name='seisin-by-email-view'), |
|
24 |
url(r'^(?P<slug>[\w,-]+)/ping/$', PingView.as_view(), |
|
25 |
name='seisin-by-email-ping'), |
|
26 |
url(r'^(?P<slug>[\w,-]+)/resource/$', ResourceView.as_view(), |
|
27 |
name='seisin-by-email-resource'), |
|
28 |
] |
passerelle/contrib/seisin_by_email/views.py | ||
---|---|---|
1 |
# passerelle - uniform access to multiple data sources and services |
|
2 |
# Copyright (C) 2015 Entr'ouvert |
|
3 |
# |
|
4 |
# This program is free software: you can redistribute it and/or modify it |
|
5 |
# under the terms of the GNU Affero General Public License as published |
|
6 |
# by the Free Software Foundation, either version 3 of the License, or |
|
7 |
# (at your option) any later version. |
|
8 |
# |
|
9 |
# This program is distributed in the hope that it will be useful, |
|
10 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 |
# GNU Affero General Public License for more details. |
|
13 |
# |
|
14 |
# You should have received a copy of the GNU Affero General Public License |
|
15 |
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
16 | ||
17 |
from django.views.generic import DetailView as GenericDetailView |
|
18 |
from django.utils.decorators import method_decorator |
|
19 |
from django.views.decorators.csrf import csrf_exempt |
|
20 | ||
21 |
from passerelle.compat import json_loads |
|
22 |
import passerelle.utils as utils |
|
23 |
from passerelle.soap import sudsobject_to_dict, client_to_jsondict |
|
24 | ||
25 |
from .soap import get_client |
|
26 |
from .models import SeisinByEmailManagement |
|
27 | ||
28 | ||
29 |
class SeisinByEmailManagementDetailView(GenericDetailView): |
|
30 |
model = SeisinByEmailManagement |
|
31 |
template_name = 'passerelle/contrib/seisin_by_email/detail.html' |
|
32 | ||
33 | ||
34 |
class DetailView(GenericDetailView): |
|
35 |
model = SeisinByEmailManagement |
|
36 | ||
37 |
def get_client(self): |
|
38 |
return get_client(self.get_object()) |
|
39 | ||
40 |
def get_data(self, request, *args, **kwargs): |
|
41 |
raise NotImplementedError |
|
42 | ||
43 |
@utils.protected_api('can_access') |
|
44 |
def get(self, request, *args, **kwargs): |
|
45 |
data = self.get_data(request, *args, **kwargs) |
|
46 |
return utils.response_for_json(request, data) |
|
47 | ||
48 | ||
49 |
class PingView(DetailView): |
|
50 |
def get_data(self, request, *args, **kwargs): |
|
51 |
client = self.get_client() |
|
52 |
res = {'ping': 'pong'} |
|
53 |
if 'debug' in request.GET: |
|
54 |
res['client'] = client_to_jsondict(client) |
|
55 |
return res |
|
56 | ||
57 | ||
58 |
class ResourceView(DetailView): |
|
59 |
@method_decorator(csrf_exempt) |
|
60 |
def dispatch(self, *args, **kwargs): |
|
61 |
return super(ResourceView, self).dispatch(*args, **kwargs) |
|
62 | ||
63 |
@utils.protected_api('can_access') |
|
64 |
def post(self, request, *args, **kwargs): |
|
65 |
client = self.get_client() |
|
66 |
formdata = json_loads(request.body) |
|
67 |
fields = formdata.get('fields', {}) |
|
68 |
extras = formdata.get('extra', {}) |
|
69 | ||
70 |
debug = 'debug' in request.GET |
|
71 |
if debug: |
|
72 |
debug_output = {} |
|
73 | ||
74 |
# attachment: only one (the first) |
|
75 |
attachmentData = client.factory.create('arrayOfAttachmentContent') |
|
76 |
attachmentData.source = '?' |
|
77 |
for name, value in fields.items(): |
|
78 |
if isinstance(value, dict) and value.get('filename') and value.get('content'): |
|
79 |
attachmentData.fileName = '"%s"' % value['filename'] |
|
80 |
attachmentData.attachmentType = value.get('content_type') |
|
81 |
attachmentData.source = value['content'] |
|
82 |
break |
|
83 | ||
84 |
if debug: |
|
85 |
debug_output['attachmentData'] = '%r' % attachmentData |
|
86 | ||
87 |
# data |
|
88 |
data = client.factory.create('listOfData') |
|
89 |
data.datas = [] |
|
90 |
for name, value in extras.items(): |
|
91 |
if not name.startswith('seisin_by_email_data_'): |
|
92 |
continue |
|
93 |
item = client.factory.create('arrayOfDataContent') |
|
94 |
item.key = name[21:] |
|
95 |
item.value = value |
|
96 |
data.datas.append(item) |
|
97 | ||
98 |
if debug: |
|
99 |
debug_output['data'] = '%r' % data |
|
100 | ||
101 |
# other variables |
|
102 |
departement_number = extras.get('seisin_by_email_departement_number', '') |
|
103 |
target_entity = extras.get('seisin_by_email_target_entity', -1) |
|
104 |
theme = extras.get('seisin_by_email_theme', '') |
|
105 |
userType = extras.get('seisin_by_email_userType', '') |
|
106 |
request_object = extras.get('seisin_by_email_request_object', '') |
|
107 | ||
108 |
if debug: |
|
109 |
debug_output['departement_number'] = departement_number |
|
110 |
debug_output['target_entity'] = target_entity |
|
111 |
debug_output['theme'] = theme |
|
112 |
debug_output['userType'] = userType |
|
113 |
debug_output['request_object'] = request_object |
|
114 | ||
115 |
# call sendSeisinByEmail web service |
|
116 |
results = client.service.sendSeisinByEmail(departement_number, |
|
117 |
target_entity, |
|
118 |
theme, |
|
119 |
userType, |
|
120 |
request_object, |
|
121 |
data, |
|
122 |
attachmentData) |
|
123 |
data = sudsobject_to_dict(results) |
|
124 | ||
125 |
if debug: |
|
126 |
data['debug'] = debug_output |
|
127 | ||
128 |
return utils.response_for_json(request, data) |
tests/settings.py | ||
---|---|---|
29 | 29 |
'passerelle.contrib.meyzieu_newsletters', |
30 | 30 |
'passerelle.contrib.nancypoll', |
31 | 31 |
'passerelle.contrib.planitech', |
32 |
'passerelle.contrib.seisin_by_email', |
|
33 | 32 |
'passerelle.contrib.solis_apa', |
34 | 33 |
'passerelle.contrib.strasbourg_eu', |
35 | 34 |
'passerelle.contrib.stub_invoices', |
36 |
- |