コード例 #1
0
ファイル: system_config.py プロジェクト: wjbailey/LinOTP
    def __init__(self, manage_ui):
        """
        @param manage_ui Pass the manage_ui instance
        """

        # Call the default constructor
        ManageDialog.__init__(self, manage_ui, self.body_id)
コード例 #2
0
    def __init__(self, manage_ui):
        ManageDialog.__init__(self, manage_ui, 'dialog_resolvers')
        self.resolvers = None

        self.new_resolvers_dialog = NewResolverDialog(manage_ui)
        self.no_realms_defined_dialog = ManageDialog(manage_ui,
                                                     'text_no_realm')
コード例 #3
0
    def __init__(self, manage_ui):
        ManageDialog.__init__(self, manage_ui, 'dialog_resolvers')
        self.resolvers = None

        self.new_resolvers_dialog = NewResolverDialog(manage_ui)
        self.no_realms_defined_dialog = ManageDialog(
            manage_ui, 'text_no_realm')
        self.alert_box_handler = self.manage.alert_box_handler
コード例 #4
0
    def __init__(self, manage_ui):
        """
        @param manage_ui Pass the manage_ui instance
        """

        # Call the default constructor
        ManageDialog.__init__(self,
                              manage_ui,
                              self.body_id)
コード例 #5
0
    def __init__(self, testcase):
        """
        Create a new ManageUi instance. Normally this will be called
        from a derived class

        :param testcase: The test case that is controlling the UI
        """
        self.testcase = testcase

        self.welcome_screen = ManageDialog(self, 'welcome_screen',
                                           'welcome_screen_close')

        self.useridresolver_manager = UserIdResolverManager(self)
        self.realm_manager = RealmManager(self)
        self.token_view = TokenView(self)
        self.user_view = UserView(self)
        self.policy_view = PolicyManager(self)

        self.alert_dialog = ManageDialog(self, 'alert_box')
コード例 #6
0
    def __init__(self, testcase):
        """
        Create a new ManageUi instance. Normally this will be called
        from a derived class

        :param testcase: The test case that is controlling the UI
        """
        self.testcase = testcase
        self.test_data_dir = os.path.normpath(
            os.path.join(os.path.split(__file__)[0], '..', 'testdata'))

        self.welcome_screen = ManageDialog(self, 'welcome_screen',
                                           'welcome_screen_close')

        self.useridresolver_manager = UserIdResolverManager(self)
        self.realm_manager = RealmManager(self)
        self.token_view = TokenView(self)
        self.user_view = UserView(self)
        self.policy_view = PolicyManager(self)
        self.system_config = SystemConfig(self)
        self.alert_box_handler = AlertBoxHandler(self)

        self.alert_dialog = ManageDialog(self, 'alert_box')
コード例 #7
0
    def __init__(self, testcase):
        """
        Create a new ManageUi instance. Normally this will be called
        from a derived class

        :param testcase: The test case that is controlling the UI
        """
        self.testcase = testcase
        self.test_data_dir = os.path.normpath(os.path.join(
            os.path.split(__file__)[0], '..', 'testdata'
        ))

        self.welcome_screen = ManageDialog(
            self, 'welcome_screen', 'welcome_screen_close')

        self.useridresolver_manager = UserIdResolverManager(self)
        self.realm_manager = RealmManager(self)
        self.token_view = TokenView(self)
        self.user_view = UserView(self)
        self.policy_view = PolicyManager(self)
        self.system_config = SystemConfig(self)

        self.alert_dialog = ManageDialog(self, 'alert_box')
コード例 #8
0
 def __init__(self, manage_ui):
     ManageDialog.__init__(self, manage_ui, 'dialog_realms')
     self.edit_realm_dialog = EditRealmDialog(manage_ui)
コード例 #9
0
 def __init__(self, manage_ui):
     super(TokenView, self).__init__(manage_ui)
     self.delete_confirm_dialog = ManageDialog(manage_ui,
                                               'dialog_delete_token')
コード例 #10
0
class ManageUi(object):
    """
    Object for representing the manage page itself. There should be
    a single ManageUi object to represent the browser page
    """

    URL = "/manage"

    testcase = None
    "The UnitTest class that is running the tests"

    welcome_screen = None
    "Welcome screen dialog"

    useridresolver_manager = None
    "UserIdResolver manager dialog"

    realm_manager = None
    "Realm manager dialog"
    token_view = None
    "Tokens tab"

    user_view = None
    "Users tab"

    policy_view = None
    "Policy tab"

    alert_dialog = None
    "Access to the alert box dialog element"

    # CSS selectors

    # Menu entry "Import Token File"
    MENU_LINOTP_IMPORT_TOKEN_CSS = '#menu > li:nth-of-type(3)'
    "CSS of the LinOTP Import Token menu"

    # Menu entry "LinOTP Config"
    MENU_LINOTP_CONFIG_CSS = '#menu > li'
    "CSS of the LinOTP Config menu"

    def __init__(self, testcase):
        """
        Create a new ManageUi instance. Normally this will be called
        from a derived class

        :param testcase: The test case that is controlling the UI
        """
        self.testcase = testcase
        self.test_data_dir = os.path.normpath(
            os.path.join(os.path.split(__file__)[0], '..', 'testdata'))

        self.welcome_screen = ManageDialog(self, 'welcome_screen',
                                           'welcome_screen_close')

        self.useridresolver_manager = UserIdResolverManager(self)
        self.realm_manager = RealmManager(self)
        self.token_view = TokenView(self)
        self.user_view = UserView(self)
        self.policy_view = PolicyManager(self)
        self.system_config = SystemConfig(self)
        self.alert_box_handler = AlertBoxHandler(self)

        self.alert_dialog = ManageDialog(self, 'alert_box')

    def _is_url_open(self):
        possible_urls = (self.URL, self.URL + '/', self.URL + '/#')
        return self.driver.current_url.endswith(possible_urls)

    @property
    def manage_url(self):
        """
        The URL of the page
        """
        return self.testcase.base_url + self.URL

    @property
    def driver(self):
        """
        Return a reference to the selenium driver
        """
        return self.testcase.driver

    def check_url(self):
        """
        Check we are on the right page
        """
        assert self._is_url_open(), \
            'URL %s should end with %s - page not loaded?' % \
            (self.driver.current_url, self.URL)
        self.testcase.assertEquals(self.driver.title, 'LinOTP 2 Management')

    def find_by_css(self, css_value):
        """
        Return the element indicated by CSS selector
        """
        self.check_url()
        return helper.find_by_css(self.driver, css_value)

    def find_all_by_css(self, css_value):
        """
        Return a list of elements indicated by CSS selector
        """
        self.check_url()
        return self.driver.find_elements_by_css_selector(css_value)

    def find_by_id(self, id_value):
        """
        Return the element by ID
        """
        self.check_url()
        return helper.find_by_id(self.driver, id_value)

    def find_by_class(self, class_name):
        """
        Return the element by its class name
        """
        return helper.find_by_class(self.driver, class_name)

    def find_by_xpath(self, xpath):
        """
        Return the element by its xpath
        """
        return helper.find_by_xpath(self.driver, xpath)

    def open_manage(self):
        if not self._is_url_open():
            self.driver.get(self.manage_url)

            self.welcome_screen.close_if_open()

    def activate_menu_item(self, menu_css, menu_item_id):
        """
        Open the manage UI and select the given menu item.

        If there are open dialogs in the UI, these will be
        closed first.

        Throws an assertion if this dialog does not have an associated menu entry
        """
        assert menu_item_id, "Open dialog requested but no menu id specified (menu_item_id"
        assert menu_css, "Open dialog requested but no toplevel menu specified (menu_css)"

        self.open_manage()

        menu_element = self.find_by_css(menu_css)
        #helper.hover(self.driver, menu_element)

        self.close_dialogs_and_click(menu_element)

        self.find_by_id(menu_item_id).click()

    def close_dialogs_and_click(self, element):
        """
        Click the given element. If it fails, close
        all dialogs and then retry
        """
        try:
            element.click()
        except WebDriverException:
            self.close_all_dialogs()
            # Retry
            element.click()

    def close_all_dialogs(self):
        """
        Close all active dialogs down
        """

        # Find all open dialogs
        dialogs = self.find_all_by_css('.ui-dialog[style*="display: block"]')

        # Sort by depth (the z-index attribute in reverse order)
        dialogs.sort(key=methodcaller('get_attribute', 'z-index'),
                     reverse=True)

        # Close them
        for dialog in dialogs:
            logging.debug('Closing dialog %s' %
                          dialog.get_attribute('aria-describedby'))
            dialog.find_element_by_css_selector(
                ManageDialog.CLOSEBUTTON_CSS).click()

    def check_alert(self,
                    expected_text=None,
                    click_accept=False,
                    click_dismiss=False):
        """
        Process popup window:
        * check the text contents
        * close or dismiss the box

        :param expected_text: Text contents expected. An exception will be raised if not found
        :param click_accept: If set, will click the accept button
        :param click_dismiss: If set, will close the dialog
        """

        assert not click_accept or not click_dismiss, "check_alert cannot click both accept and dismiss"

        alert = self.driver.switch_to_alert()
        alert_text = alert.text

        if click_accept:
            alert.accept()
        elif click_dismiss:
            alert.dismiss()

        if expected_text:
            assert alert_text == expected_text, "Expecting alert text:%s found:%s" % (
                expected_text, alert_text)

    def wait_for_waiting_finished(self):
        """
        Some elements, e.g. the realms dialog, take some time for network communication.
        During this period, the do_waiting is displayed. Wait for this to disappear
        """
        WebDriverWait(self.driver, 10).until_not(
            EC.visibility_of_element_located((By.ID, "do_waiting")))

    def is_element_visible(self, css):
        """
        Check whether a given element is visible without waiting
        """
        if not self._is_url_open():
            return False

        try:
            self.testcase.disableImplicitWait()
            element = EC.visibility_of_element_located(
                (By.CSS_SELECTOR, css))(self.driver)
            self.testcase.enableImplicitWait()
        except Exception:
            return False

        is_visible = (element is not False)
        return is_visible
コード例 #11
0
 def __init__(self, manage_ui):
     ManageDialog.__init__(self, manage_ui, 'dialog_realms')
     self.edit_realm_dialog = EditRealmDialog(manage_ui)
     self.alert_box_handler = self.manage.alert_box_handler
コード例 #12
0
class UserIdResolverManager(ManageDialog):
    """
    Management dialog for userIdResolvers
    """
    new_button_id = 'button_resolver_new'
    close_button_id = 'button_resolver_close'
    menu_item_id = 'menu_edit_resolvers'

    def __init__(self, manage_ui):
        ManageDialog.__init__(self, manage_ui, 'dialog_resolvers')
        self.resolvers = None

        self.new_resolvers_dialog = NewResolverDialog(manage_ui)
        self.no_realms_defined_dialog = ManageDialog(manage_ui,
                                                     'text_no_realm')

    @staticmethod
    def get_resolver_for_type(resolver_type):
        "Return the derived class for a given resolver type"
        if resolver_type == 'ldapresolver':
            return LdapUserIdResolver
        elif resolver_type == 'sqlresolver':
            return SqlUserIdResolver
        elif resolver_type == 'passwdresolver':
            return PasswdUserIdResolver
        else:
            raise Exception("Unknown UserIdResolver type:%s" % (resolver_type))

    @staticmethod
    def parse_resolver_element(line):
        # Given an element, parse out resolver info

        class ResolverElement:
            def __init__(self, name, resolverType, element=None):
                self.name = name
                self.resolverType = resolverType
                self.element = element
                self.name_in_dialog = "%s [%s]" % (name, resolverType)

        try:
            name_element = line.find_element_by_css_selector('.name')
            # New style line (2.9.2) with managed flag
            resolver_element = name_element
        except NoSuchElementException:
            # Pre 2.9.2 without managed flag
            resolver_element = line

        resolver_name_re = r'([\w\-]+) \[([\w\-]+)\]$'

        m = re.match(resolver_name_re, resolver_element.text)
        assert m, 'Error in resolver regexp for "%s"' % (resolver_element, )

        assert(line.get_attribute("class") in
               ('ui-widget-content ui-selectee', 'ui-widget-content ui-selectee ui-selected')), \
            "Resolver dialog line class unknown"

        return ResolverElement(m.group(1), m.group(2), line)

    def parse_contents(self):
        """
        Parse the resolver dialog list and build a list of resolvers
        """
        # Ensure server communication is finished
        self.wait_for_waiting_finished()

        # Ensure resolvers list element is visible
        resolvers_list = self.find_by_id("dialog_resolvers")

        self.resolvers = []

        # The dialog could be empty, so disable implicit wait for the list
        with self.implicit_wait_disabled():
            lines = resolvers_list.find_elements_by_css_selector(
                '#resolvers_list > ol > li')

            for line in lines:
                self.resolvers.append(self.parse_resolver_element(line))

    def _get_resolver_by_name(self, name):
        """
        Get resolver given the name
        Return tuple:
         resolver name
         type
         name in dialog
        """
        r = [r for r in self.resolvers if r.name == name]
        assert len(
            r) == 1, "Resolver name %s not found in current resolver list" % (
                name, )
        resolver = r[0]
        return resolver

    def get_defined_resolvers(self):
        """
        Return a list of currently defined resolver names
        """
        self.raise_if_closed()
        return [r.name for r in self.resolvers]

    def create_resolver(self, data):
        resolver_type = data['type']

        self.open()
        oldlist = self.get_defined_resolvers()

        assert data[
            'name'] not in oldlist, 'Trying to define a resolver which already exists'

        oldcount = len(oldlist)
        self.find_by_id(self.new_button_id).click()
        self.new_resolvers_dialog.check_text(
            'Which type of resolver do you want to create?')

        resolverClass = self.get_resolver_for_type(resolver_type)
        resolver = resolverClass(self)

        assert resolver.newbutton_id, "Resolver new button id is not defined"
        self.new_resolvers_dialog.click_button(resolver.newbutton_id)

        # Fill in new resolver form
        resolver.fill_form(data)

        self.find_by_id(resolver.savebutton_id).click()

        # We should be back to the resolver list
        self.raise_if_closed()
        self.reparse()

        newlist = self.get_defined_resolvers()
        newcount = len(newlist)
        if newcount != oldcount + 1:
            logging.error("Could not create resolver! %s", data)
            assert newcount == oldcount + 1

        return data['name']

    def close(self):
        super(UserIdResolverManager, self).close()
        if self.no_realms_defined_dialog.is_open():
            self._handle_first_resolver_dialogs()

    def _handle_first_resolver_dialogs(self):
        self.no_realms_defined_dialog.raise_if_closed()
        self.no_realms_defined_dialog.close()

        # The realms dialog now opens - close it
        realms = self.manage.realm_manager
        realms.raise_if_closed()
        realms.close()

    def reload(self):
        # Close and reopen
        self.close_if_open()
        self.open()

    def select_resolver(self, name):
        resolver = self._get_resolver_by_name(name)
        resolver.element.click()
        return resolver

    def edit_resolver(self, name):
        """
        return resolver, given open dialog
        """
        self.raise_if_closed()
        resolver = self.select_resolver(name)
        self.find_by_id("button_resolver_edit").click()
        return resolver

    def delete_resolver(self, name):
        """Click on resolver in list and delete it"""
        driver = self.driver

        resolver_count = len(self.resolvers)

        self.select_resolver(name)
        self.find_by_id("button_resolver_delete").click()
        self.testcase.assertEquals("Deleting resolver",
                                   self.find_by_id("ui-id-3").text)

        t = find_by_css(driver, "#dialog_resolver_ask_delete > p").text
        self.testcase.assertEqual(t, r"Do you want to delete the resolver?")

        self.find_by_id("button_resolver_ask_delete_delete").click()

        # We should be back to the resolver list
        self.raise_if_closed()
        self.manage.wait_for_waiting_finished()

        # Reload resolvers
        self.parse_contents()

        assert (len(self.resolvers) == resolver_count - 1), (
            'The number of resolvers shown should decrease after deletion. Before: %s, after:%s'
            % (resolver_count, len(self.resolvers)))

    def clear_resolvers(self):
        """Clear all existing resolvers"""
        self.open()

        while True:
            resolvers = self.resolvers
            if not resolvers:
                break
            self.delete_resolver(resolvers[0].name)

        self.close()

    def test_connection(self, name, expected_users=None):
        """Test the connection with the corresponding button in the UI.
        Return the number of found users.
        """
        self.open()
        self.edit_resolver(name)
        resolver = self._get_resolver_by_name(name)

        resolver_info = self.get_resolver_for_type(resolver.resolverType)(self)
        testbutton_id = resolver_info.testbutton_id
        cancelbutton_id = resolver_info.editcancel_button_id

        if not testbutton_id:
            # This resolver type does not have a test button (passwd)
            num_found = -1
        else:
            self.find_by_id(testbutton_id).click()

            # Wait for alert box to be shown and then get contents
            alert_box = self.manage.alert_dialog
            alert_box.wait_for_dialog()
            alert_box_text = alert_box.get_text()

            m = re.search("Number of users found: (?P<nusers>\d+)",
                          alert_box_text)
            if m is None:
                raise Exception("test_connection for %s failed: %s" %
                                (name, alert_box_text))
            num_found = int(m.group('nusers'))

            if expected_users:
                assert num_found == expected_users, "Expected number of users:%s, found:%s" % (
                    expected_users, num_found)

            # Close the popup
            alert_box.close()

        # Close the resolver edit box
        self.find_by_id(cancelbutton_id).click()

        return num_found
コード例 #13
0
class ManageUi(object):
    """
    Object for representing the manage page itself. There should be
    a single ManageUi object to represent the browser page
    """

    URL = "/manage"

    testcase = None
    "The UnitTest class that is running the tests"

    welcome_screen = None
    "Welcome screen dialog"

    useridresolver_manager = None
    "UserIdResolver manager dialog"

    realm_manager = None
    "Realm manager dialog"
    token_view = None
    "Tokens tab"

    user_view = None
    "Users tab"

    policy_view = None
    "Policy tab"

    alert_dialog = None
    "Access to the alert box dialog element"

    # CSS selectors

    # Menu entry "Import Token File"
    MENU_LINOTP_IMPORT_TOKEN_CSS = '#menu > li:nth-of-type(3)'
    "CSS of the LinOTP Import Token menu"

    # Menu entry "LinOTP Config"
    MENU_LINOTP_CONFIG_CSS = '#menu > li'
    "CSS of the LinOTP Config menu"

    def __init__(self, testcase):
        """
        Create a new ManageUi instance. Normally this will be called
        from a derived class

        :param testcase: The test case that is controlling the UI
        """
        self.testcase = testcase
        self.test_data_dir = os.path.normpath(os.path.join(
            os.path.split(__file__)[0], '..', 'testdata'
        ))

        self.welcome_screen = ManageDialog(
            self, 'welcome_screen', 'welcome_screen_close')

        self.useridresolver_manager = UserIdResolverManager(self)
        self.realm_manager = RealmManager(self)
        self.token_view = TokenView(self)
        self.user_view = UserView(self)
        self.policy_view = PolicyManager(self)
        self.system_config = SystemConfig(self)

        self.alert_dialog = ManageDialog(self, 'alert_box')

    def _is_url_open(self):
        possible_urls = (self.URL, self.URL + '/', self.URL + '/#')
        return self.driver.current_url.endswith(possible_urls)

    @property
    def manage_url(self):
        """
        The URL of the page
        """
        return self.testcase.base_url + self.URL

    @property
    def alert_box_handler(self):
        """
        Return an instance of an alert box handler.
        """
        return AlertBoxHandler(self)

    @property
    def driver(self):
        """
        Return a reference to the selenium driver
        """
        return self.testcase.driver

    def check_url(self):
        """
        Check we are on the right page
        """
        assert self._is_url_open(), \
            'URL %s should end with %s - page not loaded?' % \
            (self.driver.current_url, self.URL)
        self.testcase.assertEquals(self.driver.title, 'LinOTP 2 Management')

    def find_by_css(self, css_value):
        """
        Return the element indicated by CSS selector
        """
        self.check_url()
        return helper.find_by_css(self.driver, css_value)

    def find_all_by_css(self, css_value):
        """
        Return a list of elements indicated by CSS selector
        """
        self.check_url()
        return self.driver.find_elements_by_css_selector(css_value)

    def find_by_id(self, id_value):
        """
        Return the element by ID
        """
        self.check_url()
        return helper.find_by_id(self.driver, id_value)

    def find_by_class(self, class_name):
        """
        Return the element by its class name
        """
        return helper.find_by_class(self.driver, class_name)

    def find_by_xpath(self, xpath):
        """
        Return the element by its xpath
        """
        return helper.find_by_xpath(self.driver, xpath)

    def open_manage(self):
        if not self._is_url_open():
            self.driver.get(self.manage_url)

            self.welcome_screen.close_if_open()

    def activate_menu_item(self, menu_css, menu_item_id):
        """
        Open the manage UI and select the given menu item.

        If there are open dialogs in the UI, these will be
        closed first.

        Throws an assertion if this dialog does not have an associated menu entry
        """
        assert menu_item_id, "Open dialog requested but no menu id specified (menu_item_id"
        assert menu_css, "Open dialog requested but no toplevel menu specified (menu_css)"

        self.open_manage()

        menu_element = self.find_by_css(menu_css)
        # helper.hover(self.driver, menu_element)

        self.close_dialogs_and_click(menu_element)

        self.find_by_id(menu_item_id).click()

    def close_dialogs_and_click(self, element):
        """
        Click the given element. If it fails, close
        all dialogs and then retry
        """
        try:
            element.click()
        except WebDriverException:
            self.close_all_dialogs()
            # Retry
            element.click()

    def close_all_dialogs(self):
        """
        Close all active dialogs down
        """

        # Find all open dialogs
        dialogs = self.find_all_by_css('.ui-dialog[style*="display: block"]')

        # Sort by depth (the z-index attribute in reverse order)
        dialogs.sort(
            key=methodcaller('get_attribute', 'z-index'), reverse=True)

        # Close them
        for dialog in dialogs:
            logging.debug('Closing dialog %s' %
                          dialog.get_attribute('aria-describedby'))
            dialog.find_element_by_css_selector(
                ManageDialog.CLOSEBUTTON_CSS).click()

    def check_alert(self, expected_text=None, click_accept=False, click_dismiss=False):
        """
        Process popup window:
        * check the text contents
        * close or dismiss the box

        :param expected_text: Text contents expected. An exception will be raised if not found
        :param click_accept: If set, will click the accept button
        :param click_dismiss: If set, will close the dialog
        """

        assert not click_accept or not click_dismiss, "check_alert cannot click both accept and dismiss"

        alert = self.driver.switch_to_alert()
        alert_text = alert.text

        if click_accept:
            alert.accept()
        elif click_dismiss:
            alert.dismiss()

        if expected_text:
            assert alert_text == expected_text, "Expecting alert text:%s found:%s" % (
                expected_text, alert_text)

    def wait_for_waiting_finished(self):
        """
        Some elements, e.g. the realms dialog, take some time for network communication.
        During this period, the do_waiting is displayed. Wait for this to disappear
        """
        WebDriverWait(self.driver, 10).until_not(
            EC.visibility_of_element_located((By.ID, "do_waiting")))

    def is_element_visible(self, css):
        """
        Check whether a given element is visible without waiting
        """
        if not self._is_url_open():
            return False

        try:
            self.testcase.disableImplicitWait()
            element = EC.visibility_of_element_located(
                (By.CSS_SELECTOR, css))(self.driver)
            self.testcase.enableImplicitWait()
        except Exception:
            return False

        is_visible = (element is not False)
        return is_visible

    def admin_api_call(self,
                       call,
                       params=None):
        """
        Give the API endpoint (call) and the params. Omit the session
        because it will be added automatically to your params.
        :param call Something like 'system/delPolicy'
        :param params Something like {'name': 'policy1'}
        :return Return json structure with API result
        """

        if(params is None):
            params = {}

        url = self.testcase.http_protocol + \
            "://" + self.testcase.http_host + \
            ":" + self.testcase.http_port + "/"

        params['session'] = helper.get_session(url,
                                               self.testcase.http_username,
                                               self.testcase.http_password)

        auth = requests.auth.HTTPDigestAuth(
            self.testcase.http_username,
            self.testcase.http_password)

        response = requests.post(url + call.strip('/'),
                                 auth=auth,
                                 params=params,
                                 cookies={'admin_session': params['session']},
                                 verify=False)

        response.raise_for_status()

        return response.json()
コード例 #14
0
class UserIdResolverManager(ManageDialog):
    """
    Management dialog for userIdResolvers
    """
    new_button_id = 'button_resolver_new'
    close_button_id = 'button_resolver_close'
    menu_item_id = 'menu_edit_resolvers'

    alert_box_handler = None

    def __init__(self, manage_ui):
        ManageDialog.__init__(self, manage_ui, 'dialog_resolvers')
        self.resolvers = None

        self.new_resolvers_dialog = NewResolverDialog(manage_ui)
        self.no_realms_defined_dialog = ManageDialog(
            manage_ui, 'text_no_realm')
        self.alert_box_handler = self.manage.alert_box_handler

    @staticmethod
    def get_resolver_for_type(resolver_type):
        "Return the derived class for a given resolver type"
        if resolver_type == 'ldapresolver':
            return LdapUserIdResolver
        elif resolver_type == 'sqlresolver':
            return SqlUserIdResolver
        elif resolver_type == 'passwdresolver':
            return PasswdUserIdResolver
        else:
            raise Exception("Unknown UserIdResolver type:%s" % (resolver_type))

    @staticmethod
    def parse_resolver_element(line):
        # Given an element, parse out resolver info

        class ResolverElement:

            def __init__(self, name, resolverType, element=None):
                self.name = name
                self.resolverType = resolverType
                self.element = element
                self.name_in_dialog = "%s [%s]" % (name, resolverType)

        try:
            name_element = line.find_element_by_css_selector('.name')
            # New style line (2.9.2) with managed flag
            resolver_element = name_element
        except NoSuchElementException:
            # Pre 2.9.2 without managed flag
            resolver_element = line

        resolver_name_re = r'([\w\-]+) \[([\w\-]+)\]$'

        m = re.match(resolver_name_re, resolver_element.text)
        assert m, 'Error in resolver regexp for "%s"' % (resolver_element,)

        assert('ui-selectee' in line.get_attribute("class").split(" ")), \
            "Resolver dialog line not selectable"

        return ResolverElement(m.group(1), m.group(2), line)

    def parse_contents(self):
        """
        Parse the resolver dialog list and build a list of resolvers
        """
        # Ensure server communication is finished
        self.wait_for_waiting_finished()

        # Ensure resolvers list element is visible
        resolvers_list = self.find_by_id("dialog_resolvers")

        self.resolvers = []

        # The dialog could be empty, so disable implicit wait for the list
        with self.implicit_wait_disabled():
            lines = resolvers_list.find_elements_by_css_selector(
                '#resolvers_list > ol > li')

            for line in lines:
                self.resolvers.append(self.parse_resolver_element(line))

    def _get_resolver_by_name(self, name):
        """
        Get resolver given the name
        Return tuple:
         resolver name
         type
         name in dialog
        """
        r = [r for r in self.resolvers if r.name == name]
        assert len(
            r) == 1, "Resolver name %s not found in current resolver list" % (name,)
        resolver = r[0]
        return resolver

    def get_defined_resolvers(self):
        """
        Return a list of currently defined resolver names
        """
        self.raise_if_closed()
        return [r.name for r in self.resolvers]

    def create_resolver(self, data):
        resolver_type = data['type']

        self.open()
        oldlist = self.get_defined_resolvers()

        assert data[
            'name'] not in oldlist, 'Trying to define a resolver which already exists'

        oldcount = len(oldlist)
        self.find_by_id(self.new_button_id).click()
        self.new_resolvers_dialog.check_text(
            'Which type of resolver do you want to create?')

        resolverClass = self.get_resolver_for_type(resolver_type)
        resolver = resolverClass(self)

        assert resolver.newbutton_id, "Resolver new button id is not defined"
        self.new_resolvers_dialog.click_button(
            resolver.newbutton_id)

        # Fill in new resolver form
        resolver.fill_form(data)

        self.find_by_id(resolver.savebutton_id).click()

        # We should be back to the resolver list
        self.raise_if_closed()
        self.reparse()

        newlist = self.get_defined_resolvers()
        newcount = len(newlist)
        if newcount != oldcount + 1:
            logging.error("Could not create resolver! %s", data)
            assert newcount == oldcount + 1

        return data['name']

    def close(self):
        super(UserIdResolverManager, self).close()
        if self.no_realms_defined_dialog.is_open():
            self._handle_first_resolver_dialogs()

    def _handle_first_resolver_dialogs(self):
        self.no_realms_defined_dialog.raise_if_closed()
        self.no_realms_defined_dialog.close()

        # The realms dialog now opens - close it
        realms = self.manage.realm_manager
        realms.raise_if_closed()
        realms.close()

    def reload(self):
        # Close and reopen
        self.close_if_open()
        self.open()

    def select_resolver(self, name):
        resolver = self._get_resolver_by_name(name)
        resolver.element.click()
        return resolver

    def edit_resolver(self, name):
        """
        return resolver, given open dialog
        """
        self.raise_if_closed()
        resolver = self.select_resolver(name)
        self.find_by_id("button_resolver_edit").click()
        return resolver

    def delete_resolver(self, name):
        """Click on resolver in list and delete it"""
        driver = self.driver

        resolver_count = len(self.resolvers)

        self.select_resolver(name)
        self.find_by_id("button_resolver_delete").click()
        self.testcase.assertEquals(
            "Deleting resolver", self.find_by_id("ui-id-3").text)

        t = find_by_css(driver, "#dialog_resolver_ask_delete > p").text
        self.testcase.assertEqual(t, r"Do you want to delete the resolver?")

        self.find_by_id("button_resolver_ask_delete_delete").click()

        # We should be back to the resolver list
        self.raise_if_closed()
        self.manage.wait_for_waiting_finished()

        # Resolver name would be e. g. : 'test_realm5 [SE_musicians ]'
        # Capture only resolver name.
        resolver = re.search(r'([^\[(]+)', name).group(1).strip(' ')
        delete_ok = self.alert_box_handler.check_last_message(
            "Resolver deleted successfully: " + resolver)
        assert delete_ok, "Error during resolver deletion!"

        # Reload resolvers
        self.parse_contents()

        assert (len(self.resolvers) == resolver_count - 1), (
            'The number of resolvers shown should decrease after deletion. Before: %s, after:%s'
            % (resolver_count, len(self.resolvers))
        )

    def clear_resolvers_via_api(self):
        """
        Get all resolvers via API call
        and delete all by resolver name.
        """

        # Get the resolvers in json format
        json_response = self.manage.admin_api_call("system/getResolvers")

        resolvers = json_response["result"]["value"]
        if(resolvers):
            for curr_resolver in resolvers:
                self.manage.admin_api_call("system/delResolver",
                                           {'resolver': resolvers[curr_resolver]['resolvername']})

    def clear_resolvers(self):
        """
        Clear all existing resolvers.

        The clean up will be done via
        the following steps.
        1. Clear all alert boxes in the /manage UI
        2. Open the resolver dialog and get all
           resolvers.
        3. Delete resolver x and check alert box.
        4. Repeat 3. #resolvers times
        """

        # /manage needs to be open for clean up
        # alert box messages.
        self.manage.open_manage()

        # Maybe /manage was already open:
        #
        # Ensure that dialogs are closed.
        # Otherwise we can not clear the old
        # alert boxes. Realm dialog blocks
        # underlying GUI elements.
        self.manage.close_all_dialogs()

        self.alert_box_handler.clear_messages()

        # The open method 'reparses' the dialog.
        # This reparse sets an internal list
        # with current realms.
        self.open()

        while True:
            # self.resolvers only returns the
            # reparsed list of resolvers - set by self.open.
            # Does not 'parse' the list in the GUI again.
            resolvers = self.resolvers
            if not resolvers:
                break
            self.delete_resolver(resolvers[0].name)

        self.close()

    def test_connection(self, name, expected_users=None):
        """Test the connection with the corresponding button in the UI.
        Return the number of found users.
        """
        self.open()
        self.edit_resolver(name)
        resolver = self._get_resolver_by_name(name)

        resolver_info = self.get_resolver_for_type(resolver.resolverType)(self)
        testbutton_id = resolver_info.testbutton_id
        cancelbutton_id = resolver_info.editcancel_button_id

        if not testbutton_id:
            # This resolver type does not have a test button (passwd)
            num_found = -1
        else:
            self.find_by_id(testbutton_id).click()

            # Wait for alert box to be shown and then get contents
            alert_box = self.manage.alert_dialog
            alert_box.wait_for_dialog()
            alert_box_text = alert_box.get_text()

            m = re.search(
                "Number of users found: (?P<nusers>\d+)", alert_box_text)
            if m is None:
                raise Exception(
                    "test_connection for %s failed: %s" % (name, alert_box_text))
            num_found = int(m.group('nusers'))

            if expected_users:
                assert num_found == expected_users, "Expected number of users:%s, found:%s" % (
                    expected_users, num_found)

            # Close the popup
            alert_box.close()

        # Close the resolver edit box
        self.find_by_id(cancelbutton_id).click()

        return num_found
コード例 #15
0
 def __init__(self, manage_ui):
     ManageDialog.__init__(self, manage_ui, 'dialog_realms')
     self.edit_realm_dialog = EditRealmDialog(manage_ui)
     self.alert_box_handler = self.manage.alert_box_handler