Révision 5c65415c
Ajouté par Jérôme Schneider il y a environ 10 ans
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 © 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 © 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
add support for new project creation
Closes #3524