Projet

Général

Profil

0001-ozwillo-create-ozwillo-app-in-contrib-14935.patch

Jean-Baptiste Jaillet, 09 février 2017 19:17

Télécharger (19,3 ko)

Voir les différences:

Subject: [PATCH] ozwillo: create ozwillo app in contrib (#14935)

 hobo/contrib/__init__.py                           |   0
 hobo/contrib/ozwillo/README.txt                    |  11 ++
 hobo/contrib/ozwillo/__init__.py                   |   0
 .../ozwillo/examples/import-site-agents.json       |  30 ++++
 .../ozwillo/examples/import-site-template.json     | 169 +++++++++++++++++++++
 hobo/contrib/ozwillo/examples/template_recipe.json |  72 +++++++++
 hobo/contrib/ozwillo/urls.py                       |  26 ++++
 hobo/contrib/ozwillo/views.py                      | 142 +++++++++++++++++
 hobo/urls.py                                       |   4 +
 9 files changed, 454 insertions(+)
 create mode 100644 hobo/contrib/__init__.py
 create mode 100644 hobo/contrib/ozwillo/README.txt
 create mode 100644 hobo/contrib/ozwillo/__init__.py
 create mode 100644 hobo/contrib/ozwillo/examples/import-site-agents.json
 create mode 100644 hobo/contrib/ozwillo/examples/import-site-template.json
 create mode 100644 hobo/contrib/ozwillo/examples/template_recipe.json
 create mode 100644 hobo/contrib/ozwillo/urls.py
 create mode 100644 hobo/contrib/ozwillo/views.py
hobo/contrib/ozwillo/README.txt
1
To run this plugin well, you have to set some files in /etc/hobo/ozwillo :
2
- the files are in the folder examples.
3
- it's a common recipe for your publik, and two extracts of user and agent combo.
4

  
5
You have to set several var in a settings.json too :
6
-OZWILLO_SECRET
7
-OZWILLO_ENV_DOMAIN (e.g: sictiam.dev.entrouvert.org)
8
-OZWILLO_DESTRUCTION_URI 
9
-OZWILLO_DESTRUCTION_SECRET
10

  
11
And finally you have to enable in INSTALLED_APPS hobo.contrib.ozwillo.
hobo/contrib/ozwillo/examples/import-site-agents.json
1
[
2
    {
3
        "cells": [
4
            {
5
                "fields": {
6
                    "extra_css_class": "",
7
                    "groups": [],
8
                    "order": 1,
9
                    "placeholder": "content",
10
                    "public": true,
11
                    "restricted_to_unlogged": false,
12
                    "slug": "services",
13
                    "text": "<h2>Bienvenue</h2>\r\n"
14
                },
15
                "model": "data.textcell"
16
            }
17
        ],
18
        "fields": {
19
            "exclude_from_navigation": false,
20
            "groups": [],
21
            "order": 1,
22
            "parent": null,
23
            "public": false,
24
            "redirect_url": "",
25
            "slug": "index",
26
            "template_name": "standard",
27
            "title": "Accueil"
28
        }
29
    }
30
]
hobo/contrib/ozwillo/examples/import-site-template.json
1
[
2
    {
3
        "cells": [
4
            {
5
                "fields": {
6
                    "extra_css_class": "",
7
                    "groups": [],
8
                    "order": 0,
9
                    "placeholder": "content",
10
                    "public": true,
11
                    "restricted_to_unlogged": true,
12
                    "slug": "",
13
                    "text": "<h2>Bienvenue</h2>\r\n\r\n<p>Bienvenue sur votre compte usager.</p>\r\n\r\n<p>Pour suivre vos d&eacute;marches en cours, cr&eacute;ez votre compte personnel ou identifiez-vous depuis <a href=\"/login/\">la page de connexion</a>.</p>\r\n"
14
                },
15
                "model": "data.textcell"
16
            },
17
            {
18
                "fields": {
19
                    "extra_css_class": "",
20
                    "groups": [],
21
                    "order": 1,
22
                    "placeholder": "content",
23
                    "public": false,
24
                    "restricted_to_unlogged": false,
25
                    "slug": "",
26
                    "text": "<h2>Bienvenue</h2>\r\n\r\n<p>Bienvenue sur votre compte usager.</p>\r\n"
27
                },
28
                "model": "data.textcell"
29
            },
30
            {
31
                "fields": {
32
                    "extra_css_class": "",
33
                    "groups": [],
34
                    "order": 2,
35
                    "placeholder": "right",
36
                    "public": true,
37
                    "restricted_to_unlogged": false,
38
                    "slug": "",
39
                    "wcs_site": ""
40
                },
41
                "model": "wcs.trackingcodeinputcell"
42
            },
43
            {
44
                "fields": {
45
                    "extra_css_class": "",
46
                    "groups": [],
47
                    "order": 3,
48
                    "placeholder": "right",
49
                    "public": true,
50
                    "restricted_to_unlogged": true,
51
                    "slug": "",
52
                    "text": "<h2>Demandes en cours</h2>\r\n\r\n<p>Connectez-vous pour voir vos demandes en cours.</p>\r\n"
53
                },
54
                "model": "data.textcell"
55
            },
56
            {
57
                "fields": {
58
                    "current_forms": true,
59
                    "done_forms": false,
60
                    "extra_css_class": "",
61
                    "groups": [],
62
                    "order": 4,
63
                    "placeholder": "right",
64
                    "public": false,
65
                    "restricted_to_unlogged": false,
66
                    "slug": "",
67
                    "wcs_site": ""
68
                },
69
                "model": "wcs.wcscurrentformscell"
70
            },
71
            {
72
                "fields": {
73
                    "extra_css_class": "",
74
                    "groups": [],
75
                    "order": 5,
76
                    "placeholder": "footer",
77
                    "public": true,
78
                    "restricted_to_unlogged": false,
79
                    "slug": "",
80
                    "text": "<p>Ce service est propos&eacute; par le <a href=\"http://www.sictiam.fr/\">SICTIAM</a>.</p>\r\n"
81
                },
82
                "model": "data.textcell"
83
            },
84
            {
85
                "fields": {
86
                    "category_reference": "eservices:nous-contacter",
87
                    "extra_css_class": "",
88
                    "groups": [],
89
                    "limit": null,
90
                    "manual_order": {
91
                        "data": []
92
                    },
93
                    "order": 6,
94
                    "ordering": "popularity",
95
                    "placeholder": "content",
96
                    "public": true,
97
                    "restricted_to_unlogged": false,
98
                    "slug": ""
99
                },
100
                "model": "wcs.wcsformsofcategorycell"
101
            }
102
        ],
103
        "fields": {
104
            "exclude_from_navigation": false,
105
            "groups": [],
106
            "order": 1,
107
            "parent": null,
108
            "public": true,
109
            "redirect_url": "",
110
            "slug": "index",
111
            "template_name": "two-columns",
112
            "title": "Accueil"
113
        }
114
    },
115
    {
116
        "cells": [
117
            {
118
                "fields": {
119
                    "extra_css_class": "",
120
                    "groups": [],
121
                    "order": 0,
122
                    "placeholder": "footer",
123
                    "public": true,
124
                    "restricted_to_unlogged": false,
125
                    "slug": ""
126
                },
127
                "model": "data.parentcontentcell"
128
            }
129
        ],
130
        "fields": {
131
            "exclude_from_navigation": false,
132
            "groups": [],
133
            "order": 2,
134
            "parent": null,
135
            "public": true,
136
            "redirect_url": "https://connexion-instance_name.sictiam.dev.entrouvert.org/accounts/",
137
            "slug": "mon-compte",
138
            "template_name": "standard",
139
            "title": "Mon compte"
140
        }
141
    },
142
    {
143
        "cells": [
144
            {
145
                "fields": {
146
                    "extra_css_class": "",
147
                    "groups": [],
148
                    "order": 0,
149
                    "placeholder": "footer",
150
                    "public": true,
151
                    "restricted_to_unlogged": false,
152
                    "slug": ""
153
                },
154
                "model": "data.parentcontentcell"
155
            }
156
        ],
157
        "fields": {
158
            "exclude_from_navigation": false,
159
            "groups": [],
160
            "order": 3,
161
            "parent": null,
162
            "public": true,
163
            "redirect_url": "https://demarches-instance_name.sictiam.dev.entrouvert.org/saisine-par-voie-electronique/tryauth",
164
            "slug": "nous-contacter",
165
            "template_name": "standard",
166
            "title": "Nous contacter"
167
        }
168
    }
169
]
hobo/contrib/ozwillo/examples/template_recipe.json
1
{
2
   "steps" : [
3
      {
4
         "create-hobo" : {
5
            "url" : "https://${hobo}/"
6
         }
7
      },
8
      {
9
         "create-authentic" : {
10
            "title" : "Connexion",
11
            "url" : "https://${authentic}/"
12
         }
13
      },
14
      {
15
         "set-idp" : {}
16
      },
17
      {
18
         "create-superuser" : {
19
           "username" : "admin",
20
           "email" : "admin@example.net"
21
         }
22
      },
23
      {
24
         "create-combo" : {
25
            "template_name" : "portal-user",
26
            "title" : "Compte citoyen",
27
            "url" : "https://${combo}/"
28
         }
29
      },
30
      {
31
         "create-combo" : {
32
            "template_name" : "portal-agent",
33
            "title" : "Portail agent",
34
            "url" : "https://${combo_agent}/",
35
            "slug" : "portal-agent"
36
         }
37
      },
38
      {
39
         "create-wcs" : {
40
            "url" : "https://${wcs}/",
41
            "title" : "Démarches",
42
            "template_name": "export.wcs"
43
         }
44
      },
45
      {
46
	 "create-fargo" : {
47
	    "url" : "https://${fargo}/",
48
            "title" : "Porte documents"
49
         }
50
      },	 
51
      {
52
         "create-passerelle" : {
53
            "url" : "https://${passerelle}/",
54
            "title" : "Passerelle"
55
         }
56
      },
57
      {
58
       	 "set-theme" : {
59
                          "theme" : "publik"
60
                       }
61
      }
62
   ],
63
   "variables" : {
64
      "authentic" : "connexion-instance_name.sictiam.dev.entrouvert.org",
65
      "combo" : "instance_name.sictiam.dev.entrouvert.org",
66
      "combo_agent" : "agents-instance_name.sictiam.dev.entrouvert.org",
67
      "hobo" : "hobo-instance_name.sictiam.dev.entrouvert.org",
68
      "wcs" : "demarches-instance_name.sictiam.dev.entrouvert.org",
69
      "passerelle": "passerelle-instance_name.sictiam.dev.entrouvert.org",
70
      "fargo": "porte-documents-instance_name.sictiam.dev.entrouvert.org"
71
   }
72
}
hobo/contrib/ozwillo/urls.py
1
# Ozwillo plugin to deploy
2
# Copyright (C) 2017  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 patterns, url, include
18

  
19
from . import views
20

  
21

  
22
urlpatterns = patterns('',
23
    url(r'create-publik-instance', views.create_publik_instance, name='ozwillo-create-publik-instance'),
24
    url(r'delete-publik-instance', views.delete_publik_instance, name='ozwillo-delete-publik-instance'),
25
)
26

  
hobo/contrib/ozwillo/views.py
1
# Ozwillo plugin to deploy Publik
2
# Copyright (C) 2017  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
import os
17
import logging
18
import requests
19
import io
20
import json
21
import subprocess
22
import hmac
23
import tempfile
24
from hashlib import sha1
25

  
26
from django.conf import settings
27
from django.http import HttpResponseForbidden, HttpResponseBadRequest, HttpResponseNotFound
28
from django.core.management import call_command
29

  
30

  
31
logger = logging.getLogger(__name__)
32

  
33
def valid_signature_required(func):
34
    signature_header_name = 'X-Hub-Signature'
35
    api_secret = settings.OZWILLO_SECRET
36
    def wrapper(request):
37
        if signature_header_name in request.headers:
38
             if request.headers[signature_header_name].startswith('sha1='):
39
                 algo, received_hmac = request.headers[signature_header_name].rsplit('=')
40
                 computed_hmac = hmac.new(api_secret, request.data, sha1).hexdigest()
41
                 # the received hmac is uppercase according to
42
                 # http://doc.ozwillo.com/#ref-3-2-1
43
                 if received_hmac.lower() != computed_hmac:
44
                     logger.error('Invalid HMAC')
45
                     return HttpResponseForbidden('Invalid HMAC')
46
             else:
47
                 logger.error('Invalid HMAC algo')
48
                 return HttpResponseForbidden('Invalid HMAC algo')
49
        else:
50
             logger.error('No HMAC in the header')
51
             return HttpResponseForbidden('No HMAC in the header')
52
        return func(request)
53
    return wrapper
54

  
55
def is_ozwillo_enabled(func):
56
    if not os.path.exists('/etc/hobo/ozwillo'):
57
        return HttpResponseNotFound('Owillo providing is not active here.')
58
    return func
59

  
60
@is_ozwillo_enabled
61
@valid_signature_required
62
def create_publik_instance(request):
63
    data = json.loads(request.body)
64

  
65
    logger.debug(data)
66

  
67
    client_id = data.pop('client_id')
68
    client_secret = data.pop('client_secret')
69
    instance_id = data.pop('instance_id')
70
    instance_name = data.pop('organization_name', None)
71

  
72
    if not instance_name:
73
        return HttpResponseBadRequest('Missing parameter "instance_name"')
74

  
75
    registration_uri = data.pop('instance_registration_uri')
76
    organization = data['organization']
77
    user = data['user']
78

  
79
    services = {'services': [{
80
                    'local_id': 'publik',
81
                    'name': 'Publik - %s' % (instance_name),
82
                    'service_uri':'https://connexion-%s.%s/accounts/oidc/login' % (instance_name, settings.OZWILLO_ENV_DOMAIN),
83
                    'description': 'Gestion de la relation usagers',
84
                    'tos_uri': 'https://publik.entrouvert.com/',
85
                    'policy_uri': 'https://publik.entrouvert.com/',
86
                    'icon': 'https://publik.entrouvert.com/static/img/logo-publik.png',
87
                    'payment_option': 'FREE',
88
                    'target_audience': ['PUBLIC_BODIES',
89
                                        'CITIZENS',
90
                                        'COMPANIES'],
91
                    'contacts': ['https://publik.entrouvert.com/'],
92
                    'redirect_uris':['https://connexion-%s.%s/accounts/oidc/callback' % (instance_name, settings.OZWILLO_ENV_DOMAIN)],
93
                }],
94
                'instance_id': instance_id,
95
                'destruction_uri': settings.OZWILLO_DESTRUCTION_URI,
96
                'destruction_secret': settings.OZWILLO_DESTRUCTION_SECRET,
97
                'needed_scopes': []
98
    }
99

  
100
    logger.debug(services)
101

  
102
    template_recipe = json.load(open('/etc/hobo/ozwillo/template_recipe.json', 'rb'))
103
    var = template_recipe['variables']
104
    for key, value in var.items():
105
        var[key] = value.replace('instance_name', instance_name)
106

  
107
    template_recipe['variables'] = var
108
    domain = var['combo']
109
    domain_agent = var['combo_agent']
110
    imp_site_template = json.load(open('/etc/hobo/ozwillo/import-site-template.json', 'r'))
111

  
112
    for row in imp_site_template:
113
        row['fields']['redirect_url'] = row['fields']['redirect_url'].replace('instance_name', instance_name)
114

  
115
    combo_file_handle, combo_file_path = tempfile.mkstemp()
116
    recipe_file_handle, recipe_file_path = tempfile.mkstemp()
117

  
118
    with io.open(combo_file_path, 'w', encoding='utf-8') as f:
119
        f.write(unicode(json.dumps(imp_site_template, ensure_ascii=False)))
120

  
121
    with io.open(recipe_file_path, 'w', encoding='utf-8') as f:
122
        f.write(unicode(json.dumps(template_recipe, ensure_ascii=False)))
123

  
124
    call_command('cook', recipe_file_path)
125
    subprocess.call(['sudo', '-u', 'combo', 'combo-manage',
126
                     'tenant_command', 'import_site',
127
                     combo_file_path, '-d', domain])
128
    subprocess.call(['sudo', '-u', 'combo', 'combo-manage',
129
                     'tenant_command', 'import_site',
130
                     '/etc/hobo/import-site-agents.json', '-d', domain_agent])
131

  
132
    os.remove(combo_file_path)
133
    os.remove(recipe_file_path)
134

  
135
    headers = {'Content-type': 'application/json', 'Accept': 'application/json'}
136
    requests.post(registration_uri, data=json.dumps(services), auth=(client_id, client_secret), headers=headers)
137

  
138
@is_ozwillo_enabled
139
@valid_signature_required
140
def delete_publik_instance(request):
141
    pass
142

  
hobo/urls.py
32 32
    url(r'^login/local/$', login_local), # to be used as backup, in case of idp down
33 33
    url(r'^accounts/mellon/', include('mellon.urls')),
34 34
)
35
if 'hobo.contrib.ozwillo' in settings.INSTALLED_APPS:
36
    urlpatterns += patterns('',
37
                           url(r'ozwillo/', include('hobo.contrib.ozwillo.urls'))
38
                          )
35
-