Projet

Général

Profil

« Précédent | Suivant » 

Révision 5c65415c

Ajouté par Jérôme Schneider il y a environ 10 ans

add support for new project creation

Closes #3524

Voir les différences:

MANIFEST.in
4 4

  
5 5
recursive-include mandaye/alembic *
6 6
recursive-include mandaye/templates *.html
7
recursive-include skel *
7
recursive-include mandya/skel *
mandaye/global_config.py
40 40
static_root = os.path.join(_PROJECT_PATH, 'mandaye/static')
41 41
# Data dir
42 42
data_dir = os.path.join(_PROJECT_PATH, 'data')
43
# Skel root
44
skel_root = os.path.join(_PROJECT_PATH, 'mandaye/skel')
43 45

  
44 46
# Email notification configuration
45 47
email_notification = False
mandaye/skel/MANIFEST.in
1
include COPYING MANIFEST.in VERSION
2
recursive-include {project_name}/templates *.html
3
recursive-include {project_name}/static *
mandaye/skel/data/README
1
Folder where Mandaye files will be stored.
2
It's only use to store metadata files.
mandaye/skel/example.module/__init__.py
1
__version__="0.1"
mandaye/skel/example.module/auth/example.py
1
"""
2
Here you can overload Mandaye default authentification
3
method like SAML2Auth or AuthForm
4
"""
5

  
6
from mandaye.auth.authform import AuthForm
7
from mandaye.auth.saml2 import SAML2Auth
8

  
9
class MyAuthSAML(SAML2Auth):
10
    """ Overload Mandaye SAML2Auth authentification
11
    """
12
    pass
13

  
14
class MyAuth(AuthForm):
15
    """ Overload Mandaye AuthForm authentification
16
    """
17
    pass
18

  
mandaye/skel/example.module/config.py
1
import logging
2
import os
3

  
4
_PROJECT_PATH = os.path.join(os.path.dirname(__file__), '..')
5

  
6
## Virtual hosts configuration
7
hosts = {{}}
8

  
9
## SQL Backend config
10
# Database configuration
11
# http://docs.sqlalchemy.org/en/rel_0_7/core/engines.html
12
# rfc 1738 https://tools.ietf.org/html/rfc1738
13
# dialect+driver://username:password@host:port/database
14
db_url = 'sqlite:///' + os.path.join(_PROJECT_PATH, 'test.db')
15

  
16
## Log configuration
17
debug = False
18
syslog = False
19
log_file = os.path.join(_PROJECT_PATH, '{project_name}/{project_name}.log')
20
log_level = logging.INFO
21
# Log rotation
22
# W[0-6] : weekly (0: Monday), D: day, ... (python doc)
23
log_when = 'W6'
24
# Every week
25
log_interval = 1
26
# BackupCount (keep one year of log)
27
log_backup = 52
28

  
29
## PATH
30
# Template directory
31
template_directory = os.path.join(_PROJECT_PATH, '{project_name}/templates')
32
# Static url
33
static_url = '/mandaye/static'
34
# Static folder
35
static_root = os.path.join(_PROJECT_PATH, '{project_name}/static')
36
# Data dir
37
data_dir = os.path.join(_PROJECT_PATH, 'data')
38

  
39
# Email notification configuration
40
email_notification = False
41
email_prefix = '[Mandaye CAM]'
42
smtp_host = 'localhost'
43
smtp_port = 25
44
email_from = 'traceback@entrouvert.com'
45
email_to = ['admin@localhost']
46

  
47
# platform : should be prod, recette or dev
48
platform = "prod"
49

  
50
# Use long traceback with xtraceback
51
use_long_trace = True
52

  
53
# Ask Mandaye to auto decompress a response message
54
# Decompress response only if you load a filter
55
auto_decompress = True
56

  
57
# Encrypt service provider passwords with a secret
58
# You should install pycypto to use this feature
59
encrypt_sp_password = False
60
# Must be a 16, 24, or 32 bytes long
61
encrypt_secret = ''
62

  
63
# Beaker session configuration
64
session_opts = {{
65
    'session.type': 'file',
66
    'session.cookie_expires': True,
67
    'session.timeout': 3600,
68
    'session.data_dir': '/var/tmp/beaker'
69
}}
70

  
71
# Choose storage
72
# Only mandaye.backends.sql at the moment
73
storage_backend = "mandaye.backends.sql"
74

  
75
# Needed if ssl is activated
76
ssl = False
77
keyfile = ''
78
certfile = ''
79

  
80
SAML_SIGNATURE_PUBLIC_KEY = '''-----BEGIN CERTIFICATE-----
81
MIIDIzCCAgugAwIBAgIJANUBoick1pDpMA0GCSqGSIb3DQEBBQUAMBUxEzARBgNV
82
BAoTCkVudHJvdXZlcnQwHhcNMTAxMjE0MTUzMzAyWhcNMTEwMTEzMTUzMzAyWjAV
83
MRMwEQYDVQQKEwpFbnRyb3V2ZXJ0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
84
CgKCAQEAvxFkfPdndlGgQPDZgFGXbrNAc/79PULZBuNdWFHDD9P5hNhZn9Kqm4Cp
85
06Pe/A6u+g5wLnYvbZQcFCgfQAEzziJtb3J55OOlB7iMEI/T2AX2WzrUH8QT8NGh
86
ABONKU2Gg4XiyeXNhH5R7zdHlUwcWq3ZwNbtbY0TVc+n665EbrfV/59xihSqsoFr
87
kmBLH0CoepUXtAzA7WDYn8AzusIuMx3n8844pJwgxhTB7Gjuboptlz9Hri8JRdXi
88
VT9OS9Wt69ubcNoM6zuKASmtm48UuGnhj8v6XwvbjKZrL9kA+xf8ziazZfvvw/VG
89
Tm+IVFYB7d1x457jY5zjjXJvNysoowIDAQABo3YwdDAdBgNVHQ4EFgQUeF8ePnu0
90
fcAK50iBQDgAhHkOu8kwRQYDVR0jBD4wPIAUeF8ePnu0fcAK50iBQDgAhHkOu8mh
91
GaQXMBUxEzARBgNVBAoTCkVudHJvdXZlcnSCCQDVAaInJNaQ6TAMBgNVHRMEBTAD
92
AQH/MA0GCSqGSIb3DQEBBQUAA4IBAQAy8l3GhUtpPHx0FxzbRHVaaUSgMwYKGPhE
93
IdGhqekKUJIx8et4xpEMFBl5XQjBNq/mp5vO3SPb2h2PVSks7xWnG3cvEkqJSOeo
94
fEEhkqnM45b2MH1S5uxp4i8UilPG6kmQiXU2rEUBdRk9xnRWos7epVivTSIv1Ncp
95
lG6l41SXp6YgIb2ToT+rOKdIGIQuGDlzeR88fDxWEU0vEujZv/v1PE1YOV0xKjTT
96
JumlBc6IViKhJeo1wiBBrVRIIkKKevHKQzteK8pWm9CYWculxT26TZ4VWzGbo06j
97
o2zbumirrLLqnt1gmBDvDvlOwC/zAAyL4chbz66eQHTiIYZZvYgy
98
-----END CERTIFICATE-----'''
99

  
100
SAML_SIGNATURE_PRIVATE_KEY = '''-----BEGIN RSA PRIVATE KEY-----
101
MIIEpAIBAAKCAQEAvxFkfPdndlGgQPDZgFGXbrNAc/79PULZBuNdWFHDD9P5hNhZ
102
n9Kqm4Cp06Pe/A6u+g5wLnYvbZQcFCgfQAEzziJtb3J55OOlB7iMEI/T2AX2WzrU
103
H8QT8NGhABONKU2Gg4XiyeXNhH5R7zdHlUwcWq3ZwNbtbY0TVc+n665EbrfV/59x
104
ihSqsoFrkmBLH0CoepUXtAzA7WDYn8AzusIuMx3n8844pJwgxhTB7Gjuboptlz9H
105
ri8JRdXiVT9OS9Wt69ubcNoM6zuKASmtm48UuGnhj8v6XwvbjKZrL9kA+xf8ziaz
106
Zfvvw/VGTm+IVFYB7d1x457jY5zjjXJvNysoowIDAQABAoIBAQCj8t2iKXya10HG
107
V6Saaeih8aftoLBV38VwFqqjPU0+iKqDpk2JSXBhjI6s7uFIsaTNJpR2Ga1qvns1
108
hJQEDMQSLhJvXfBgSkHylRWCpJentr4E3D7mnw5pRsd61Ev9U+uHcdv/WHP4K5hM
109
xsdiwXNXD/RYd1Q1+6bKrCuvnNJVmWe0/RV+r3T8Ni5xdMVFbRWt/VEoE620XX6c
110
a9TQPiA5i/LRVyie+js7Yv+hVjGOlArtuLs6ECQsivfPrqKLOBRWcofKdcf+4N2e
111
3cieUqwzC15C31vcMliD9Hax9c1iuTt9Q3Xzo20fOSazAnQ5YBEExyTtrFBwbfQu
112
ku6hp81pAoGBAN6bc6iJtk5ipYpsaY4ZlbqdjjG9KEXB6G1MExPU7SHXOhOF0cDH
113
/pgMsv9hF2my863MowsOj3OryVhdQhwA6RrV263LRh+JU8NyHV71BwAIfI0BuVfj
114
6r24KudwtUcvMr9pJIrJyMAMaw5ZyNoX7YqFpS6fcisSJYdSBSoxzrzVAoGBANu6
115
xVeMqGavA/EHSOQP3ipDZ3mnWbkDUDxpNhgJG8Q6lZiwKwLoSceJ8z0PNY3VetGA
116
RbqtqBGfR2mcxHyzeqVBpLnXZC4vs/Vy7lrzTiHDRZk2SG5EkHMSKFA53jN6S/nJ
117
JWpYZC8lG8w4OHaUfDHFWbptxdGYCgY4//sjeiuXAoGBANuhurJ99R5PnA8AOgEW
118
4zD1hLc0b4ir8fvshCIcAj9SUB20+afgayRv2ye3Dted1WkUL4WYPxccVhLWKITi
119
rRtqB03o8m3pG3kJnUr0LIzu0px5J/o8iH3ZOJOTE3iBa+uI/KHmxygc2H+XPGFa
120
HGeAxuJCNO2kAN0Losbnz5dlAoGAVsCn94gGWPxSjxA0PC7zpTYVnZdwOjbPr/pO
121
LDE0cEY9GBq98JjrwEd77KibmVMm+Z4uaaT0jXiYhl8pyJ5IFwUS13juCbo1z/u/
122
ldMoDvZ8/R/MexTA/1204u/mBecMJiO/jPw3GdIJ5phv2omHe1MSuSNsDfN8Sbap
123
gmsgaiMCgYB/nrTk89Fp7050VKCNnIt1mHAcO9cBwDV8qrJ5O3rIVmrg1T6vn0aY
124
wRiVcNacaP+BivkrMjr4BlsUM6yH4MOBsNhLURiiCL+tLJV7U0DWlCse/doWij4U
125
TKX6tp6oI+7MIJE6ySZ0cBqOiydAkBePZhu57j6ToBkTa0dbHjn1WA==
126
-----END RSA PRIVATE KEY-----'''
127

  
128
# Import local config
129
try:
130
    from ..{project_name}.local_config import *
131
except:
132
    pass
133

  
mandaye/skel/example.module/configs/linuxfr_saml_example.py
1

  
2
from {project_name}.auth.example import MyAuthSAML
3
from {project_name}.filters.example import ReplayFilter
4

  
5
from mandaye.configs import saml2 as saml2_config
6

  
7
form_values = {{
8
        'login_url': '/compte/connexion',
9
        'form_attrs': {{ 'id': 'new_account' }},
10
        'post_fields': ['account[login]', 'account[password]'],
11
        'username_field': 'account[login]',
12
        'password_field': 'account[password]',
13
}}
14

  
15
auth = MyAuthSAML(form_values, 'linuxfr', saml2_config)
16

  
17
linuxfr_mapping = [
18
            {{
19
                'path': r'/mandaye/associate$',
20
                'method': 'GET',
21
                'on_response': [{{
22
                    'filter': ReplayFilter.associate,
23
                    'values': {{
24
                        'action': '/mandaye/associate',
25
                        'template': 'associate.html',
26
                        'sp_name': 'Linux FR',
27
                        'login_name': form_values['username_field'],
28
                        'password_name': form_values['password_field'],
29
                        }},
30
                    }},]
31
                }},
32
            {{
33
                'path':  r'/mandaye/associate$',
34
                'method': 'POST',
35
                'response': [
36
                    {{
37
                        'filter': auth.associate_submit,
38
                        'values': {{
39
                            'connection_url': '/mandaye/sso',
40
                            'associate_url': '/mandaye/associate',
41
                            }},
42
                        'condition': "response.code==302"
43
                        }},
44
                    ]
45
                }},
46
            ]
47

  
48
linuxfr_mapping.extend(auth.get_default_mapping())
49

  
mandaye/skel/example.module/filters/example.py
1

  
2
from mandaye.template import serve_template
3

  
4
class ReplayFilter:
5

  
6
    @staticmethod
7
    def associate(env, values, request, response):
8
        associate = serve_template(values.get('template'), **values)
9
        response.msg = associate
10
        return response
11

  
mandaye/skel/example.module/static/css/style.css
1
/* theme derived and inspired by TerraFirma
2
 * <http://www.oswd.org/design/information/id/3557/>
3
 */
4

  
5
html, body {
6
	margin: 0;
7
	font-family: sans-serif;
8
	font-size: 12px;
9
}
10

  
11
body#iframe {
12
    background: white;
13
}
14

  
15
html {
16
	background: #F9F9F7 url(../images/a1.gif) repeat-x;
17
	color: #44b2cb;
18
}
19

  
20
a
21
{
22
	color: #44b2cb;
23
	text-decoration: underline;
24
}
25

  
26
a:hover
27
{
28
	text-decoration: none;
29
}
30

  
31

  
32
div#wrap {
33
	background: white;
34
	width: 640px;
35
	margin: 5em auto;
36
	padding: 15px;
37
	-moz-border-radius: 6px;
38
	-webkit-border-radius:6px;
39
	-moz-box-shadow: 0 0 4px rgba(0,0,0,0.75);
40
	-webkit-box-shadow: 0 0 4px rgba(0,0,0,0.75);
41
	position: relative;
42
}
43

  
44
#header
45
{
46
	position: absolute;
47
	background: url(../images/a8.png) repeat-x;
48
	-moz-border-radius: 6px 0 0 6px;
49
	-webkit-border-radius: 6px 0 0 6px;
50
	width: 450px;
51
	height: 92px;
52
	color: #fff;
53
	padding-left: 20px;
54
}
55

  
56
#header h1
57
{
58
	font-size: 23px;
59
	letter-spacing: -1px;
60
	padding-top: 30px;
61
	margin: 0;
62
}
63

  
64
#header span
65
{
66
	margin: 0;
67
	font-size: 13px;
68
	font-weight: normal;
69
	color: #FCE2CA;
70
}
71

  
72
#splash
73
{
74
	position: absolute;
75
	right: 20px;
76
	background: url(../images/eo.png) no-repeat;
77
	width: 153px;
78
	height: 92px;
79
	-moz-border-radius: 0 6px 6px 0;
80
	-webkit-border-radius: 0 6px 6px 0;
81
}
82

  
83
div#content {
84
	margin: 1em 1ex;
85
	margin-top: 130px;
86
	padding: 1ex;
87
}
88

  
89
div#content h2 {
90
	margin-top: 0;
91
	font-weight: normal;
92
	color: #656551;
93
	font-size: 18px;
94
	letter-spacing: -1px;
95
	line-height: 25px;
96
	margin-bottom: 20px;
97
	padding: 0 0 10px 15px;
98
	position: relative;
99
	top: 4px;
100
	background: url(../images/a22.gif) bottom repeat-x;
101
}
102

  
103
#footer
104
{
105
	font-size: 70%;
106
	position: relative;
107
	clear: both;
108
	height: 66px;
109
	text-align: center;
110
	line-height: 66px;
111
	background-image: url(../images/a8.png);
112
	color: #fff;
113
}
114

  
115
#footer a
116
{
117
	color: #8C8C73;
118
}
119

  
120

  
121
form#login-form p {
122
	float: left;
123
	width: 40%;
124
}
125

  
126
form#login-form input.submit {
127
	float: right;
128
	width: 18%;
129
	margin-top: 30px;
130
}
131

  
132
div.login-actions {
133
	clear: both;
134
	padding-top: 1em;
135
}
136

  
137
div.login-actions p {
138
	margin: 0;
139
}
140

  
141
form p {
142
	margin: 0 0 1em 0;
143
}
144

  
145
form p label {
146
	display: block;
147
}
148

  
149
form p input,
150
form p textarea {
151
	margin-left: 10px;
152
}
153

  
154
ul.messages {
155
	margin: 0;
156
	padding: 0;
157
	list-style: none;
158
}
159

  
160
ul.messages li.error {
161
	color: #e80404;
162
}
163

  
164
ul.errorlist {
165
	margin: 0;
166
	padding: 0;
167
	color: #e80404;
168
	list-style: none;
169
}
170

  
171
input, textarea {
172
	padding: 5px;
173
	border: 1px solid #cccccc;
174
	color:#666666;
175
	background: white;
176
	color: black;
177
}
178

  
179
textarea:focus, input[type="text"]:focus, input[type="password"]:focus {
180
	border: 1px solid #4690d6;
181
	color:#333333;
182
}
183

  
184
input[type=submit] {
185
	color: #ffffff;
186
	background:#4690d6;
187
	border: 1px solid #2a567f;
188
	font-weight: bold;
189
	padding: 2px 8px 2px 8px;
190
	margin: 0;
191
	cursor: pointer;
192
}
193

  
194

  
195
input[type=submit]:hover {
196
	border-color: #0e1d2b;
197
}
198

  
199
form#login-form ul.errorlist {
200
	margin-bottom: 1em;
201
	width: 80%;
202
	font-weight: normal;
203
}
204

  
205
/* OpenID Stuff */
206

  
207
#openid_btns, #openid_btns br {
208
	clear: both;
209
}
210

  
211
#openid_highlight a {
212
	border: 1px solid #888;
213
}
214

  
215
#openid_input_area input[type=submit] {
216
	padding-top: 0;
217
	margin-top: 0;
218
	margin-left: 1em;
219
}
220

  
221
.openid_large_btn {
222
	width: 100px;
223
	height: 60px;
224
	border: 1px solid #DDD;
225
	margin: 3px;
226
	float: left;
227
}
228
.openid_small_btn {
229
	width: 24px;
230
	height: 24px;
231
	border: 1px solid #DDD;
232
	margin: 3px;
233
	float: left;
234
}
235

  
236
a.openid_large_btn:focus {
237
	outline: none;
238
}
239
a.openid_large_btn:focus {
240
	-moz-outline-style: none;
241
}
242
.openid_selected {
243
	border: 4px solid #DDD;
244
}
245

  
246
#openid_input_area {
247
	clear: both;
248
	padding-top: 2.5em;
249
}
250

  
251
li.indented {
252
	margin-left: 50px;
253
}
254

  
255
ul.NoBullet {
256
	list-style-type: none;
257
}
258

  
259
div#content h4 {
260
	margin-bottom: 5px;
261
	margin-top: 30px;
262
}
263

  
264
div#content p {
265
        margin-top: 0;
266
}
267

  
268
div.errors {
269
	margin: 0;
270
	padding: 0;
271
	color: #e80404;
272
	list-style: none;
273
}
274

  
275
div#breadcrumb {
276
	font-size: 80%;
277
	margin-bottom: 1em;
278
}
279

  
280
div#user {
281
	position: absolute;
282
	top: 115px;
283
	right: 12px;
284
}
285

  
286
a#logout {
287
	font-size: 100%;
288
}
289

  
290

  
291
.ui-tabs .ui-tabs-hide {
292
     display: none;
293
}
294

  
295
h4 {
296
	padding-left: 0.5em;
297
}
298

  
299
h4 + div, div#profile {
300
	padding-left: 1em;
301
}
302

  
303

  
304
div#menu {
305
position: relative;
306
background: #46461F url(../images/a17.gif) repeat-x;
307
height: 67px;
308
padding: 0px 20px 0px 5px;
309
margin: 136px 0px 0px 0px;
310
}
311

  
312
#menu ul
313
{
314
        padding: 0;
315
        margin: 0;
316
}
317

  
318
#menu ul li
319
{
320
display: inline;
321
line-height: 52px;
322
padding-left: 3px;
323
}
324

  
325
#menu ul li.first
326
{
327
border-left: 0px;
328
}
329

  
330
#menu ul li a
331
{
332
background-color: transparent;
333
background-repeat: repeat-x;
334
padding: 8px 12px 8px 12px;
335
font-size: 12px;
336
color: #fff;
337
font-weight: bold;
338
}
339
#menu ul li a:hover
340
{
341
background: #fff url(../images/a18.gif) repeat-x top;
342
color: #4A4A24;
343
text-decoration: none;
344
}
345

  
346
#eo
347
{
348
position: absolute;
349
top: 0px;
350
line-height: 52px;
351
color: #BDBDA2;
352
right: 30px;
353
font-weight: bold;
354
font-size: 12px;
355
letter-spacing: -1px;
356
}
357

  
358
#eo a {
359
        color: inherit;
360
        text-decoration: none;
361
}
362

  
363
ul#tab-nav {
364
        list-style: none;
365
        padding: 0;
366
        width: 160px;
367
        float: left;
368
}
369

  
370
ul#tab-nav li {
371
        line-height: 300%;
372
        position: relative;
373
        right: -1px;
374
        border: 1px solid transparent;
375
}
376

  
377
ul#tab-nav li.ui-tabs-selected {
378
        border: 1px solid #ccc;
379
        border-right: 1px solid white;
380
}
381

  
382
ul#tab-nav a {
383
        display: block;
384
        padding-left: 1ex;
385
        outline: none;
386
        -moz-user-focus:ignore;
387
}
388

  
389
ul#tab-nav a:hover {
390
}
391

  
392
ul#tab-nav a:active {
393
}
394

  
395
/* XXX: add a class to divs, so it works in IE */
396
div#tabs > div {
397
        border: 1px solid #ccc;
398
        float: left;
399
        width: 420px;
400
        padding: 10px;
401
        min-height: 26em;
402
}
403

  
404
a.bigbutton {
405
	display: block;
406
	-moz-border-radius: 6px;
407
	-webkit-border-radius:6px;
408
	border: 1px solid black;
409
	margin: 2em 0;
410
	line-height: 300%;
411
	text-align: center;
412
	text-decoration: none;
413
	font-weight: bold;
414
	-webkit-box-shadow: 0 0 4px rgba(0,0,0,0.75);
415
	-moz-box-shadow: 0 0 4px rgba(0,0,0,0.75);
416
}
417

  
418
a.bigbutton:hover {
419
	background: #eee;
420
}
421

  
422
div#providers {
423
	display: none;
424
}
425

  
426
#modalOverlay {
427
	height:100%;
428
	width:100%;
429
	position:fixed;
430
	left:0;
431
	top:0;
432
	z-index:3000;
433
	background-color: rgba(0, 0, 0, 0.8);
434
	cursor:wait;
435
}
436

  
437
div#popup {
438
	display: none;
439
	position:fixed;
440
	width:500px;
441
	left:50%;
442
	margin-left:-250px;
443
	z-index:3100;
444
	top: 10%;
445
}
446

  
447
div#popup div {
448
	position: relative;
449
	margin: 0;
450
	background: white;
451
	border: 1px solid black;
452
	border-color: #333 black black #333;
453
}
454

  
455
div#popup h2 {
456
	text-align: center;
457
}
458

  
459
div#popup ul {
460
	max-height: 70px;
461
	overflow: auto;
462
	margin: 0 1em 1em 1em;
463
	padding: 0 1em 1em 1em;
464
}
465

  
466
div#popup h3 {
467
	margin-bottom: 4px;
468
	padding-left: 10px;
469
}
470

  
471
div#popup p {
472
	margin: 5px;
473
}
474

  
475
div#popup a#close {
476
	float: right;
477
	padding: 1ex;
478
}
479

  
480
a.roleid_button {
481
    -moz-border-radius: 5px;
482
    -webkit-border-radius: 5px;
483
    border-radius: 5px;
484
    background: #5C5C5C;
485
    color: #44b2cb;
486
    font-weight: bold;
487
    padding-top: 5px;
488
    padding-bottom: 5px;
489
    padding-right: 10px;
490
    padding-left: 10px;
491
    margin: 0;
492
    cursor: pointer;
493
    text-decoration: none;
494
}
495

  
496
a.roleid_button:hover {
497
    background: black;
498
}
mandaye/skel/example.module/templates/associate.html
1
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
2
<html>
3
  <head>
4
  <link rel="stylesheet" href="${static_url}/css/style.css" />
5
    <title>1er connexion</title>
6
  </head>
7
  <body>
8
    <div id="wrap">
9
      <div id="header">
10
        <h1>Première connexion</h1>
11
        <span>Associer un compte</span>
12
      </div>
13
      <div id="splash"></div>
14
      <div id="content">
15
        <h1>Association</h1>
16
        <p>Associer ${sp_name} avec votre compte citoyen</p>
17
        <form action="${action}" method="post" accept-charset="utf-8">
18
          <div>
19
            <label for="username">Utilisateur</label>
20
            <input type="text" name="${login_name}" value="" id="username" />
21
          </div>
22
          <div>
23
            <label for="password">Mot de passe</label>
24
            <input type="password" name="${password_name}" value="" id="password" />
25
          </div>
26
          <p><input type="submit" value="Associer"></p>
27
        </form>
28
      </div>
29
      <div id="footer">
30
        Copyright &copy; 2013 Entr'ouvert
31
      </div>
32
    </div>
33
  </body>
34
</html>
mandaye/skel/example.module/wsgi.py
1

  
2
import os
3

  
4
from mandaye.server import MandayeApp
5

  
6
from {project_name} import config
7
from beaker.middleware import SessionMiddleware
8

  
9
os.environ['MANDAYE_CONFIG_MODULE'] = '{project_name}.config'
10

  
11
application = SessionMiddleware(MandayeApp(), config.session_opts)
12

  
13

  
mandaye/skel/local_config.py.example
1
## Virtual hosts configuration
2
hosts = {{
3
        'linuxfrsaml.local:8000': [
4
            {{
5
                'path': r'/',
6
                'target': 'http://linuxfr.org',
7
                'mapping': '{project_name}.configs.linuxfr_saml_example.linuxfr_mapping'
8
                }},
9
            ],
10

  
11
        }}
12

  
13
## SQL Backend config
14
# http://docs.sqlalchemy.org/en/rel_0_7/core/engines.html
15
# rfc 1738 https://tools.ietf.org/html/rfc1738
16
# dialect+driver://username:password@host:port/database
17
db_url = 'sqlite:///test.db'
18

  
19
## Logging configuration
20
debug = False
mandaye/skel/manager.py
1
#! /usr/bin/python
2
# -*- coding: utf-8 -*-
3

  
4
""" Script to administrate mandaye server
5
"""
6

  
7
import os
8
os.environ['MANDAYE_CONFIG_MODULE'] = '{project_name}.config'
9

  
10
import base64
11

  
12
from optparse import OptionParser
13

  
14
from mandaye import config
15
from mandaye.log import logger
16

  
17
def get_cmd_options():
18
    usage = "usage: %prog --createdb|--upgradedb|--cryptpwd"
19
    parser = OptionParser(usage=usage)
20
    parser.add_option("--createdb",
21
            dest="createdb",
22
            default=False,
23
            action="store_true",
24
            help="Create Mandaye database"
25
            )
26
    parser.add_option("--upgradedb",
27
            dest="upgradedb",
28
            default=False,
29
            action="store_true",
30
            help="Upgrade Mandaye database"
31
            )
32
    parser.add_option("--cryptpwd",
33
            dest="cryptpwd",
34
            default=False,
35
            action="store_true",
36
            help="Crypt external password in Mandaye's database"
37
            )
38
    (options, args) = parser.parse_args()
39
    return options
40

  
41
def encrypt_pwd(pwd):
42
    from Crypto.Cipher import AES
43
    logger.debug("Encrypt password")
44
    enc_pwd = pwd
45
    if config.encrypt_secret:
46
        try:
47
            cipher = AES.new(config.encrypt_secret, AES.MODE_CFB)
48
            enc_pwd = cipher.encrypt(pwd)
49
            enc_pwd = base64.b64encode(enc_pwd)
50
        except Exception, e:
51
            if config.debug:
52
                traceback.print_exc()
53
            logger.warning('Password encrypting failed %s' % e)
54
    else:
55
        logger.warning("You must set a secret to use pwd encryption")
56
    return enc_pwd
57

  
58
def main():
59
    options = get_cmd_options()
60
    if options.createdb or options.upgradedb:
61
        logger.info("Creating or upgrading database...")
62
        from alembic.config import Config
63
        from alembic import command
64
        from mandaye import global_config
65
        alembic_cfg = Config(global_config.alembic_cfg)
66
        alembic_cfg.set_main_option("script_location", global_config.alembic_script_path)
67
        command.upgrade(alembic_cfg, "head")
68
        logger.info("Database upgraded")
69
    if options.cryptpwd:
70
        from mandaye.backends.default import ManagerSPUser
71
        for user in ManagerSPUser.all():
72
            user.password = encrypt_pwd(user.password)
73
        ManagerSPUser.save()
74

  
75
if __name__ == "__main__":
76
    main()
77

  
mandaye/skel/requirements.txt
1
gunicorn>=0.17
2
mandaye>=0.7.1
mandaye/skel/server.py
1
#!/usr/bin/env python
2
# -*- coding: utf-8 -*-
3

  
4
""" Script to launch mandaye with gunicorn server
5
"""
6

  
7
import os
8
os.environ['MANDAYE_CONFIG_MODULE'] = '{project_name}.config'
9

  
10
import sys
11

  
12
from mandaye.log import logger
13
from gunicorn.app.wsgiapp import WSGIApplication
14

  
15
class MandayeWSGIApplication(WSGIApplication):
16

  
17
    def init(self, parser, opts, args):
18
        self.cfg.set("default_proc_name", "{project_name}.wsgi:application")
19
        self.app_uri = "{project_name}.wsgi:application"
20

  
21
def main():
22
    """ The ``gunicorn`` command line runner for launcing Gunicorn with
23
    generic WSGI applications.
24
    """
25
    logger.info('{project_name} reverse-proxy start')
26
    MandayeWSGIApplication("%(prog)s [OPTIONS]").run()
27

  
28
if __name__ == "__main__":
29
    main()
30

  
mandaye/skel/setup.py
1
#! /usr/bin/env python
2

  
3
'''
4
   Setup script for {project_name} RP
5
'''
6

  
7
import os
8
import subprocess
9

  
10
from setuptools import setup, find_packages
11
from sys import version
12

  
13
import {project_name}
14

  
15
install_requires=[
16
        'gunicorn>=0.17',
17
        'mandaye>=0.7.1',
18
]
19

  
20
def get_version():
21
    if os.path.exists('VERSION'):
22
        version_file = open('VERSION', 'r')
23
        version = version_file.read()
24
        version_file.close()
25
        return version
26
    if os.path.exists('.git'):
27
        p = subprocess.Popen(['git','describe','--match=v*'],
28
                stdout=subprocess.PIPE)
29
        result = p.communicate()[0]
30
        version = result.split()[0][1:]
31
        return version.replace('-','.')
32
    return {project_name}.__version__
33

  
34
setup(name="{project_name}",
35
      version=get_version(),
36
      license="AGPLv3 or later",
37
      description="{project_name} rp is a Mandaye project, modular reverse proxy to authenticate",
38
      url="http://dev.entrouvert.org/projects/reverse-proxy/",
39
      author="Author",
40
      author_email="author@example.com",
41
      maintainer="Maintainer",
42
      maintainer_email="maintainer@exmaple.com",
43
      scripts=['{project_name}_manager', '{project_name}_server'],
44
      packages=find_packages(),
45
      include_package_data=True,
46
      install_requires=install_requires
47
)
48

  
scripts/mandaye-admin
1
#!/usr/bin/env python
2
# -*- coding: utf-8 -*-
3

  
4
""" Script to manage mandaye project
5
"""
scripts/mandaye-admin.py
1
#! /usr/bin/python
2
# -*- coding: utf-8 -*-
3

  
4
""" Script to create mandaye projects
5
"""
6

  
7
import os
8
import re
9
import shutil
10
import sys
11

  
12
from optparse import OptionParser
13

  
14
from mandaye import config, global_config
15
from mandaye.log import logger
16

  
17
def get_cmd_options():
18
    usage = "usage: %prog --newproject"
19
    parser = OptionParser(usage=usage)
20
    parser.add_option("-n", "--newproject",
21
            dest="project_name",
22
            metavar="PROJECT_NAME",
23
            help="PROJECT_NAME: the name of teh new mandaye's project"
24
            )
25
    (options, args) = parser.parse_args()
26
    if not options.project_name:
27
        parser.error("You must set --newproject option")
28
    if options.project_name:
29
        if not re.search(r'^[_a-zA-Z]\w*$', options.project_name):
30
            parser.error("project_name %s is not a valid name."
31
                    "Please use use only numbers, letters and underscores.")
32
    return options
33

  
34
def main():
35
    options = get_cmd_options()
36
    if options.project_name:
37
        project_name = options.project_name
38
        module = os.path.join(project_name,
39
                project_name)
40
        modue_example = os.path.join(project_name,
41
                "example.module")
42
        skel = global_config.skel_root
43
        logger.info("Creating project %s ..." % project_name)
44
        if os.path.exists(project_name):
45
            print "%s folder already exist" % project_name
46
            sys.exit(1)
47
        shutil.copytree(skel, project_name)
48
        for root, dirs, files in os.walk(project_name):
49
            if not "templates" in root and not "static" in root:
50
                print root
51
                for filename in files:
52
                    file_path = os.path.join(root, filename)
53
                    print file_path
54
                    with open(file_path, "r") as f:
55
                        content = f.read()
56
                    with open(file_path, "w") as f:
57
                        print content.format(project_name=project_name)
58
                        f.write(content.format(project_name=project_name))
59
        shutil.move(modue_example, module)
60

  
61
if __name__ == "__main__":
62
    main()
63

  
setup.py
48 48
      author_email="info@entrouvert.org",
49 49
      maintainer="Jerome Schneider",
50 50
      maintainer_email="jschneider@entrouvert.com",
51
      scripts=['scripts/mandaye-admin'],
51
      scripts=['scripts/mandaye-admin.py'],
52 52
      include_package_data = True,
53 53
      packages=find_packages(),
54 54
      install_requires=install_requires
skel/MANIFEST.in
1
include COPYING MANIFEST.in VERSION
2
recursive-include {module_name}/templates *.html
3
recursive-include {module_name}/static *
skel/data/README
1
Folder where Mandaye files will be stored.
2
It's only use to store metadata files.
skel/example.module/auth/example.py
1
"""
2
Here you can overload Mandaye default authentification
3
method like SAML2Auth or AuthForm
4
"""
5

  
6
from mandaye.auth.authform import AuthForm
7
from mandaye.auth.saml2 import SAML2Auth
8

  
9
class MyAuthSAML(SAML2Auth):
10
    """ Overload Mandaye SAML2Auth authentification
11
    """
12
    pass
13

  
14
class MyAuth(AuthForm):
15
    """ Overload Mandaye AuthForm authentification
16
    """
17
    pass
18

  
skel/example.module/config.py
1
import logging
2
import os
3

  
4
_PROJECT_PATH = os.path.join(os.path.dirname(__file__), '..')
5

  
6
## Virtual hosts configuration
7
hosts = {}
8

  
9
## SQL Backend config
10
# Database configuration
11
# http://docs.sqlalchemy.org/en/rel_0_7/core/engines.html
12
# rfc 1738 https://tools.ietf.org/html/rfc1738
13
# dialect+driver://username:password@host:port/database
14
db_url = 'sqlite:///' + os.path.join(_PROJECT_PATH, 'test.db')
15

  
16
## Log configuration
17
debug = False
18
syslog = False
19
log_file = os.path.join(_PROJECT_PATH, '{module_name}/{module_name}.log')
20
log_level = logging.INFO
21
# Log rotation
22
# W[0-6] : weekly (0: Monday), D: day, ... (python doc)
23
log_when = 'W6'
24
# Every week
25
log_interval = 1
26
# BackupCount (keep one year of log)
27
log_backup = 52
28

  
29
## PATH
30
# Template directory
31
template_directory = os.path.join(_PROJECT_PATH, '{module_name}/templates')
32
# Static url
33
static_url = '/mandaye/static'
34
# Static folder
35
static_root = os.path.join(_PROJECT_PATH, '{module_name}/static')
36
# Data dir
37
data_dir = os.path.join(_PROJECT_PATH, 'data')
38

  
39
# Email notification configuration
40
email_notification = False
41
email_prefix = '[Mandaye CAM]'
42
smtp_host = 'localhost'
43
smtp_port = 25
44
email_from = 'traceback@entrouvert.com'
45
email_to = ['admin@localhost']
46

  
47
# platform : should be prod, recette or dev
48
platform = "prod"
49

  
50
# Use long traceback with xtraceback
51
use_long_trace = True
52

  
53
# Ask Mandaye to auto decompress a response message
54
# Decompress response only if you load a filter
55
auto_decompress = True
56

  
57
# Encrypt service provider passwords with a secret
58
# You should install pycypto to use this feature
59
encrypt_sp_password = False
60
# Must be a 16, 24, or 32 bytes long
61
encrypt_secret = ''
62

  
63
# Beaker session configuration
64
session_opts = {
65
    'session.type': 'file',
66
    'session.cookie_expires': True,
67
    'session.timeout': 3600,
68
    'session.data_dir': '/var/tmp/beaker'
69
}
70

  
71
# Choose storage
72
# Only mandaye.backends.sql at the moment
73
storage_backend = "mandaye.backends.sql"
74

  
75
# Needed if ssl is activated
76
ssl = False
77
keyfile = ''
78
certfile = ''
79

  
80
SAML_SIGNATURE_PUBLIC_KEY = '''-----BEGIN CERTIFICATE-----
81
MIIDIzCCAgugAwIBAgIJANUBoick1pDpMA0GCSqGSIb3DQEBBQUAMBUxEzARBgNV
82
BAoTCkVudHJvdXZlcnQwHhcNMTAxMjE0MTUzMzAyWhcNMTEwMTEzMTUzMzAyWjAV
83
MRMwEQYDVQQKEwpFbnRyb3V2ZXJ0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
84
CgKCAQEAvxFkfPdndlGgQPDZgFGXbrNAc/79PULZBuNdWFHDD9P5hNhZn9Kqm4Cp
85
06Pe/A6u+g5wLnYvbZQcFCgfQAEzziJtb3J55OOlB7iMEI/T2AX2WzrUH8QT8NGh
86
ABONKU2Gg4XiyeXNhH5R7zdHlUwcWq3ZwNbtbY0TVc+n665EbrfV/59xihSqsoFr
87
kmBLH0CoepUXtAzA7WDYn8AzusIuMx3n8844pJwgxhTB7Gjuboptlz9Hri8JRdXi
88
VT9OS9Wt69ubcNoM6zuKASmtm48UuGnhj8v6XwvbjKZrL9kA+xf8ziazZfvvw/VG
89
Tm+IVFYB7d1x457jY5zjjXJvNysoowIDAQABo3YwdDAdBgNVHQ4EFgQUeF8ePnu0
90
fcAK50iBQDgAhHkOu8kwRQYDVR0jBD4wPIAUeF8ePnu0fcAK50iBQDgAhHkOu8mh
91
GaQXMBUxEzARBgNVBAoTCkVudHJvdXZlcnSCCQDVAaInJNaQ6TAMBgNVHRMEBTAD
92
AQH/MA0GCSqGSIb3DQEBBQUAA4IBAQAy8l3GhUtpPHx0FxzbRHVaaUSgMwYKGPhE
93
IdGhqekKUJIx8et4xpEMFBl5XQjBNq/mp5vO3SPb2h2PVSks7xWnG3cvEkqJSOeo
94
fEEhkqnM45b2MH1S5uxp4i8UilPG6kmQiXU2rEUBdRk9xnRWos7epVivTSIv1Ncp
95
lG6l41SXp6YgIb2ToT+rOKdIGIQuGDlzeR88fDxWEU0vEujZv/v1PE1YOV0xKjTT
96
JumlBc6IViKhJeo1wiBBrVRIIkKKevHKQzteK8pWm9CYWculxT26TZ4VWzGbo06j
97
o2zbumirrLLqnt1gmBDvDvlOwC/zAAyL4chbz66eQHTiIYZZvYgy
98
-----END CERTIFICATE-----'''
99

  
100
SAML_SIGNATURE_PRIVATE_KEY = '''-----BEGIN RSA PRIVATE KEY-----
101
MIIEpAIBAAKCAQEAvxFkfPdndlGgQPDZgFGXbrNAc/79PULZBuNdWFHDD9P5hNhZ
102
n9Kqm4Cp06Pe/A6u+g5wLnYvbZQcFCgfQAEzziJtb3J55OOlB7iMEI/T2AX2WzrU
103
H8QT8NGhABONKU2Gg4XiyeXNhH5R7zdHlUwcWq3ZwNbtbY0TVc+n665EbrfV/59x
104
ihSqsoFrkmBLH0CoepUXtAzA7WDYn8AzusIuMx3n8844pJwgxhTB7Gjuboptlz9H
105
ri8JRdXiVT9OS9Wt69ubcNoM6zuKASmtm48UuGnhj8v6XwvbjKZrL9kA+xf8ziaz
106
Zfvvw/VGTm+IVFYB7d1x457jY5zjjXJvNysoowIDAQABAoIBAQCj8t2iKXya10HG
107
V6Saaeih8aftoLBV38VwFqqjPU0+iKqDpk2JSXBhjI6s7uFIsaTNJpR2Ga1qvns1
108
hJQEDMQSLhJvXfBgSkHylRWCpJentr4E3D7mnw5pRsd61Ev9U+uHcdv/WHP4K5hM
109
xsdiwXNXD/RYd1Q1+6bKrCuvnNJVmWe0/RV+r3T8Ni5xdMVFbRWt/VEoE620XX6c
110
a9TQPiA5i/LRVyie+js7Yv+hVjGOlArtuLs6ECQsivfPrqKLOBRWcofKdcf+4N2e
111
3cieUqwzC15C31vcMliD9Hax9c1iuTt9Q3Xzo20fOSazAnQ5YBEExyTtrFBwbfQu
112
ku6hp81pAoGBAN6bc6iJtk5ipYpsaY4ZlbqdjjG9KEXB6G1MExPU7SHXOhOF0cDH
113
/pgMsv9hF2my863MowsOj3OryVhdQhwA6RrV263LRh+JU8NyHV71BwAIfI0BuVfj
114
6r24KudwtUcvMr9pJIrJyMAMaw5ZyNoX7YqFpS6fcisSJYdSBSoxzrzVAoGBANu6
115
xVeMqGavA/EHSOQP3ipDZ3mnWbkDUDxpNhgJG8Q6lZiwKwLoSceJ8z0PNY3VetGA
116
RbqtqBGfR2mcxHyzeqVBpLnXZC4vs/Vy7lrzTiHDRZk2SG5EkHMSKFA53jN6S/nJ
117
JWpYZC8lG8w4OHaUfDHFWbptxdGYCgY4//sjeiuXAoGBANuhurJ99R5PnA8AOgEW
118
4zD1hLc0b4ir8fvshCIcAj9SUB20+afgayRv2ye3Dted1WkUL4WYPxccVhLWKITi
119
rRtqB03o8m3pG3kJnUr0LIzu0px5J/o8iH3ZOJOTE3iBa+uI/KHmxygc2H+XPGFa
120
HGeAxuJCNO2kAN0Losbnz5dlAoGAVsCn94gGWPxSjxA0PC7zpTYVnZdwOjbPr/pO
121
LDE0cEY9GBq98JjrwEd77KibmVMm+Z4uaaT0jXiYhl8pyJ5IFwUS13juCbo1z/u/
122
ldMoDvZ8/R/MexTA/1204u/mBecMJiO/jPw3GdIJ5phv2omHe1MSuSNsDfN8Sbap
123
gmsgaiMCgYB/nrTk89Fp7050VKCNnIt1mHAcO9cBwDV8qrJ5O3rIVmrg1T6vn0aY
124
wRiVcNacaP+BivkrMjr4BlsUM6yH4MOBsNhLURiiCL+tLJV7U0DWlCse/doWij4U
125
TKX6tp6oI+7MIJE6ySZ0cBqOiydAkBePZhu57j6ToBkTa0dbHjn1WA==
126
-----END RSA PRIVATE KEY-----'''
127

  
128
# Import local config
129
try:
130
    from ..{module_name}.local_config import *
131
except ImportError, e:
132
    if not 'local_config' in e.args[0]:
133
        raise ImproperlyConfigured('Error while importing "local_config.py"')
134

  
skel/example.module/configs/linuxfr_saml_example.py
1

  
2
from {module_name}.auth.example import MyAuthSAML
3
from {module_name}.filters.example import ReplayFilter
4

  
5
from mandaye.configs import saml2 as saml2_config
6

  
7
form_values = {
8
        'login_url': '/compte/connexion',
9
        'form_attrs': { 'id': 'new_account' },
10
        'post_fields': ['account[login]', 'account[password]'],
11
        'username_field': 'account[login]',
12
        'password_field': 'account[password]',
13
}
14

  
15
auth = MyAuthSAML(form_values, 'linuxfr', saml2_config)
16

  
17
linuxfr_mapping = [
18
            {
19
                'path': r'/mandaye/associate$',
20
                'method': 'GET',
21
                'on_response': [{
22
                    'filter': ReplayFilter.associate,
23
                    'values': {
24
                        'action': '/mandaye/associate',
25
                        'template': 'associate.html',
26
                        'sp_name': 'Linux FR',
27
                        'login_name': form_values['username_field'],
28
                        'password_name': form_values['password_field'],
29
                        },
30
                    },]
31
                },
32
            {
33
                'path':  r'/mandaye/associate$',
34
                'method': 'POST',
35
                'response': [
36
                    {
37
                        'filter': auth.associate_submit,
38
                        'values': {
39
                            'connection_url': '/mandaye/sso',
40
                            'associate_url': '/mandaye/associate',
41
                            },
42
                        'condition': "response.code==302"
43
                        },
44
                    ]
45
                },
46
            ]
47

  
48
linuxfr_mapping.extend(auth.get_default_mapping())
49

  
skel/example.module/filters/example.py
1

  
2
from mandaye.template import serve_template
3

  
4
class ReplayFilter:
5

  
6
    @staticmethod
7
    def associate(env, values, request, response):
8
        associate = serve_template(values.get('template'), **values)
9
        response.msg = associate
10
        return response
11

  
skel/example.module/static/css/style.css
1
/* theme derived and inspired by TerraFirma
2
 * <http://www.oswd.org/design/information/id/3557/>
3
 */
4

  
5
html, body {
6
	margin: 0;
7
	font-family: sans-serif;
8
	font-size: 12px;
9
}
10

  
11
body#iframe {
12
    background: white;
13
}
14

  
15
html {
16
	background: #F9F9F7 url(../images/a1.gif) repeat-x;
17
	color: #44b2cb;
18
}
19

  
20
a
21
{
22
	color: #44b2cb;
23
	text-decoration: underline;
24
}
25

  
26
a:hover
27
{
28
	text-decoration: none;
29
}
30

  
31

  
32
div#wrap {
33
	background: white;
34
	width: 640px;
35
	margin: 5em auto;
36
	padding: 15px;
37
	-moz-border-radius: 6px;
38
	-webkit-border-radius:6px;
39
	-moz-box-shadow: 0 0 4px rgba(0,0,0,0.75);
40
	-webkit-box-shadow: 0 0 4px rgba(0,0,0,0.75);
41
	position: relative;
42
}
43

  
44
#header
45
{
46
	position: absolute;
47
	background: url(../images/a8.png) repeat-x;
48
	-moz-border-radius: 6px 0 0 6px;
49
	-webkit-border-radius: 6px 0 0 6px;
50
	width: 450px;
51
	height: 92px;
52
	color: #fff;
53
	padding-left: 20px;
54
}
55

  
56
#header h1
57
{
58
	font-size: 23px;
59
	letter-spacing: -1px;
60
	padding-top: 30px;
61
	margin: 0;
62
}
63

  
64
#header span
65
{
66
	margin: 0;
67
	font-size: 13px;
68
	font-weight: normal;
69
	color: #FCE2CA;
70
}
71

  
72
#splash
73
{
74
	position: absolute;
75
	right: 20px;
76
	background: url(../images/eo.png) no-repeat;
77
	width: 153px;
78
	height: 92px;
79
	-moz-border-radius: 0 6px 6px 0;
80
	-webkit-border-radius: 0 6px 6px 0;
81
}
82

  
83
div#content {
84
	margin: 1em 1ex;
85
	margin-top: 130px;
86
	padding: 1ex;
87
}
88

  
89
div#content h2 {
90
	margin-top: 0;
91
	font-weight: normal;
92
	color: #656551;
93
	font-size: 18px;
94
	letter-spacing: -1px;
95
	line-height: 25px;
96
	margin-bottom: 20px;
97
	padding: 0 0 10px 15px;
98
	position: relative;
99
	top: 4px;
100
	background: url(../images/a22.gif) bottom repeat-x;
101
}
102

  
103
#footer
104
{
105
	font-size: 70%;
106
	position: relative;
107
	clear: both;
108
	height: 66px;
109
	text-align: center;
110
	line-height: 66px;
111
	background-image: url(../images/a8.png);
112
	color: #fff;
113
}
114

  
115
#footer a
116
{
117
	color: #8C8C73;
118
}
119

  
120

  
121
form#login-form p {
122
	float: left;
123
	width: 40%;
124
}
125

  
126
form#login-form input.submit {
127
	float: right;
128
	width: 18%;
129
	margin-top: 30px;
130
}
131

  
132
div.login-actions {
133
	clear: both;
134
	padding-top: 1em;
135
}
136

  
137
div.login-actions p {
138
	margin: 0;
139
}
140

  
141
form p {
142
	margin: 0 0 1em 0;
143
}
144

  
145
form p label {
146
	display: block;
147
}
148

  
149
form p input,
150
form p textarea {
151
	margin-left: 10px;
152
}
153

  
154
ul.messages {
155
	margin: 0;
156
	padding: 0;
157
	list-style: none;
158
}
159

  
160
ul.messages li.error {
161
	color: #e80404;
162
}
163

  
164
ul.errorlist {
165
	margin: 0;
166
	padding: 0;
167
	color: #e80404;
168
	list-style: none;
169
}
170

  
171
input, textarea {
172
	padding: 5px;
173
	border: 1px solid #cccccc;
174
	color:#666666;
175
	background: white;
176
	color: black;
177
}
178

  
179
textarea:focus, input[type="text"]:focus, input[type="password"]:focus {
180
	border: 1px solid #4690d6;
181
	color:#333333;
182
}
183

  
184
input[type=submit] {
185
	color: #ffffff;
186
	background:#4690d6;
187
	border: 1px solid #2a567f;
188
	font-weight: bold;
189
	padding: 2px 8px 2px 8px;
190
	margin: 0;
191
	cursor: pointer;
192
}
193

  
194

  
195
input[type=submit]:hover {
196
	border-color: #0e1d2b;
197
}
198

  
199
form#login-form ul.errorlist {
200
	margin-bottom: 1em;
201
	width: 80%;
202
	font-weight: normal;
203
}
204

  
205
/* OpenID Stuff */
206

  
207
#openid_btns, #openid_btns br {
208
	clear: both;
209
}
210

  
211
#openid_highlight a {
212
	border: 1px solid #888;
213
}
214

  
215
#openid_input_area input[type=submit] {
216
	padding-top: 0;
217
	margin-top: 0;
218
	margin-left: 1em;
219
}
220

  
221
.openid_large_btn {
222
	width: 100px;
223
	height: 60px;
224
	border: 1px solid #DDD;
225
	margin: 3px;
226
	float: left;
227
}
228
.openid_small_btn {
229
	width: 24px;
230
	height: 24px;
231
	border: 1px solid #DDD;
232
	margin: 3px;
233
	float: left;
234
}
235

  
236
a.openid_large_btn:focus {
237
	outline: none;
238
}
239
a.openid_large_btn:focus {
240
	-moz-outline-style: none;
241
}
242
.openid_selected {
243
	border: 4px solid #DDD;
244
}
245

  
246
#openid_input_area {
247
	clear: both;
248
	padding-top: 2.5em;
249
}
250

  
251
li.indented {
252
	margin-left: 50px;
253
}
254

  
255
ul.NoBullet {
256
	list-style-type: none;
257
}
258

  
259
div#content h4 {
260
	margin-bottom: 5px;
261
	margin-top: 30px;
262
}
263

  
264
div#content p {
265
        margin-top: 0;
266
}
267

  
268
div.errors {
269
	margin: 0;
270
	padding: 0;
271
	color: #e80404;
272
	list-style: none;
273
}
274

  
275
div#breadcrumb {
276
	font-size: 80%;
277
	margin-bottom: 1em;
278
}
279

  
280
div#user {
281
	position: absolute;
282
	top: 115px;
283
	right: 12px;
284
}
285

  
286
a#logout {
287
	font-size: 100%;
288
}
289

  
290

  
291
.ui-tabs .ui-tabs-hide {
292
     display: none;
293
}
294

  
295
h4 {
296
	padding-left: 0.5em;
297
}
298

  
299
h4 + div, div#profile {
300
	padding-left: 1em;
301
}
302

  
303

  
304
div#menu {
305
position: relative;
306
background: #46461F url(../images/a17.gif) repeat-x;
307
height: 67px;
308
padding: 0px 20px 0px 5px;
309
margin: 136px 0px 0px 0px;
310
}
311

  
312
#menu ul
313
{
314
        padding: 0;
315
        margin: 0;
316
}
317

  
318
#menu ul li
319
{
320
display: inline;
321
line-height: 52px;
322
padding-left: 3px;
323
}
324

  
325
#menu ul li.first
326
{
327
border-left: 0px;
328
}
329

  
330
#menu ul li a
331
{
332
background-color: transparent;
333
background-repeat: repeat-x;
334
padding: 8px 12px 8px 12px;
335
font-size: 12px;
336
color: #fff;
337
font-weight: bold;
338
}
339
#menu ul li a:hover
340
{
341
background: #fff url(../images/a18.gif) repeat-x top;
342
color: #4A4A24;
343
text-decoration: none;
344
}
345

  
346
#eo
347
{
348
position: absolute;
349
top: 0px;
350
line-height: 52px;
351
color: #BDBDA2;
352
right: 30px;
353
font-weight: bold;
354
font-size: 12px;
355
letter-spacing: -1px;
356
}
357

  
358
#eo a {
359
        color: inherit;
360
        text-decoration: none;
361
}
362

  
363
ul#tab-nav {
364
        list-style: none;
365
        padding: 0;
366
        width: 160px;
367
        float: left;
368
}
369

  
370
ul#tab-nav li {
371
        line-height: 300%;
372
        position: relative;
373
        right: -1px;
374
        border: 1px solid transparent;
375
}
376

  
377
ul#tab-nav li.ui-tabs-selected {
378
        border: 1px solid #ccc;
379
        border-right: 1px solid white;
380
}
381

  
382
ul#tab-nav a {
383
        display: block;
384
        padding-left: 1ex;
385
        outline: none;
386
        -moz-user-focus:ignore;
387
}
388

  
389
ul#tab-nav a:hover {
390
}
391

  
392
ul#tab-nav a:active {
393
}
394

  
395
/* XXX: add a class to divs, so it works in IE */
396
div#tabs > div {
397
        border: 1px solid #ccc;
398
        float: left;
399
        width: 420px;
400
        padding: 10px;
401
        min-height: 26em;
402
}
403

  
404
a.bigbutton {
405
	display: block;
406
	-moz-border-radius: 6px;
407
	-webkit-border-radius:6px;
408
	border: 1px solid black;
409
	margin: 2em 0;
410
	line-height: 300%;
411
	text-align: center;
412
	text-decoration: none;
413
	font-weight: bold;
414
	-webkit-box-shadow: 0 0 4px rgba(0,0,0,0.75);
415
	-moz-box-shadow: 0 0 4px rgba(0,0,0,0.75);
416
}
417

  
418
a.bigbutton:hover {
419
	background: #eee;
420
}
421

  
422
div#providers {
423
	display: none;
424
}
425

  
426
#modalOverlay {
427
	height:100%;
428
	width:100%;
429
	position:fixed;
430
	left:0;
431
	top:0;
432
	z-index:3000;
433
	background-color: rgba(0, 0, 0, 0.8);
434
	cursor:wait;
435
}
436

  
437
div#popup {
438
	display: none;
439
	position:fixed;
440
	width:500px;
441
	left:50%;
442
	margin-left:-250px;
443
	z-index:3100;
444
	top: 10%;
445
}
446

  
447
div#popup div {
448
	position: relative;
449
	margin: 0;
450
	background: white;
451
	border: 1px solid black;
452
	border-color: #333 black black #333;
453
}
454

  
455
div#popup h2 {
456
	text-align: center;
457
}
458

  
459
div#popup ul {
460
	max-height: 70px;
461
	overflow: auto;
462
	margin: 0 1em 1em 1em;
463
	padding: 0 1em 1em 1em;
464
}
465

  
466
div#popup h3 {
467
	margin-bottom: 4px;
468
	padding-left: 10px;
469
}
470

  
471
div#popup p {
472
	margin: 5px;
473
}
474

  
475
div#popup a#close {
476
	float: right;
477
	padding: 1ex;
478
}
479

  
480
a.roleid_button {
481
    -moz-border-radius: 5px;
482
    -webkit-border-radius: 5px;
483
    border-radius: 5px;
484
    background: #5C5C5C;
485
    color: #44b2cb;
486
    font-weight: bold;
487
    padding-top: 5px;
488
    padding-bottom: 5px;
489
    padding-right: 10px;
490
    padding-left: 10px;
491
    margin: 0;
492
    cursor: pointer;
493
    text-decoration: none;
494
}
495

  
496
a.roleid_button:hover {
497
    background: black;
498
}
skel/example.module/templates/associate.html
1
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
2
<html>
3
  <head>
4
  <link rel="stylesheet" href="${static_url}/css/style.css" />
5
    <title>1er connexion</title>
6
  </head>
7
  <body>
8
    <div id="wrap">
9
      <div id="header">
10
        <h1>Première connexion</h1>
11
        <span>Associer un compte</span>
12
      </div>
13
      <div id="splash"></div>
14
      <div id="content">
15
        <h1>Association</h1>
16
        <p>Associer ${sp_name} avec votre compte citoyen</p>
17
        <form action="${action}" method="post" accept-charset="utf-8">
18
          <div>
19
            <label for="username">Utilisateur</label>
20
            <input type="text" name="${login_name}" value="" id="username" />
21
          </div>
22
          <div>
23
            <label for="password">Mot de passe</label>
24
            <input type="password" name="${password_name}" value="" id="password" />
25
          </div>
26
          <p><input type="submit" value="Associer"></p>
27
        </form>
28
      </div>
29
      <div id="footer">
30
        Copyright &copy; 2013 Entr'ouvert
31
      </div>
32
    </div>
33
  </body>
34
</html>
skel/example.module/wsgi.py
1

  
2
import os
3

  
4
from mandaye.server import MandayeApp
5

  
6
from {module_name} import config
7
from beaker.middleware import SessionMiddleware
8

  
9
os.environ['MANDAYE_CONFIG_MODULE'] = '{module_name}.config'
10

  
11
application = SessionMiddleware(MandayeApp(), config.session_opts)
12

  
13

  
skel/local_config.py.example
1
## Virtual hosts configuration
2
hosts = {
3
        'linuxfrsaml.local:8000': [
4
            {
5
                'path': r'/',
6
                'target': 'http://linuxfr.org',
7
                'mapping': '{module_name}.configs.linuxfr_saml_example.linuxfr_mapping'
8
                },
9
            ],
10

  
11
        }
12

  
13
## SQL Backend config
14
# http://docs.sqlalchemy.org/en/rel_0_7/core/engines.html
15
# rfc 1738 https://tools.ietf.org/html/rfc1738
16
# dialect+driver://username:password@host:port/database
17
db_url = 'sqlite:///test.db'
18

  
19
## Logging configuration
20
debug = False
skel/manager.template
1
#! /usr/bin/python
2
# -*- coding: utf-8 -*-
3

  
4
""" Script to administrate mandaye server
5
"""
6

  
7
import os
8
os.environ['MANDAYE_CONFIG_MODULE'] = '{module_name}.config'
9

  
10
import base64
11

  
12
from optparse import OptionParser
13

  
14
from mandaye import config
15
from mandaye.log import logger
16

  
17
def get_cmd_options():
18
    usage = "usage: %prog --createdb|--upgradedb|--cryptpwd"
19
    parser = OptionParser(usage=usage)
20
    parser.add_option("--createdb",
21
            dest="createdb",
22
            default=False,
23
            action="store_true",
24
            help="Create Mandaye database"
25
            )
26
    parser.add_option("--upgradedb",
27
            dest="upgradedb",
28
            default=False,
29
            action="store_true",
30
            help="Upgrade Mandaye database"
31
            )
32
    parser.add_option("--cryptpwd",
33
            dest="cryptpwd",
34
            default=False,
35
            action="store_true",
36
            help="Crypt external password in Mandaye's database"
37
            )
38
    (options, args) = parser.parse_args()
39
    return options
40

  
41
def encrypt_pwd(pwd):
42
    from Crypto.Cipher import AES
43
    logger.debug("Encrypt password")
44
    enc_pwd = pwd
45
    if config.encrypt_secret:
46
        try:
47
            cipher = AES.new(config.encrypt_secret, AES.MODE_CFB)
48
            enc_pwd = cipher.encrypt(pwd)
49
            enc_pwd = base64.b64encode(enc_pwd)
50
        except Exception, e:
51
            if config.debug:
52
                traceback.print_exc()
53
            logger.warning('Password encrypting failed %s' % e)
54
    else:
55
        logger.warning("You must set a secret to use pwd encryption")
56
    return enc_pwd
57

  
58
def main():
59
    options = get_cmd_options()
60
    if options.createdb or options.upgradedb:
61
        logger.info("Creating or upgrading database...")
62
        from alembic.config import Config
63
        from alembic import command
64
        from mandaye import global_config
65
        alembic_cfg = Config(global_config.alembic_cfg)
66
        alembic_cfg.set_main_option("script_location", global_config.alembic_script_path)
67
        command.upgrade(alembic_cfg, "head")
68
        logger.info("Database upgraded")
69
    if options.cryptpwd:
70
        from mandaye.backends.default import ManagerSPUser
71
        for user in ManagerSPUser.all():
72
            user.password = encrypt_pwd(user.password)
73
        ManagerSPUser.save()
74

  
75
if __name__ == "__main__":
76
    main()
77

  
skel/requirements.txt
1
gunicorn>=0.17
2
mandaye>=0.7.1
skel/server.template
1
#!/usr/bin/env python
2
# -*- coding: utf-8 -*-
3

  
4
""" Script to launch mandaye with gunicorn server
5
"""
6

  
7
import os
8
os.environ['MANDAYE_CONFIG_MODULE'] = '{module_name}.config'
9

  
10
import sys
11

  
12
from mandaye.log import logger
13
from gunicorn.app.wsgiapp import WSGIApplication
14

  
15
class MandayeWSGIApplication(WSGIApplication):
16

  
17
    def init(self, parser, opts, args):
18
        self.cfg.set("default_proc_name", "{module_name}.wsgi:application")
19
        self.app_uri = "{module_name}.wsgi:application"
20

  
21
def main():
22
    """ The ``gunicorn`` command line runner for launcing Gunicorn with
23
    generic WSGI applications.
24
    """
25
    logger.info('{project_name} reverse-proxy start')
26
    MandayeWSGIApplication("%(prog)s [OPTIONS]").run()
27

  
28
if __name__ == "__main__":
29
    main()
30

  
skel/setup.py.template
1
#! /usr/bin/env python
2

  
3
'''
4
   Setup script for {project_name} RP
5
'''
6

  
7
import os
8
import subprocess
9

  
10
from setuptools import setup, find_packages
11
from sys import version
12

  
13
import {module_name}
14

  
15
install_requires=[
16
        'gunicorn>=0.17',
17
        'mandaye>=0.7.1',
18
]
19

  
20
def get_version():
21
    if os.path.exists('VERSION'):
22
        version_file = open('VERSION', 'r')
23
        version = version_file.read()
24
        version_file.close()
25
        return version
26
    if os.path.exists('.git'):
27
        p = subprocess.Popen(['git','describe','--match=v*'],
28
                stdout=subprocess.PIPE)
29
        result = p.communicate()[0]
30
        version = result.split()[0][1:]
31
        return version.replace('-','.')
32
    return {module_name}.VERSION
33

  
34
setup(name="{project_name}",
35
      version=get_version(),
36
      license="AGPLv3 or later",
37
      description="{project_name} rp is a Mandaye project, modular reverse proxy to authenticate",
38
      url="http://dev.entrouvert.org/projects/reverse-proxy/",
39
      author="Author",
40
      author_email="author@example.com",
41
      maintainer="Maintainer",
42
      maintainer_email="maintainer@exmaple.com",
43
      scripts=['{module_name}_manager', '{module_name}_server'],
44
      packages=find_packages(),
45
      include_package_data=True,
46
      install_requires=install_requires
47
)
48

  

Formats disponibles : Unified diff