]> git.proxmox.com Git - ceph.git/blame - ceph/src/pybind/mgr/dashboard/controllers/saml2.py
import quincy beta 17.1.0
[ceph.git] / ceph / src / pybind / mgr / dashboard / controllers / saml2.py
CommitLineData
11fdf7f2 1# -*- coding: utf-8 -*-
11fdf7f2 2
11fdf7f2
TL
3import cherrypy
4
5try:
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
11except ImportError:
12 python_saml_imported = False
13
eafe8130 14from .. import mgr
11fdf7f2
TL
15from ..exceptions import UserDoesNotExist
16from ..services.auth import JwtManager
17from ..tools import prepare_url_prefix
a4b75251 18from . import BaseController, ControllerAuthMixin, Endpoint, Router, allow_empty_body
11fdf7f2
TL
19
20
a4b75251 21@Router('/auth/saml2', secure=False)
f67539c2 22class 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))