|
1 # |
|
2 # Copyright (c) 2008-2015 Thierry Florac <tflorac AT ulthar.net> |
|
3 # All Rights Reserved. |
|
4 # |
|
5 # This software is subject to the provisions of the Zope Public License, |
|
6 # Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. |
|
7 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED |
|
8 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
|
9 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS |
|
10 # FOR A PARTICULAR PURPOSE. |
|
11 # |
|
12 |
|
13 __docformat__ = 'restructuredtext' |
|
14 |
|
15 |
|
16 # import standard library |
|
17 import base64 |
|
18 |
|
19 # import interfaces |
|
20 from pyams_security.interfaces import ICredentialsPlugin |
|
21 |
|
22 # import packages |
|
23 from pyams_security.credential import Credentials |
|
24 from pyams_utils.registry import utility_config |
|
25 from pyams_utils.wsgi import wsgi_environ_cache |
|
26 |
|
27 from pyams_security import _ |
|
28 |
|
29 |
|
30 ENVKEY_PARSED_CREDENTIALS = "pyams_security.http.basic.credentials" |
|
31 |
|
32 |
|
33 @utility_config(name='http', provides=ICredentialsPlugin) |
|
34 class HttpBasicCredentialsPlugin(object): |
|
35 """HTTP basic credentials plug-in |
|
36 |
|
37 This credential plug-in is mainly used by automation processes using |
|
38 XML-RPC or JSON-RPC requests launched from batch scripts. |
|
39 |
|
40 Copied from pyramid_httpauth package. |
|
41 """ |
|
42 |
|
43 prefix = 'http' |
|
44 title = _("HTTP Basic credentials") |
|
45 enabled = True |
|
46 |
|
47 @wsgi_environ_cache(ENVKEY_PARSED_CREDENTIALS) |
|
48 def extract_credentials(self, request, **kwargs): |
|
49 """Extract login/password credentials from given request""" |
|
50 auth = request.headers.get('Authorization') |
|
51 if not auth: |
|
52 return None |
|
53 try: |
|
54 scheme, params = auth.split(' ', 1) |
|
55 if scheme.lower() != 'basic': |
|
56 return None |
|
57 token_bytes = base64.b64decode(params.strip()) |
|
58 try: |
|
59 token = token_bytes.decode('utf-8') |
|
60 except UnicodeDecodeError: |
|
61 token = token_bytes.decode('latin-1') |
|
62 login, password = token.split(':', 1) |
|
63 return Credentials(self.prefix, login, login=login, password=password) |
|
64 except (ValueError, TypeError): |
|
65 return None |