From 8c0c92e30c17ab34a3ba0b3b8188a9f178772398 Mon Sep 17 00:00:00 2001
From: Thomas NOEL <tnoel@entrouvert.com>
Date: Fri, 29 May 2020 21:21:35 +0200
Subject: [PATCH 1/2] remove contrib.maarch (#43487)

---
 passerelle/contrib/maarch/README              |  15 -
 passerelle/contrib/maarch/__init__.py         |   0
 .../contrib/maarch/migrations/0001_initial.py |  33 ---
 .../migrations/0002_management_log_level.py   |  20 --
 .../0003_rename_maarch_model_20160624_0329.py |  19 --
 .../migrations/0004_auto_20170920_0951.py     |  19 --
 .../0005_remove_maarch_log_level.py           |  19 --
 .../contrib/maarch/migrations/__init__.py     |   0
 passerelle/contrib/maarch/models.py           |  44 ---
 passerelle/contrib/maarch/soap.py             |  61 ----
 .../passerelle/contrib/maarch/detail.html     |  21 --
 passerelle/contrib/maarch/urls.py             |  28 --
 passerelle/contrib/maarch/views.py            | 269 ------------------
 passerelle/static/css/style.css               |   4 -
 tests/settings.py                             |   1 -
 tests/test_generic_endpoint.py                |   4 +-
 16 files changed, 2 insertions(+), 555 deletions(-)
 delete mode 100644 passerelle/contrib/maarch/README
 delete mode 100644 passerelle/contrib/maarch/__init__.py
 delete mode 100644 passerelle/contrib/maarch/migrations/0001_initial.py
 delete mode 100644 passerelle/contrib/maarch/migrations/0002_management_log_level.py
 delete mode 100644 passerelle/contrib/maarch/migrations/0003_rename_maarch_model_20160624_0329.py
 delete mode 100644 passerelle/contrib/maarch/migrations/0004_auto_20170920_0951.py
 delete mode 100644 passerelle/contrib/maarch/migrations/0005_remove_maarch_log_level.py
 delete mode 100644 passerelle/contrib/maarch/migrations/__init__.py
 delete mode 100644 passerelle/contrib/maarch/models.py
 delete mode 100644 passerelle/contrib/maarch/soap.py
 delete mode 100644 passerelle/contrib/maarch/templates/passerelle/contrib/maarch/detail.html
 delete mode 100644 passerelle/contrib/maarch/urls.py
 delete mode 100644 passerelle/contrib/maarch/views.py

diff --git a/passerelle/contrib/maarch/README b/passerelle/contrib/maarch/README
deleted file mode 100644
index ea6a75f5..00000000
--- a/passerelle/contrib/maarch/README
+++ /dev/null
@@ -1,15 +0,0 @@
-Connect Publik with Maarch LetterBox
-====================================
-
-Compatible with Maarch 1.4 SOAP webservices.
-http://maarchcourrier.com/
-
-How to use
-----------
-
-1) Install python-suds
-
-2) Add to your settings.py
-
-# local_settings.py:
-INSTALLED_APPS += ('passerelle.contrib.maarch',)
diff --git a/passerelle/contrib/maarch/__init__.py b/passerelle/contrib/maarch/__init__.py
deleted file mode 100644
index e69de29b..00000000
diff --git a/passerelle/contrib/maarch/migrations/0001_initial.py b/passerelle/contrib/maarch/migrations/0001_initial.py
deleted file mode 100644
index 197d0559..00000000
--- a/passerelle/contrib/maarch/migrations/0001_initial.py
+++ /dev/null
@@ -1,33 +0,0 @@
-# -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
-from django.db import models, migrations
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('base', '0001_initial'),
-    ]
-
-    operations = [
-        migrations.CreateModel(
-            name='Management',
-            fields=[
-                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
-                ('title', models.CharField(verbose_name='Title', max_length=50)),
-                ('slug', models.SlugField(verbose_name='Identifier', unique=True)),
-                ('description', models.TextField(verbose_name='Description')),
-                ('wsdl_url', models.CharField(help_text='Maarch WSDL URL', max_length=128, verbose_name='WSDL URL')),
-                ('verify_cert', models.BooleanField(default=True, verbose_name='Check HTTPS Certificate validity')),
-                ('username', models.CharField(max_length=128, verbose_name='Username', blank=True)),
-                ('password', models.CharField(max_length=128, verbose_name='Password', blank=True)),
-                ('keystore', models.FileField(help_text='Certificate and private key in PEM format', upload_to=b'maarch', null=True, verbose_name='Keystore', blank=True)),
-                ('users', models.ManyToManyField(to='base.ApiUser', related_name='_management_users_+', related_query_name='+', blank=True)),
-            ],
-            options={
-                'verbose_name': 'Maarch',
-            },
-            bases=(models.Model,),
-        ),
-    ]
diff --git a/passerelle/contrib/maarch/migrations/0002_management_log_level.py b/passerelle/contrib/maarch/migrations/0002_management_log_level.py
deleted file mode 100644
index ebe3fa24..00000000
--- a/passerelle/contrib/maarch/migrations/0002_management_log_level.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
-from django.db import models, migrations
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('maarch', '0001_initial'),
-    ]
-
-    operations = [
-        migrations.AddField(
-            model_name='management',
-            name='log_level',
-            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')]),
-            preserve_default=True,
-        ),
-    ]
diff --git a/passerelle/contrib/maarch/migrations/0003_rename_maarch_model_20160624_0329.py b/passerelle/contrib/maarch/migrations/0003_rename_maarch_model_20160624_0329.py
deleted file mode 100644
index 621666f6..00000000
--- a/passerelle/contrib/maarch/migrations/0003_rename_maarch_model_20160624_0329.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
-from django.db import models, migrations
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('base', '0002_auto_20151009_0326'),
-        ('maarch', '0002_management_log_level'),
-    ]
-
-    operations = [
-        migrations.RenameModel(
-            'Management',
-            'Maarch'
-        ),
-    ]
diff --git a/passerelle/contrib/maarch/migrations/0004_auto_20170920_0951.py b/passerelle/contrib/maarch/migrations/0004_auto_20170920_0951.py
deleted file mode 100644
index b435359b..00000000
--- a/passerelle/contrib/maarch/migrations/0004_auto_20170920_0951.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('maarch', '0003_rename_maarch_model_20160624_0329'),
-    ]
-
-    operations = [
-        migrations.AlterField(
-            model_name='maarch',
-            name='slug',
-            field=models.SlugField(verbose_name='Identifier', unique=True),
-        ),
-    ]
diff --git a/passerelle/contrib/maarch/migrations/0005_remove_maarch_log_level.py b/passerelle/contrib/maarch/migrations/0005_remove_maarch_log_level.py
deleted file mode 100644
index d12a9fdd..00000000
--- a/passerelle/contrib/maarch/migrations/0005_remove_maarch_log_level.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.11.12 on 2018-11-19 13:42
-from __future__ import unicode_literals
-
-from django.db import migrations
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('maarch', '0004_auto_20170920_0951'),
-    ]
-
-    operations = [
-        migrations.RemoveField(
-            model_name='maarch',
-            name='log_level',
-        ),
-    ]
diff --git a/passerelle/contrib/maarch/migrations/__init__.py b/passerelle/contrib/maarch/migrations/__init__.py
deleted file mode 100644
index e69de29b..00000000
diff --git a/passerelle/contrib/maarch/models.py b/passerelle/contrib/maarch/models.py
deleted file mode 100644
index 7cb1d53f..00000000
--- a/passerelle/contrib/maarch/models.py
+++ /dev/null
@@ -1,44 +0,0 @@
-# passerelle - uniform access to multiple data sources and services
-# Copyright (C) 2015  Entr'ouvert
-#
-# This program is free software: you can redistribute it and/or modify it
-# under the terms of the GNU Affero General Public License as published
-# by the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-from django.core.urlresolvers import reverse
-from django.db import models
-from django.utils.translation import ugettext_lazy as _
-
-from passerelle.base.models import BaseResource
-
-class Maarch(BaseResource):
-    wsdl_url = models.CharField(max_length=128, blank=False,
-            verbose_name=_('WSDL URL'),
-            help_text=_('Maarch WSDL URL'))
-    verify_cert = models.BooleanField(default=True,
-            verbose_name=_('Check HTTPS Certificate validity'))
-    username = models.CharField(max_length=128, blank=True,
-            verbose_name=_('Username'))
-    password = models.CharField(max_length=128, blank=True,
-            verbose_name=_('Password'))
-    keystore = models.FileField(upload_to='maarch', null=True, blank=True,
-            verbose_name=_('Keystore'),
-            help_text=_('Certificate and private key in PEM format'))
-
-    category = _('Business Process Connectors')
-
-    class Meta:
-        verbose_name = _('Maarch')
-
-    @classmethod
-    def get_verbose_name(cls):
-        return cls._meta.verbose_name
diff --git a/passerelle/contrib/maarch/soap.py b/passerelle/contrib/maarch/soap.py
deleted file mode 100644
index ac2cd7dd..00000000
--- a/passerelle/contrib/maarch/soap.py
+++ /dev/null
@@ -1,61 +0,0 @@
-# passerelle - uniform access to multiple data sources and services
-# Copyright (C) 2015  Entr'ouvert
-#
-# This program is free software: you can redistribute it and/or modify it
-# under the terms of the GNU Affero General Public License as published
-# by the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-# borrowed from https://pypi.python.org/pypi/suds_requests
-# and https://docs.oracle.com/cd/E50245_01/E50253/html/vmprg-soap-example-authentication-python.html
-
-import requests
-
-from django.conf import settings
-from django.utils.six import StringIO
-from suds.transport.http import HttpAuthenticated
-from suds.transport import Reply
-from suds.client import Client
-
-
-class Transport(HttpAuthenticated):
-    def __init__(self, model, **kwargs):
-        self.model = model
-        HttpAuthenticated.__init__(self, **kwargs) # oldstyle class...
-
-    def get_requests_kwargs(self):
-        kwargs = {}
-        if self.model.username:
-            kwargs['auth'] = (self.model.username, self.model.password)
-        if self.model.keystore:
-            kwargs['cert'] = (self.model.keystore.path, self.model.keystore.path)
-        if not self.model.verify_cert:
-            kwargs['verify'] = False
-        if settings.REQUESTS_PROXIES:
-            kwargs['proxies'] = settings.REQUESTS_PROXIES
-        return kwargs
-
-    def open(self, request):
-        resp = requests.get(request.url, headers=request.headers,
-                **self.get_requests_kwargs())
-        return StringIO(resp.content)
-
-    def send(self, request):
-        self.addcredentials(request)
-        resp = requests.post(request.url, data=request.message,
-                headers=request.headers, **self.get_requests_kwargs())
-        result = Reply(resp.status_code, resp.headers, resp.content)
-        return result
-
-
-def get_client(model):
-    transport = Transport(model)
-    return Client(model.wsdl_url, transport=transport, cache=None)
diff --git a/passerelle/contrib/maarch/templates/passerelle/contrib/maarch/detail.html b/passerelle/contrib/maarch/templates/passerelle/contrib/maarch/detail.html
deleted file mode 100644
index dec3ad7d..00000000
--- a/passerelle/contrib/maarch/templates/passerelle/contrib/maarch/detail.html
+++ /dev/null
@@ -1,21 +0,0 @@
-{% extends "passerelle/manage/service_view.html" %}
-{% load i18n passerelle %}
-
-{% block description %}
-{% endblock %}
-
-{% block endpoints %}
-<ul>
-<li>{% trans 'Check WSDL availability:' %} <a href="{% url 'maarch-ping' slug=object.slug %}"
-        >{{ site_base_uri }}{% url 'maarch-ping' slug=object.slug %}</a>[?debug]</li>
-<li>{% trans 'Store a resource:' %} POST <a href="{% url 'maarch-resource' slug=object.slug %}"
-        >{{ site_base_uri }}{% url 'maarch-resource' slug=object.slug %}</a> (payload: JSON w.c.s. formdata)</li>
-</ul>
-{% endblock %}
-
-{% block security %}
-<p>
-{% trans 'Access is limited to the following API users:' %}
-</p>
-{% access_rights_table resource=object permission='can_access' %}
-{% endblock %}
diff --git a/passerelle/contrib/maarch/urls.py b/passerelle/contrib/maarch/urls.py
deleted file mode 100644
index dacf7321..00000000
--- a/passerelle/contrib/maarch/urls.py
+++ /dev/null
@@ -1,28 +0,0 @@
-# passerelle - uniform access to multiple data sources and services
-# Copyright (C) 2015  Entr'ouvert
-#
-# This program is free software: you can redistribute it and/or modify it
-# under the terms of the GNU Affero General Public License as published
-# by the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-from django.conf.urls import include, url
-
-from .views import *
-
-urlpatterns = [
-    url(r'^(?P<slug>[\w,-]+)/$', MaarchDetailView.as_view(),
-        name='maarch-view'),
-    url(r'^(?P<slug>[\w,-]+)/ping/$', PingView.as_view(),
-        name='maarch-ping'),
-    url(r'^(?P<slug>[\w,-]+)/resource/$', ResourceView.as_view(),
-        name='maarch-resource'),
-]
diff --git a/passerelle/contrib/maarch/views.py b/passerelle/contrib/maarch/views.py
deleted file mode 100644
index ca2d692f..00000000
--- a/passerelle/contrib/maarch/views.py
+++ /dev/null
@@ -1,269 +0,0 @@
-# passerelle - uniform access to multiple data sources and services
-# Copyright (C) 2015  Entr'ouvert
-#
-# This program is free software: you can redistribute it and/or modify it
-# under the terms of the GNU Affero General Public License as published
-# by the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-import requests
-from datetime import datetime
-import logging
-
-from django.views.generic import DetailView as GenericDetailView
-from django.utils.decorators import method_decorator
-from django.utils.six.moves.urllib import parse as urlparse
-from django.views.decorators.csrf import csrf_exempt
-
-from passerelle.compat import json_loads
-import passerelle.utils as utils
-from passerelle.soap import sudsobject_to_dict, client_to_jsondict
-
-from .soap import get_client
-from .models import Maarch
-
-logger = logging.getLogger('passerelle.contrib.maarch')
-
-class MaarchException(Exception):
-    pass
-
-class MaarchDetailView(GenericDetailView):
-    model = Maarch
-    template_name = 'passerelle/contrib/maarch/detail.html'
-
-
-class DetailView(GenericDetailView):
-    model = Maarch
-
-    def get_client(self):
-        return get_client(self.get_object())
-
-    def get_data(self, request, *args, **kwargs):
-        raise NotImplementedError
-
-    @utils.protected_api('can_access')
-    def get(self, request, *args, **kwargs):
-        data = self.get_data(request, *args, **kwargs)
-        return utils.response_for_json(request, data)
-
-
-class PingView(DetailView):
-    def get_data(self, request, *args, **kwargs):
-        client = self.get_client()
-        res = {'ping': 'pong'}
-        if 'debug' in request.GET:
-            res['client'] = client_to_jsondict(client)
-        return res
-
-
-class ResourceView(DetailView):
-    @method_decorator(csrf_exempt)
-    def dispatch(self, *args, **kwargs):
-        return super(ResourceView, self).dispatch(*args, **kwargs)
-
-    @utils.protected_api('can_access')
-    def post(self, request, *args, **kwargs):
-        client = self.get_client()
-        formdata = json_loads(request.body)
-        extras = formdata.get('extra', {})
-
-        debug = 'debug' in request.GET
-        if debug:
-            debug_output = {}
-
-        # get formdef schema from wcs API
-        url = formdata['url']
-        p = urlparse.urlsplit(url)
-        scheme, netloc, path, query, fragment = \
-            p.scheme, p.netloc, p.path, p.query, p.fragment
-        schema_path = path.rsplit('/', 2)[0] + '/schema'
-        schema_url = urlparse.urlunsplit((scheme, netloc, schema_path, query, fragment))
-        schema = requests.get(schema_url).json()
-
-        # storeAttachmentResource attachments: list, build from formdata file fields
-        attachments = []
-
-        #
-        # build document (encodedFile and fileFormat)
-        #
-
-        document = u'<html>'
-        document += u'<head><meta charset="utf-8"></head>'
-        document += '<body>'
-        document += u'<h1>%s</h1>' % schema['name']
-        page = ''
-        empty_page = True
-        for field in schema['fields']:
-            if field['type'] == 'page':
-                # add last page, if it contains values
-                if page and not empty_page:
-                    document += page
-                page = u'<hr /><h2>%s</h2>' % field['label']
-                empty_page = True
-            elif field['type'] == 'title':
-                page += u'<h3>%s</h3>' % field['label']
-            elif 'varname' in field:
-                varname = field['varname']
-                value = formdata['fields'].get(varname)
-                if not value:
-                    continue
-                if field['type'] == 'file':
-                    # field is a file: add it to attachments list
-                    value['fileFormat'] = value['content_type'].split('/')[1] # FIXME (how ?)
-                    attachments.append(value)
-                    value = '%s' % value['filename']
-                page += u'<dl>'
-                page += u'<dt>%s</dt>' % field['label']
-                page += u'<dd>%s</dd>' % value
-                page += u'</dl>'
-                empty_page = False
-        if page and not empty_page: # add last page, if it contains values
-            document += page
-        document += u'</body></html>'
-        encodedFile = document.encode('utf-8').encode('base64')
-        fileFormat = 'html'
-
-        if debug:
-            debug_output['document'] = document
-
-        #
-        # build metadata for storeResource and storeExtResource
-        #
-
-        # storeResource metadata
-        metadata = {}
-        # storeExtResource metadata
-        ext_metadata = {}
-
-        # extract metadata and ext_metadata from formdata['extra']
-        for name, value in extras.items():
-            if name.startswith('maarch_metadata_'):
-                metadata[name[16:]] = value
-            if name.startswith('maarch_ext_metadata_'):
-                ext_metadata[name[20:]] = value
-
-        # prepare metadata for SOAP call
-        def prepare_soap_metadata(metadata):
-            datas = []
-            for name, value in metadata.items():
-                data = client.factory.create('arrayOfDataContent')
-                data.column = name
-                if name.endswith('_date'):
-                    data.type = 'date'
-                    value = datetime.strptime(value[:19], '%Y-%m-%dT%H:%M:%S')
-                    value = value.strftime('%d-%m-%Y %H:%M:%S')
-                elif isinstance(value, basestring):
-                    data.type = 'string'
-                elif isinstance(value, int):
-                    data.type = 'int'
-                elif isinstance(value, float):
-                    data.type = 'float'
-                elif value is None:
-                    data.type = 'string'
-                    value = ''
-                data.value = value
-                datas.append(data)
-            soap_metadata = client.factory.create('arrayOfData')
-            soap_metadata.datas = datas
-            return soap_metadata
-
-        metadata = prepare_soap_metadata(metadata)
-        ext_metadata = prepare_soap_metadata(ext_metadata)
-
-        if debug:
-            debug_output['metadata'] = '%r' % metadata
-            debug_output['ext_metadata'] = '%r' % ext_metadata
-
-        #
-        # get other Maarch variables (letterbox configuration by default)
-        #
-
-        collId = extras.get('maarch_collId') or 'letterbox_coll'
-        table = extras.get('maarch_table') or 'res_letterbox'
-        status = extras.get('maarch_status') or 'ATT'
-        ext_table = extras.get('maarch_ext_table') or 'mlb_coll_ext'
-
-        if debug:
-            debug_output['collId'] = collId
-            debug_output['table'] = table
-            debug_output['status'] = status
-            debug_output['ext_table'] = ext_table
-
-        # if INES ESB (Tibco) between passerelle and Maarch, add a "maarch_id"
-        # parameter. Get value from formdata or workflow options.
-        maarch_id = extras.get('maarch_id')
-
-        if debug:
-            debug_output['maarch_id'] = maarch_id
-
-        #
-        # call Maarch web services
-        #
-        logger.debug('storeResource+Ext+Attachment: start')
-
-        # store the resource (storeResource)
-        logger.debug('storeResource: encodedFile(size):%r fileFormat:%r '
-                     'collId:%r table:%r status:%r', len(encodedFile),
-                        fileFormat, collId, table, status)
-        logger.debug('storeResource: metadata: %r', metadata)
-        if maarch_id:
-            logger.debug('storeResource: INES maarch_id: %r', maarch_id)
-            results = client.service.storeResource(
-                    maarch_id,
-                    encodedFile, metadata, collId,
-                    table, fileFormat, status)
-        else:
-            results = client.service.storeResource(
-                    encodedFile, metadata, collId,
-                    table, fileFormat, status)
-        data = sudsobject_to_dict(results)
-        logger.debug('storeResource result: %r', data)
-
-        resId = data.get('resId')
-        if not resId:
-            raise MaarchException('no resId after storeResource')
-        logger.debug('storeResource result: resId:%r', resId)
-
-        logger.debug('storeExtResource: resId:%r ext_table:%r', resId,
-                     ext_table)
-        logger.debug('storeExtResource: ext_metadata: %r', ext_metadata)
-        # store external metadata (storeExtResource)
-        if maarch_id:
-            logger.debug('storeExtResource: INES maarch_id: %r', maarch_id)
-            results = client.service.storeExtResource(
-                    maarch_id,
-                    resId, ext_metadata, ext_table)
-        else:
-            results = client.service.storeExtResource(
-                    resId, ext_metadata, ext_table)
-
-        # store attachments
-        for attachment in attachments:
-            logger.debug('storeAttachmentResource: resId:%r collId:%r '
-                         'content(size):%r fileFormat:%r filename:%r', resId,
-                             collId, len(attachment['content']),
-                             attachment['fileFormat'], attachment['filename'])
-            if maarch_id:
-                logger.debug('storeAttachmentResource: INES maarch_id: %r', maarch_id)
-                client.service.storeAttachmentResource(
-                        maarch_id,
-                        resId, collId, attachment['content'],
-                        attachment['fileFormat'], attachment['filename'])
-            else:
-                client.service.storeAttachmentResource(
-                        resId, collId, attachment['content'],
-                        attachment['fileFormat'], attachment['filename'])
-
-        if debug:
-            data['debug'] = debug_output
-
-        logger.debug('storeResource+Ext+Attachment: resId:%r -- end', resId)
-        return utils.response_for_json(request, data)
diff --git a/passerelle/static/css/style.css b/passerelle/static/css/style.css
index 4ffdc996..107a8e9b 100644
--- a/passerelle/static/css/style.css
+++ b/passerelle/static/css/style.css
@@ -157,10 +157,6 @@ li.connector.clicrdv a::before {
 	content: "\f073"; /* calendar */
 }
 
-li.connector.maarch a::before {
-	content: "\f0e0"; /* envelope */
-}
-
 li.connector.cmisconnector a::before {
 	content: "\f15b"; /* file */
 }
diff --git a/tests/settings.py b/tests/settings.py
index 56ce06ef..d0fab79d 100644
--- a/tests/settings.py
+++ b/tests/settings.py
@@ -25,7 +25,6 @@ INSTALLED_APPS += (
     'passerelle.contrib.iparapheur',
     'passerelle.contrib.iws',
     'passerelle.contrib.lille_urban_card',
-    'passerelle.contrib.maarch',
     'passerelle.contrib.mdph13',
     'passerelle.contrib.meyzieu_newsletters',
     'passerelle.contrib.nancypoll',
diff --git a/tests/test_generic_endpoint.py b/tests/test_generic_endpoint.py
index 75a38429..58a102f7 100644
--- a/tests/test_generic_endpoint.py
+++ b/tests/test_generic_endpoint.py
@@ -506,9 +506,9 @@ def test_endpoint_cookies(app, db, monkeypatch, httpbin):
 
 def test_https_warnings(app, db, monkeypatch, httpbin_secure, relax_openssl):
     from requests.exceptions import SSLError
-    from passerelle.contrib.maarch.models import Maarch
+    from passerelle.apps.arcgis.models import ArcGIS
 
-    resource = utils.make_resource(Maarch, wsdl_url='https://example.com/', slug='slug', verify_cert=True)
+    resource = utils.make_resource(ArcGIS, base_url='https://example.com/', slug='gis', verify_cert=True)
     with pytest.raises(SSLError):
         resource.requests.get(httpbin_secure.join('/get/'))
     resource.verify_cert = False
-- 
2.26.2

