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