]>
Commit | Line | Data |
---|---|---|
11fdf7f2 | 1 | # -*- coding: utf-8 -*- |
11fdf7f2 | 2 | |
11fdf7f2 TL |
3 | import cherrypy |
4 | ||
5 | try: | |
6 | from onelogin.saml2.auth import OneLogin_Saml2_Auth | |
7 | from onelogin.saml2.errors import OneLogin_Saml2_Error | |
8 | from onelogin.saml2.settings import OneLogin_Saml2_Settings | |
9 | ||
10 | python_saml_imported = True | |
11 | except ImportError: | |
12 | python_saml_imported = False | |
13 | ||
eafe8130 | 14 | from .. import mgr |
11fdf7f2 TL |
15 | from ..exceptions import UserDoesNotExist |
16 | from ..services.auth import JwtManager | |
17 | from ..tools import prepare_url_prefix | |
a4b75251 | 18 | from . import BaseController, ControllerAuthMixin, Endpoint, Router, allow_empty_body |
11fdf7f2 TL |
19 | |
20 | ||
a4b75251 | 21 | @Router('/auth/saml2', secure=False) |
f67539c2 | 22 | class Saml2(BaseController, ControllerAuthMixin): |
11fdf7f2 TL |
23 | |
24 | @staticmethod | |
25 | def _build_req(request, post_data): | |
26 | return { | |
27 | 'https': 'on' if request.scheme == 'https' else 'off', | |
28 | 'http_host': request.host, | |
29 | 'script_name': request.path_info, | |
30 | 'server_port': str(request.port), | |
31 | 'get_data': {}, | |
32 | 'post_data': post_data | |
33 | } | |
34 | ||
35 | @staticmethod | |
36 | def _check_python_saml(): | |
37 | if not python_saml_imported: | |
9f95a23c | 38 | raise cherrypy.HTTPError(400, 'Required library not found: `python3-saml`') |
11fdf7f2 TL |
39 | try: |
40 | OneLogin_Saml2_Settings(mgr.SSO_DB.saml2.onelogin_settings) | |
41 | except OneLogin_Saml2_Error: | |
42 | raise cherrypy.HTTPError(400, 'Single Sign-On is not configured.') | |
43 | ||
f67539c2 | 44 | @Endpoint('POST', path="", version=None) |
adb31ebb | 45 | @allow_empty_body |
11fdf7f2 TL |
46 | def auth_response(self, **kwargs): |
47 | Saml2._check_python_saml() | |
48 | req = Saml2._build_req(self._request, kwargs) | |
49 | auth = OneLogin_Saml2_Auth(req, mgr.SSO_DB.saml2.onelogin_settings) | |
50 | auth.process_response() | |
51 | errors = auth.get_errors() | |
52 | ||
53 | if auth.is_authenticated(): | |
54 | JwtManager.reset_user() | |
55 | username_attribute = auth.get_attribute(mgr.SSO_DB.saml2.get_username_attribute()) | |
56 | if username_attribute is None: | |
57 | raise cherrypy.HTTPError(400, | |
58 | 'SSO error - `{}` not found in auth attributes. ' | |
59 | 'Received attributes: {}' | |
60 | .format( | |
61 | mgr.SSO_DB.saml2.get_username_attribute(), | |
62 | auth.get_attributes())) | |
63 | username = username_attribute[0] | |
64 | url_prefix = prepare_url_prefix(mgr.get_module_option('url_prefix', default='')) | |
65 | try: | |
66 | mgr.ACCESS_CTRL_DB.get_user(username) | |
67 | except UserDoesNotExist: | |
68 | raise cherrypy.HTTPRedirect("{}/#/sso/404".format(url_prefix)) | |
69 | ||
70 | token = JwtManager.gen_token(username) | |
71 | JwtManager.set_user(JwtManager.decode_token(token)) | |
72 | token = token.decode('utf-8') | |
f67539c2 | 73 | self._set_token_cookie(url_prefix, token) |
11fdf7f2 | 74 | raise cherrypy.HTTPRedirect("{}/#/login?access_token={}".format(url_prefix, token)) |
9f95a23c TL |
75 | |
76 | return { | |
77 | 'is_authenticated': auth.is_authenticated(), | |
78 | 'errors': errors, | |
79 | 'reason': auth.get_last_error_reason() | |
80 | } | |
11fdf7f2 | 81 | |
f67539c2 | 82 | @Endpoint(xml=True, version=None) |
11fdf7f2 TL |
83 | def metadata(self): |
84 | Saml2._check_python_saml() | |
85 | saml_settings = OneLogin_Saml2_Settings(mgr.SSO_DB.saml2.onelogin_settings) | |
86 | return saml_settings.get_sp_metadata() | |
87 | ||
f67539c2 | 88 | @Endpoint(json_response=False, version=None) |
11fdf7f2 TL |
89 | def login(self): |
90 | Saml2._check_python_saml() | |
91 | req = Saml2._build_req(self._request, {}) | |
92 | auth = OneLogin_Saml2_Auth(req, mgr.SSO_DB.saml2.onelogin_settings) | |
93 | raise cherrypy.HTTPRedirect(auth.login()) | |
94 | ||
f67539c2 | 95 | @Endpoint(json_response=False, version=None) |
11fdf7f2 TL |
96 | def slo(self): |
97 | Saml2._check_python_saml() | |
98 | req = Saml2._build_req(self._request, {}) | |
99 | auth = OneLogin_Saml2_Auth(req, mgr.SSO_DB.saml2.onelogin_settings) | |
100 | raise cherrypy.HTTPRedirect(auth.logout()) | |
101 | ||
f67539c2 | 102 | @Endpoint(json_response=False, version=None) |
11fdf7f2 TL |
103 | def logout(self, **kwargs): |
104 | # pylint: disable=unused-argument | |
105 | Saml2._check_python_saml() | |
106 | JwtManager.reset_user() | |
f67539c2 TL |
107 | token = JwtManager.get_token_from_header() |
108 | self._delete_token_cookie(token) | |
11fdf7f2 TL |
109 | url_prefix = prepare_url_prefix(mgr.get_module_option('url_prefix', default='')) |
110 | raise cherrypy.HTTPRedirect("{}/#/login".format(url_prefix)) |