Source code for x2gobroker.basicauth

# -*- coding: utf-8 -*-
# vim:fenc=utf-8

# This file is part of the  X2Go Project - https://www.x2go.org
# Copyright (C) 2012-2020 by Mike Gabriel <mike.gabriel@das-netzwerkteam.de>
#
# X2Go Session Broker is free software; you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# X2Go Session Broker is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.

"""\
Module providing a function for handling BasicAuth request processing.

"""

# modules
import base64

[docs]def require_basic_auth(realm, validate_callback): """\ Handler for ``http(s)://`` BasisAuth processing. This function is used as a decorator for web request handler classes (such as tornado.web.RequestHandler). :param realm: authentication realm :type realm: ``str`` :param validate_callback: callback function for validating credentials :type validate_callback: ``func`` :returns: authentication :func:`execute()` function (or ``False``) :rtype: ``func`` or ``bool`` """ def require_basic_auth_decorator(handler_class): def wrap_execute(handler_execute): def require_basic_auth(handler, kwargs): def create_auth_header(): handler.set_status(401) handler.set_header('WWW-Authenticate', 'Basic realm="{realm}"'.format(realm=realm)) handler._transforms = [] handler.finish() kwargs['basicauth_user'], access = validate_callback('check-credentials', 'FALSE') if access: kwargs['basicauth_pass'] = 'anonymous access granted' return True auth_header = handler.request.headers.get('Authorization') if auth_header is None or not auth_header.startswith('Basic '): create_auth_header() else: auth_decoded = base64.decodestring(auth_header[6:].encode()).decode() username, kwargs['basicauth_pass'] = [ s for s in auth_decoded.split(':', 2) ] kwargs['basicauth_user'], access = validate_callback(username, kwargs['basicauth_pass']) if access: return True else: create_auth_header() def _execute(self, transforms, *args, **kwargs): if not require_basic_auth(self, kwargs): return False return handler_execute(self, transforms, *args, **kwargs) return _execute handler_class._execute = wrap_execute(handler_class._execute) return handler_class return require_basic_auth_decorator