def __init__(self): """ Creates a new UGXLSReader """ self.workbook = None self.indices = {} self.users_and_groups = UsersAndGroups()
def test_update_password(self): """ Tests updating a user password. """ sync = SyncUserAndGroups( tsurl=TS_URL, username=TS_USER, password=TS_PASSWORD, disable_ssl=True, ) auag = UsersAndGroups() auag.add_user( User(name="userx", display_name="User X", password="******")) sync.update_user_password(userid="userx", currentpassword="******", password="******")
def test_syncing_user_and_groups_without_password(self): """ Tests adding users and groups to ThoughtSpot. """ auag = UsersAndGroups() auag.add_group( Group( name="Group 1", display_name="This is Group 1", description="A group for testing.", group_names=[], )) auag.add_group( Group( name="Group 2", display_name="This is Group 2", description="Another group for testing.", group_names=["Group 1"], )) auag.add_user( User( name="User1", password="******", display_name="User 1", group_names=["Group 1"], )) auag.add_user( User( name="User2", password="******", display_name="User 2", group_names=["Group 1", "Group 2"], )) # only works on Bill's AWS instance. sync = SyncUserAndGroups( tsurl=TS_URL, username=TS_USER, password=TS_PASSWORD, global_password="******", disable_ssl=True, ) sync.sync_users_and_groups(auag)
class UGXLSReader(object): """ Reads user and group info from an Excel file that is formatted the same as the UGXLSWriter writes. """ required_sheets = ["Users", "Groups"] required_columns = { "Users": ["Name", "Password", "Display Name", "Email", "Groups", "Visibility"], "Groups": ["Name", "Display Name", "Description", "Groups", "Visibility"], } def __init__(self): """ Creates a new UGXLSReader """ self.workbook = None self.indices = {} self.users_and_groups = UsersAndGroups() def read_from_excel(self, filepath): """ Reads users and groups from the given file. :param filepath: Path to the Excel file to read from. :type filepath: str :return: Returns the users and groups read from the Excel file. The users and groups are not validated :rtype UsersAndGroups so that they can be modified prior to validation. """ self.workbook = xlrd.open_workbook(filepath) if self._verify_file_format(): self._get_column_indices() self._read_users_from_workbook() self._read_groups_from_workbook() return self.users_and_groups def _verify_file_format(self): """ :return: True if the format of the workbook is valid. :rtype: bool """ is_valid = True sheet_names = self.workbook.sheet_names() for required_sheet in UGXLSReader.required_sheets: if required_sheet not in sheet_names: eprint("Error: missing sheet %s!" % required_sheet) is_valid = False else: sheet = self.workbook.sheet_by_name(required_sheet) header_row = sheet.row_values(rowx=0, start_colx=0) for required_column in UGXLSReader.required_columns[ required_sheet]: if required_column not in header_row: eprint("Error: missing column %s in sheet %s!" % (required_column, required_sheet)) is_valid = False return is_valid def _get_column_indices(self): """ Reads the sheets to get all of the column indices. Assumes the format was already checked. """ sheet_names = self.workbook.sheet_names() for sheet_name in sheet_names: if sheet_name in self.required_sheets: sheet = self.workbook.sheet_by_name(sheet_name) col_indices = {} ccnt = 0 for col in sheet.row_values(rowx=0, start_colx=0): col_indices[col] = ccnt ccnt += 1 self.indices[sheet_name] = col_indices def _read_users_from_workbook(self): """ Reads all the users from the workbook. """ table_sheet = self.workbook.sheet_by_name("Users") indices = self.indices["Users"] for row_count in range(1, table_sheet.nrows): row = table_sheet.row_values(rowx=row_count, start_colx=0) # "Name", "Password", "Display Name", "Email", "Description", "Groups", "Visibility" username = row[indices["Name"]] password = row[indices["Password"]] display_name = row[indices["Display Name"]] email = row[indices["Email"]] groups = [] if row[indices["Groups"]] and row[indices["Groups"]]: groups = ast.literal_eval( row[indices["Groups"]] ) # assumes a valid list format, e.g. ["a", "b", ...] visibility = row[indices["Visibility"]] try: user = User( name=username, password=password, display_name=display_name, mail=email, group_names=groups, visibility=visibility, ) # The format should be consistent with only one user per line. self.users_and_groups.add_user( user, duplicate=UsersAndGroups.RAISE_ERROR_ON_DUPLICATE) except: eprint("Error reading user with name %s" % username) def _read_groups_from_workbook(self): """ Reads all the groups from the workbook. """ table_sheet = self.workbook.sheet_by_name("Groups") indices = self.indices["Groups"] for row_count in range(1, table_sheet.nrows): row = table_sheet.row_values(rowx=row_count, start_colx=0) # Name", "Display Name", "Description", "Groups", "Visibility" group_name = row[indices["Name"]] display_name = row[indices["Display Name"]] description = row[indices["Description"]] visibility = row[indices["Visibility"]] groups = [] if row[indices["Groups"]] and row[indices["Groups"]]: groups = ast.literal_eval( row[indices["Groups"]] ) # assumes a valid list format, e.g. ["a", "b", ...] try: group = Group( name=group_name, display_name=display_name, description=description, group_names=groups, visibility=visibility, ) # The format should be consistent with only one group per line. self.users_and_groups.add_group( group, duplicate=UsersAndGroups.RAISE_ERROR_ON_DUPLICATE) except: eprint("Error reading group with name %s" % group_name)
def test_read_ugs_from_excel(self): """Writes a test file, then reads from it.""" uags_out = UsersAndGroups() uags_out.add_user( User( name="user1", password="******", display_name="User 1", mail="*****@*****.**", group_names=["Group1"], visibility=Visibility.DEFAULT, )) uags_out.add_user( User( name="user2", password="******", display_name="User 2", mail="*****@*****.**", group_names=["Group1", "Group2"], visibility=Visibility.DEFAULT, )) uags_out.add_user( User( name="user3", password="******", display_name="User 3", mail="*****@*****.**", group_names=["Group3"], visibility=Visibility.NON_SHAREABLE, )) uags_out.add_group( Group( name="Group1", display_name="Group 1", description="Test group 1", visibility=Visibility.DEFAULT, )) uags_out.add_group( Group( name="Group2", display_name="Group 2", description="Test group 2", group_names=["Group1"], visibility=Visibility.DEFAULT, )) uags_out.add_group( Group( name="Group3", display_name="Group 3", description="Test group 3", group_names=["Group1", "Group2"], visibility=Visibility.NON_SHAREABLE, )) excel_filename = "test_read_write.xlsx" UGXLSWriter().write(uags_out, excel_filename) uags_in = UGXLSReader().read_from_excel(excel_filename) os.remove(excel_filename) # Verify the users. user = uags_in.get_user("user1") self.assertIsNotNone(user) self.assertEqual("user1", user.name) self.assertEqual("pwd1", user.password) self.assertEqual("User 1", user.displayName) self.assertEqual("*****@*****.**", user.mail) self.assertEqual(["Group1"], user.groupNames) self.assertEqual(Visibility.DEFAULT, user.visibility) user = uags_in.get_user("user2") self.assertIsNotNone(user) self.assertEqual("user2", user.name) self.assertEqual("pwd2", user.password) self.assertEqual("User 2", user.displayName) self.assertEqual("*****@*****.**", user.mail) self.assertEqual(["Group1", "Group2"], user.groupNames) self.assertEqual(Visibility.DEFAULT, user.visibility) user = uags_in.get_user("user3") self.assertIsNotNone(user) self.assertEqual("user3", user.name) self.assertEqual("pwd3", user.password) self.assertEqual("User 3", user.displayName) self.assertEqual("*****@*****.**", user.mail) self.assertEqual(["Group3"], user.groupNames) self.assertEqual(Visibility.NON_SHAREABLE, user.visibility) # Verify the groups. group = uags_in.get_group("Group1") self.assertEqual("Group1", group.name) self.assertEqual("Group 1", group.displayName) self.assertEqual("Test group 1", group.description) self.assertEqual([], group.groupNames) self.assertEqual(Visibility.DEFAULT, group.visibility) group = uags_in.get_group("Group2") self.assertEqual("Group2", group.name) self.assertEqual("Group 2", group.displayName) self.assertEqual("Test group 2", group.description) self.assertEqual(["Group1"], group.groupNames) self.assertEqual(Visibility.DEFAULT, group.visibility) group = uags_in.get_group("Group3") self.assertEqual("Group3", group.name) self.assertEqual("Group 3", group.displayName) self.assertEqual("Test group 3", group.description) self.assertEqual(["Group1", "Group2"], group.groupNames) self.assertEqual(Visibility.NON_SHAREABLE, group.visibility)
def test_is_valid(self): """Tests validating users and groups.""" auag = UsersAndGroups() auag.add_group(Group("group1")) auag.add_group(Group("group2", group_names=["group1"])) auag.add_user(User("user1", group_names=["group1"])) auag.add_user(User("user2", group_names=["group1", "group2"])) results = auag.is_valid() self.assertTupleEqual((results.result, results.issues), (True, [])) auag.add_user(User("user3", group_names=["group3"])) # group3 doesn't exist. results = auag.is_valid() self.assertFalse(results.result)
def test_to_json(self): """Tests converting to JSON""" auag = UsersAndGroups() auag.add_group(Group("group1")) auag.add_group(Group("group2", group_names=["group1"])) auag.add_user(User("user1", group_names=["group1"])) auag.add_user(User("user2", group_names=["group1", "group2"])) json_str = auag.to_json() self.assertTrue(json_str.startswith("[{ ")) self.assertTrue(json_str.endswith("}]")) self.assertTrue('"name":"user1"' in json_str) self.assertTrue('"name":"user2"' in json_str) self.assertTrue('"name":"group1"' in json_str) self.assertTrue('"name":"group2"' in json_str)
def test_adding_and_removing_groups(self): """Tests adding and removing groups.""" auag = UsersAndGroups() auag.add_group(Group("Group1")) auag.add_group(Group("Group2")) auag.add_group(Group("Group3")) self.assertTrue(auag.has_group("Group1")) self.assertTrue(auag.has_group("Group2")) self.assertTrue(auag.has_group("Group3")) self.assertEqual(auag.number_groups(), 3) auag.remove_group("Group1") self.assertFalse(auag.has_group("Group1")) self.assertEqual(auag.number_groups(), 2) self.assertTrue(auag.has_group("Group2")) u = auag.get_group("Group2") self.assertTrue(u.name, "Group2") self.assertIsNone(auag.get_group("noone"))
def test_adding_and_removing_users(self): """Tests adding and removing users.""" auag = UsersAndGroups() auag.add_user(User("user1")) auag.add_user(User("user2")) self.assertTrue(auag.has_user("user1")) self.assertFalse(auag.has_user("user6")) self.assertEqual(auag.number_users(), 2) auag.remove_user("user1") self.assertFalse(auag.has_user("user1")) self.assertEqual(auag.number_users(), 1) self.assertTrue(auag.has_user("user2")) u = auag.get_user("user2") self.assertTrue(u.name, "user2") self.assertIsNone(auag.get_user("noone"))
def create_common_users_and_groups(self): """ Creates a set of users and groups that can be used in multiple tests. """ auag = UsersAndGroups() auag.add_group( Group( name="Group 1", display_name="This is Group 1", description="A group for testing.", group_names=[], visibility=Visibility.DEFAULT, ) ) auag.add_group( Group( name="Group 2", display_name="This is Group 2", description="Another group for testing.", group_names=["Group 1"], visibility=Visibility.NON_SHAREABLE, ) ) # Testing for ability to handle embedded quotes. auag.add_group( Group( name='Group "3"', display_name='This is Group "3"', description='Another "group" for testing.', group_names=["Group 1"], visibility=Visibility.NON_SHAREABLE, ) ) auag.add_user( User( name="User1", password="******", display_name="User 1", mail="*****@*****.**", group_names=["Group 1"], ) ) auag.add_user( User( name="User2", password="******", display_name="User 2", mail="*****@*****.**", group_names=["Group 1", "Group 2"], visibility=Visibility.NON_SHAREABLE, ) ) # Testing for ability to handle embedded quotes. auag.add_user( User( name='User "3"', password="******", display_name='User "3"', mail="*****@*****.**", group_names=['Group "3"'], ) ) print(auag) sync = SyncUserAndGroups( tsurl=TS_URL, username=TS_USER, password=TS_PASSWORD, disable_ssl=True, ) sync.sync_users_and_groups(auag)
def test_duplicate_groups(self): """Tests creating duplicate groups with different flags.""" auag = UsersAndGroups() # create a duplicate with default flag to raise an error. auag.add_group(Group(name="group1")) with self.assertRaises(Exception): auag.add_group(Group(name="group1")) # create with overwrite. auag.add_group( Group(name="group2", group_names=["group2"]), duplicate=UsersAndGroups.OVERWRITE_ON_DUPLICATE, ) u = auag.get_group("group2") self.assertEqual(u.name, "group2") self.assertEqual(u.groupNames, ["group2"]) auag.add_group( Group(name="group2", group_names=["group3"]), duplicate=UsersAndGroups.OVERWRITE_ON_DUPLICATE, ) u = auag.get_group("group2") self.assertEqual(u.name, "group2") self.assertEqual(u.groupNames, ["group3"]) # create with update. auag.add_group( Group(name="group3", group_names=["group2"]), duplicate=UsersAndGroups.OVERWRITE_ON_DUPLICATE, ) u = auag.get_group("group3") self.assertEqual(u.name, "group3") self.assertEqual(u.groupNames, ["group2"]) auag.add_group( Group(name="group3", group_names=["group3"]), duplicate=UsersAndGroups.UPDATE_ON_DUPLICATE, ) u = auag.get_group("group3") self.assertEqual(u.groupNames, ["group2", "group3"])
def test_duplicate_users(self): """Tests creating duplicate users with different flags.""" auag = UsersAndGroups() # create a duplicate with default flag to raise an error. auag.add_user(User(name="user1")) with self.assertRaises(Exception): auag.add_user(User(name="user1")) # create with overwrite. auag.add_user( User(name="user2", mail="*****@*****.**", group_names=["group2"]), duplicate=UsersAndGroups.OVERWRITE_ON_DUPLICATE, ) u = auag.get_user("user2") self.assertEqual(u.name, "user2") self.assertEqual(u.mail, "*****@*****.**") self.assertEqual(u.groupNames, ["group2"]) auag.add_user( User(name="user2", mail="*****@*****.**", group_names=["group3"]), duplicate=UsersAndGroups.OVERWRITE_ON_DUPLICATE, ) u = auag.get_user("user2") self.assertEqual(u.name, "user2") self.assertEqual(u.mail, "*****@*****.**") self.assertEqual(u.groupNames, ["group3"]) # create with update. auag.add_user( User(name="user3", mail="*****@*****.**", group_names=["group2"]), duplicate=UsersAndGroups.UPDATE_ON_DUPLICATE, ) u = auag.get_user("user3") self.assertEqual(u.name, "user3") self.assertEqual(u.mail, "*****@*****.**") self.assertEqual(u.groupNames, ["group2"]) auag.add_user( User(name="user3", mail="*****@*****.**", group_names=["group3"]), duplicate=UsersAndGroups.UPDATE_ON_DUPLICATE, ) u = auag.get_user("user3") self.assertEqual(u.mail, "*****@*****.**") self.assertEqual(u.groupNames, ["group3", "group2"]) # create with ignore. auag.add_user( User(name="user4", mail="*****@*****.**", group_names=["group2"]), duplicate=UsersAndGroups.IGNORE_ON_DUPLICATE, ) u = auag.get_user("user4") self.assertEqual(u.name, "user4") self.assertEqual(u.mail, "*****@*****.**") self.assertEqual(u.groupNames, ["group2"]) auag.add_user( User(name="user4", mail="*****@*****.**", group_names=["group3"]), duplicate=UsersAndGroups.IGNORE_ON_DUPLICATE, ) u = auag.get_user("user4") self.assertEqual(u.name, "user4") self.assertEqual(u.mail, "*****@*****.**") self.assertEqual(u.groupNames, ["group2"])
def get_test_json(): """Creates some JSON for testing.""" uags = UsersAndGroups() uags.add_group( Group( name="Group 1", display_name="This is Group 1", description="A group for testing.", group_names=[], )) uags.add_group( Group( name="Group 2", display_name="This is Group 2", description="Another group for testing.", group_names=["Group 1"], visibility=Visibility.NON_SHAREABLE, )) uags.add_user( User( name="User1", password="******", display_name="User 1", mail="*****@*****.**", group_names=["Group 1"], )) uags.add_user( User( name="User2", password="******", display_name="User 2", mail="*****@*****.**", group_names=["Group 1", "Group 2"], visibility=Visibility.NON_SHAREABLE, )) return uags.to_json()
def test_write_to_xls(self): """Tests writing users and groups.""" uags = UsersAndGroups() uags.add_group( Group( name="Group 1", display_name="This is Group 1", description="A group for testing.", group_names=[], )) uags.add_group( Group( name="Group 2", display_name="This is Group 2", description="Another group for testing.", group_names=["Group 1"], )) uags.add_group( Group( name='Group "3"', display_name='This is Group "3"', description='Another "group" for testing.', group_names=["Group 1", "Group 2"], )) uags.add_user( User( name="User1", password="******", display_name="User 1", mail="*****@*****.**", group_names=["Group 1"], )) uags.add_user( User( name="User2", password="******", display_name="User 2", mail="*****@*****.**", group_names=["Group 1", "Group 2"], )) # Testing for ability to handle embedded quotes. uags.add_user( User( name='User "3"', password="******", display_name='User "3"', mail="*****@*****.**", group_names=['Group "3"'], )) writer = UGXLSWriter() writer.write(uags, "test_uags")