def test_host_submit_form(self):
        """Edit and submit host edition form"""
        datamgr = DataManager(alignak_webui.app.app, session=self.session)

        # Get host and service in the backend
        host = datamgr.get_host({'where': {'name': 'alignak_glpi'}})
        services = datamgr.get_host_services(host)
        service = services[0]

        print('Enable edition mode')
        response = self.app.post('/edition_mode', params={'state': 'on'})
        session = response.request.environ['beaker.session']
        # edition_mode is defined and activated in the session...
        assert 'edition_mode' in session
        assert True == session['edition_mode']
        assert response.json == {'edition_mode': True, 'message': 'Edition mode enabled'}

        print('get page /host_form (edition mode) - with an host id')
        response = self.app.get('/host_form/%s' % host.id)
        response.mustcontain(
            '''<div id="form_host">''',
            '''<form role="form" data-element="%s" class="element_form " method="post" action="/host_form/%s">''' % (
            host.id, host.id),
            '''$('form[data-element="%s"]').on("submit", function (evt) {''' % host.id
        )

        print('Post form updates')
        data = {
            'name': host.name,
            'alias': "Alias edited"
        }
        response = self.app.post('/host_form/%s' % host.id, params=data)
        assert response.json == {
            "_message": "host 'alignak_glpi' updated", "alias": "Alias edited"
        }
Example #2
0
    def setUp(self):
        print("setting up ...")
        self.dmg = DataManager(alignak_webui.app.app)
        print('Data manager', self.dmg)

        # Initialize and do not load
        assert self.dmg.user_login('admin', 'admin', load=False)
    def test_host_delete(self):
        """Delete the newly created hosts"""
        datamgr = DataManager(alignak_webui.app.app, session=self.session)

        # Count hosts
        count = datamgr.count_objects('host')
        print("Host count: %s" % count)

        # Get host and service in the backend
        host = datamgr.get_host({'where': {'name': 'pi1'}})

        assert datamgr.delete_object('service', host) is False
        assert datamgr.delete_object('host', host) is True

        # Count hosts (one less!)
        new_count = datamgr.count_objects('host')
        print("Host count: %s" % new_count)
        assert new_count == count - 1

        # Get host and service in the backend
        host = datamgr.get_host({'where': {'name': 'pi2'}})

        assert datamgr.delete_object('service', host) is False
        assert datamgr.delete_object('host', host) is True

        # Count hosts (one less!)
        new_count = datamgr.count_objects('host')
        print("Host count: %s" % new_count)
        assert new_count == count - 2
Example #4
0
    def setUp(self):
        self.dmg = DataManager(alignak_webui.app.app)
        print('Data manager', self.dmg)

        # Initialize and load ... no reset
        assert self.dmg.user_login('admin', 'admin')
        result = self.dmg.load()
Example #5
0
    def test_host_form(self):
        """View host edition form"""

        # Get host in the backend
        datamgr = DataManager(alignak_webui.app.app, session=self.session)
        host = datamgr.get_host({'where': {'name': 'alignak_glpi'}})

        print('get page /host_form (reading mode)')
        response = self.app.get('/host_form/%s' % host.id)
        response.mustcontain(
            '''<div id="form_host">''',
            '''<form role="form" data-element="%s" class="element_form " >''' %
            host.id,
            no=[
                '''$('form[data-element="%s"]').on("submit", function (evt) {'''
                % host.id
            ])

        print('Enable edition mode')
        response = self.app.post('/edition_mode', params={'state': 'on'})
        session = response.request.environ['beaker.session']
        # edition_mode is defined and activated in the session...
        assert 'edition_mode' in session
        assert True == session['edition_mode']
        assert response.json == {
            'edition_mode': True,
            'message': 'Edition mode enabled'
        }

        print('get page /host_form (edition mode) - with an host id')
        response = self.app.get('/host_form/%s' % host.id)
        response.mustcontain(
            '''<div id="form_host">''',
            '''<form role="form" data-element="%s" class="element_form " method="post" action="/host_form/%s">'''
            % (host.id, host.id),
            '''$('form[data-element="%s"]').on("submit", function (evt) {''' %
            host.id)

        print('get page /host_form (edition mode) - with an host name')
        response = self.app.get('/host_form/%s' % host.name)
        response.mustcontain(
            '''<div id="form_host">''',
            '''<form role="form" data-element="%s" class="element_form " method="post" action="/host_form/%s">'''
            % (host.id, host.id),
            '''$('form[data-element="%s"]').on("submit", function (evt) {''' %
            host.id)

        print('get page /host_form (edition mode) - for a new host')
        response = self.app.get('/host_form/unknown_host')
        response.mustcontain(
            '''<div id="form_host">''',
            '''<form role="form" data-element="None" class="element_form " method="post" action="/host_form/None">''',
            '''<h4>You are creating a new host.</h4>''',
            '''$('form[data-element="None"]').on("submit", function (evt) {''')
    def test_host_form(self):
        """View host edition form"""

        # Get host in the backend
        datamgr = DataManager(alignak_webui.app.app, session=self.session)
        host = datamgr.get_host({'where': {'name': 'alignak_glpi'}})

        print('get page /host_form (reading mode)')
        response = self.app.get('/host_form/%s' % host.id)
        response.mustcontain(
            '''<div id="form_host">''',
            '''<form role="form" data-element="%s" class="element_form " >''' % host.id,
            no = [
                '''$('form[data-element="%s"]').on("submit", function (evt) {''' % host.id
            ]
        )

        print('Enable edition mode')
        response = self.app.post('/edition_mode', params={'state': 'on'})
        session = response.request.environ['beaker.session']
        # edition_mode is defined and activated in the session...
        assert 'edition_mode' in session
        assert True == session['edition_mode']
        assert response.json == {'edition_mode': True, 'message': 'Edition mode enabled'}

        print('get page /host_form (edition mode) - with an host id')
        response = self.app.get('/host_form/%s' % host.id)
        response.mustcontain(
            '''<div id="form_host">''',
            '''<form role="form" data-element="%s" class="element_form " method="post" action="/host_form/%s">''' % (
            host.id, host.id),
            '''$('form[data-element="%s"]').on("submit", function (evt) {''' % host.id
        )

        print('get page /host_form (edition mode) - with an host name')
        response = self.app.get('/host_form/%s' % host.name)
        response.mustcontain(
            '''<div id="form_host">''',
            '''<form role="form" data-element="%s" class="element_form " method="post" action="/host_form/%s">''' % (
            host.id, host.id),
            '''$('form[data-element="%s"]').on("submit", function (evt) {''' % host.id
        )

        print('get page /host_form (edition mode) - for a new host')
        response = self.app.get('/host_form/unknown_host')
        response.mustcontain(
            '''<div id="form_host">''',
            '''<form role="form" data-element="None" class="element_form " method="post" action="/host_form/None">''',
            '''<h4>You are creating a new host.</h4>''',
            '''$('form[data-element="None"]').on("submit", function (evt) {'''
        )
Example #7
0
    def user_authentication(self, username, password, session=None):
        """
        Authenticate a user thanks to his username / password

        The authentication is requested near the data manager. This functions uses the data manager
        of the current session, else it creates a new one.

        Stores the authenticated User object in the session to make it available
        """

        logger.warning("user_authentication, authenticating: %s", username)

        # Session...
        # session = request.environ['beaker.session']

        session['login_message'] = None
        # if not session:
        if 'current_user' not in session or not session['current_user'] or \
                not isinstance(session['current_user'], dict):
            # Build DM without any session or user parameter
            self.datamgr = DataManager(self.app)

            # Set user for the data manager and try to log-in.
            if not self.datamgr.user_login(username, password, load=(password is not None)):
                self.datamgr.load()
                session['login_message'] = self.datamgr.connection_message
                session['current_user'] = None

                logger.warning("user authentication refused: %s", session['login_message'])
                return False

            # Update application variables
            # self.current_user = self.datamgr.logged_in_user

            # Update session variables
            # session['current_user'] = self.current_user
            session['current_user'] = self.datamgr.logged_in_user
            session['current_realm'] = self.datamgr.my_realm
            # session['current_ls'] = self.datamgr.my_ls

        logger.debug("user_authentication, current user authenticated")
        return session
Example #8
0
    def test_host_submit_form(self):
        """Edit and submit host edition form"""
        datamgr = DataManager(alignak_webui.app.app, session=self.session)

        # Get host and service in the backend
        host = datamgr.get_host({'where': {'name': 'alignak_glpi'}})
        services = datamgr.get_host_services(host)
        service = services[0]

        print('Enable edition mode')
        response = self.app.post('/edition_mode', params={'state': 'on'})
        session = response.request.environ['beaker.session']
        # edition_mode is defined and activated in the session...
        assert 'edition_mode' in session
        assert True == session['edition_mode']
        assert response.json == {
            'edition_mode': True,
            'message': 'Edition mode enabled'
        }

        print('get page /host_form (edition mode) - with an host id')
        response = self.app.get('/host_form/%s' % host.id)
        response.mustcontain(
            '''<div id="form_host">''',
            '''<form role="form" data-element="%s" class="element_form " method="post" action="/host_form/%s">'''
            % (host.id, host.id),
            '''$('form[data-element="%s"]').on("submit", function (evt) {''' %
            host.id)

        print('Post form updates')
        data = {'name': host.name, 'alias': "Alias edited"}
        response = self.app.post('/host_form/%s' % host.id, params=data)
        assert response.json == {
            "_message": "host 'alignak_glpi' updated",
            "alias": "Alias edited"
        }
    def setUp(self):
        # Test application
        self.app = TestApp(alignak_webui.app.session_app)

        response = self.app.get('/login')
        response.mustcontain('<form role="form" method="post" action="/login">')

        response = self.app.post('/login', {'username': '******', 'password': '******'})
        # Redirected twice: /login -> / -> /dashboard !
        redirected_response = response.follow()
        redirected_response = redirected_response.follow()
        session = redirected_response.request.environ['beaker.session']
        # A host cookie now exists
        assert self.app.cookies['Alignak-WebUI']
        # Get a data manager
        self.dmg = DataManager(alignak_webui.app.app, session=session)
Example #10
0
    def test_2_1_creation_load(self):
        """ Datamanager creation and load """
        print('------------------------------')
        print('test creation')

        datamanager = DataManager(alignak_webui.app.app)
        assert datamanager.my_backend
        assert datamanager.loaded == False
        assert datamanager.logged_in_user is None
        print('Data manager', datamanager)
        # Got known managed elements classes
        assert len(datamanager.known_classes) == COUNT_KNOWN_CLASSES

        # Initialize and load fail ...
        print('DM load failed')
        result = datamanager.load()
        # Refused because no backend logged-in user
        assert not result

        # Login error
        print('DM logging bad password')
        assert not datamanager.user_login('admin', 'fake')
        print(datamanager.connection_message)
        assert datamanager.connection_message == 'Access denied! Check your username and password.'
        print(datamanager.logged_in_user)
        assert not datamanager.logged_in_user

        # Create new datamanager - do not use default backend address
        print('DM initialization')
        datamanager = DataManager(alignak_webui.app.app)
        assert datamanager.my_backend
        assert datamanager.loaded == False
        assert datamanager.logged_in_user is None
        print('Data manager', datamanager)

        # Initialize and load fail ...
        print('DM load fail')
        result = datamanager.load()
        # Refused because no backend logged-in user
        assert not result

        # Login error
        print('DM logging bad password')
        assert not datamanager.user_login('admin', 'fake')
        print(datamanager.connection_message)
        assert datamanager.connection_message == 'Access denied! Check your username and password.'
        print(datamanager.logged_in_user)
        assert not datamanager.logged_in_user

        # User login but do not load yet
        print('DM login ok')
        assert datamanager.user_login('admin', 'admin', load=False)
        assert datamanager.connection_message == 'Access granted'
        print("Logged user: %s" % datamanager.logged_in_user)
        assert datamanager.logged_in_user
        assert datamanager.logged_in_user is not None
        assert datamanager.logged_in_user.id is not None
        assert datamanager.logged_in_user.get_username() == 'admin'
        assert datamanager.logged_in_user.authenticated
        user_token = datamanager.logged_in_user.token
        print(User._cache[datamanager.logged_in_user.id].__dict__)

        print('DM reset')
        datamanager.reset()
        # Still logged-in...
        assert datamanager.logged_in_user
        assert datamanager.logged_in_user is not None

        print('DM reset - logout')
        datamanager.reset(logout=True)
        # Logged-out...
        assert not datamanager.logged_in_user
        assert datamanager.logged_in_user is None

        # User login with an authentication token
        print('DM login - token')
        assert datamanager.user_login(user_token)
        # When user authentication is made thanks to a token, DM is not loaded ... it is assumed that load already occured!

        print('DM login')
        assert datamanager.user_login('admin', 'admin', load=False)
        print(datamanager.logged_in_user)
        print(datamanager.logged_in_user.token)
        user_token = datamanager.logged_in_user.token
        assert datamanager.user_login(user_token)
        assert datamanager.connection_message == 'Access granted'

        assert datamanager.logged_in_user
        assert datamanager.logged_in_user is not None
        assert datamanager.logged_in_user.id is not None
        assert datamanager.logged_in_user.get_username() == 'admin'
        assert datamanager.logged_in_user.authenticated
Example #11
0
class WebUI(object):
    """
    WebUI application
    """
    def __init__(self, app, name='alignak_webui', config=None):
        """
        Application initialization

        :param: config
        :type: dict
        """
        logger.info("Initializing application...")
        self.reduced_mode = os.environ.get('ALIGNAK_WEBUI_REDUCED', False)
        if self.reduced_mode:
            logger.warning("- reduced mode: %s!", self.reduced_mode)

        # Store all the plugins
        self.plugins = []

        # Store all the widgets
        self.widgets = {}

        # Store all the tables
        self.tables = {}

        # Store all the lists
        self.lists = {}

        # Helper class
        self.helper = Helper()

        # Application configuration
        self.app = app
        self.name = name
        self.config = config

        # Application data manager and connection
        self.datamgr = None
        self.current_user = None

        # Load plugins in the plugins directory ...
        self.plugins_dir = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'plugins')
        self.plugins_count = self.load_plugins(plugins_dir=self.plugins_dir)
        logger.info("loaded %d plugins from: %s", self.plugins_count, self.plugins_dir)

    def load_plugins(self, plugins_dir):
        # pylint: disable=too-many-locals, too-many-nested-blocks, undefined-loop-variable
        """
        Load plugins from the provided directory

        If the plugin has
        - 'pages', declare routes for the pages
        - 'widgets', declare widgets in the main widgets list

        Register the plugin 'views' directory in the Bottle views

        If the plugin has a 'load_config' function, call it
        """
        # ---
        # Reduced mode without authentication
        # ---
        if self.reduced_mode:
            plugins_dir = "%s_reduced" % plugins_dir
        logger.debug("load plugins from: %s", plugins_dir)

        # Get list of sub directories
        try:
            plugin_names = [
                fname for fname in os.listdir(plugins_dir)
                if os.path.isdir(os.path.join(plugins_dir, fname))
            ]
        except OSError as exp:  # pragma: no cover - simple security ...
            logger.error("plugins directory '%s' does not exist!", plugins_dir)
            return 0

        # Try to import all found supposed modules
        i = 0
        for plugin_name in plugin_names:
            logger.debug("trying to load plugin '%s' ...", plugin_name)
            try:
                # Import the module in the package namespace
                plugin = import_module(
                    '.%s.%s.%s' % (plugins_dir.rsplit('/')[-1], plugin_name, plugin_name),
                    __package__
                )

                # Plugin declared classes ...
                classes = inspect.getmembers(plugin, inspect.isclass)

                # Find "Plugin" sub classes in imported module ...
                p_classes = [co for dummy, co in classes if issubclass(co, Plugin) and co != Plugin]
                if p_classes:
                    logger.debug("Found plugins classes: %s", p_classes)
                    cfg_files = [
                        os.path.join(os.path.join(plugins_dir, plugin_name), 'settings.cfg'),
                        '~/%s/plugin_%s.cfg' % (self.name, plugin_name),
                        '/etc/%s/plugin_%s.cfg' % (self.name, plugin_name),
                        '/usr/local/etc/%s/plugin_%s.cfg' % (self.name, plugin_name),
                    ]

                    for p_class in p_classes:
                        # Create a plugin instance
                        plugin_instance = p_class(self, plugin_name, cfg_files)

                        if not plugin_instance.is_enabled():
                            logger.warning("Plugin '%s' is disabled!", plugin_name)
                            continue

                        i += 1
                        self.plugins.append(plugin_instance)

                # Add the views sub-directory of the plugin in the Bottle templates path
                dir_views = os.path.join(
                    os.path.join(plugins_dir, plugin_name), 'views'
                )
                if os.path.isdir(dir_views):
                    TEMPLATE_PATH.append(os.path.join(
                        os.path.join(plugins_dir, plugin_name), 'views'
                    ))
                    logger.debug("registered views directory '%s'", os.path.join(
                        os.path.join(plugins_dir, plugin_name), 'views'
                    ))

                logger.debug("registered plugin '%s'", plugin_name)

            except Exception as exp:  # pragma: no cover - simple security ...
                logger.exception("loading plugin %s, exception: %s", plugin_name, exp)

        return i

    def get_url(self, name):  # pylint:disable=no-self-use
        """
        Get the URL for a named route
        :param name:
        :return:
        """
        return self.app.get_url(name)

    @property
    def js_list(self):
        """
        Get the list of Javascript files
        :return:
        """
        js_list = [
            "/static/js/jquery-1.12.0.min.js",
            "/static/js/jquery-ui-1.11.4.min.js"
        ]

        if self.config.get('bootstrap4', '0') == '1':
            js_list += [
                "/static/js/bootstrap4.min.js"
            ]
        else:
            js_list += [
                "/static/js/bootstrap.min.js"
            ]

        js_list += [
            "/static/js/moment-with-langs.min.js",
            "/static/js/daterangepicker.js",
            "/static/js/jquery.jclock.js",
            "/static/js/jquery.jTruncate.js",
            "/static/js/typeahead.bundle.min.js",
            "/static/js/screenfull.js",
            "/static/js/alertify.min.js",
            "/static/js/BootSideMenu.js",
            "/static/js/selectize.min.js",
            "/static/js/Chart.min.js",
            "/static/js/jstree.min.js",
        ]

        if self.config.get('bootstrap4', '0') == '1':
            js_list += [
                "/static/js/datatables.bootstrap4.min.js"
            ]
        else:
            js_list += [
                "/static/js/datatables.min.js"
                # "/static/js/datatables.js"
            ]

        js_list += [
            "/static/js/material/arrive.min.js",
            "/static/js/material/material.min.js",
            "/static/js/material/ripples.min.js"
        ]

        return js_list

    @property
    def css_list(self):
        """
        Get the list of Javascript files
        :return:
        """
        if self.config.get('bootstrap4', '0') == '1':
            css_list = [
                "/static/css/bootstrap4.min.css"
            ]
        else:
            css_list = [
                "/static/css/bootstrap.min.css"
            ]

        css_list += [
            "/static/css/font-awesome.min.css",
            "/static/css/typeahead.css",
            "/static/css/daterangepicker.css",
            "/static/css/alertify/alertify.min.css",
            "/static/css/alertify/bootstrap.min.css",
            "/static/css/BootSideMenu.css",
            "/static/css/timeline.css",
            "/static/css/selectize.bootstrap3.css",
        ]

        css_list += [
            "/static/css/font-roboto.css",
            "/static/css/material-icons.css",
            "/static/css/material/bootstrap-material-design.min.css",
            "/static/css/material/ripples.min.css"
        ]

        css_list += [
            "/static/css/jstree/style.min.css",
        ]
        if self.config.get('bootstrap4', '0') == '1':
            css_list += [
                "/static/css/datatables.bootstrap4.min.css",
            ]
        else:
            css_list += [
                "/static/css/datatables.min.css",
            ]

        css_list += [
            "/static/css/alignak_webui.css",
            "/static/css/alignak_webui-items.css"
        ]

        return css_list

    # ---------------------------------------------------------------------------------------------
    # User authentication
    # ---------------------------------------------------------------------------------------------
    def user_authentication(self, username, password, session=None):
        """
        Authenticate a user thanks to his username / password

        The authentication is requested near the data manager. This functions uses the data manager
        of the current session, else it creates a new one.

        Stores the authenticated User object in the session to make it available
        """

        logger.warning("user_authentication, authenticating: %s", username)

        # Session...
        # session = request.environ['beaker.session']

        session['login_message'] = None
        # if not session:
        if 'current_user' not in session or not session['current_user'] or \
                not isinstance(session['current_user'], dict):
            # Build DM without any session or user parameter
            self.datamgr = DataManager(self.app)

            # Set user for the data manager and try to log-in.
            if not self.datamgr.user_login(username, password, load=(password is not None)):
                self.datamgr.load()
                session['login_message'] = self.datamgr.connection_message
                session['current_user'] = None

                logger.warning("user authentication refused: %s", session['login_message'])
                return False

            # Update application variables
            # self.current_user = self.datamgr.logged_in_user

            # Update session variables
            # session['current_user'] = self.current_user
            session['current_user'] = self.datamgr.logged_in_user
            session['current_realm'] = self.datamgr.my_realm
            # session['current_ls'] = self.datamgr.my_ls

        logger.debug("user_authentication, current user authenticated")
        return session

    def find_plugin(self, name):
        """Find a plugin with its name or its backend endpoint"""
        for plugin in self.plugins:
            if plugin.name == name:
                return plugin
        for plugin in self.plugins:
            if plugin.backend_endpoint == name:
                return plugin
        return None

    def get_widgets_for(self, place):
        """For a specific place like 'dashboard' or 'external', returns the widgets list
        sorted by the defined widget order property"""
        widgets_list = []
        for plugin in self.plugins:
            logger.debug("WebUI plugin %s", plugin)
            for widget in plugin.widgets.get(place, []):
                logger.debug(" - widget %s, order: %d, %s", widget['name'], widget['order'], widget)
                # Check if the widget requires a specific plugin to be present and enabled
                if widget.get('plugin', None):
                    needed_plugin = self.find_plugin(widget.get('plugin', None))
                    if not needed_plugin or not needed_plugin.is_enabled():
                        logger.debug("Widget '%s' ignored because of missing "
                                     "or disabled plugin: %s", widget['name'], plugin)
                        continue

                widgets_list.append(widget)

        sorted_widgets = sorted(widgets_list, key=lambda x: x['order'], reverse=False)
        return sorted_widgets

    def get_tables_for(self, place):
        """For a specific place like 'external', return the application tables list"""
        tables = []
        for plugin in self.plugins:
            if place in plugin.tables:
                tables = tables + plugin.tables[place]
        return tables

    ##
    # Make responses for browser client requests
    # ------------------------------------------------------------------------------------------
    @staticmethod
    def response_ok(message="Ok"):
        """Request is ok"""
        response.status = 200
        response.content_type = 'application/json'
        return json.dumps(
            {'status': 'ok', 'message': message}
        )

    @staticmethod
    def response_data(data):
        """Request is ok and contains data"""
        response.status = 200
        response.content_type = 'application/json'
        return json.dumps(data)

    @staticmethod
    def response_invalid_parameters(message="Missing parameter"):
        """Request parameters are invalid"""
        response.status = 400
        response.content_type = 'application/json'
        return json.dumps(
            {'status': 'ko', 'message': message}
        )

    @staticmethod
    def response_missing_file(message="No file selected for upload"):
        """File to upload missing parameter"""
        return WebUI.response_ko(message=message, code=412)

    @staticmethod
    def response_ko(message="Error!", code=409):
        """
        Request failed
        """
        response.status = code
        response.content_type = 'application/json'

        return json.dumps(
            {'status': 'ko', 'message': message}
        )
Example #12
0
class TestNotAdmin(unittest2.TestCase):
    def setUp(self):
        self.dmg = DataManager(alignak_webui.app.app)
        print('Data manager', self.dmg)

    @unittest2.skip(
        "Skipped because creating a new user do not allow him to get its own data (timeperiod get is 404)!"
    )
    def test_4_1_load(self):
        """ Datamanager load, not admin user """
        print('test load not admin user')

        # Initialize and load ... no reset
        assert self.dmg.user_login('admin', 'admin')
        result = self.dmg.load()
        print("Result:", result)
        assert result == 0  # No new objects created ...

        # Get main realm
        realm_all = self.dmg.get_realm({'where': {'name': 'All'}})

        # Get main TP
        tp_all = self.dmg.get_timeperiod({'where': {'name': '24x7'}})

        # Create a non admin user ...
        # Create a new user
        print('create a user')
        data = {
            "name": "not_admin",
            "alias": "Testing user - not administrator",
            "min_business_impact": 0,
            "email": "*****@*****.**",
            "is_admin": False,
            "expert": False,
            "can_submit_commands": False,
            "host_notifications_enabled": True,
            "host_notification_period": tp_all.id,
            "host_notification_commands": [],
            "host_notification_options": ["d", "u", "r"],
            "service_notifications_enabled": True,
            "service_notification_period": tp_all.id,
            "service_notification_commands": [],
            "service_notification_options": ["w", "u", "c", "r"],
            "definition_order": 100,
            "address1": "",
            "address2": "",
            "address3": "",
            "address4": "",
            "address5": "",
            "address6": "",
            "pager": "",
            "notificationways": [],
            "_realm": realm_all.id
        }
        new_user_id = self.dmg.add_user(data)
        print("New user id: %s" % new_user_id)

        # Logout
        # self.dmg.reset(logout=True)
        # assert not self.dmg.backend.connected
        # assert self.dmg.logged_in_user is None
        # assert self.dmg.loaded == False

        # Login as not_admin created user
        assert self.dmg.user_login('admin', 'admin', load=False)
        print("-----")

        assert self.dmg.user_login('not_admin', 'NOPASSWORDSET', load=False)
        assert self.dmg.my_backend.connected
        assert self.dmg.logged_in_user
        print("Logged-in user: %s" % self.dmg.logged_in_user)
        assert self.dmg.logged_in_user.get_username() == 'not_admin'
        print('logged in as not_admin')

        # Initialize and load ...
        result = self.dmg.load()
        print("Result:", result)
        print("Objects count:", self.dmg.get_objects_count())
        print("Objects count:", self.dmg.get_objects_count('host'))
        print("Objects count:", self.dmg.get_objects_count('service'))
        print("Objects count (log):", self.dmg.get_objects_count(log=True))
        # assert result == 0                          # Only the newly created user, so no new objects loaded
        # assert self.dmg.get_objects_count() == 1    # not_admin user

        # Initialize and load ... with reset
        result = self.dmg.load(reset=True)
        print("Result:", result)
        print("Objects count:", self.dmg.get_objects_count())
        print("Objects count:", self.dmg.get_objects_count('host'))
        print("Objects count:", self.dmg.get_objects_count('service'))
        print("Objects count (log):", self.dmg.get_objects_count(log=True))
        # assert result == 3                          # not_admin user + test_service + relation
        # assert self.dmg.get_objects_count() == 3    # not_admin user + test_service + relation

        # Not admin user can see only its own data, ...
        # -------------------------------------------

        # Do not check the length because the backend contains more elements than needed ...
        # dump_backend(not_admin_user=True, test_service=True)

        # Get users
        items = self.dmg.get_users()
        print("Users:", items)
        # assert len(items) == 1
        # 1 user only ...

        # Get commands
        items = self.dmg.get_commands()
        print("Commands:", items)
        # assert len(items) == 1

        # Get realms
        items = self.dmg.get_realms()
        print("Commands:", items)
        # assert len(items) == 1

        # Get timeperiods
        items = self.dmg.get_timeperiods()
        print("Commands:", items)
        # assert len(items) == 1

        # Get hosts
        items = self.dmg.get_hosts()
        print("Hosts:", items)
        # assert len(items) == 1

        # Get services
        items = self.dmg.get_services()
        print("Services:", items)
        # assert len(items) == 1

        result = self.dmg.delete_user(new_user_id)
        # Cannot delete the current logged-in user
        assert not result

        # Logout
        self.dmg.reset(logout=True)
        assert not self.dmg.my_backend.connected
        assert self.dmg.logged_in_user is None
        assert self.dmg.loaded == False

        # Login as admin
        assert self.dmg.user_login('admin', 'admin', load=False)
        assert self.dmg.my_backend.connected
        assert self.dmg.logged_in_user.get_username() == 'admin'

        result = self.dmg.delete_user(new_user_id)
        # Can delete the former logged-in user
        assert result
Example #13
0
class TestLoadCreate(unittest2.TestCase):
    def setUp(self):
        self.dmg = DataManager(alignak_webui.app.app)
        print('Data manager', self.dmg)

    def test_3_1_load(self):
        """ Datamanager load """
        print('test load as admin')

        # Initialize and load ... no reset
        assert self.dmg.user_login('admin', 'admin')
        result = self.dmg.load()
        print("Result:", result)
        # self.assertEqual(result, 0)  # No new objects created ...

        # Initialize and load ... with reset
        result = self.dmg.load(reset=True)
        print("Result:", result)
        # Must not have loaded any objects ... behavior changed, no more objects loading on login
        # self.assertEqual(result, 0)

    def test_3_3_get_errors(self):
        """ Datamanager objects get errors """
        print('test get errors')

        # Initialize and load ... no reset
        assert self.dmg.user_login('admin', 'admin')
        result = self.dmg.load()
        print("Result:", result)
        assert result == 0  # No new objects created ...

        # Get elements error
        item = self.dmg.get_user('unknown')
        assert not item
        item = self.dmg.get_userrestrictrole('unknown')
        assert not item
        item = self.dmg.get_realm('unknown')
        assert not item
        item = self.dmg.get_host('unknown')
        assert not item
        item = self.dmg.get_hostgroup('unknown')
        assert not item
        item = self.dmg.get_hostdependency('unknown')
        assert not item
        item = self.dmg.get_service('unknown')
        assert not item
        item = self.dmg.get_servicegroup('unknown')
        assert not item
        item = self.dmg.get_servicedependency('unknown')
        assert not item
        item = self.dmg.get_command('unknown')
        assert not item
        item = self.dmg.get_history('unknown')
        assert not item
        item = self.dmg.get_logcheckresult('unknown')
        assert not item
        item = self.dmg.get_timeperiod('unknown')
        assert not item
Example #14
0
class TestHosts(unittest2.TestCase):
    def setUp(self):
        print("setting up ...")
        self.dmg = DataManager(alignak_webui.app.app)
        print('Data manager', self.dmg)

        # Initialize and do not load
        assert self.dmg.user_login('admin', 'admin', load=False)

    def tearDown(self):
        print("tearing down ...")
        # Logout
        self.dmg.reset(logout=True)

    def test_hosts(self):
        """ Datamanager objects get - hosts """
        print("Get all hosts")

        # Get main realm
        self.dmg.get_realm({'where': {'name': 'All'}})

        # Get main TP
        self.dmg.get_timeperiod({'where': {'name': '24x7'}})

        # Get all hosts
        hosts = self.dmg.get_hosts()
        assert 13 == len(hosts)
        print("---")
        for host in hosts:
            print("Got host: %s" % host)

        # Get all hosts (really all...)
        hosts = self.dmg.get_hosts(all_elements=True)
        assert 13 == len(hosts)
        print("---")
        for host in hosts:
            print("Got host: %s" % host)

        # Get all hosts (with all embedded relations)
        hosts = self.dmg.get_hosts(embedded=True)
        assert 13 == len(hosts)
        print("---")
        for host in hosts:
            print("Got host: %s" % host)

        # Get all hosts templates
        hosts = self.dmg.get_hosts(template=True)
        assert 28 == len(hosts)
        print("---")
        for host in hosts:
            print("Got host template: %s" % host)

        # Get one host
        hosts = self.dmg.get_hosts({'where': {'name': 'alignak_glpi'}})
        assert 1 == len(hosts)
        print("---")
        for host in hosts:
            print("Got host: %s" % host)
        assert hosts[0].name == 'alignak_glpi'

        # Get one host
        host = self.dmg.get_host({'where': {'name': 'alignak_glpi'}})
        assert host.name == 'alignak_glpi'

        # Get one host
        host = self.dmg.get_host(host._id)
        assert host.name == 'alignak_glpi'
        assert host.status == 'UNREACHABLE'

        # Get host services
        services = self.dmg.get_host_services({'where': {'name': 'unknown'}})
        assert services == -1

        services = self.dmg.get_host_services(
            {'where': {
                'name': 'alignak_glpi'
            }})
        print("---")
        service_name = ''
        for service in services:
            print("Got service: %s" % service)
            service_name = service['name']
        assert len(services) > 1
        services = self.dmg.get_host_services(
            {'where': {
                'name': 'alignak_glpi'
            }},
            search={'where': {
                'name': service_name
            }})
        services = self.dmg.get_host_services(host)
        assert len(services) > 1

        # Get host overall state
        (state, status) = self.dmg.get_host_overall_state(host)
        print("Host overall state: %s %s" % (state, status))
        assert state == 3
        assert status == 'warning'

    def test_host(self):
        """ Datamanager objects get - host """
        print("--- test Item")

        # Get main realm
        self.dmg.get_realm({'where': {'name': 'All'}})

        # Get main TP
        self.dmg.get_timeperiod({'where': {'name': '24x7'}})

        # Get host
        host = self.dmg.get_host({'where': {'name': 'localhost'}})

        print(host.__dict__)
        print(host.check_period)
        assert isinstance(host.check_command, Command)
        assert host.check_command
    def test_host_new_host(self):
        """Create a new host edition form"""

        datamgr = DataManager(alignak_webui.app.app, session=self.session)

        # Get realm in the backend
        realm = datamgr.get_realm({'where': {'name': 'All'}})
        # Get host template in the backend
        template = datamgr.get_host({'where': {'name': 'generic-host', '_is_template': True}})

        print('Enable edition mode')
        response = self.app.post('/edition_mode', params={'state': 'on'})
        session = response.request.environ['beaker.session']
        # edition_mode is defined and activated in the session...
        assert 'edition_mode' in session
        assert True == session['edition_mode']
        assert response.json == {'edition_mode': True, 'message': 'Edition mode enabled'}

        # Count hosts
        count = datamgr.count_objects('host')
        print("Host count: %s" % count)

        print('get page /host_form (edition mode) - for a new host')
        response = self.app.get('/host_form/unknown_host')
        response.mustcontain(
            '''<div id="form_host">''',
            '''<form role="form" data-element="None" class="element_form " method="post" action="/host_form/None">''',
            '''<h4>You are creating a new host.</h4>''',
            '''$('form[data-element="None"]').on("submit", function (evt) {'''
        )

        # A name is enough to create a new host
        print('Host creation - missing name')
        data = {
            "_is_template": False,
        }
        response = self.app.post('/host_form/None', params=data)
        print(response.json)
        assert response.json == {
            '_is_template': False,
            '_message': 'host creation failed!',
            '_errors': ['']
        }

        # A name is enough to create a new host
        print('Host creation without template')
        data = {
            "_is_template": False,
            'name': "New host",
            'alias': "Friendly name"
        }
        response = self.app.post('/host_form/None', params=data)
        # Returns the new item _id
        new_host_id = response.json['_id']
        resp = response.json
        resp.pop('_id')
        assert resp == {
            "_message": "New host created",
            "_realm": realm.id,

            "_is_template": False,
            "name": "New host",
            'alias': "Friendly name"
        }

        # Count hosts (one more!)
        new_count = datamgr.count_objects('host')
        print("Host count: %s" % new_count)
        assert new_count == count + 1

        # Get the new host in the backend
        host = datamgr.get_host({'where': {'name': 'New host'}})
        assert host
        assert host.id == new_host_id
        assert host.name == "New host"
        assert host.alias == "Friendly name"

        print('Host creation with a template')
        data = {
            "_is_template": False,
            "_templates": [template.id],
            'name': "New host 2",
            'alias': "Friendly name 2"
        }
        response = self.app.post('/host_form/None', params=data)
        # Returns the new item _id
        new_host_id = response.json['_id']
        resp = response.json
        resp.pop('_id')
        assert resp == {
            "_message": "New host created",
            "_realm": realm.id,

            "_is_template": False,
            "_templates": [template.id],
            "name": "New host 2",
            'alias': "Friendly name 2"
        }

        # Count hosts (one more!)
        new_count = datamgr.count_objects('host')
        print("Host count: %s" % new_count)
        assert new_count == count + 2

        # Get the new host in the backend
        host = datamgr.get_host({'where': {'name': 'New host 2'}})
        assert host
        assert host.id == new_host_id
        assert host.name == "New host 2"
        assert host.alias == "Friendly name 2"
Example #16
0
    def test_recheck(self):
        """ Actions - recheck"""
        print('test recheck')

        print('get page /recheck/form/add')
        response = self.app.get('/recheck/form/add')
        response.mustcontain(
            '<form class="form-horizontal" data-item="recheck" data-action="add" '
        )

        # Current user is admin
        session = response.request.environ['beaker.session']
        assert 'current_user' in session and session['current_user']
        assert session['current_user'].get_username() == 'admin'

        # Data manager
        datamgr = DataManager(alignak_webui.app.app, session=session)

        # Get host, user and realm in the backend
        host = datamgr.get_host({'where': {'name': 'localhost'}})
        user = datamgr.get_user({'where': {'name': 'admin'}})

        # -------------------------------------------
        # Add a recheck
        # Missing livestate_id!
        data = {
            "host": host.id,
            "service": None,
            "sticky": True,
            "persistent": True,
            "notify": True,
            "comment": "User comment",
        }
        response = self.app.post('/recheck/add', data, status=400)

        # Recheck an host
        data = {
            "elements_type": 'host',
            "element_id": host.id,
            "comment": "User comment",
        }
        response = self.app.post('/recheck/add', data)
        assert response.json['status'] == "ok"
        assert response.json['message'] == "Check request sent for localhost. "

        # Recheck a service
        service = datamgr.get_service(
            {'where': {
                'host': host.id,
                'name': 'Cpu'
            }})
        data = {
            "elements_type": 'service',
            "element_id": service.id,
            "comment": "User comment",
        }
        response = self.app.post('/recheck/add', data)
        assert response.json['status'] == "ok"
        assert response.json[
            'message'] == "Check request sent for localhost/Cpu. "

        # Recheck several services
        service1 = datamgr.get_service(
            {'where': {
                'host': host.id,
                'name': 'Cpu'
            }})
        service2 = datamgr.get_service(
            {'where': {
                'host': host.id,
                'name': 'Memory'
            }})
        data = {
            "action": "add",
            "elements_type": 'service',
            "element_id": [service1.id, service2.id, 'test'],
            "comment": "User comment",
        }
        response = self.app.post('/recheck/add', data)
        assert response.json['status'] == "ok"
        assert response.json[
            'message'] == "Check request sent for localhost/Cpu. Check request sent for localhost/Memory. service element test does not exist. "
Example #17
0
def external(widget_type, identifier, action=None):
    # pylint: disable=too-many-return-statements, unsupported-membership-test
    # pylint: disable=unsubscriptable-object, too-many-locals
    """Application external identifier

    Use internal authentication (if a user is logged-in) or external basic authentication provided
    by the requiring application.

    Search in the known 'widget_type' (widget or table) to find the element 'identifier'.

    Use the 'links' parameter to prefix the navigation URLs.
    """

    logger.warning("external request, url: %s %s", request.method,
                   request.urlparts.path)

    # Get the WebUI instance
    webui = request.app.config['webui']

    # Get the server session (it always exist...)
    session = request.environ['beaker.session']
    st = datetime.datetime.fromtimestamp(
        session['_creation_time']).strftime('%Y-%m-%d %H:%M:%S')
    origin = request.environ.get(
        'HTTP_X_FORWARDED_FOR') or request.environ.get('REMOTE_ADDR')
    logger.debug("client: %s, session: %s / %s / %s", origin, session.id, st,
                 session)

    current_user = None
    if 'current_user' in session and session['current_user']:
        current_user = session['current_user']

        # Get the application instance authentication
        logger.debug("webapp: %s, request app: %s", webapp, request.app)
        logger.debug("current_user: %s", current_user)
        if not webapp.user_authentication(current_user.token, None, session):
            # Redirect to application login page
            logger.warning(
                "External request. User in the session is not authenticated. "
                "Redirecting to the login page...")
            redirect('/login')
        credentials = current_user.token + ':'

    else:
        # Authenticate external access...
        if 'Authorization' not in request.headers or not request.headers[
                'Authorization']:
            logger.warning("external application access denied")
            response.status = 401
            response.content_type = 'text/html'
            return _(
                '<div>'
                '<h1>External access denied.</h1>'
                '<p>To embed an Alignak WebUI widget or table, you must provide credentials.<br>'
                'Log into the Alignak WebUI with your credentials, or make a request '
                'with a Basic-Authentication allowing access to Alignak backend.</p>'
                '</div>')

        # Get HTTP authentication
        authentication = request.headers.get('Authorization')
        username, password = parse_auth(authentication)

        # Get the application instance authentication
        logger.debug("external application, checking authentication for %s",
                     username)
        if not webapp.user_authentication(username, password, session):
            logger.warning("external application access denied for %s",
                           username)
            response.status = 401
            response.content_type = 'text/html'
            return _(
                '<div>'
                '<h1>External access denied.</h1>'
                '<p>The provided credentials do not grant you access to Alignak WebUI.<br>'
                'Please provide proper credentials.</p>'
                '</div>')

        current_user = session['current_user']
        credentials = current_user.token + ':'

        # Make session data available in the templates
        BaseTemplate.defaults['current_user'] = session['current_user']

        # Make data manager available in the request and in the templates
        request.app.datamgr = DataManager(webapp, session=session)
        request.app.datamgr.load()
        logger.warning("request.app.datamgr: %s", request.app.datamgr)
        BaseTemplate.defaults['datamgr'] = request.app.datamgr

    logger.info("External request, element type: %s", widget_type)

    if widget_type not in [
            'files', 'widget', 'table', 'list', 'host', 'service', 'user'
    ]:
        logger.warning("External application requested unknown type: %s",
                       widget_type)
        response.status = 409
        response.content_type = 'text/html'
        return _('<div><h1>Unknown required type: %s.</h1>'
                 '<p>The required type is unknwown</p></div>' % widget_type)

    if widget_type == 'files':
        if identifier == 'js_list':
            response.status = 200
            response.content_type = 'application/json'
            return json.dumps({'status': 'ok', 'files': webui.js_list})

        if identifier == 'css_list':
            response.status = 200
            response.content_type = 'application/json'
            return json.dumps({'status': 'ok', 'files': webui.css_list})

        logger.warning("External application requested unknown files: %s",
                       identifier)
        response.status = 409
        response.content_type = 'application/json'
        return json.dumps({
            'status': 'ko',
            'message': "Unknown files list: %s" % identifier
        })

    if widget_type == 'widget':
        found_widget = None
        for widget in webui.get_widgets_for('external'):
            if identifier == widget['id']:
                found_widget = widget
                break
        else:
            logger.warning("External application requested unknown widget: %s",
                           identifier)
            response.status = 409
            response.content_type = 'text/html'
            return _('<div><h1>Unknown required widget: %s.</h1>'
                     '<p>The required widget is not available.</p></div>' %
                     identifier)
        logger.debug("found widget: %s", found_widget)

        embedded_element = found_widget['function'](embedded=True,
                                                    identifier=identifier,
                                                    credentials=credentials)

        if request.params.get('page', 'no') == 'no':
            return embedded_element

        return template('external_widget',
                        {'embedded_element': embedded_element})

    if widget_type == 'table':
        found_table = None
        for table in webui.get_tables_for('external'):
            if identifier == table['id']:
                found_table = table
                break
        else:
            logger.warning("External application requested unknown table: %s",
                           identifier)
            response.status = 409
            response.content_type = 'text/html'
            return _('<div><h1>Unknown required table: %s.</h1>'
                     '<p>The required table is not available.</p></div>' %
                     identifier)
        logger.info("Found table: %s", found_table)

        if action and action in found_table['actions']:
            logger.info("Required action: %s = %s", action,
                        found_table['actions'][action])
            return found_table['actions'][action]()

        if request.params.get('page', 'no') == 'no':
            return found_table['function'](embedded=True,
                                           identifier=identifier,
                                           credentials=credentials)

        return template(
            'external_table', {
                'embedded_element':
                found_table['function'](embedded=True,
                                        identifier=identifier,
                                        credentials=credentials)
            })

    if widget_type == 'list':
        if identifier in webui.lists:
            return webui.lists[identifier]['function'](embedded=True)

        logger.warning("External application requested unknown list: %s",
                       identifier)
        response.status = 409
        response.content_type = 'text/html'
        return _('<div><h1>Unknown required list: %s.</h1>'
                 '<p>The required list is not available.</p></div>' %
                 identifier)

    if widget_type in ['host', 'service', 'user']:
        if not action:
            logger.warning(
                "External application requested %s widget without widget name",
                widget_type)
            response.status = 409
            response.content_type = 'text/html'
            return _('<div><h1>Missing %s widget name.</h1>'
                     '<p>You must provide a widget name</p></div>' %
                     widget_type)

        # Identifier is the element identifier, not the widget one !
        found_widget = None
        for widget in webui.get_widgets_for(widget_type):
            if action == widget['id']:
                found_widget = widget
                break
        else:
            logger.warning("External application requested unknown widget: %s",
                           action)
            response.status = 409
            response.content_type = 'text/html'
            return _('<div><h1>Unknown required widget: %s.</h1>'
                     '<p>The required widget is not available.</p></div>' %
                     action)
        logger.debug("Found %s widget: %s", widget_type, found_widget)

        if request.params.get('page', 'no') == 'no':
            return found_widget['function'](element_id=identifier,
                                            widget_id=found_widget['id'],
                                            embedded=True,
                                            identifier=identifier,
                                            credentials=credentials)

        return template(
            'external_widget', {
                'embedded_element':
                found_widget['function'](element_id=identifier,
                                         widget_id=found_widget['id'],
                                         embedded=True,
                                         identifier=identifier,
                                         credentials=credentials)
            })
    def setUp(self):
        # Test application
        self.app = TestApp(alignak_webui.app.session_app)

        print('login accepted - go to home page')
        self.login_response = self.app.post('/login', {'username': '******', 'password': '******'})

        # A session cookie exist
        assert self.app.cookies['Alignak-WebUI']
        for cookie in self.app.cookiejar:
            if cookie.name=='Alignak-WebUI':
                assert cookie.expires is None

        # A session exists and it contains: current user, his realm and his live synthesis
        self.session = self.login_response.request.environ['beaker.session']
        assert 'current_user' in self.session and self.session['current_user']
        assert self.session['current_user'].name == 'admin'
        assert 'current_realm' in self.session and self.session['current_realm']
        assert self.session['current_realm'].name == 'All'
        # assert 'current_ls' in self.session and self.session['current_ls']

        # edition_mode is defined but not activated in the session...
        assert 'edition_mode' in self.session
        assert False == self.session['edition_mode']

        print('Enable edition mode')
        response = self.app.post('/edition_mode', params={'state': 'on'})
        assert response.json == {'edition_mode': True, 'message': 'Edition mode enabled'}
        self.session = response.request.environ['beaker.session']
        # edition_mode is defined and activated in the session...
        assert 'edition_mode' in self.session
        assert True == self.session['edition_mode']

        self.datamgr = DataManager(alignak_webui.app.app, session=self.session)

        # Get realm in the backend
        self.realm = self.datamgr.get_realm({'where': {'name': 'All'}})
        print("Realm: %s" % self.realm)
        assert self.realm.name == 'All'

        # Count hosts templates
        self.hosts_templates_count = self.datamgr.count_objects('host', search={'where': {'_is_template': True}})
        print("Hosts templates count: %s" % self.hosts_templates_count)
        assert self.hosts_templates_count == hosts_templates_count

        # Count services templates
        self.services_templates_count = self.datamgr.count_objects('service', search={'where': {'_is_template': True}})
        print("Services templates count: %s" % self.services_templates_count)
        assert self.services_templates_count == services_templates_count

        # Count users templates
        self.users_templates_count = self.datamgr.count_objects('user', search={'where': {'_is_template': True}})
        print("Users templates count: %s" % self.users_templates_count)
        assert self.users_templates_count == users_templates_count

        # Count hosts
        self.hosts_count = self.datamgr.count_objects('host', search={'where': {'_is_template': False}})
        print("Hosts count: %s" % self.hosts_count)

        # Count services
        self.services_count = self.datamgr.count_objects('service', search={'where': {'_is_template': False}})
        print("Services count: %s" % self.services_count)

        # Count users
        self.users_count = self.datamgr.count_objects('user', search={'where': {'_is_template': False}})
        print("users count: %s" % self.users_count)
Example #19
0
    def test_acknowledge(self):
        """ Actions - acknowledge"""
        print('test actions')

        print('get page /acknowledge/form/add')
        response = self.app.get('/acknowledge/form/add')
        response.mustcontain(
            '<form class="form-horizontal" data-item="acknowledge" data-action="add" '
        )

        # Get Data manager in the session
        session = response.request.environ['beaker.session']
        assert 'current_user' in session and session['current_user']
        assert session['current_user'].get_username() == 'admin'

        datamgr = DataManager(alignak_webui.app.app, session=session)

        # Get host and user in the backend
        host = datamgr.get_host({'where': {'name': 'localhost'}})
        user = datamgr.get_user({'where': {'name': 'admin'}})

        # -------------------------------------------
        # Add an acknowledge
        # Missing element_id!
        data = {
            "elements_type": "host",
            "element_id": host.id,
            "service": None,
            "sticky": True,
            "persistent": True,
            "notify": True,
            "comment": "User comment",
        }
        self.app.post('/acknowledge/add', data, status=400)

        # Acknowledge an host
        data = {
            "action": "add",
            "elements_type": 'host',  # Default value, can be omitted ...
            "element_id": host.id,
            "sticky": True,
            "persistent": True,
            "notify": True,
            "comment": "User comment",
        }
        response = self.app.post('/acknowledge/add', data)
        assert response.json['status'] == "ok"
        assert response.json['message'] == \
                         "Acknowledge sent for localhost. "

        # Acknowledge a service
        service = datamgr.get_service(
            {'where': {
                'host': host.id,
                'name': 'Cpu'
            }})
        data = {
            "action": "add",
            "elements_type": 'service',
            "element_id": service.id,
            "sticky": True,
            "persistent": True,
            "notify": True,
            "comment": "User comment",
        }
        response = self.app.post('/acknowledge/add', data)
        assert response.json['status'] == "ok"
        assert response.json['message'] == \
                         "Acknowledge sent for localhost/Cpu. "

        # Acknowledge several services
        service1 = datamgr.get_service(
            {'where': {
                'host': host.id,
                'name': 'Cpu'
            }})
        service2 = datamgr.get_service(
            {'where': {
                'host': host.id,
                'name': 'Memory'
            }})
        data = {
            "action": "add",
            "elements_type": 'service',
            "element_id": [service1.id, service2.id],
            "sticky": True,
            "persistent": True,
            "notify": True,
            "comment": "User comment",
        }
        response = self.app.post('/acknowledge/add', data)
        assert response.json['status'] == "ok"
        assert response.json['message'] == \
                         "Acknowledge sent for localhost/Cpu. " \
                         "Acknowledge sent for localhost/Memory. " \

        # Acknowledge several services
        service1 = datamgr.get_service(
            {'where': {
                'host': host.id,
                'name': 'Cpu'
            }})
        service2 = datamgr.get_service(
            {'where': {
                'host': host.id,
                'name': 'Memory'
            }})
        data = {
            "action": "add",
            "elements_type": 'service',
            "element_id": [service1.id, service2.id, 'test'],
            "sticky": True,
            "persistent": True,
            "notify": True,
            "comment": "User comment",
        }
        response = self.app.post('/acknowledge/add', data)
        assert response.json['status'] == "ok"
        assert response.json['message'] == \
                         "Acknowledge sent for localhost/Cpu. " \
                         "Acknowledge sent for localhost/Memory. " \
                         "service element test does not exist. "
    def setUp(self):
        # Test application
        self.app = TestApp(alignak_webui.app.session_app)

        print('login accepted - go to home page')
        self.login_response = self.app.post('/login', {
            'username': '******',
            'password': '******'
        })

        # A session cookie exist
        assert self.app.cookies['Alignak-WebUI']
        for cookie in self.app.cookiejar:
            if cookie.name == 'Alignak-WebUI':
                assert cookie.expires is None

        # A session exists and it contains: current user, his realm and his live synthesis
        self.session = self.login_response.request.environ['beaker.session']
        assert 'current_user' in self.session and self.session['current_user']
        assert self.session['current_user'].name == 'admin'
        assert 'current_realm' in self.session and self.session['current_realm']
        assert self.session['current_realm'].name == 'All'
        # assert 'current_ls' in self.session and self.session['current_ls']

        # edition_mode is defined but not activated in the session...
        assert 'edition_mode' in self.session
        assert False == self.session['edition_mode']

        print('Enable edition mode')
        response = self.app.post('/edition_mode', params={'state': 'on'})
        assert response.json == {
            'edition_mode': True,
            'message': 'Edition mode enabled'
        }
        self.session = response.request.environ['beaker.session']
        # edition_mode is defined and activated in the session...
        assert 'edition_mode' in self.session
        assert True == self.session['edition_mode']

        self.datamgr = DataManager(alignak_webui.app.app, session=self.session)

        # Get realm in the backend
        self.realm = self.datamgr.get_realm({'where': {'name': 'All'}})
        print("Realm: %s" % self.realm)
        assert self.realm.name == 'All'

        # Count hosts templates
        self.hosts_templates_count = self.datamgr.count_objects(
            'host', search={'where': {
                '_is_template': True
            }})
        print("Hosts templates count: %s" % self.hosts_templates_count)
        assert self.hosts_templates_count == hosts_templates_count

        # Count services templates
        self.services_templates_count = self.datamgr.count_objects(
            'service', search={'where': {
                '_is_template': True
            }})
        print("Services templates count: %s" % self.services_templates_count)
        assert self.services_templates_count == services_templates_count

        # Count users templates
        self.users_templates_count = self.datamgr.count_objects(
            'user', search={'where': {
                '_is_template': True
            }})
        print("Users templates count: %s" % self.users_templates_count)
        assert self.users_templates_count == users_templates_count

        # Count hosts
        self.hosts_count = self.datamgr.count_objects(
            'host', search={'where': {
                '_is_template': False
            }})
        print("Hosts count: %s" % self.hosts_count)

        # Count services
        self.services_count = self.datamgr.count_objects(
            'service', search={'where': {
                '_is_template': False
            }})
        print("Services count: %s" % self.services_count)

        # Count users
        self.users_count = self.datamgr.count_objects(
            'user', search={'where': {
                '_is_template': False
            }})
        print("users count: %s" % self.users_count)
Example #21
0
    def test_change_password(self):
        """ Actions - acknowledge"""
        print('test password change')

        print('get page /password_change_request')
        response = self.app.get('/password_change_request')
        response.mustcontain(
            '<form id="password_change" class="form-horizontal" data-action="password" method="post" action="/change_password" role="form">'
        )

        # Get Data manager in the session
        session = response.request.environ['beaker.session']
        assert 'current_user' in session and session['current_user']
        assert session['current_user'].get_username() == 'admin'

        datamgr = DataManager(alignak_webui.app.app, session=session)

        # Get guest user in the backend
        user = datamgr.get_user({'where': {'name': 'guest'}})

        # -------------------------------------------
        # Change a password
        # Missing element_id!
        data = {
            # "element_id": user.id,
            "elements_type": 'user',
            "elements_name": 'guest',
            "password1": "NewPassword2017",
            "password2": "NewPassword2017",
            "valid_form": "true"
        }
        self.app.post('/change_password', data, status=400)

        # Empty passwords
        data = {
            "element_id": user.id,
            "elements_type": 'user',
            "elements_name": 'guest',
            "password1": "",
            "password2": "",
            "valid_form": "true"
        }
        self.app.post('/change_password', data, status=400)
        data = {
            "element_id": user.id,
            "elements_type": 'user',
            "elements_name": 'guest',
            "password1": "NewPassword2017",
            "password2": "",
            "valid_form": "true"
        }
        self.app.post('/change_password', data, status=400)

        # Invalid form
        data = {
            "element_id": user.id,
            "elements_type": 'user',
            "elements_name": 'guest',
            "password1": "NewPassword2017",
            "password2": "NewPassword2017",
            "valid_form": "false"
        }
        self.app.post('/change_password', data, status=400)

        # -------------------------------------------
        # Change a password
        data = {
            "element_id": user.id,
            "elements_type": 'user',  # Default value, can be omitted ...
            "elements_name": 'guest',
            "password1": "NewPassword2017",
            "password2": "NewPassword2017",
            "valid_form": "true"
        }
        response = self.app.post('/change_password', data)
        assert response.json['status'] == "ok"
        assert response.json['message'] == "User guest updated."

        # -------------------------------------------
        # Log-out the admin user
        response = self.app.get('/logout')
        redirected_response = response.follow()
        redirected_response.mustcontain(
            '<form role="form" method="post" action="/login">')

        # Log-in with the new password
        response = self.app.post('/login', {
            'username': '******',
            'password': '******'
        })
        # Redirected twice: /login -> / -> /dashboard !
        redirected_response = response.follow()
        redirected_response = redirected_response.follow()
        # redirected_response.mustcontain('<div id="dashboard">')
        self.stored_response = redirected_response
        # A host cookie now exists
        assert self.app.cookies['Alignak-WebUI']

        # Redirected twice: /login -> / -> /livestate
        redirected_response = response.follow()
        redirected_response = redirected_response.follow()
        redirected_response.mustcontain('<div id="livestate">')
Example #22
0
class TestBasic(unittest2.TestCase):
    def setUp(self):
        self.dmg = DataManager(alignak_webui.app.app)
        print('Data manager', self.dmg)

        # Initialize and load ... no reset
        assert self.dmg.user_login('admin', 'admin')
        result = self.dmg.load()

    def tearDown(self):
        # Logout
        self.dmg.reset(logout=True)
        assert not self.dmg.my_backend.connected
        assert self.dmg.logged_in_user is None
        assert self.dmg.loaded == False

    def test_5_1_get_simple(self):
        """ Datamanager objects get - simple elements """
        print('test objects get simple objects')

        # Get realms
        items = self.dmg.get_realms()
        for item in items:
            print("Got: ", item)
            assert item.id
            item.get_html_state()
        assert len(items) == 4

        # Get commands
        items = self.dmg.get_commands()
        for item in items:
            print("Got: ", item)
            assert item.id
            icon_status = item.get_html_state()
        assert len(items) == 50  # Backend pagination limit ...

        # Get timeperiods
        items = self.dmg.get_timeperiods()
        for item in items:
            print("Got: ", item)
            assert item.id
            item.get_html_state()
        assert len(items) == 5

    def test_5_1_get_linked(self):
        """ Datamanager objects get - linked elements """
        print('test objects get linked')

        # Get hosts
        items = self.dmg.get_hosts()
        for item in items:
            print("Got: ", item)
            assert item.id
            assert isinstance(item.check_command, Command)  # Must be an object
            assert isinstance(item.check_period,
                              TimePeriod)  # Must be an object
        assert len(items) == 13

        # Get services
        items = self.dmg.get_services()
        for item in items:
            print("Got: ", item)
            assert item.id
            assert isinstance(item.check_command, Command)  # Must be an object
            assert isinstance(item.check_period,
                              TimePeriod)  # Must be an object
        assert len(items) == 50  # Backend pagination limit ...

    def test_5_1_get_linked_groups(self):
        """ Datamanager objects get - group elements """
        print('test objects get self linked')

        # Get hostgroups
        items = self.dmg.get_hostgroups()
        for item in items:
            print("Got: ", item)
            assert item.id
            if item.level != 0:
                assert isinstance(item._parent, HostGroup)  # Must be an object
        assert len(items) == 12

        # Get servicegroups
        items = self.dmg.get_servicegroups()
        for item in items:
            print("Got: ", item)
            assert item.id
            if item.level != 0:
                assert isinstance(item._parent,
                                  ServiceGroup)  # Must be an object
        assert len(items) == 10

        # Get usergroups
        items = self.dmg.get_usergroups()
        for item in items:
            print("Got: ", item)
            assert item.id
            if item.level != 0:
                assert isinstance(item._parent, UserGroup)  # Must be an object
        assert len(items) == 7

    def test_5_3_livesynthesis(self):
        """ Datamanager objects get - livesynthesis """
        print('test livesynthesis')

        self.maxDiff = None

        # Get livesynthesis - user logged-in realm and its sub-realms
        expected_ls = {
            '_id': self.dmg.my_ls['_id'],
            'hosts_synthesis': {
                'nb_elts': 7,
                'nb_not_monitored': 0,
                'pct_not_monitored': 0.0,
                # 'business_impact': 0,
                'warning_threshold': 2.0,
                'global_warning_threshold': 2.0,
                'critical_threshold': 5.0,
                'global_critical_threshold': 5.0,
                'nb_up': 0,
                'pct_up': 0.0,
                'nb_up_hard': 0,
                'nb_up_soft': 0,
                'nb_down': 0,
                'pct_down': 0.0,
                'nb_down_hard': 0,
                'nb_down_soft': 0,
                'nb_unreachable': 7,
                'pct_unreachable': 100.0,
                'nb_unreachable_hard': 7,
                'nb_unreachable_soft': 0,
                'nb_problems': 7,
                'pct_problems': 100.0,
                'nb_flapping': 0,
                'pct_flapping': 0.0,
                'nb_acknowledged': 0,
                'pct_acknowledged': 0.0,
                'nb_in_downtime': 0,
                'pct_in_downtime': 0.0,
            },
            'services_synthesis': {
                'nb_elts': 241,
                'nb_not_monitored': 0,
                'pct_not_monitored': 0.0,
                # 'business_impact': 0,
                'warning_threshold': 2.0,
                'global_warning_threshold': 2.0,
                'critical_threshold': 5.0,
                'global_critical_threshold': 5.0,
                'nb_ok': 0,
                'pct_ok': 0.0,
                'nb_ok_hard': 0,
                'nb_ok_soft': 0,
                'nb_warning': 0,
                'pct_warning': 0.0,
                'nb_warning_hard': 0,
                'nb_warning_soft': 0,
                'nb_critical': 0,
                'pct_critical': 0.0,
                'nb_critical_hard': 0,
                'nb_critical_soft': 0,
                'nb_unknown': 241,
                'pct_unknown': 100.0,
                'nb_unknown_hard': 241,
                'nb_unknown_soft': 0,
                'nb_unreachable': 0,
                'pct_unreachable': 0.0,
                'nb_unreachable_hard': 0,
                'nb_unreachable_soft': 0,
                'nb_problems': 0,
                'pct_problems': 0.0,
                'nb_flapping': 0,
                'pct_flapping': 0.0,
                'nb_acknowledged': 0,
                'pct_acknowledged': 0.0,
                'nb_in_downtime': 0,
                'pct_in_downtime': 0.0
            }
        }
        got_ls = self.dmg.get_livesynthesis({
            'concatenation': '1',
            'where': {
                '_realm': self.dmg.my_realm.id
            }
        })
        assert got_ls['hosts_synthesis'] == expected_ls['hosts_synthesis']
        assert got_ls['services_synthesis'] == expected_ls[
            'services_synthesis']

        # Get livesynthesis - user logged-in realm and no sub realms
        expected_ls = {
            '_id': self.dmg.my_ls['_id'],
            'hosts_synthesis': {
                'nb_elts': 7,
                'nb_not_monitored': 0,
                'pct_not_monitored': 0.0,
                # 'business_impact': 0,
                'warning_threshold': 2.0,
                'global_warning_threshold': 2.0,
                'critical_threshold': 5.0,
                'global_critical_threshold': 5.0,
                'nb_up': 0,
                'pct_up': 0.0,
                'nb_up_hard': 0,
                'nb_up_soft': 0,
                'nb_down': 0,
                'pct_down': 0.0,
                'nb_down_hard': 0,
                'nb_down_soft': 0,
                'nb_unreachable': 7,
                'pct_unreachable': 100.0,
                'nb_unreachable_hard': 7,
                'nb_unreachable_soft': 0,
                'nb_problems': 7,
                'pct_problems': 100.0,
                'nb_flapping': 0,
                'pct_flapping': 0.0,
                'nb_acknowledged': 0,
                'pct_acknowledged': 0.0,
                'nb_in_downtime': 0,
                'pct_in_downtime': 0.0,
            },
            'services_synthesis': {
                'nb_elts': 241,
                'nb_not_monitored': 0,
                'pct_not_monitored': 0.0,
                # 'business_impact': 0,
                'warning_threshold': 2.0,
                'global_warning_threshold': 2.0,
                'critical_threshold': 5.0,
                'global_critical_threshold': 5.0,
                'nb_ok': 0,
                'pct_ok': 0.0,
                'nb_ok_hard': 0,
                'nb_ok_soft': 0,
                'nb_warning': 0,
                'pct_warning': 0.0,
                'nb_warning_hard': 0,
                'nb_warning_soft': 0,
                'nb_critical': 0,
                'pct_critical': 0.0,
                'nb_critical_hard': 0,
                'nb_critical_soft': 0,
                'nb_unknown': 241,
                'pct_unknown': 100.0,
                'nb_unknown_hard': 241,
                'nb_unknown_soft': 0,
                'nb_unreachable': 0,
                'pct_unreachable': 0.0,
                'nb_unreachable_hard': 0,
                'nb_unreachable_soft': 0,
                'nb_problems': 0,
                'pct_problems': 0.0,
                'nb_flapping': 0,
                'pct_flapping': 0.0,
                'nb_acknowledged': 0,
                'pct_acknowledged': 0.0,
                'nb_in_downtime': 0,
                'pct_in_downtime': 0.0
            }
        }
        got_ls = self.dmg.get_livesynthesis(self.dmg.my_ls['_id'])
        assert got_ls['hosts_synthesis'] == expected_ls['hosts_synthesis']
        assert got_ls['services_synthesis'] == expected_ls[
            'services_synthesis']
    def test_service_widgets(self):
        """External - service widgets"""
        print('allowed service widgets external access')

        # Log in to get Data manager in the session
        response = self.app.get('/login')
        response.mustcontain('<form role="form" method="post" action="/login">')

        print('login accepted - go to home page')
        response = self.app.post('/login', {'username': '******', 'password': '******'})
        # Redirected twice: /login -> / -> /dashboard !
        redirected_response = response.follow()
        redirected_response = redirected_response.follow()
        redirected_response.mustcontain('<div id="livestate">')

        session = redirected_response.request.environ['beaker.session']
        assert 'current_user' in session and session['current_user']
        assert session['current_user'].get_username() == 'admin'

        datamgr = DataManager(alignak_webui.app.app, session=session)

        # Get host and service in the backend
        host = datamgr.get_host({'where': {'name': 'KNM-Shinken'}})
        print("Host: %s" % host)
        services = datamgr.get_host_services(host)
        print("Services: %s" % services)
        # service = datamgr.get_service({'where': {'name': 'http', 'host': host.id}})
        service = services[0]
        print("Service: %s" % service)
        # assert False

        # Get external service widget - no widget identifier
        self.app.authorization = ('Basic', ('admin', 'admin'))
        response = self.app.get(
            '/external/service/%s' % service.id,
            status=409
        )
        response.mustcontain('<div><h1>Missing service widget name.</h1><p>You must provide a widget name</p></div>')

        # Get external service widget - unknown widget
        self.app.authorization = ('Basic', ('admin', 'admin'))
        response = self.app.get(
            '/external/service/%s/unknown' % service.id,
            status=409
        )
        response.mustcontain('<div><h1>Unknown required widget: unknown.</h1><p>The required widget is not available.</p></div>')

        # Service information
        # Get external service widget
        self.app.authorization = ('Basic', ('admin', 'admin'))
        response = self.app.get(
            '/external/service/%s/information?page' % service.id
        )
        response.mustcontain(
            '<!DOCTYPE html>',
            '<html lang="en">',
            '<body>',
            '<section>',
            '<div id="wd_panel_information" class="panel panel-default alignak_webui_widget embedded">',
            '<!-- Service information widget -->',
            '</section>',
            '</body>'
        )

        # Get external service widget, no page parameter
        self.app.authorization = ('Basic', ('admin', 'admin'))
        response = self.app.get(
            '/external/service/%s/information' % service.id
        )
        response.mustcontain(
            '<div id="wd_panel_information" class="panel panel-default alignak_webui_widget embedded">',
            '<!-- Service information widget -->',
        )

        # service configuration
        # Get external service widget
        self.app.authorization = ('Basic', ('admin', 'admin'))
        response = self.app.get(
            '/external/service/%s/configuration?page' % service.id
        )
        response.mustcontain(
            '<!DOCTYPE html>',
            '<html lang="en">',
            '<body>',
            '<section>',
            '<div id="wd_panel_configuration" class="panel panel-default alignak_webui_widget embedded">',
            '<!-- Service configuration widget -->',
            '</section>',
            '</body>'
        )

        # Get external service widget, no page parameter
        self.app.authorization = ('Basic', ('admin', 'admin'))
        response = self.app.get(
            '/external/service/%s/configuration' % service.id
        )
        response.mustcontain(
            '<div id="wd_panel_configuration" class="panel panel-default alignak_webui_widget embedded">',
            '<!-- Service configuration widget -->',
        )

        # Service timeline
        # Get external service widget
        self.app.authorization = ('Basic', ('admin', 'admin'))
        response = self.app.get(
            '/external/service/%s/timeline?page' % service.id
        )
        response.mustcontain(
            '<!DOCTYPE html>',
            '<html lang="en">',
            '<body>',
            '<section>',
            '<div id="wd_panel_timeline" class="panel panel-default alignak_webui_widget embedded">',
            '<!-- Service timeline widget -->',
            '</section>',
            '</body>',
            '<div class="alert alert-info">',
            '<p>No available history events.</p>',
            '</div>'
        )

        # Get external service widget, no page parameter
        self.app.authorization = ('Basic', ('admin', 'admin'))
        response = self.app.get(
            '/external/service/%s/timeline' % service.id
        )
        response.mustcontain(
            '<div id="wd_panel_timeline" class="panel panel-default alignak_webui_widget embedded">',
            '<!-- Service timeline widget -->',
        )

        # service metrics
        # Get external service widget
        self.app.authorization = ('Basic', ('admin', 'admin'))
        response = self.app.get(
            '/external/service/%s/metrics?page' % service.id
        )
        response.mustcontain(
            '<!DOCTYPE html>',
            '<html lang="en">',
            '<body>',
            '<section>',
            '<div id="wd_panel_metrics" class="panel panel-default alignak_webui_widget embedded">',
            '<!-- Service metrics widget -->',
            '</section>',
            '</body>'
        )

        # Get external service widget, no page parameter
        self.app.authorization = ('Basic', ('admin', 'admin'))
        response = self.app.get(
            '/external/service/%s/metrics' % service.id
        )
        response.mustcontain(
            '<div id="wd_panel_metrics" class="panel panel-default alignak_webui_widget embedded">',
            '<!-- Service metrics widget -->',
        )
Example #24
0
 def setUp(self):
     self.dmg = DataManager(alignak_webui.app.app)
     print('Data manager', self.dmg)
    def test_user_widgets(self):
        """External - user widgets"""
        print('allowed user widgets external access')

        # Log in to get Data manager in the session
        response = self.app.get('/login')
        response.mustcontain('<form role="form" method="post" action="/login">')

        print('login accepted - go to home page')
        response = self.app.post('/login', {'username': '******', 'password': '******'})
        # Redirected twice: /login -> / -> /dashboard !
        redirected_response = response.follow()
        redirected_response = redirected_response.follow()
        redirected_response.mustcontain('<div id="livestate">')

        session = redirected_response.request.environ['beaker.session']
        assert 'current_user' in session and session['current_user']
        assert session['current_user'].get_username() == 'admin'

        datamgr = DataManager(alignak_webui.app.app, session=session)

        # Get user in the backend
        user = datamgr.get_user({'where': {'name': 'imported_admin'}})

        # Get external user widget - no widget identifier
        self.app.authorization = ('Basic', ('admin', 'admin'))
        response = self.app.get(
            '/external/user/%s' % user.id,
            status=409
        )
        response.mustcontain(
            '<div><h1>Missing user widget name.</h1><p>You must provide a widget name</p></div>')

        # Get external user widget - unknown widget
        self.app.authorization = ('Basic', ('admin', 'admin'))
        response = self.app.get(
            '/external/user/%s/unknown' % user.id,
            status=409
        )
        response.mustcontain(
            '<div><h1>Unknown required widget: unknown.</h1><p>The required widget is not available.</p></div>')

        # Service information
        # Get external user widget
        self.app.authorization = ('Basic', ('admin', 'admin'))
        response = self.app.get(
            '/external/user/%s/information?page' % user.id
        )
        print(response)
        response.mustcontain(
            '<!DOCTYPE html>',
            '<html lang="en">',
            '<body>',
            '<section>',
            '<div id="wd_panel_information" class="panel panel-default alignak_webui_widget embedded">',
            '<!-- User information widget -->',
            '</section>',
            '</body>'
        )

        # Get external user widget, no page parameter
        self.app.authorization = ('Basic', ('admin', 'admin'))
        response = self.app.get(
            '/external/user/%s/information' % user.id
        )
        response.mustcontain(
            '<div id="wd_panel_information" class="panel panel-default alignak_webui_widget embedded">',
            '<!-- User information widget -->',
        )
Example #26
0
class TestRelations(unittest2.TestCase):
    def setUp(self):
        print("setting up ...")
        self.dmg = DataManager(alignak_webui.app.app)
        print('Data manager', self.dmg)

        # Initialize and do not load
        assert self.dmg.user_login('admin', 'admin', load=False)

    def tearDown(self):
        print("tearing down ...")
        # Logout
        self.dmg.reset(logout=True)

    def test_relation_host_command(self):
        """ Datamanager objects get - host/command relation """
        print("--- test Item")

        # Get main realm
        self.dmg.get_realm({'where': {'name': 'All'}})

        # Get main TP
        self.dmg.get_timeperiod({'where': {'name': '24x7'}})

        # Get host
        host = self.dmg.get_host({'where': {'name': 'localhost'}})

        print(host.__dict__)
        print(host.check_period)
        assert isinstance(host.check_command, Command)
        assert host.check_command

    def test_relation_host_service(self):
        """ Datamanager objects get - host/services relation """
        print("--- test Item")

        # Get main realm
        self.dmg.get_realm({'where': {'name': 'All'}})

        # Get main TP
        self.dmg.get_timeperiod({'where': {'name': '24x7'}})

        # Get host
        host = self.dmg.get_host({'where': {'name': 'localhost'}})
        print("Host: ", host.__dict__)

        # Get services of this host
        service = self.dmg.get_service(
            {'where': {
                'name': 'Shinken2-broker',
                'host_name': host.id
            }})
        print("Services: ", service)
    def test_change_password(self):
        """ Actions - acknowledge"""
        print('test password change')

        print('get page /password_change_request')
        response = self.app.get('/password_change_request')
        response.mustcontain(
            '<form id="password_change" class="form-horizontal" data-action="password" method="post" action="/change_password" role="form">'
        )

        # Get Data manager in the session
        session = response.request.environ['beaker.session']
        assert 'current_user' in session and session['current_user']
        assert session['current_user'].get_username() == 'admin'

        datamgr = DataManager(alignak_webui.app.app, session=session)

        # Get guest user in the backend
        user = datamgr.get_user({'where': {'name': 'guest'}})

        # -------------------------------------------
        # Change a password
        # Missing element_id!
        data = {
            # "element_id": user.id,
            "elements_type": 'user',
            "elements_name": 'guest',
            "password1": "NewPassword2017",
            "password2": "NewPassword2017",
            "valid_form": "true"
        }
        self.app.post('/change_password', data, status=400)

        # Empty passwords
        data = {
            "element_id": user.id,
            "elements_type": 'user',
            "elements_name": 'guest',
            "password1": "",
            "password2": "",
            "valid_form": "true"
        }
        self.app.post('/change_password', data, status=400)
        data = {
            "element_id": user.id,
            "elements_type": 'user',
            "elements_name": 'guest',
            "password1": "NewPassword2017",
            "password2": "",
            "valid_form": "true"
        }
        self.app.post('/change_password', data, status=400)

        # Invalid form
        data = {
            "element_id": user.id,
            "elements_type": 'user',
            "elements_name": 'guest',
            "password1": "NewPassword2017",
            "password2": "NewPassword2017",
            "valid_form": "false"
        }
        self.app.post('/change_password', data, status=400)

        # -------------------------------------------
        # Change a password
        data = {
            "element_id": user.id,
            "elements_type": 'user',    # Default value, can be omitted ...
            "elements_name": 'guest',
            "password1": "NewPassword2017",
            "password2": "NewPassword2017",
            "valid_form": "true"
        }
        response = self.app.post('/change_password', data)
        assert response.json['status'] == "ok"
        assert response.json['message'] == "User guest updated."

        # -------------------------------------------
        # Log-out the admin user
        response = self.app.get('/logout')
        redirected_response = response.follow()
        redirected_response.mustcontain('<form role="form" method="post" action="/login">')

        # Log-in with the new password
        response = self.app.post('/login', {'username': '******', 'password': '******'})
        # Redirected twice: /login -> / -> /dashboard !
        redirected_response = response.follow()
        redirected_response = redirected_response.follow()
        # redirected_response.mustcontain('<div id="dashboard">')
        self.stored_response = redirected_response
        # A host cookie now exists
        assert self.app.cookies['Alignak-WebUI']

        # Redirected twice: /login -> / -> /livestate
        redirected_response = response.follow()
        redirected_response = redirected_response.follow()
        redirected_response.mustcontain('<div id="livestate">')
Example #28
0
    def test_host_new_host(self):
        """Create a new host edition form"""

        datamgr = DataManager(alignak_webui.app.app, session=self.session)

        # Get realm in the backend
        realm = datamgr.get_realm({'where': {'name': 'All'}})
        # Get host template in the backend
        template = datamgr.get_host(
            {'where': {
                'name': 'generic-host',
                '_is_template': True
            }})

        print('Enable edition mode')
        response = self.app.post('/edition_mode', params={'state': 'on'})
        session = response.request.environ['beaker.session']
        # edition_mode is defined and activated in the session...
        assert 'edition_mode' in session
        assert True == session['edition_mode']
        assert response.json == {
            'edition_mode': True,
            'message': 'Edition mode enabled'
        }

        # Count hosts
        count = datamgr.count_objects('host')
        print("Host count: %s" % count)

        print('get page /host_form (edition mode) - for a new host')
        response = self.app.get('/host_form/unknown_host')
        response.mustcontain(
            '''<div id="form_host">''',
            '''<form role="form" data-element="None" class="element_form " method="post" action="/host_form/None">''',
            '''<h4>You are creating a new host.</h4>''',
            '''$('form[data-element="None"]').on("submit", function (evt) {''')

        # A name is enough to create a new host
        print('Host creation - missing name')
        data = {
            "_is_template": False,
        }
        response = self.app.post('/host_form/None', params=data)
        print(response.json)
        assert response.json == {
            '_is_template': False,
            '_message': 'host creation failed!',
            '_errors': ['']
        }

        # A name is enough to create a new host
        print('Host creation without template')
        data = {
            "_is_template": False,
            'name': "New host",
            'alias': "Friendly name"
        }
        response = self.app.post('/host_form/None', params=data)
        # Returns the new item _id
        new_host_id = response.json['_id']
        resp = response.json
        resp.pop('_id')
        assert resp == {
            "_message": "New host created",
            "_realm": realm.id,
            "_is_template": False,
            "name": "New host",
            'alias': "Friendly name"
        }

        # Count hosts (one more!)
        new_count = datamgr.count_objects('host')
        print("Host count: %s" % new_count)
        assert new_count == count + 1

        # Get the new host in the backend
        host = datamgr.get_host({'where': {'name': 'New host'}})
        assert host
        assert host.id == new_host_id
        assert host.name == "New host"
        assert host.alias == "Friendly name"

        print('Host creation with a template')
        data = {
            "_is_template": False,
            "_templates": [template.id],
            'name': "New host 2",
            'alias': "Friendly name 2"
        }
        response = self.app.post('/host_form/None', params=data)
        # Returns the new item _id
        new_host_id = response.json['_id']
        resp = response.json
        resp.pop('_id')
        assert resp == {
            "_message": "New host created",
            "_realm": realm.id,
            "_is_template": False,
            "_templates": [template.id],
            "name": "New host 2",
            'alias': "Friendly name 2"
        }

        # Count hosts (one more!)
        new_count = datamgr.count_objects('host')
        print("Host count: %s" % new_count)
        assert new_count == count + 2

        # Get the new host in the backend
        host = datamgr.get_host({'where': {'name': 'New host 2'}})
        assert host
        assert host.id == new_host_id
        assert host.name == "New host 2"
        assert host.alias == "Friendly name 2"
Example #29
0
    def test_downtime(self):
        """ Actions - downtime"""
        print('test actions')

        print('get page /downtime/form/add')
        response = self.app.get('/downtime/form/add')
        response.mustcontain(
            '<form class="form-horizontal" data-item="downtime" data-action="add"'
        )

        # Current user is admin
        session = response.request.environ['beaker.session']
        assert 'current_user' in session and session['current_user']
        assert session['current_user'].get_username() == 'admin'

        # Data manager
        datamgr = DataManager(alignak_webui.app.app, session=session)

        # Get host, user and realm in the backend
        host = datamgr.get_host({'where': {'name': 'localhost'}})
        user = datamgr.get_user({'where': {'name': 'admin'}})

        now = datetime.utcnow()
        later = now + timedelta(days=2, hours=4, minutes=3, seconds=12)
        now = timegm(now.timetuple())
        later = timegm(later.timetuple())

        # -------------------------------------------
        # Add an downtime
        # Missing livestate_id!
        data = {
            "action": "add",
            "host": host.id,
            "service": None,
            "start_time": now,
            "end_time": later,
            "fixed": False,
            'duration': 86400,
            "comment": "User comment",
        }
        self.app.post('/downtime/add', data, status=400)

        # downtime an host
        data = {
            "action": "add",
            "element_id": host.id,
            "start_time": now,
            "end_time": later,
            "fixed": False,
            'duration': 86400,
            "comment": "User comment",
        }
        response = self.app.post('/downtime/add', data)
        assert response.json['status'] == "ok"
        assert response.json['message'] == \
                         "Downtime sent for localhost. "

        # downtime a service
        service = datamgr.get_service(
            {'where': {
                'host': host.id,
                'name': 'Cpu'
            }})
        data = {
            "action": "add",
            "elements_type": 'service',
            "element_id": service.id,
            "start_time": now,
            "end_time": later,
            "fixed": False,
            'duration': 86400,
            "comment": "User comment",
        }
        response = self.app.post('/downtime/add', data)
        assert response.json['status'] == "ok"
        assert response.json['message'] == \
                         "Downtime sent for localhost/Cpu. "

        # downtime several services
        service1 = datamgr.get_service(
            {'where': {
                'host': host.id,
                'name': 'Cpu'
            }})
        service2 = datamgr.get_service(
            {'where': {
                'host': host.id,
                'name': 'Memory'
            }})
        data = {
            "action": "add",
            "elements_type": 'service',
            "element_id": [service1.id, service2.id, 'test'],
            "start_time": now,
            "end_time": later,
            "fixed": False,
            'duration': 86400,
            "comment": "User comment",
        }
        response = self.app.post('/downtime/add', data)
        assert response.json['status'] == "ok"
        assert response.json['message'] == \
                         "Downtime sent for localhost/Cpu. " \
                         "Downtime sent for localhost/Memory. " \
                         "service element test does not exist. "
Example #30
0
    def test_host_delete(self):
        """Delete the newly created hosts"""
        datamgr = DataManager(alignak_webui.app.app, session=self.session)

        # Count hosts
        count = datamgr.count_objects('host')
        print("Host count: %s" % count)

        # Get host and service in the backend
        host = datamgr.get_host({'where': {'name': 'pi1'}})

        assert datamgr.delete_object('service', host) is False
        assert datamgr.delete_object('host', host) is True

        # Count hosts (one less!)
        new_count = datamgr.count_objects('host')
        print("Host count: %s" % new_count)
        assert new_count == count - 1

        # Get host and service in the backend
        host = datamgr.get_host({'where': {'name': 'pi2'}})

        assert datamgr.delete_object('service', host) is False
        assert datamgr.delete_object('host', host) is True

        # Count hosts (one less!)
        new_count = datamgr.count_objects('host')
        print("Host count: %s" % new_count)
        assert new_count == count - 2
Example #31
0
    def test_command(self):
        """ Actions - command"""
        print('test command')

        print('get page /command/form/add')
        response = self.app.get('/command/form/add')
        response.mustcontain(
            '<form class="form-horizontal" data-item="command" data-action="add" '
        )

        print('get page /command/parameters - bad parameters')
        response = self.app.get('/command/parameters', status=409)
        assert response.json == {'error': "the command 'None' does not exist"}
        response = self.app.get(
            '/command/parameters?command=fake&elements_type=host', status=409)
        assert response.json == {'error': "the command 'fake' does not exist"}
        response = self.app.get(
            '/command/parameters?command=process_host_check_result&elements_type=fake',
            status=409)
        assert response.json == {
            'error': "the plugin for 'fake' is not existing or not installed"
        }

        print('get page /command/parameters')
        response = self.app.get(
            '/command/parameters?elements_type=host&command=process_host_check_result'
        )
        expected = {
            "ls_state_id": {
                "allowed": {
                    "0": "Up",
                    "1": "Down (1)",
                    "2": "Not used (2)",
                    "3": "Not used (3)",
                    "4": "Unreachable"
                },
                "allowed_0": "Up",
                "allowed_1": "Down (1)",
                "allowed_2": "Not used (2)",
                "allowed_3": "Not used (3)",
                "allowed_4": "Unreachable",
                "comment":
                "Current state identifier. O: UP, 1: DOWN, 2/3: NOT USED, 4: UNREACHABLE",
                "default": 3,
                "title": "State identifier",
                "editable": True,
                "hidden": True,
                "type": "integer"
            },
            "ls_output": {
                "default": "Check output from WebUI",
                "type": "string",
                "title": "Output",
                "editable": True,
                "comment": "Last check output"
            },
            "ls_long_output": {
                "default": "",
                "type": "string",
                "title": "Long output",
                "editable": True,
                "visible": False,
                "comment": "Last check long output"
            },
            "ls_perf_data": {
                "default": "",
                "type": "string",
                "title": "Performance data",
                "editable": True,
                "visible": False,
                "comment": "Last check performance data"
            }
        }
        assert expected == response.json

        # Current user is admin
        session = response.request.environ['beaker.session']
        assert 'current_user' in session and session['current_user']
        assert session['current_user'].get_username() == 'admin'

        # Data manager
        datamgr = DataManager(alignak_webui.app.app, session=session)

        # Get host and user in the backend
        host = datamgr.get_host({'where': {'name': 'localhost'}})
        user = datamgr.get_user({'where': {'name': 'admin'}})

        # -------------------------------------------
        # Add a command
        # Missing or invalid parameters!
        data = {
            # "command": "test",
            "elements_type": 'host',
            "element_id": host.id
        }
        response = self.app.post('/command/add', data, status=400)
        print(response)

        # Unknown command
        data = {
            "command": "test",
            "elements_type": 'host',
            "element_id": host.id
        }
        response = self.app.post('/command/add', data, status=400)

        # Missing command parameter
        data = {
            "command": "process_host_check_result",
            "elements_type": 'host',
            "element_id": host.id
        }
        response = self.app.post('/command/add', data, status=400)

        # Command for an host
        data = {
            "command": "process_host_check_result",
            "elements_type": 'host',
            "element_id": host.id,
            "ls_state_id": '0',
            "ls_output": "New output...",
            "ls_long_output": "",
            "ls_perf_data": "",
        }
        response = self.app.post('/command/add', data, status=409)
        # As of #193...
        assert response.json['status'] == "ko"
        assert response.json[
            'message'] == "Failed sending a command for localhost. "
Example #32
0
def before_request():
    # pylint: disable=unsupported-membership-test, unsubscriptable-object
    """Function called since an HTTP request is received, and before any other function.

    Checks if a user session exists

    Some URLs do not need any authentication:
        - ping, heartbeat mechanism used for page or page elements refresh
        - login / logout
        - static files (js, css, ...)
    """
    logger.debug("before_request, url: %s %s", request.method,
                 request.urlparts.path)

    # Static application and plugins files
    if request.urlparts.path.startswith('/static'):
        return

    # External URLs routing ...
    if request.urlparts.path.startswith('/external'):
        return

    # Login/logout specific URLs routing ...
    if request.urlparts.path.startswith('/login'):
        return
    if request.urlparts.path.startswith('/logout'):
        return

    # Get the server session (it always exist...)
    session = request.environ['beaker.session']
    sct = datetime.datetime.fromtimestamp(
        session['_creation_time']).strftime('%Y-%m-%d %H:%M:%S')
    sat = datetime.datetime.fromtimestamp(
        session['_accessed_time']).strftime('%Y-%m-%d %H:%M:%S')
    logger.debug(
        "client: %s, route: %s, session: %s / %s - %s / %s",
        request.environ.get('HTTP_X_FORWARDED_FOR')
        or request.environ.get('REMOTE_ADDR'), request.urlparts.path,
        session.id, sct, sat, session)

    current_user = None
    if 'current_user' in session:
        current_user = session['current_user']

    # Session authentication ...
    if not current_user:
        # ping and heartbeat URLs have a specific HTTP status code
        if request.urlparts.path.startswith('/ping'):
            abort(401,
                  json.dumps({
                      'status': 'ok',
                      'message': 'No user session'
                  }))

        if request.urlparts.path.startswith('/heartbeat'):
            logger.error("no user: %s", current_user)
            abort(401,
                  json.dumps({
                      'status': 'ok',
                      'message': 'Session expired'
                  }))

        origin = request.environ.get(
            'HTTP_X_FORWARDED_FOR') or request.environ.get('REMOTE_ADDR')
        logger.debug("client: %s, cookie: %s", origin,
                     request.environ.get('HTTP_COOKIE'))

        # Stop Alignak backend thread
        # ***** Not yet implemented...

        # Redirect to application login page
        logger.warning(
            "Requesting %s. "
            "The session expired or there is no user in the session. "
            "Redirecting to the login page...", request.urlparts.path)

        redirect('/login')

    # Authenticate the session user
    logger.debug("webapp: %s, request app: %s", webapp, request.app)
    logger.info("current_user: %s", current_user)
    if not webapp.user_authentication(current_user.token, None, session):
        # Redirect to application login page
        logger.warning("user in the session is not authenticated. "
                       "Redirecting to the login page...")
        redirect('/login')

    # Make session current user available in the templates
    BaseTemplate.defaults['current_user'] = current_user

    # Make session edition mode available in the templates
    if 'edition_mode' not in session:
        session['edition_mode'] = False
    BaseTemplate.defaults['edition_mode'] = session['edition_mode']
    logger.debug("before_request, edition mode: %s", session['edition_mode'])

    logger.debug("webapp + datamgr: %s / %s", webapp, webapp.datamgr)

    # Initialize data manager and make it available in the request and in the templates
    # if webapp.datamgr is None:  # pragma: no cover, should never happen!
    webapp.datamgr = DataManager(request.app, session=session)
    if not webapp.datamgr.connected:
        redirect('/login')

    # Load initial objects from the DM
    # request.app.datamgr = DataManager(webapp, session=session)
    request.app.datamgr = webapp.datamgr
    request.app.datamgr.load()
    # Do not yet remove this... will be made later;)
    # if request.app.datamgr.logged_in_user.get_username() != 'admin':
    #     logger.warning("client: %s, session: %s, cookie: %s, route: %s",
    #                    request.environ.get('HTTP_X_FORWARDED_FOR') or
    #                    request.environ.get('REMOTE_ADDR'),
    #                    session.id,
    #                    request.environ.get('HTTP_COOKIE'),
    #                    request.urlparts.path)
    #     logger.warning("request.app.datamgr: %s", request.app.datamgr)
    # else:
    #     logger.error("client: %s, session: %s, cookie: %s, route: %s",
    #                  request.environ.get('HTTP_X_FORWARDED_FOR') or
    #                  request.environ.get('REMOTE_ADDR'),
    #                  session.id,
    #                  request.environ.get('HTTP_COOKIE'),
    #                  request.urlparts.path)
    #     logger.error("request.app.datamgr: %s", request.app.datamgr)
    logger.debug("request.app.datamgr: %s", request.app.datamgr)
    BaseTemplate.defaults['datamgr'] = request.app.datamgr

    logger.debug("before_request, call function for route: %s",
                 request.urlparts.path)