#!/usr/bin/env python

# Contributors Listed Below - COPYRIGHT 2016
# [+] International Business Machines Corp.
#
#
# 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.

import os
import sys
import dbus
import dbus.exceptions
import json
import logging
from xml.etree import ElementTree
from rocket import Rocket
from bottle import Bottle, abort, request, response, JSONPlugin, HTTPError
import obmc.utils.misc
import obmc.utils.pathtree
from obmc.dbuslib.introspection import IntrospectionNodeParser
import obmc.mapper
import spwd
import grp
import crypt

DBUS_UNKNOWN_INTERFACE = 'org.freedesktop.UnknownInterface'
DBUS_UNKNOWN_METHOD = 'org.freedesktop.DBus.Error.UnknownMethod'
DBUS_INVALID_ARGS = 'org.freedesktop.DBus.Error.InvalidArgs'
DBUS_TYPE_ERROR = 'org.freedesktop.DBus.Python.TypeError'
DELETE_IFACE = 'org.openbmc.Object.Delete'

_4034_msg = "The specified %s cannot be %s: '%s'"


def valid_user(session, *a, **kw):
    ''' Authorization plugin callback that checks
    that the user is logged in. '''
    if session is None:
        abort(403, 'Login required')


class UserInGroup:
    ''' Authorization plugin callback that checks that the user is logged in
    and a member of a group. '''
    def __init__(self, group):
        self.group = group

    def __call__(self, session, *a, **kw):
        valid_user(session, *a, **kw)
        res = False

        try:
            res = session['user'] in grp.getgrnam(self.group)[3]
        except KeyError:
            pass

        if not res:
            abort(403, 'Insufficient access')


def find_case_insensitive(value, lst):
    return next((x for x in lst if x.lower() == value.lower()), None)


def makelist(data):
    if isinstance(data, list):
        return data
    elif data:
        return [data]
    else:
        return []


class RouteHandler(object):
    _require_auth = makelist(valid_user)

    def __init__(self, app, bus, verbs, rules):
        self.app = app
        self.bus = bus
        self.mapper = obmc.mapper.Mapper(bus)
        self._verbs = makelist(verbs)
        self._rules = rules
        self.intf_match = obmc.utils.misc.org_dot_openbmc_match

    def _setup(self, **kw):
        request.route_data = {}
        if request.method in self._verbs:
            return self.setup(**kw)
        else:
            self.find(**kw)
            raise HTTPError(
                405, "Method not allowed.", Allow=','.join(self._verbs))

    def __call__(self, **kw):
        return getattr(self, 'do_' + request.method.lower())(**kw)

    def install(self):
        self.app.route(
            self._rules, callback=self,
            method=['GET', 'PUT', 'PATCH', 'POST', 'DELETE'])

    @staticmethod
    def try_mapper_call(f, callback=None, **kw):
        try:
            return f(**kw)
        except dbus.exceptions.DBusException, e:
            if e.get_dbus_name() != obmc.mapper.MAPPER_NOT_FOUND:
                raise
            if callback is None:
                def callback(e, **kw):
                    abort(404, str(e))

            callback(e, **kw)

    @staticmethod
    def try_properties_interface(f, *a):
        try:
            return f(*a)
        except dbus.exceptions.DBusException, e:
            if DBUS_UNKNOWN_INTERFACE in e.get_dbus_message():
                # interface doesn't have any properties
                return None
            if DBUS_UNKNOWN_METHOD == e.get_dbus_name():
                # properties interface not implemented at all
                return None
            raise


class DirectoryHandler(RouteHandler):
    verbs = 'GET'
    rules = '<path:path>/'

    def __init__(self, app, bus):
        super(DirectoryHandler, self).__init__(
            app, bus, self.verbs, self.rules)

    def find(self, path='/'):
        return self.try_mapper_call(
            self.mapper.get_subtree_paths, path=path, depth=1)

    def setup(self, path='/'):
        request.route_data['map'] = self.find(path)

    def do_get(self, path='/'):
        return request.route_data['map']


class ListNamesHandler(RouteHandler):
    verbs = 'GET'
    rules = ['/list', '<path:path>/list']

    def __init__(self, app, bus):
        super(ListNamesHandler, self).__init__(
            app, bus, self.verbs, self.rules)

    def find(self, path='/'):
        return self.try_mapper_call(
            self.mapper.get_subtree, path=path).keys()

    def setup(self, path='/'):
        request.route_data['map'] = self.find(path)

    def do_get(self, path='/'):
        return request.route_data['map']


class ListHandler(RouteHandler):
    verbs = 'GET'
    rules = ['/enumerate', '<path:path>/enumerate']

    def __init__(self, app, bus):
        super(ListHandler, self).__init__(
            app, bus, self.verbs, self.rules)

    def find(self, path='/'):
        return self.try_mapper_call(
            self.mapper.get_subtree, path=path)

    def setup(self, path='/'):
        request.route_data['map'] = self.find(path)

    def do_get(self, path='/'):
        objs = {}
        mapper_data = request.route_data['map']
        managers = {}
        owners = []

        # look for objectmanager implementations as they result
        # in fewer dbus calls
        for path, bus_data in mapper_data.iteritems():
            for owner, interfaces in bus_data.iteritems():
                owners.append(owner)
                if dbus.BUS_DAEMON_IFACE + '.ObjectManager' in interfaces:
                    managers[owner] = path

        # also look in the parent objects
        ancestors = self.mapper.get_ancestors(path)

        # finally check the root for one too
        try:
            ancestors.update({path: self.mapper.get_object(path)})
        except dbus.exceptions.DBusException, e:
            if e.get_dbus_name() != obmc.mapper.MAPPER_NOT_FOUND:
                raise

        for path, bus_data in ancestors.iteritems():
            for owner, interfaces in bus_data.iteritems():
                if dbus.BUS_DAEMON_IFACE + '.ObjectManager' in interfaces:
                    managers[owner] = path

        # make all the manager gmo (get managed objects) calls
        results = {}
        for owner, path in managers.iteritems():
            if owner not in owners:
                continue
            obj = self.bus.get_object(owner, path, introspect=False)
            iface = dbus.Interface(
                obj, dbus.BUS_DAEMON_IFACE + '.ObjectManager')

            # flatten (remove interface names) gmo results
            for path, interfaces in iface.GetManagedObjects().iteritems():
                if path not in mapper_data.iterkeys():
                    continue
                properties = {}
                for iface, props in interfaces.iteritems():
                    properties.update(props)
                results.setdefault(path, {}).setdefault(owner, properties)

        # make dbus calls for any remaining objects
        for path, bus_data in mapper_data.iteritems():
            for owner, interfaces in bus_data.iteritems():
                if results.setdefault(path, {}).setdefault(owner, {}):
                    continue
                results.setdefault(path, {}).setdefault(
                    owner,
                    self.app.instance_handler.get_properties_on_bus(
                        path, owner, interfaces))

        objs = {}
        for path, owners in results.iteritems():
            for owner, properties in owners.iteritems():
                objs.setdefault(path, {}).update(properties)

        return objs


class MethodHandler(RouteHandler):
    verbs = 'POST'
    rules = '<path:path>/action/<method>'
    request_type = list

    def __init__(self, app, bus):
        super(MethodHandler, self).__init__(
            app, bus, self.verbs, self.rules)

    def find(self, path, method):
        busses = self.try_mapper_call(
            self.mapper.get_object, path=path)
        for items in busses.iteritems():
            m = self.find_method_on_bus(path, method, *items)
            if m:
                return m

        abort(404, _4034_msg % ('method', 'found', method))

    def setup(self, path, method):
        request.route_data['method'] = self.find(path, method)

    def do_post(self, path, method):
        try:
            if request.parameter_list:
                return request.route_data['method'](*request.parameter_list)
            else:
                return request.route_data['method']()

        except dbus.exceptions.DBusException, e:
            if e.get_dbus_name() == DBUS_INVALID_ARGS:
                abort(400, str(e))
            if e.get_dbus_name() == DBUS_TYPE_ERROR:
                abort(400, str(e))
            raise

    @staticmethod
    def find_method_in_interface(method, obj, interface, methods):
        if methods is None:
            return None

        method = find_case_insensitive(method, methods.keys())
        if method is not None:
            iface = dbus.Interface(obj, interface)
            return iface.get_dbus_method(method)

    def find_method_on_bus(self, path, method, bus, interfaces):
        obj = self.bus.get_object(bus, path, introspect=False)
        iface = dbus.Interface(obj, dbus.INTROSPECTABLE_IFACE)
        data = iface.Introspect()
        parser = IntrospectionNodeParser(
            ElementTree.fromstring(data),
            intf_match=obmc.utils.misc.ListMatch(interfaces))
        for x, y in parser.get_interfaces().iteritems():
            m = self.find_method_in_interface(
                method, obj, x, y.get('method'))
            if m:
                return m


class PropertyHandler(RouteHandler):
    verbs = ['PUT', 'GET']
    rules = '<path:path>/attr/<prop>'

    def __init__(self, app, bus):
        super(PropertyHandler, self).__init__(
            app, bus, self.verbs, self.rules)

    def find(self, path, prop):
        self.app.instance_handler.setup(path)
        obj = self.app.instance_handler.do_get(path)
        try:
            obj[prop]
        except KeyError, e:
            if request.method == 'PUT':
                abort(403, _4034_msg % ('property', 'created', str(e)))
            else:
                abort(404, _4034_msg % ('property', 'found', str(e)))

        return {path: obj}

    def setup(self, path, prop):
        request.route_data['obj'] = self.find(path, prop)

    def do_get(self, path, prop):
        return request.route_data['obj'][path][prop]

    def do_put(self, path, prop, value=None):
        if value is None:
            value = request.parameter_list

        prop, iface, properties_iface = self.get_host_interface(
            path, prop, request.route_data['map'][path])
        try:
            properties_iface.Set(iface, prop, value)
        except ValueError, e:
            abort(400, str(e))
        except dbus.exceptions.DBusException, e:
            if e.get_dbus_name() == DBUS_INVALID_ARGS:
                abort(403, str(e))
            raise

    def get_host_interface(self, path, prop, bus_info):
        for bus, interfaces in bus_info.iteritems():
            obj = self.bus.get_object(bus, path, introspect=True)
            properties_iface = dbus.Interface(
                obj, dbus_interface=dbus.PROPERTIES_IFACE)

            info = self.get_host_interface_on_bus(
                path, prop, properties_iface, bus, interfaces)
            if info is not None:
                prop, iface = info
                return prop, iface, properties_iface

    def get_host_interface_on_bus(self, path, prop, iface, bus, interfaces):
        for i in interfaces:
            properties = self.try_properties_interface(iface.GetAll, i)
            if properties is None:
                continue
            prop = find_case_insensitive(prop, properties.keys())
            if prop is None:
                continue
            return prop, i


class SchemaHandler(RouteHandler):
    verbs = ['GET']
    rules = '<path:path>/schema'

    def __init__(self, app, bus):
        super(SchemaHandler, self).__init__(
            app, bus, self.verbs, self.rules)

    def find(self, path):
        return self.try_mapper_call(
            self.mapper.get_object,
            path=path)

    def setup(self, path):
        request.route_data['map'] = self.find(path)

    def do_get(self, path):
        schema = {}
        for x in request.route_data['map'].iterkeys():
            obj = self.bus.get_object(x, path, introspect=False)
            iface = dbus.Interface(obj, dbus.INTROSPECTABLE_IFACE)
            data = iface.Introspect()
            parser = IntrospectionNodeParser(
                ElementTree.fromstring(data))
            for x, y in parser.get_interfaces().iteritems():
                schema[x] = y

        return schema


class InstanceHandler(RouteHandler):
    verbs = ['GET', 'PUT', 'DELETE']
    rules = '<path:path>'
    request_type = dict

    def __init__(self, app, bus):
        super(InstanceHandler, self).__init__(
            app, bus, self.verbs, self.rules)

    def find(self, path, callback=None):
        return {path: self.try_mapper_call(
            self.mapper.get_object,
            callback,
            path=path)}

    def setup(self, path):
        callback = None
        if request.method == 'PUT':
            def callback(e, **kw):
                abort(403, _4034_msg % ('resource', 'created', path))

        if request.route_data.get('map') is None:
            request.route_data['map'] = self.find(path, callback)

    def do_get(self, path):
        properties = {}
        for item in request.route_data['map'][path].iteritems():
            properties.update(self.get_properties_on_bus(
                path, *item))

        return properties

    @staticmethod
    def get_properties_on_iface(properties_iface, iface):
        properties = InstanceHandler.try_properties_interface(
            properties_iface.GetAll, iface)
        if properties is None:
            return {}
        return properties

    def get_properties_on_bus(self, path, bus, interfaces):
        properties = {}
        obj = self.bus.get_object(bus, path, introspect=False)
        properties_iface = dbus.Interface(
            obj, dbus_interface=dbus.PROPERTIES_IFACE)
        for i in interfaces:
            if not self.intf_match(i):
                continue
            properties.update(self.get_properties_on_iface(
                properties_iface, i))

        return properties

    def do_put(self, path):
        # make sure all properties exist in the request
        obj = set(self.do_get(path).keys())
        req = set(request.parameter_list.keys())

        diff = list(obj.difference(req))
        if diff:
            abort(403, _4034_msg % (
                'resource', 'removed', '%s/attr/%s' % (path, diff[0])))

        diff = list(req.difference(obj))
        if diff:
            abort(403, _4034_msg % (
                'resource', 'created', '%s/attr/%s' % (path, diff[0])))

        for p, v in request.parameter_list.iteritems():
            self.app.property_handler.do_put(
                path, p, v)

    def do_delete(self, path):
        for bus_info in request.route_data['map'][path].iteritems():
            if self.bus_missing_delete(path, *bus_info):
                abort(403, _4034_msg % ('resource', 'removed', path))

        for bus in request.route_data['map'][path].iterkeys():
            self.delete_on_bus(path, bus)

    def bus_missing_delete(self, path, bus, interfaces):
        return DELETE_IFACE not in interfaces

    def delete_on_bus(self, path, bus):
        obj = self.bus.get_object(bus, path, introspect=False)
        delete_iface = dbus.Interface(
            obj, dbus_interface=DELETE_IFACE)
        delete_iface.Delete()


class SessionHandler(MethodHandler):
    ''' Handles the /login and /logout routes, manages
    server side session store and session cookies.  '''

    rules = ['/login', '/logout']
    login_str = "User '%s' logged %s"
    bad_passwd_str = "Invalid username or password"
    no_user_str = "No user logged in"
    bad_json_str = "Expecting request format { 'data': " \
        "[<username>, <password>] }, got '%s'"
    _require_auth = None
    MAX_SESSIONS = 16

    def __init__(self, app, bus):
        super(SessionHandler, self).__init__(
            app, bus)
        self.hmac_key = os.urandom(128)
        self.session_store = []

    @staticmethod
    def authenticate(username, clear):
        try:
            encoded = spwd.getspnam(username)[1]
            return encoded == crypt.crypt(clear, encoded)
        except KeyError:
            return False

    def invalidate_session(self, session):
        try:
            self.session_store.remove(session)
        except ValueError:
            pass

    def new_session(self):
        sid = os.urandom(32)
        if self.MAX_SESSIONS <= len(self.session_store):
            self.session_store.pop()
        self.session_store.insert(0, {'sid': sid})

        return self.session_store[0]

    def get_session(self, sid):
        sids = [x['sid'] for x in self.session_store]
        try:
            return self.session_store[sids.index(sid)]
        except ValueError:
            return None

    def get_session_from_cookie(self):
        return self.get_session(
            request.get_cookie(
                'sid', secret=self.hmac_key))

    def do_post(self, **kw):
        if request.path == '/login':
            return self.do_login(**kw)
        else:
            return self.do_logout(**kw)

    def do_logout(self, **kw):
        session = self.get_session_from_cookie()
        if session is not None:
            user = session['user']
            self.invalidate_session(session)
            response.delete_cookie('sid')
            return self.login_str % (user, 'out')

        return self.no_user_str

    def do_login(self, **kw):
        session = self.get_session_from_cookie()
        if session is not None:
            return self.login_str % (session['user'], 'in')

        if len(request.parameter_list) != 2:
            abort(400, self.bad_json_str % (request.json))

        if not self.authenticate(*request.parameter_list):
            return self.bad_passwd_str

        user = request.parameter_list[0]
        session = self.new_session()
        session['user'] = user
        response.set_cookie(
            'sid', session['sid'], secret=self.hmac_key,
            secure=True,
            httponly=True)
        return self.login_str % (user, 'in')

    def find(self, **kw):
        pass

    def setup(self, **kw):
        pass


class AuthorizationPlugin(object):
    ''' Invokes an optional list of authorization callbacks. '''

    name = 'authorization'
    api = 2

    class Compose:
        def __init__(self, validators, callback, session_mgr):
            self.validators = validators
            self.callback = callback
            self.session_mgr = session_mgr

        def __call__(self, *a, **kw):
            sid = request.get_cookie('sid', secret=self.session_mgr.hmac_key)
            session = self.session_mgr.get_session(sid)
            for x in self.validators:
                x(session, *a, **kw)

            return self.callback(*a, **kw)

    def apply(self, callback, route):
        undecorated = route.get_undecorated_callback()
        if not isinstance(undecorated, RouteHandler):
            return callback

        auth_types = getattr(
            undecorated, '_require_auth', None)
        if not auth_types:
            return callback

        return self.Compose(
            auth_types, callback, undecorated.app.session_handler)


class JsonApiRequestPlugin(object):
    ''' Ensures request content satisfies the OpenBMC json api format. '''
    name = 'json_api_request'
    api = 2

    error_str = "Expecting request format { 'data': <value> }, got '%s'"
    type_error_str = "Unsupported Content-Type: '%s'"
    json_type = "application/json"
    request_methods = ['PUT', 'POST', 'PATCH']

    @staticmethod
    def content_expected():
        return request.method in JsonApiRequestPlugin.request_methods

    def validate_request(self):
        if request.content_length > 0 and \
                request.content_type != self.json_type:
            abort(415, self.type_error_str % request.content_type)

        try:
            request.parameter_list = request.json.get('data')
        except ValueError, e:
            abort(400, str(e))
        except (AttributeError, KeyError, TypeError):
            abort(400, self.error_str % request.json)

    def apply(self, callback, route):
        verbs = getattr(
            route.get_undecorated_callback(), '_verbs', None)
        if verbs is None:
            return callback

        if not set(self.request_methods).intersection(verbs):
            return callback

        def wrap(*a, **kw):
            if self.content_expected():
                self.validate_request()
            return callback(*a, **kw)

        return wrap


class JsonApiRequestTypePlugin(object):
    ''' Ensures request content type satisfies the OpenBMC json api format. '''
    name = 'json_api_method_request'
    api = 2

    error_str = "Expecting request format { 'data': %s }, got '%s'"

    def apply(self, callback, route):
        request_type = getattr(
            route.get_undecorated_callback(), 'request_type', None)
        if request_type is None:
            return callback

        def validate_request():
            if not isinstance(request.parameter_list, request_type):
                abort(400, self.error_str % (str(request_type), request.json))

        def wrap(*a, **kw):
            if JsonApiRequestPlugin.content_expected():
                validate_request()
            return callback(*a, **kw)

        return wrap


class JsonApiResponsePlugin(object):
    ''' Emits normal responses in the OpenBMC json api format. '''
    name = 'json_api_response'
    api = 2

    def apply(self, callback, route):
        def wrap(*a, **kw):
            resp = {'data': callback(*a, **kw)}
            resp['status'] = 'ok'
            resp['message'] = response.status_line
            return resp
        return wrap


class JsonApiErrorsPlugin(object):
    ''' Emits error responses in the OpenBMC json api format. '''
    name = 'json_api_errors'
    api = 2

    def __init__(self, **kw):
        self.app = None
        self.function_type = None
        self.original = None
        self.json_opts = {
            x: y for x, y in kw.iteritems()
            if x in ['indent', 'sort_keys']}

    def setup(self, app):
        self.app = app
        self.function_type = type(app.default_error_handler)
        self.original = app.default_error_handler
        self.app.default_error_handler = self.function_type(
            self.json_errors, app, Bottle)

    def apply(self, callback, route):
        return callback

    def close(self):
        self.app.default_error_handler = self.function_type(
            self.original, self.app, Bottle)

    def json_errors(self, res, error):
        response_object = {'status': 'error', 'data': {}}
        response_object['message'] = error.status_line
        response_object['data']['description'] = str(error.body)
        if error.status_code == 500:
            response_object['data']['exception'] = repr(error.exception)
            response_object['data']['traceback'] = error.traceback.splitlines()

        json_response = json.dumps(response_object, **self.json_opts)
        response.content_type = 'application/json'
        return json_response


class RestApp(Bottle):
    def __init__(self, bus):
        super(RestApp, self).__init__(autojson=False)
        self.bus = bus
        self.mapper = obmc.mapper.Mapper(bus)

        self.install_hooks()
        self.install_plugins()
        self.create_handlers()
        self.install_handlers()

    def install_plugins(self):
        # install json api plugins
        json_kw = {'indent': 2, 'sort_keys': True}
        self.install(JSONPlugin(**json_kw))
        self.install(JsonApiErrorsPlugin(**json_kw))
        self.install(AuthorizationPlugin())
        self.install(JsonApiResponsePlugin())
        self.install(JsonApiRequestPlugin())
        self.install(JsonApiRequestTypePlugin())

    def install_hooks(self):
        self.real_router_match = self.router.match
        self.router.match = self.custom_router_match
        self.add_hook('before_request', self.strip_extra_slashes)

    def create_handlers(self):
        # create route handlers
        self.session_handler = SessionHandler(self, self.bus)
        self.directory_handler = DirectoryHandler(self, self.bus)
        self.list_names_handler = ListNamesHandler(self, self.bus)
        self.list_handler = ListHandler(self, self.bus)
        self.method_handler = MethodHandler(self, self.bus)
        self.property_handler = PropertyHandler(self, self.bus)
        self.schema_handler = SchemaHandler(self, self.bus)
        self.instance_handler = InstanceHandler(self, self.bus)

    def install_handlers(self):
        self.session_handler.install()
        self.directory_handler.install()
        self.list_names_handler.install()
        self.list_handler.install()
        self.method_handler.install()
        self.property_handler.install()
        self.schema_handler.install()
        # this has to come last, since it matches everything
        self.instance_handler.install()

    def custom_router_match(self, environ):
        ''' The built-in Bottle algorithm for figuring out if a 404 or 405 is
            needed doesn't work for us since the instance rules match
            everything. This monkey-patch lets the route handler figure
            out which response is needed.  This could be accomplished
            with a hook but that would require calling the router match
            function twice.
        '''
        route, args = self.real_router_match(environ)
        if isinstance(route.callback, RouteHandler):
            route.callback._setup(**args)

        return route, args

    @staticmethod
    def strip_extra_slashes():
        path = request.environ['PATH_INFO']
        trailing = ("", "/")[path[-1] == '/']
        parts = filter(bool, path.split('/'))
        request.environ['PATH_INFO'] = '/' + '/'.join(parts) + trailing

if __name__ == '__main__':
    log = logging.getLogger('Rocket.Errors')
    log.setLevel(logging.INFO)
    log.addHandler(logging.StreamHandler(sys.stdout))

    bus = dbus.SystemBus()
    app = RestApp(bus)
    default_cert = os.path.join(
        sys.prefix, 'share', os.path.basename(__file__), 'cert.pem')

    server = Rocket(
        ('0.0.0.0', 443, default_cert, default_cert),
        'wsgi', {'wsgi_app': app},
        min_threads=1,
        max_threads=1)
    server.start()
