1 import datetime |
1 import datetime |
2 import logging |
2 import logging |
3 import warnings |
3 import warnings |
4 |
4 |
|
5 from zope.interface import implementer |
|
6 |
|
7 from pyramid.settings import asbool |
5 from pyramid.authorization import ACLAuthorizationPolicy |
8 from pyramid.authorization import ACLAuthorizationPolicy |
6 from pyramid_cubicweb.core import get_principals |
9 from pyramid_cubicweb.core import get_principals |
|
10 from pyramid_multiauth import MultiAuthenticationPolicy |
7 |
11 |
8 from pyramid.authentication import AuthTktAuthenticationPolicy |
12 from pyramid.authentication import AuthTktAuthenticationPolicy |
|
13 |
|
14 from pyramid.interfaces import IAuthenticationPolicy |
9 |
15 |
10 log = logging.getLogger(__name__) |
16 log = logging.getLogger(__name__) |
11 |
17 |
12 |
18 |
13 class CubicWebAuthTktAuthenticationPolicy(AuthTktAuthenticationPolicy): |
19 @implementer(IAuthenticationPolicy) |
|
20 class UpdateLoginTimeAuthenticationPolicy(object): |
14 """An authentication policy that update the user last_login_time. |
21 """An authentication policy that update the user last_login_time. |
15 |
22 |
16 The update is done in the 'remember' method, which is called on login, |
23 The update is done in the 'remember' method, which is called by the login |
17 and each time the authentication ticket is reissued. |
24 views login, |
18 |
|
19 Meaning, the last_login_time is updated reissue_time seconds (maximum) |
|
20 before the last request by the user. |
|
21 |
25 |
22 Usually used via :func:`includeme`. |
26 Usually used via :func:`includeme`. |
23 """ |
27 """ |
24 |
28 |
|
29 def authenticated_userid(self, request): |
|
30 pass |
|
31 |
|
32 def effective_principals(self, request): |
|
33 return () |
|
34 |
25 def remember(self, request, principal, **kw): |
35 def remember(self, request, principal, **kw): |
26 headers = super(CubicWebAuthTktAuthenticationPolicy, self).remember( |
|
27 request, principal, **kw) |
|
28 try: |
36 try: |
29 repo = request.registry['cubicweb.repository'] |
37 repo = request.registry['cubicweb.repository'] |
30 with repo.internal_cnx() as cnx: |
38 with repo.internal_cnx() as cnx: |
31 cnx.execute( |
39 cnx.execute( |
32 "SET U last_login_time %(now)s WHERE U eid %(user)s", { |
40 "SET U last_login_time %(now)s WHERE U eid %(user)s", { |
33 'now': datetime.datetime.now(), |
41 'now': datetime.datetime.now(), |
34 'user': principal}) |
42 'user': principal}) |
35 cnx.commit() |
43 cnx.commit() |
36 except: |
44 except: |
37 log.exception("Failed to update last_login_time") |
45 log.exception("Failed to update last_login_time") |
38 return headers |
46 return () |
|
47 |
|
48 def forget(self, request): |
|
49 return () |
39 |
50 |
40 |
51 |
41 def includeme(config): |
52 def includeme(config): |
42 """ Activate the CubicWeb AuthTkt authentication policy. |
53 """ Activate the CubicWeb AuthTkt authentication policy. |
43 |
54 |
44 Usually called via ``config.include('pyramid_cubicweb.auth')``. |
55 Usually called via ``config.include('pyramid_cubicweb.auth')``. |
45 |
56 |
46 See also :ref:`defaults_module` |
57 See also :ref:`defaults_module` |
47 """ |
58 """ |
48 secret = config.registry['cubicweb.config']['pyramid-auth-secret'] |
59 settings = config.registry.settings |
49 |
60 |
50 if not secret: |
61 policies = [] |
51 secret = 'notsosecret' |
|
52 warnings.warn(''' |
|
53 |
62 |
54 !! WARNING !! !! WARNING !! |
63 if asbool(settings.get('cubicweb.auth.update_login_time', True)): |
|
64 policies.append(UpdateLoginTimeAuthenticationPolicy()) |
55 |
65 |
56 The authentication cookies are signed with a static secret key. |
66 if asbool(settings.get('cubicweb.auth.authtkt', True)): |
57 To put your own secret key, edit your all-in-one.conf file |
67 secret = config.registry['cubicweb.config']['pyramid-auth-secret'] |
58 and set the 'pyramid-auth-secret' key. |
|
59 |
68 |
60 YOU SHOULD STOP THIS INSTANCE unless your really know what you |
69 if not secret: |
61 are doing !! |
70 secret = 'notsosecret' |
|
71 warnings.warn(''' |
62 |
72 |
63 ''') |
73 !! WARNING !! !! WARNING !! |
64 |
74 |
65 config.set_authentication_policy( |
75 The authentication cookies are signed with a static secret key. |
66 CubicWebAuthTktAuthenticationPolicy( |
76 To put your own secret key, edit your all-in-one.conf file |
67 secret, callback=get_principals, hashalg='sha512', |
77 and set the 'pyramid-auth-secret' key. |
68 reissue_time=3600)) |
78 |
|
79 YOU SHOULD STOP THIS INSTANCE unless your really know what you |
|
80 are doing !! |
|
81 |
|
82 ''') |
|
83 |
|
84 policies.append( |
|
85 AuthTktAuthenticationPolicy( |
|
86 secret, hashalg='sha512', reissue_time=3600)) |
|
87 |
|
88 kw = {} |
|
89 if asbool(settings.get('cubicweb.auth.groups_principals', True)): |
|
90 kw['callback'] = get_principals |
|
91 |
|
92 authpolicy = MultiAuthenticationPolicy(policies, **kw) |
|
93 config.registry['cubicweb.authpolicy'] = authpolicy |
|
94 |
|
95 config.set_authentication_policy(authpolicy) |
69 config.set_authorization_policy(ACLAuthorizationPolicy()) |
96 config.set_authorization_policy(ACLAuthorizationPolicy()) |