Révision e0ea574b
Ajouté par Jérôme Schneider il y a presque 11 ans
README.rst | ||
---|---|---|
52 | 52 |
* sqlalchemy-migrate:: http://pypi.python.org/pypi/sqlalchemy-migrate |
53 | 53 |
|
54 | 54 |
|
55 |
You can install all those dependencies quickly using pip:: |
|
56 |
|
|
57 |
pip install poster SQLAlchemy Beaker Mako lxml gunicorn sqlalchemy-migrate xtraceback |
|
58 |
|
|
59 |
or easy_install:: |
|
60 |
|
|
61 |
easy_install poster SQLAlchemy Beaker Mako lxml gunicorn sqlalchemy-migrate xtraceback |
|
62 |
|
|
63 |
or apt-get (Debian based distributions):: |
|
55 |
Quick installation |
|
56 |
------------------ |
|
64 | 57 |
|
65 |
apt-get install gunicorn python-poster python-sqlalchemy python-beaker python-mako python-lxml python-setuptools |
|
58 |
Install at least Python >=2.5 and pip in your system. |
|
59 |
For example with Debian or a Debian based distribution:: |
|
66 | 60 |
|
67 |
It's recommanded to install the following modules
|
|
61 |
sudo apt-get install python python-pip
|
|
68 | 62 |
|
69 |
* PyCrypto >= 2.3:: http://pypi.python.org/pypi/pycrypto |
|
70 |
* Static >= 0.4:: http://pypi.python.org/pypi/static |
|
63 |
Then install virtualenv :: |
|
71 | 64 |
|
72 |
You can install this Python modules with pip::
|
|
65 |
pip install virtualenv
|
|
73 | 66 |
|
74 |
pip install pycrypto static
|
|
67 |
Create your virtualenv activate it::
|
|
75 | 68 |
|
76 |
Quick installation |
|
77 |
------------------ |
|
69 |
virtualenv mandaye |
|
70 |
source mandaye/bin/activate |
|
71 |
pip install -U pip |
|
78 | 72 |
|
79 |
Install at least Python >=2.5 and setuptools or distribute and enter this command in a shell::
|
|
73 |
Install mandaye::
|
|
80 | 74 |
|
75 |
$ tar xfvz mandaye-VERSION.tar.gz |
|
76 |
$ cd mandaye-VERSION |
|
77 |
$ pip install -r requirements.txt |
|
81 | 78 |
$ python setup.py install |
82 | 79 |
|
83 | 80 |
If you want to develop use this command line:: |
... | ... | |
88 | 85 |
Quick Start |
89 | 86 |
----------- |
90 | 87 |
|
91 |
Configure MANDAYE_PATH/mandaye/config.py with your own preferences. |
|
92 |
You must configure the database uri and the log file. |
|
93 |
|
|
94 |
First create your database:: |
|
88 |
First step is to create a mandaye project:: |
|
95 | 89 |
|
96 |
$ mandaye_admin.py --createdb
|
|
90 |
$ mandaye_admin.py --newproject
|
|
97 | 91 |
|
98 | 92 |
Launch mandaye server:: |
99 | 93 |
|
mandaye/auth/authform.py | ||
---|---|---|
16 | 16 |
from urlparse import parse_qs |
17 | 17 |
|
18 | 18 |
from mandaye import config, VERSION |
19 |
from mandaye.db import sql_session |
|
20 | 19 |
from mandaye.exceptions import MandayeException |
21 |
from mandaye.models import Site, ExtUser, LocalUser |
|
22 | 20 |
from mandaye.log import logger |
23 | 21 |
from mandaye.http import HTTPResponse, HTTPHeader, HTTPRequest |
24 | 22 |
from mandaye.response import _500, _302, _401 |
25 | 23 |
from mandaye.response import template_response |
26 | 24 |
from mandaye.server import get_response |
27 | 25 |
|
26 |
from mandaye.config.backend import ManagerIDPUser, ManagerSPUser,\ |
|
27 |
ManagerServiceProvider |
|
28 |
|
|
28 | 29 |
try: |
29 | 30 |
from Crypto.Cipher import AES |
30 | 31 |
except ImportError: |
31 |
config.encrypt_ext_password = False
|
|
32 |
config.encrypt_sp_password = False
|
|
32 | 33 |
|
33 | 34 |
class AuthForm(object): |
34 | 35 |
|
... | ... | |
72 | 73 |
|
73 | 74 |
def _encrypt_pwd(self, post_values): |
74 | 75 |
""" This method allows you to encrypt a password |
75 |
To use this feature you muste set encrypt_ext_password to True
|
|
76 |
To use this feature you muste set encrypt_sp_password to True
|
|
76 | 77 |
in your configuration and set a secret in encrypt_secret |
77 | 78 |
post_values: containt the post values |
78 | 79 |
return None and modify post_values |
... | ... | |
98 | 99 |
def _decrypt_pwd(self, post_values): |
99 | 100 |
""" This method allows you to dencrypt a password encrypt with |
100 | 101 |
_encrypt_pwd method. To use this feature you muste set |
101 |
encrypt_ext_password to True in your configuration and
|
|
102 |
encrypt_sp_password to True in your configuration and
|
|
102 | 103 |
set a secret in encrypt_secret |
103 | 104 |
post_values: containt the post values |
104 | 105 |
return None and modify post_values |
... | ... | |
120 | 121 |
|
121 | 122 |
def _get_password(self, post_values): |
122 | 123 |
if self.form_values.has_key('password_field'): |
123 |
if config.encrypt_ext_password:
|
|
124 |
if config.encrypt_sp_password:
|
|
124 | 125 |
return self._encrypt_pwd( |
125 | 126 |
post_values[self.form_values['password_field']] |
126 | 127 |
) |
... | ... | |
182 | 183 |
request = HTTPRequest(cookies, headers, "POST", params) |
183 | 184 |
return get_response(env, request, action, cj) |
184 | 185 |
|
185 |
def _save_association(self, env, local_login, post_values):
|
|
186 |
def _save_association(self, env, unique_id, post_values):
|
|
186 | 187 |
""" save an association in the database |
187 | 188 |
env: wsgi environment |
188 |
local_login: the Mandaye login
|
|
189 |
unique_id: idp uinique id
|
|
189 | 190 |
post_values: dict with the post values |
190 | 191 |
""" |
191 |
ext_username = post_values[self.form_values['username_field']]
|
|
192 |
if config.encrypt_ext_password:
|
|
192 |
sp_login = post_values[self.form_values['username_field']]
|
|
193 |
if config.encrypt_sp_password:
|
|
193 | 194 |
self._encrypt_pwd(post_values) |
194 |
site = sql_session().query(Site).\ |
|
195 |
filter_by(name=self.site_name).first() |
|
196 |
if not site: |
|
197 |
logger.info('Add %s site in the database' % self.site_name) |
|
198 |
site = Site(self.site_name) |
|
199 |
sql_session().add(site) |
|
200 |
local_user = sql_session().query(LocalUser).\ |
|
201 |
filter_by(login=local_login).first() |
|
202 |
if not local_user: |
|
203 |
logger.debug('Add user %s in the database' % local_login) |
|
204 |
local_user = LocalUser(login=local_login) |
|
205 |
sql_session().add(local_user) |
|
206 |
ext_user = sql_session().query(ExtUser).\ |
|
207 |
join(LocalUser).\ |
|
208 |
filter(LocalUser.login==local_login).\ |
|
209 |
filter(ExtUser.login==ext_username).\ |
|
210 |
first() |
|
211 |
if not ext_user: |
|
212 |
ext_user = ExtUser() |
|
213 |
sql_session().add(ext_user) |
|
214 |
logger.info('New association: %s with %s on site %s' % \ |
|
215 |
(ext_username, local_login, self.site_name)) |
|
216 |
ext_user.login = ext_username |
|
217 |
ext_user.post_values = post_values |
|
218 |
ext_user.local_user = local_user |
|
219 |
ext_user.last_connection = datetime.now() |
|
220 |
ext_user.site = site |
|
221 |
sql_session().commit() |
|
222 |
env['beaker.session']['login'] = local_login |
|
223 |
env['beaker.session'][self.site_name] = ext_user.id |
|
195 |
service_provider = ManagerServiceProvider.get_or_create(self.site_name) |
|
196 |
idp_user = ManagerIDPUser.get_or_create(unique_id) |
|
197 |
sp_user = ManagerSPUser.get_or_create(sp_login, post_values, |
|
198 |
idp_user, service_provider) |
|
199 |
sp_user.login = sp_login |
|
200 |
sp_user.post_values = post_values |
|
201 |
sp_user.idp_user = idp_user |
|
202 |
sp_user.last_connection = datetime.now() |
|
203 |
sp_user.service_provider = service_provider |
|
204 |
ManagerSPUser.save() |
|
205 |
env['beaker.session']['unique_id'] = unique_id |
|
206 |
env['beaker.session'][self.site_name] = sp_user.id |
|
224 | 207 |
env['beaker.session'].save() |
225 | 208 |
|
226 | 209 |
def associate_submit(self, env, values, condition, request, response): |
227 | 210 |
""" Associate your login / password into your database |
228 | 211 |
""" |
229 | 212 |
logger.debug("Trying to associate a user") |
230 |
login = env['beaker.session'].get('login')
|
|
213 |
unique_id = env['beaker.session'].get('unique_id')
|
|
231 | 214 |
if request.msg: |
232 |
if not login:
|
|
215 |
if not unique_id:
|
|
233 | 216 |
logger.warning("Association failed: user isn't login on Mandaye") |
234 | 217 |
return _302(values.get('connection_url')) |
235 | 218 |
post = parse_qs(request.msg.read(), request) |
... | ... | |
247 | 230 |
response = self.replay(env, post_values) |
248 | 231 |
if eval(condition): |
249 | 232 |
logger.debug("Replay works: save the association") |
250 |
self._save_association(env, login, post_values)
|
|
233 |
self._save_association(env, unique_id, post_values)
|
|
251 | 234 |
if qs.has_key('next_url'): |
252 | 235 |
return _302(qs['next_url'], response.cookies) |
253 | 236 |
return response |
... | ... | |
256 | 239 |
qs['type'] = 'badlogin' |
257 | 240 |
return _302(values.get('associate_url') + "?%s" % urllib.urlencode(qs)) |
258 | 241 |
|
259 |
def _login_ext_user(self, ext_user, env, condition, values):
|
|
260 |
""" Log in an external user
|
|
242 |
def _login_sp_user(self, sp_user, env, condition, values):
|
|
243 |
""" Log in sp user
|
|
261 | 244 |
""" |
262 |
if not ext_user.login:
|
|
245 |
if not sp_user.login:
|
|
263 | 246 |
return _500(env['PATH_INFO'], |
264 | 247 |
'Invalid values for AuthFormDispatcher.login') |
265 |
post_values = copy.deepcopy(ext_user.post_values)
|
|
266 |
if config.encrypt_ext_password:
|
|
248 |
post_values = copy.deepcopy(sp_user.post_values)
|
|
249 |
if config.encrypt_sp_password:
|
|
267 | 250 |
self._decrypt_pwd(post_values) |
268 | 251 |
response = self.replay(env, post_values) |
269 | 252 |
if condition and eval(condition): |
270 |
ext_user.last_connection = datetime.now()
|
|
271 |
sql_session().commit()
|
|
272 |
env['beaker.session'][self.site_name] = ext_user.id
|
|
253 |
sp_user.last_connection = datetime.now()
|
|
254 |
ManagerSPUser.save()
|
|
255 |
env['beaker.session'][self.site_name] = sp_user.id
|
|
273 | 256 |
env['beaker.session'].save() |
274 | 257 |
return response |
275 | 258 |
else: |
... | ... | |
279 | 262 |
""" Automatic login on a site with a form |
280 | 263 |
""" |
281 | 264 |
logger.debug('Trying to login on Mandaye') |
282 |
login = self.get_current_login(env) |
|
283 |
if not login: |
|
265 |
# Specific method to get current idp unique id |
|
266 |
unique_id = self.get_current_unique_id(env) |
|
267 |
if not unique_id: |
|
284 | 268 |
return _401('Access denied: invalid token') |
285 | 269 |
|
286 | 270 |
# FIXME: hack to force beaker to generate an id |
287 | 271 |
# somtimes beaker doesn't do it by himself |
288 | 272 |
env['beaker.session'].regenerate_id() |
289 | 273 |
|
290 |
env['beaker.session']['login'] = login
|
|
274 |
env['beaker.session']['unique_id'] = unique_id
|
|
291 | 275 |
env['beaker.session'].save() |
292 |
logger.debug('User %s successfully login' % env['beaker.session']['login']) |
|
293 | 276 |
|
294 |
ext_user = sql_session().query(ExtUser).\ |
|
295 |
join(LocalUser).\ |
|
296 |
join(Site).\ |
|
297 |
filter(LocalUser.login==login).\ |
|
298 |
filter(Site.name==self.site_name).\ |
|
299 |
order_by(ExtUser.last_connection.desc()).\ |
|
300 |
first() |
|
301 |
if not ext_user: |
|
302 |
logger.debug('User %s is not associate' % env['beaker.session']['login']) |
|
277 |
logger.debug('User %s successfully login' % env['beaker.session']['unique_id']) |
|
278 |
|
|
279 |
idp_user = ManagerIDPUser.get(unique_id) |
|
280 |
service_provider = ManagerServiceProvider.get(self.site_name) |
|
281 |
sp_user = ManagerSPUser.get_last_connected(idp_user, service_provider) |
|
282 |
if not sp_user: |
|
283 |
logger.debug('User %s is not associate' % env['beaker.session']['unique_id']) |
|
303 | 284 |
return _302(values.get('associate_url') + "?type=first") |
304 |
return self._login_ext_user(ext_user, env, condition, values)
|
|
285 |
return self._login_sp_user(sp_user, env, condition, values)
|
|
305 | 286 |
|
306 | 287 |
def logout(self, env, values, request, response): |
307 | 288 |
""" Destroy the Beaker session |
... | ... | |
317 | 298 |
This method must have a query string with a username parameter |
318 | 299 |
""" |
319 | 300 |
# TODO: need to logout the first |
320 |
login = env['beaker.session']['login']
|
|
301 |
unique_id = env['beaker.session']['unique_id']
|
|
321 | 302 |
qs = parse_qs(env['QUERY_STRING']) |
322 | 303 |
if not login or not qs.has_key('id'): |
323 | 304 |
return _401('Access denied: beaker session invalid or not qs id') |
324 | 305 |
id = qs['id'][0] |
325 |
ext_user = sql_session().query(ExtUser).\ |
|
326 |
join(LocalUser).\ |
|
327 |
filter(LocalUser.login==login).\ |
|
328 |
filter(ExtUser.id==id).\ |
|
329 |
first() |
|
330 |
if not ext_user: |
|
306 |
service_provider = ManagerServiceProvider.get(self.site_name) |
|
307 |
idp_user = ManagerServiceProvider.get(unique_id) |
|
308 |
sp_user = ManagerSPUser.get_last_connected(idp_user, service_provider) |
|
309 |
if not sp_user: |
|
331 | 310 |
return _302(values.get('associate_url')) |
332 |
return self._login_ext_user(ext_user, env, 'response.code==302', values)
|
|
311 |
return self._login_sp_user(sp_user, env, 'response.code==302', values)
|
|
333 | 312 |
|
334 | 313 |
def disassociate(self, env, values, request, response): |
335 | 314 |
""" Multi accounts feature |
... | ... | |
345 | 324 |
if not login or not qs.has_key('id'): |
346 | 325 |
return _401('Access denied: beaker session invalid or not id') |
347 | 326 |
id = qs['id'][0] |
348 |
ext_user = sql_session().query(ExtUser).\ |
|
349 |
join(LocalUser).\ |
|
350 |
filter(LocalUser.login==login).\ |
|
351 |
filter(ExtUser.id==id).\ |
|
352 |
first() |
|
353 |
if ext_user: |
|
354 |
logger.debug('Disassociate account %s' % ext_user.login) |
|
355 |
sql_session().delete(ext_user) |
|
356 |
sql_session().commit() |
|
327 |
sp_user = ManagerSPUser.get_by_id(id) |
|
328 |
if sp_user: |
|
329 |
ManagerSPUser.delete(sp_user) |
|
357 | 330 |
if qs.has_key('logout'): |
358 | 331 |
self.logout(env, values, request, response) |
359 | 332 |
return _302(values.get('next_url')) |
mandaye/auth/vincennes.py | ||
---|---|---|
38 | 38 |
res[keyvalue[0]] = keyvalue[1] |
39 | 39 |
return res |
40 | 40 |
|
41 |
def get_current_login(self, env):
|
|
42 |
""" Return the current Vincennes pseudo
|
|
41 |
def get_current_unique_id(self, env):
|
|
42 |
""" Return the current Vincennes unique id
|
|
43 | 43 |
""" |
44 | 44 |
from mandaye import config |
45 | 45 |
# TODO: test time validity |
... | ... | |
97 | 97 |
if not login: |
98 | 98 |
logger.debug('Auto login failed because the user is not connected on vincennes.fr') |
99 | 99 |
return _302(path, request.cookies) |
100 |
env['beaker.session']['login'] = login
|
|
100 |
env['beaker.session']['unique_id'] = unique_id
|
|
101 | 101 |
env['beaker.session'].save() |
102 | 102 |
ext_user = sql_session().query(ExtUser).\ |
103 | 103 |
join(LocalUser).\ |
mandaye/backends/default.py | ||
---|---|---|
1 |
|
|
2 |
class DefaultManagerIDPUser: |
|
3 |
|
|
4 |
@staticmethod |
|
5 |
def get(unique_id, idp_id='default'): |
|
6 |
pass |
|
7 |
|
|
8 |
@staticmethod |
|
9 |
def create(unique_id, idp_id='default'): |
|
10 |
pass |
|
11 |
|
|
12 |
@staticmethod |
|
13 |
def get_or_create(unique_id, idp_id='default'): |
|
14 |
pass |
|
15 |
|
|
16 |
@staticmethod |
|
17 |
def delete(idp_user): |
|
18 |
pass |
|
19 |
|
|
20 |
@staticmethod |
|
21 |
def save(idp_user): |
|
22 |
pass |
|
23 |
|
|
24 |
class DefaultManagerSPUser: |
|
25 |
|
|
26 |
@staticmethod |
|
27 |
def get(login, idp_user, service_provider): |
|
28 |
pass |
|
29 |
|
|
30 |
@staticmethod |
|
31 |
def get_by_id(id): |
|
32 |
pass |
|
33 |
|
|
34 |
@staticmethod |
|
35 |
def get_last_connected(idp_user, service_provider): |
|
36 |
pass |
|
37 |
|
|
38 |
@staticmethod |
|
39 |
def create(login, post_values, idp_user, service_provider): |
|
40 |
pass |
|
41 |
|
|
42 |
@staticmethod |
|
43 |
def get_or_create(login, post_values, idp_user, service_provider): |
|
44 |
pass |
|
45 |
|
|
46 |
@staticmethod |
|
47 |
def delete(sp_user): |
|
48 |
pass |
|
49 |
|
|
50 |
@staticmethod |
|
51 |
def save(sp_user): |
|
52 |
pass |
|
53 |
|
|
54 |
class DefaultServiceProvider: |
|
55 |
|
|
56 |
@staticmethod |
|
57 |
def get(name): |
|
58 |
pass |
|
59 |
|
|
60 |
@staticmethod |
|
61 |
def create(name): |
|
62 |
pass |
|
63 |
|
|
64 |
@staticmethod |
|
65 |
def get_or_create(name): |
|
66 |
pass |
|
67 |
|
|
68 |
@staticmethod |
|
69 |
def delete(service_provider): |
|
70 |
pass |
|
71 |
|
|
72 |
@staticmethod |
|
73 |
def save(service_provider): |
|
74 |
pass |
|
75 |
|
|
76 |
|
mandaye/backends/sql.py | ||
---|---|---|
1 |
|
|
2 |
from datetime import datetime |
|
3 |
|
|
4 |
from mandaye.db import sql_session |
|
5 |
from mandaye.models import IDPUser, SPUser, ServiceProvider |
|
6 |
|
|
7 |
class ManagerIDPUserSQL: |
|
8 |
|
|
9 |
@staticmethod |
|
10 |
def get(unique_id, idp_id='default'): |
|
11 |
idp_user = sql_session().query(IDPUser).\ |
|
12 |
filter_by(unique_id=unique_id, |
|
13 |
idp_id='default') |
|
14 |
if len(idp_user) > 1: |
|
15 |
logger.critical('ManagerIDPUserSQL.get %s not unique' % unique_id) |
|
16 |
raise MandayeException( |
|
17 |
'ManagerIDPUserSQL.get : %s is not unique' % unique_id) |
|
18 |
if idp_user: |
|
19 |
return idp_user.first() |
|
20 |
else: |
|
21 |
return None |
|
22 |
|
|
23 |
@staticmethod |
|
24 |
def create(unique_id, idp_id='default'): |
|
25 |
idp_user = IDPUser( |
|
26 |
unique_id=unique_id, |
|
27 |
idp_id=idp_id) |
|
28 |
sql_session().add(idp_user) |
|
29 |
return idp_user |
|
30 |
|
|
31 |
@staticmethod |
|
32 |
def get_or_create(unique_id, idp_id='default'): |
|
33 |
if ManagerIDPUserSQL.get(**kwargs): |
|
34 |
return user |
|
35 |
else: |
|
36 |
return ManagerIDPUserSQL.create(**kwargs) |
|
37 |
|
|
38 |
@staticmethod |
|
39 |
def delete(idp_user): |
|
40 |
sql_session().delete(idp_user) |
|
41 |
sql_session().commit() |
|
42 |
|
|
43 |
@staticmethod |
|
44 |
def save(): |
|
45 |
sql_session().commit() |
|
46 |
|
|
47 |
class ManagerSPUserSQL: |
|
48 |
|
|
49 |
@staticmethod |
|
50 |
def get(login, idp_user, service_provider): |
|
51 |
sp_user = sql_session().query(SPPUser).\ |
|
52 |
join(IDPUser).\ |
|
53 |
join(ServiceProvider).\ |
|
54 |
filter_by(login=login, |
|
55 |
idp_user=idp_user, |
|
56 |
service_provider=service_provider) |
|
57 |
if sp_user: |
|
58 |
return sp_user.first() |
|
59 |
else: |
|
60 |
return None |
|
61 |
|
|
62 |
@staticmethod |
|
63 |
def get_by_id(id): |
|
64 |
return sql_session().query(SPUser).\ |
|
65 |
filter(id==id).first() |
|
66 |
|
|
67 |
@staticmethod |
|
68 |
def get_last_connected(idp_user, service_provider): |
|
69 |
return sql_session().query(SPPUser).\ |
|
70 |
join(IDPUser).\ |
|
71 |
join(ServiceProvider).\ |
|
72 |
filter(idp_user=idp_user).\ |
|
73 |
filer(service_provider=service_provider).\ |
|
74 |
order_by(SPUser.last_connection.desc()).\ |
|
75 |
first() |
|
76 |
@staticmethod |
|
77 |
def get_sp_users(idp_unique_id, service_provider_name): |
|
78 |
return sql_session().query(SPUser).\ |
|
79 |
join(IDPUser).\ |
|
80 |
join(ServiceProvider).\ |
|
81 |
filter(IDPUser.unique_id==idp_unique_id).\ |
|
82 |
filter(ServiceProvider.name==service_provider_name).\ |
|
83 |
order_by(SPUser.last_connection.desc()).\ |
|
84 |
all() |
|
85 |
|
|
86 |
@staticmethod |
|
87 |
def create(login, post_values, idp_user, service_provider): |
|
88 |
sp_user = SPUser( |
|
89 |
login=login, |
|
90 |
post_values=post_values, |
|
91 |
idp_id=idp_id, |
|
92 |
service_provider = service_provider |
|
93 |
) |
|
94 |
logger.info('New association: %s with %s on site %s' % \ |
|
95 |
(login, idp_user.unique_id, service_provider.name)) |
|
96 |
sql_session().add(sp_user) |
|
97 |
sql_session().commit() |
|
98 |
return idp_user |
|
99 |
|
|
100 |
@staticmethod |
|
101 |
def get_or_create(login, post_values, idp_user, service_provider): |
|
102 |
sp_user = ManagerSPUserSQL.get(login, idp_user, service_provider) |
|
103 |
if sp_user: |
|
104 |
return sp_user |
|
105 |
else: |
|
106 |
return ManagerSPUserSQL.create(login, post_values, |
|
107 |
idp_user, service_provider) |
|
108 |
@staticmethod |
|
109 |
def all(): |
|
110 |
return sql_session().query(SPUser).all() |
|
111 |
|
|
112 |
@staticmethod |
|
113 |
def delete(sp_user): |
|
114 |
logger.debug('Disassociate account %s' % sp_user.login) |
|
115 |
sql_session().delete(sp_user) |
|
116 |
sql_session().commit() |
|
117 |
|
|
118 |
@staticmethod |
|
119 |
def save(): |
|
120 |
sql_session().commit() |
|
121 |
|
|
122 |
class ManagerServiceProviderSQL: |
|
123 |
|
|
124 |
@staticmethod |
|
125 |
def get(name): |
|
126 |
sp = sql_session().query(ServiceProvider).\ |
|
127 |
filter_by(name=name) |
|
128 |
if sp: |
|
129 |
return sp.first() |
|
130 |
else: |
|
131 |
return None |
|
132 |
|
|
133 |
@staticmethod |
|
134 |
def create(name): |
|
135 |
logger.info('Add %s service provider into the database' % name) |
|
136 |
sp = ServiceProvider(name=name) |
|
137 |
sql_session().add(sp) |
|
138 |
sql_session().commit() |
|
139 |
return sp |
|
140 |
|
|
141 |
@staticmethod |
|
142 |
def get_or_create(name): |
|
143 |
sp = ManagerServiceProviderSQL.get(name) |
|
144 |
if sp: |
|
145 |
return sp |
|
146 |
else: |
|
147 |
return ManagerServiceProviderSQL.create(name) |
|
148 |
|
|
149 |
@staticmethod |
|
150 |
def delete(service_provider): |
|
151 |
logger.debug('Delete service provider %s' % service_provider.name) |
|
152 |
sql_session().delete(service_provider) |
|
153 |
sql_session().commit() |
|
154 |
|
|
155 |
@staticmethod |
|
156 |
def save(): |
|
157 |
sql_session().commit() |
|
158 |
|
|
159 |
ManagerServiceProvider = ManagerServiceProviderSQL |
|
160 |
ManagerSPUser = ManagerSPUserSQL |
|
161 |
ManagerServiceProvider = ManagerServiceProviderSQL |
|
162 |
|
mandaye/config.py | ||
---|---|---|
1 | 1 |
import logging |
2 | 2 |
from mandaye.exceptions import ImproperlyConfigured |
3 | 3 |
|
4 |
# Database configuration |
|
5 |
# rfc 1738 http://rfc.net/rfc1738.html |
|
6 |
db_url = 'sqlite:///test.db' |
|
7 |
|
|
8 |
# Default local backend |
|
9 |
import mandaye.backends.sql |
|
10 |
backend = mandaye.backends.sql |
|
11 |
|
|
4 | 12 |
# Needed if ssl is activated |
5 | 13 |
ssl = False |
6 | 14 |
keyfile = '' |
... | ... | |
11 | 19 |
syslog = False |
12 | 20 |
log_file = '/var/log/mandaye/mandaye.log' |
13 | 21 |
log_level = logging.INFO |
22 |
|
|
14 | 23 |
# Log rotation |
15 | 24 |
# W[0-6] : weekly (0: Monday), D: day, ... (python doc) |
16 | 25 |
log_when = 'W6' |
... | ... | |
24 | 33 |
# Static folder |
25 | 34 |
static_root = 'mandaye/static' |
26 | 35 |
|
27 |
# Database configuration |
|
28 |
# rfc 1738 http://rfc.net/rfc1738.html |
|
29 |
db_url = 'sqlite:///test.db' |
|
30 | 36 |
|
31 | 37 |
# Email notification configuration |
32 | 38 |
email_notification = False |
... | ... | |
42 | 48 |
# Decompress response only if you load a filter |
43 | 49 |
auto_decompress = True |
44 | 50 |
|
45 |
# Encrypt external passwords with a secret
|
|
51 |
# Encrypt service provider passwords with a secret
|
|
46 | 52 |
# You should install pycypto to use this feature |
47 |
encrypt_ext_password = False
|
|
53 |
encrypt_sp_password = False
|
|
48 | 54 |
# Must be a 16, 24, or 32 bytes long |
49 | 55 |
encrypt_secret = '' |
50 | 56 |
|
mandaye/exceptions.py | ||
---|---|---|
9 | 9 |
class MandayeException(Exception): |
10 | 10 |
"Mandaye generic exception" |
11 | 11 |
pass |
12 |
|
mandaye/filters/vincennes.py | ||
---|---|---|
6 | 6 |
from BeautifulSoup import BeautifulSoup |
7 | 7 |
import lxml.html |
8 | 8 |
|
9 |
from mandaye.db import sql_session |
|
10 | 9 |
from mandaye.log import logger |
11 | 10 |
from mandaye.models import Site, ExtUser, LocalUser |
12 | 11 |
from mandaye.response import _302, _401 |
13 | 12 |
from mandaye.template import serve_template |
14 | 13 |
|
14 |
from mandaye.config.backend import ManagerSPUser |
|
15 |
|
|
15 | 16 |
def get_associate_form(env, values): |
16 | 17 |
""" Return association template content |
17 | 18 |
""" |
... | ... | |
37 | 38 |
""" Return the current Mandaye user """ |
38 | 39 |
site_name = values.get('site_name') |
39 | 40 |
if env['beaker.session'].get(site_name): |
40 |
return sql_session().query(ExtUser).\ |
|
41 |
get(env['beaker.session'].get(site_name)) |
|
41 |
return ManagerSPUser.get_by_id(env['beaker.session'].get(site_name)) |
|
42 | 42 |
else: |
43 | 43 |
return None |
44 | 44 |
|
... | ... | |
46 | 46 |
def get_multi_template(env, values, current_account): |
47 | 47 |
""" return the content of the multi account template |
48 | 48 |
""" |
49 |
login = env['beaker.session'].get('login')
|
|
49 |
unique_id = env['beaker.session'].get('unique_id')
|
|
50 | 50 |
if login: |
51 |
ext_users = sql_session().query(ExtUser).\ |
|
52 |
join(LocalUser).\ |
|
53 |
join(Site).\ |
|
54 |
filter(LocalUser.login==login).\ |
|
55 |
filter(Site.name==values.get('site_name')).\ |
|
56 |
order_by(ExtUser.last_connection.desc()).\ |
|
57 |
all() |
|
58 | 51 |
accounts = {} |
59 |
for ext_user in ext_users: |
|
60 |
accounts[ext_user.id] = ext_user.login |
|
52 |
sp_users = ManagerSPUser.get_sp_users(unique_id, |
|
53 |
values.get('site_name')) |
|
54 |
for sp_user in sp_users: |
|
55 |
accounts[sp_user.id] = sp_user.login |
|
61 | 56 |
if current_account: |
62 | 57 |
current_login = current_account.login |
63 | 58 |
else: |
... | ... | |
113 | 108 |
""" Modify response html to support multi accounts |
114 | 109 |
""" |
115 | 110 |
if response.msg and '<h2><div>Mon compte</div></h2>' in response.msg: |
116 |
if env['beaker.session'].get('login'):
|
|
111 |
if env['beaker.session'].get('unique_id'):
|
|
117 | 112 |
current_account = get_current_account(env, values) |
118 | 113 |
template = get_multi_template(env, values, current_account) |
119 | 114 |
if current_account: |
... | ... | |
177 | 172 |
""" |
178 | 173 |
if response.msg and\ |
179 | 174 |
'<!-- Navigation -->' in response.msg: |
180 |
login = env['beaker.session'].get('login')
|
|
175 |
login = env['beaker.session'].get('unique_id')
|
|
181 | 176 |
current_account = get_current_account(env, values) |
182 | 177 |
if login and current_account: |
183 | 178 |
disassociate = serve_template('famille/disassociate.html', |
... | ... | |
225 | 220 |
""" |
226 | 221 |
if response.msg \ |
227 | 222 |
and 'font-weight:bold;">Conservatoire de Vincennes' in response.msg: |
228 |
login = env['beaker.session'].get('login')
|
|
223 |
login = env['beaker.session'].get('unique_id')
|
|
229 | 224 |
site_name = values.get('site_name') |
230 | 225 |
current_account = get_current_account(env, values) |
231 | 226 |
if login and current_account: |
mandaye/migration/versions/001_initial_schema.py | ||
---|---|---|
1 |
import collections |
|
2 |
import json |
|
1 | 3 |
|
2 | 4 |
from datetime import datetime |
3 | 5 |
|
4 |
from sqlalchemy import * |
|
5 |
from migrate import * |
|
6 |
from sqlalchemy import Column, Integer, String, DateTime |
|
7 |
from sqlalchemy import ForeignKey |
|
8 |
from sqlalchemy.ext.declarative import declarative_base |
|
9 |
from sqlalchemy.ext.mutable import Mutable |
|
10 |
from sqlalchemy.orm import column_property, relationship, backref |
|
11 |
from sqlalchemy.types import TypeDecorator, VARCHAR |
|
12 |
|
|
13 |
Base = declarative_base() |
|
14 |
|
|
15 |
class JSONEncodedDict(TypeDecorator): |
|
16 |
"Represents an immutable structure as a json-encoded string." |
|
17 |
|
|
18 |
impl = VARCHAR |
|
19 |
|
|
20 |
def process_bind_param(self, value, dialect): |
|
21 |
if value is not None: |
|
22 |
value = json.dumps(value) |
|
23 |
return value |
|
24 |
|
|
25 |
def process_result_value(self, value, dialect): |
|
26 |
if value is not None: |
|
27 |
value = json.loads(value) |
|
28 |
return value |
|
29 |
|
|
30 |
class MutationDict(Mutable, dict): |
|
31 |
|
|
32 |
@classmethod |
|
33 |
def coerce(cls, key, value): |
|
34 |
""" Convert plain dictionaries to MutationDict. """ |
|
35 |
if not isinstance(value, MutationDict): |
|
36 |
if isinstance(value, dict): |
|
37 |
return MutationDict(value) |
|
38 |
# this call will raise ValueError |
|
39 |
return Mutable.coerce(key, value) |
|
40 |
else: |
|
41 |
return value |
|
42 |
|
|
43 |
def __setitem__(self, key, value): |
|
44 |
""" Detect dictionary set events and emit change events. """ |
|
45 |
dict.__setitem__(self, key, value) |
|
46 |
self.changed() |
|
47 |
|
|
48 |
def __delitem__(self, key): |
|
49 |
""" Detect dictionary del events and emit change events. """ |
|
50 |
dict.__delitem__(self, key) |
|
51 |
self.changed() |
|
52 |
|
|
53 |
MutationDict.associate_with(JSONEncodedDict) |
|
54 |
|
|
55 |
class ServiceProvider(Base): |
|
56 |
|
|
57 |
__tablename__ = 'service_provider' |
|
58 |
|
|
59 |
id = Column(Integer, primary_key=True) |
|
60 |
name = Column(String(50), unique=True, nullable=False) |
|
61 |
|
|
62 |
def __init__(self, name): |
|
63 |
self.name = name |
|
64 |
|
|
65 |
def __repr__(self): |
|
66 |
return "<ServiceProvider('%s')>" % (self.name) |
|
67 |
|
|
68 |
class IDPUser(Base): |
|
69 |
|
|
70 |
__tablename__ = 'idp_user' |
|
71 |
|
|
72 |
id = Column(Integer, primary_key=True) |
|
73 |
# Nameid, pseudo, email, ... |
|
74 |
unique_id = Column(String(150), nullable=False) |
|
75 |
# Entityid |
|
76 |
idp_id = Column(String(150), nullable=False) |
|
77 |
sp_users = relationship("SPUser", backref=backref('idp_user')) |
|
78 |
|
|
79 |
def __init__(self, unique_id=None, idp_id=None, sp_users=None): |
|
80 |
self.unique_id = unique_id |
|
81 |
self.idp_id = idp_id |
|
82 |
self.sp_users = sp_users |
|
83 |
|
|
84 |
def __repr__(self): |
|
85 |
return "<IDPUser %d '%s'>" % (self.id, self.unique_id) |
|
86 |
|
|
87 |
|
|
88 |
class SPUser(Base): |
|
89 |
|
|
90 |
__tablename__ = 'sp_user' |
|
91 |
|
|
92 |
id = Column(Integer, primary_key=True) |
|
93 |
post_values = Column(JSONEncodedDict, nullable=False) |
|
94 |
creation_date = Column(DateTime, default=datetime.now(), nullable=False) |
|
95 |
last_connection = Column(DateTime, default=datetime.now()) |
|
96 |
|
|
97 |
idp_user_id = Column(Integer, ForeignKey('idp_user.id')) |
|
98 |
service_provider_id = Column(Integer, ForeignKey('service_provider.id'), |
|
99 |
nullable=False) |
|
100 |
service_provider = relationship("ServiceProvider", backref=backref('users')) |
|
101 |
|
|
102 |
def __init__(self, post_values=None): |
|
103 |
self.post_values = post_values |
|
104 |
|
|
105 |
def __repr__(self): |
|
106 |
return "<SPUser '%d'>" % (self.id) |
|
6 | 107 |
|
7 | 108 |
|
8 | 109 |
def upgrade(migrate_engine): |
9 |
meta = MetaData(bind=migrate_engine) |
|
10 |
ext_users = Table('ext_users', meta, autoload=True) |
|
11 |
creation_date = Column("creation_date", DateTime, default=datetime.now()) |
|
12 |
creation_date.create(ext_users) |
|
110 |
ServiceProvider.__table__.create(migrate_engine) |
|
111 |
SPUser.__table__.create(migrate_engine) |
|
112 |
IDPUser.__table__.create(migrate_engine) |
|
13 | 113 |
|
14 | 114 |
def downgrade(migrate_engine): |
15 |
meta = MetaData(bind=migrate_engine)
|
|
16 |
ext_users = Table('ext_users', meta, autoload=True)
|
|
17 |
ext_users.c.creation_date.drop()
|
|
115 |
ServiceProvider.__table__.drop(migrate_engine)
|
|
116 |
SPUser.__table__.drop(migrate_engine)
|
|
117 |
IDPUser.__table__.drop(migrate_engine)
|
|
18 | 118 |
|
mandaye/models.py | ||
---|---|---|
1 |
|
|
1 |
""" This models is used if you are using form replay authentification |
|
2 |
""" |
|
2 | 3 |
import collections |
3 | 4 |
import json |
4 | 5 |
|
... | ... | |
11 | 12 |
from sqlalchemy.orm import column_property, relationship, backref |
12 | 13 |
from sqlalchemy.types import TypeDecorator, VARCHAR |
13 | 14 |
|
15 |
Base = declarative_base() |
|
14 | 16 |
|
15 | 17 |
class JSONEncodedDict(TypeDecorator): |
16 | 18 |
"Represents an immutable structure as a json-encoded string." |
... | ... | |
51 | 53 |
self.changed() |
52 | 54 |
|
53 | 55 |
MutationDict.associate_with(JSONEncodedDict) |
54 |
Base = declarative_base() |
|
55 | 56 |
|
56 |
class Site(Base): |
|
57 |
__tablename__ = 'sites' |
|
57 |
class ServiceProvider(Base): |
|
58 |
|
|
59 |
__tablename__ = 'service_provider' |
|
58 | 60 |
|
59 | 61 |
id = Column(Integer, primary_key=True) |
60 | 62 |
name = Column(String(50), unique=True, nullable=False) |
... | ... | |
63 | 65 |
self.name = name |
64 | 66 |
|
65 | 67 |
def __repr__(self): |
66 |
return "<Site('%s')>" % (self.name)
|
|
68 |
return "<ServiceProvider('%s')>" % (self.name)
|
|
67 | 69 |
|
68 |
class LocalUser(Base): |
|
69 |
""" Mandaye's user |
|
70 |
""" |
|
71 |
__tablename__ = 'local_users' |
|
70 |
class IDPUser(Base): |
|
72 | 71 |
|
73 |
id = Column(Integer, primary_key=True) |
|
74 |
login = Column(String(150), nullable=False, unique=True) |
|
75 |
password = Column(String(25), nullable=True) |
|
76 |
firstname = Column(String(150), nullable=True) |
|
77 |
lastname = Column(String(150), nullable=True) |
|
78 |
fullname = column_property(firstname + " " + lastname) |
|
72 |
__tablename__ = 'idp_user' |
|
79 | 73 |
|
80 |
creation_date = Column(DateTime, default=datetime.now(), nullable=False) |
|
81 |
last_connection = Column(DateTime, default=datetime.now()) |
|
74 |
id = Column(Integer, primary_key=True) |
|
75 |
# Nameid, pseudo, email, ... |
|
76 |
unique_id = Column(String(150), nullable=False) |
|
77 |
# Entityid |
|
78 |
idp_id = Column(String(150), nullable=False) |
|
79 |
sp_users = relationship("SPUser", backref=backref('idp_user')) |
|
82 | 80 |
|
83 |
def __init__(self, login=None, password=None, fullname=None):
|
|
84 |
self.login = login
|
|
85 |
self.password = password
|
|
86 |
self.fullname = fullname
|
|
81 |
def __init__(self, unique_id=None, idp_id=None, sp_users=None):
|
|
82 |
self.unique_id = unique_id
|
|
83 |
self.idp_id = idp_id
|
|
84 |
self.sp_users = sp_users
|
|
87 | 85 |
|
88 | 86 |
def __repr__(self): |
89 |
return "<LocalUser('%d %s')>" % (self.id, self.fullname) |
|
87 |
return "<IDPUser %d '%s'>" % (self.id, self.unique_id) |
|
88 |
|
|
90 | 89 |
|
91 |
class ExtUser(Base): |
|
92 |
""" User of externals applications |
|
93 |
""" |
|
94 |
__tablename__ = 'ext_users' |
|
90 |
class SPUser(Base): |
|
91 |
|
|
92 |
__tablename__ = 'sp_user' |
|
95 | 93 |
|
96 | 94 |
id = Column(Integer, primary_key=True) |
97 | 95 |
login = Column(String(150), nullable=False) |
98 |
post_values = Column(JSONEncodedDict) |
|
96 |
post_values = Column(JSONEncodedDict, nullable=False)
|
|
99 | 97 |
creation_date = Column(DateTime, default=datetime.now(), nullable=False) |
100 | 98 |
last_connection = Column(DateTime, default=datetime.now()) |
101 | 99 |
|
102 |
local_user_id = Column(Integer, ForeignKey('local_users.id'), nullable=False)
|
|
103 |
site_id = Column(Integer, ForeignKey('sites.id'), nullable=False)
|
|
104 |
local_user = relationship("LocalUser", backref=backref('ext_users'))
|
|
105 |
site = relationship("Site", backref=backref('users'))
|
|
100 |
idp_user_id = Column(Integer, ForeignKey('idp_user.id'))
|
|
101 |
service_provider_id = Column(Integer, ForeignKey('service_provider.id'),
|
|
102 |
nullable=False)
|
|
103 |
service_provider = relationship("ServiceProvider", backref=backref('users'))
|
|
106 | 104 |
|
107 |
def __init__(self, login=None, post_values=None): |
|
108 |
self.login = login |
|
105 |
def __init__(self, post_values=None): |
|
109 | 106 |
self.post_values = post_values |
110 | 107 |
|
111 | 108 |
def __repr__(self): |
112 |
return "<ExtUser '%d'>" % (self.id) |
|
113 |
|
|
109 |
return "<SPUser '%d'>" % (self.id) |
|
114 | 110 |
|
mandaye/response.py | ||
---|---|---|
76 | 76 |
tb_str = _get_traceback() |
77 | 77 |
if email: |
78 | 78 |
try: |
79 |
email.sent('Mandaye internal server error',
|
|
79 |
email.sent('Mandaye internal server error %s' % exception,
|
|
80 | 80 |
_get_text_error(tb_str, path, env=env)) |
81 | 81 |
except Exception as detail: |
82 | 82 |
logger.warning('Sent mail failed with error: %s' % detail) |
mandaye/templates/associate.html | ||
---|---|---|
1 |
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" |
|
2 |
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> |
|
3 |
|
|
4 |
<html xmlns="http://www.w3.org/1999/xhtml"> |
|
5 |
|
|
6 |
<head> |
|
7 |
<meta http-equiv="Content-type" content="text/html; charset=utf-8" /> |
|
8 |
<meta http-equiv="Content-Language" content="fr-fr" /> |
|
9 |
<title>1er connexion</title> |
|
10 |
</head> |
|
11 |
|
|
12 |
<h3>1er connexion</h3> |
|
13 |
% if error_msg: |
|
14 |
<p>${error_msg}</p> |
|
15 |
% elif description: |
|
16 |
<p>${description}</p> |
|
17 |
% endif |
|
18 |
<form action="${action}" method="post" accept-charset="utf-8"> |
|
19 |
<div> |
|
20 |
<label for="username">${username_label}</label> |
|
21 |
<input type="text" name="username" value="" id="username" /> |
|
22 |
</div> |
|
23 |
<div> |
|
24 |
<label for="password">${password_label}</label> |
|
25 |
<input type="password" name="password" value="" id="password" /> |
|
26 |
</div> |
|
27 |
<p><input type="submit" value="Enregistrer"></p> |
|
28 |
</form> |
|
29 |
|
|
30 |
</html> |
mandaye/templates/passord_replay/associate.html | ||
---|---|---|
1 |
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" |
|
2 |
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> |
|
3 |
|
|
4 |
<html xmlns="http://www.w3.org/1999/xhtml"> |
|
5 |
|
|
6 |
<head> |
|
7 |
<meta http-equiv="Content-type" content="text/html; charset=utf-8" /> |
|
8 |
<meta http-equiv="Content-Language" content="fr-fr" /> |
|
9 |
<title>1er connexion</title> |
|
10 |
</head> |
|
11 |
|
|
12 |
<h3>1er connexion</h3> |
|
13 |
% if error_msg: |
|
14 |
<p>${error_msg}</p> |
|
15 |
% elif description: |
|
16 |
<p>${description}</p> |
|
17 |
% endif |
|
18 |
<form action="${action}" method="post" accept-charset="utf-8"> |
|
19 |
<div> |
|
20 |
<label for="username">${username_label}</label> |
|
21 |
<input type="text" name="username" value="" id="username" /> |
|
22 |
</div> |
|
23 |
<div> |
|
24 |
<label for="password">${password_label}</label> |
|
25 |
<input type="password" name="password" value="" id="password" /> |
|
26 |
</div> |
|
27 |
<p><input type="submit" value="Enregistrer"></p> |
|
28 |
</form> |
|
29 |
|
|
30 |
</html> |
mandaye/templates/passord_replay/response.html | ||
---|---|---|
1 |
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> |
|
2 |
<html> |
|
3 |
<head> |
|
4 |
<title>${title}</title> |
|
5 |
</head> |
|
6 |
<body> |
|
7 |
<h1>${title}</h1> |
|
8 |
<p>${body}</p> |
|
9 |
</body> |
|
10 |
</html> |
mandaye/templates/response.html | ||
---|---|---|
1 |
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> |
|
2 |
<html> |
|
3 |
<head> |
|
4 |
<title>${title}</title> |
|
5 |
</head> |
|
6 |
<body> |
|
7 |
<h1>${title}</h1> |
|
8 |
<p>${body}</p> |
|
9 |
</body> |
|
10 |
</html> |
mandaye_admin.py | ||
---|---|---|
10 | 10 |
|
11 | 11 |
from mandaye import config |
12 | 12 |
from mandaye.log import logger |
13 |
from mandaye.models import ExtUser |
|
14 |
from mandaye.db import sql_session |
|
15 |
|
|
16 | 13 |
|
17 | 14 |
def get_cmd_options(): |
18 |
usage = "usage: %prog --createdb|--cryptpwd" |
|
15 |
usage = "usage: %prog --newproject|--createdb|--cryptpwd"
|
|
19 | 16 |
parser = OptionParser(usage=usage) |
20 | 17 |
parser.add_option("--createdb", |
21 | 18 |
dest="createdb", |
... | ... | |
29 | 26 |
action="store_true", |
30 | 27 |
help="Crypt external password in Mandaye's database" |
31 | 28 |
) |
29 |
parser.add_option("--newproject", |
|
30 |
dest="cryptpwd", |
|
31 |
default=False, |
|
32 |
action="store_true", |
|
33 |
help="Crypt external password in Mandaye's database" |
|
34 |
) |
|
32 | 35 |
(options, args) = parser.parse_args() |
33 | 36 |
return options |
34 | 37 |
|
... | ... | |
56 | 59 |
if config.db_url: |
57 | 60 |
import migrate.versioning.api |
58 | 61 |
import mandaye.migration |
59 |
from sqlalchemy import create_engine |
|
60 |
from mandaye.models import Base |
|
61 |
engine = create_engine(config.db_url) |
|
62 |
Base.metadata.create_all(engine) |
|
63 | 62 |
migrate.versioning.api.version_control(url=config.db_url, |
64 | 63 |
repository=mandaye.migration.__path__[0]) |
65 | 64 |
migrate.versioning.api.upgrade(url=config.db_url, |
66 | 65 |
repository=mandaye.migration.__path__[0]) |
67 | 66 |
logger.info("Database created") |
68 | 67 |
if options.cryptpwd: |
69 |
for user in sql_session().query(ExtUser).all(): |
|
68 |
from mandaye.config.backend import ManagerSPUserSQL |
|
69 |
for user in ManagerSPUserSQL.all(): |
|
70 | 70 |
user.password = encrypt_pwd(user.password) |
71 |
sql_session().commit()
|
|
71 |
ManagerSPUserSQL.save()
|
|
72 | 72 |
|
73 | 73 |
if __name__ == "__main__": |
74 | 74 |
main() |
75 |
|
mandaye_server.py | ||
---|---|---|
1 |
#!/usr/bin/env python |
|
2 |
# -*- coding: utf-8 -*- |
|
3 |
|
|
4 |
""" Script to launch mandaye with gunicorn server |
|
5 |
""" |
|
6 |
|
|
7 |
import sys |
|
8 |
import os |
|
9 |
|
|
10 |
from mandaye.log import logger |
|
11 |
from gunicorn.app.wsgiapp import WSGIApplication |
|
12 |
|
|
13 |
class WSGIApplication(WSGIApplication): |
|
14 |
|
|
15 |
def init(self, parser, opts, args): |
|
16 |
self.cfg.set("default_proc_name", "mandaye.wsgi:application") |
|
17 |
self.app_uri = "mandaye.wsgi:application" |
|
18 |
|
|
19 |
sys.path.insert(0, os.getcwd()) |
|
20 |
|
|
21 |
def main(): |
|
22 |
""" The ``gunicorn`` command line runner for launcing Gunicorn with |
|
23 |
generic WSGI applications. |
|
24 |
""" |
|
25 |
logger.info('Mandaye start') |
|
26 |
WSGIApplication("%prog [OPTIONS]").run() |
|
27 |
|
|
28 |
if __name__ == "__main__": |
|
29 |
main() |
pip-requirements.txt | ||
---|---|---|
1 |
Beaker==1.5.4 |
|
2 |
Mako==0.4.2 |
|
3 |
MarkupSafe==0.15 |
|
4 |
SQLAlchemy==0.7.2 |
|
5 |
distribute==0.6.10 |
|
6 |
gevent==0.13.6 |
|
7 |
greenlet==0.3.1 |
|
8 |
importlib==1.0.2 |
|
9 |
poster==0.8.1 |
|
10 |
static==0.4 |
|
11 |
wsgiref==0.1.2 |
|
12 |
xtraceback==0.3 |
requirements.txt | ||
---|---|---|
1 |
beaker>=1.6 |
|
2 |
poster>=0.8 |
|
3 |
pycrypto>=2.0 |
|
4 |
lxml>=2.0 |
|
5 |
xtraceback>=0.3 |
|
6 |
sqlalchemy>=0.7,<0.8 |
|
7 |
static |
server.py.default | ||
---|---|---|
1 |
#!/usr/bin/env python |
|
2 |
# -*- coding: utf-8 -*- |
|
3 |
|
|
4 |
""" Script to launch mandaye with gunicorn server |
|
5 |
""" |
|
6 |
|
|
7 |
import sys |
|
8 |
import os |
|
9 |
|
|
10 |
from mandaye.log import logger |
|
11 |
from gunicorn.app.wsgiapp import WSGIApplication |
|
12 |
|
|
13 |
class WSGIApplication(WSGIApplication): |
|
14 |
|
|
15 |
def init(self, parser, opts, args): |
|
16 |
self.cfg.set("default_proc_name", "mandaye.wsgi:application") |
|
17 |
self.app_uri = "mandaye.wsgi:application" |
|
18 |
|
|
19 |
sys.path.insert(0, os.getcwd()) |
|
20 |
|
|
21 |
def main(): |
|
22 |
""" The ``gunicorn`` command line runner for launcing Gunicorn with |
|
23 |
generic WSGI applications. |
|
24 |
""" |
|
25 |
logger.info('Mandaye start') |
|
26 |
WSGIApplication("%prog [OPTIONS]").run() |
|
27 |
|
|
28 |
if __name__ == "__main__": |
|
29 |
main() |
setup.py | ||
---|---|---|
7 | 7 |
import mandaye |
8 | 8 |
|
9 | 9 |
from setuptools import setup, find_packages |
10 |
from sys import version |
|
11 |
|
|
12 |
install_requires=[ |
|
13 |
'beaker>=1.6', |
|
14 |
'gunicorn>=0.13', |
|
15 |
'mako>=0.3', |
|
16 |
'poster>=0.8', |
|
17 |
'pycrypto>=2.0', |
|
18 |
'sqlalchemy>=0.6', |
|
19 |
'sqlalchemy-migrate>=0.7.2', |
|
20 |
'lxml>=2.0', |
|
21 |
'xtraceback>=0.3', |
|
22 |
'static', |
|
23 |
] |
|
24 |
|
|
25 |
if version < '2.7': |
|
26 |
install_requires.append('importlib') |
|
10 | 27 |
|
11 | 28 |
setup(name="mandaye", |
12 | 29 |
version=mandaye.VERSION, |
... | ... | |
17 | 34 |
author_email="info@entrouvert.org", |
18 | 35 |
maintainer="Jerome Schneider", |
19 | 36 |
maintainer_email="jschneider@entrouvert.com", |
20 |
scripts=['mandaye_server.py', 'mandaye_admin.py', 'mandaye_migrate.py'],
|
|
37 |
scripts=['mandaye_admin.py', 'mandaye_migrate.py'], |
|
21 | 38 |
packages=find_packages(), |
22 | 39 |
package_data={}, |
23 |
install_requires=[ |
|
24 |
'beaker>=1.6', |
|
25 |
'gunicorn>=0.13', |
|
26 |
'importlib', |
|
27 |
'mako>=0.3', |
|
28 |
'poster>=0.8', |
|
29 |
'pycrypto>=2.0', |
|
30 |
'sqlalchemy>=0.6', |
|
31 |
'sqlalchemy-migrate>=0.7.2', |
|
32 |
'lxml>=2.0', |
|
33 |
'xtraceback>=0.3', |
|
34 |
'static', |
|
35 |
], |
|
40 |
install_requires=install_requires |
|
36 | 41 |
) |
42 |
|
Formats disponibles : Unified diff
Fixes #710: manage storage backends and implement sql one
WARNING: this commit brake sql migrations