utils.py 3.19 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
# Copyright (c) 2016, Daniele Venzano
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.

16 17
"""Functions needed by the Zoe web interface."""

18 19
import logging

20 21
from zoe_lib.config import get_conf

22
from zoe_api.auth.base import BaseAuthenticator  # pylint: disable=unused-import
23
from zoe_api.auth.ldap import LDAPAuthenticator
24
from zoe_api.auth.ldapsasl import LDAPSASLAuthenticator
25
from zoe_api.auth.file import PlainTextAuthenticator
26
import zoe_api.exceptions
27
from zoe_api.web.custom_request_handler import ZoeRequestHandler
28 29 30 31 32 33 34 35 36 37 38

log = logging.getLogger(__name__)


def catch_exceptions(func):
    """
    Decorator function used to work around the static exception system available in Flask-RESTful
    :param func:
    :return:
    """
    def func_wrapper(*args, **kwargs):
39
        """The actual decorator."""
40
        self = args[0]
41 42
        try:
            return func(*args, **kwargs)
43
        except zoe_api.exceptions.ZoeAuthException:
44
            return missing_auth(self)
45
        except zoe_api.exceptions.ZoeNotFoundException as e:
46
            return error_page(self, str(e), 404)
47
        except zoe_api.exceptions.ZoeException as e:
48
            return error_page(self, str(e), 400)
49 50 51 52 53 54 55
        except Exception as e:
            log.exception(str(e))
            return {'message': str(e)}, 500

    return func_wrapper


56
def missing_auth(handler: ZoeRequestHandler):
57 58
    """Redirect to login page."""
    handler.redirect(handler.get_argument('next', u'/login'))
59 60


61 62
def get_auth_login(username, password):
    """Authenticate username and password against the configured user store."""
63
    if get_conf().auth_type == 'text':
64
        authenticator = PlainTextAuthenticator()  # type: BaseAuthenticator
65
    elif get_conf().auth_type == 'ldap':
66 67 68
        authenticator = LDAPAuthenticator()  # type: BaseAuthenticator
    elif get_conf().auth_type == 'ldapsasl':
        authenticator = LDAPSASLAuthenticator()  # type: BaseAuthenticator
69 70
    else:
        raise zoe_api.exceptions.ZoeException('Configuration error, unknown authentication method: {}'.format(get_conf().auth_type))
71
    uid, role = authenticator.auth(username, password)
72
    if uid is None:
73
        raise zoe_api.exceptions.ZoeAuthException
74 75 76 77

    return uid, role


78 79 80 81 82 83 84 85 86
def get_auth(handler: ZoeRequestHandler):
    """Try to authenticate a request."""

    if handler.get_secure_cookie('zoe'):
        cookie_val = str(handler.get_secure_cookie('zoe'))
        uid, role = cookie_val[2:-1].split('.')
        log.info('Authentication done using cookie')
        return uid, role
    else:
87
        return None, None
88 89


90
def error_page(handler: ZoeRequestHandler, error_message: str, status: int):
91
    """Generate an error page."""
92 93
    handler.set_status(status)
    handler.render('error.html', error=error_message)