def select(self, sql: str, params=None): """ Perform generic select statement Args: sql (str): SQL statement params (tuple|dict): Params for binding Returns: Result """ cursor = self.get_cursor() try: if params is None: cursor.execute(sql) else: cursor.execute(sql, params) data = cursor.fetchall() result = Result(True, "", data) if len(data) > 0: item = data[0] result.set_full_count(item["full_count"] if "full_count" in item else -1) return result except Exception as e: self.__connection.rollback() return Result(False, str(e)) finally: cursor.close()
def test_create_creates_user(self): username = "******" password = "******" first_name = "John" last_name = "Johnson" data = { "id": 1, "uuid": "ERT-123", "username": username, "first_name": first_name, "last_name": last_name, "status_id": self.status_active.get_id() } self.postgres_conn_manager.insert = MagicMock( return_value=Result(True)) self.postgres_conn_manager.select = MagicMock( return_value=Result(True, "", [data])) user = self.user_manager.create(UsernameTicket(username), PasswordTicket(password), NameTicket(first_name, last_name)) self.postgres_conn_manager.insert.assert_called_once() self.postgres_conn_manager.select.assert_called_once() self.assertEqual(data["id"], user.get_id()) self.assertEqual(data["uuid"], user.get_uuid()) self.assertEqual(data["username"], user.get_username()) self.assertEqual(data["first_name"], user.get_first_name()) self.assertEqual(data["last_name"], user.get_last_name()) self.assertEqual(data["status_id"], user.get_status().get_id())
def test_search_searches_pools(self): data = [{ "id": 1, "uuid": "ERT-123", "status_id": self.active_status.get_id(), "const": "CONST_ONE" }, { "id": 2, "uuid": "ERT-456", "status_id": self.active_status.get_id(), "const": "CONST_TWO" }] result = Result(True, "", data) result.set_full_count(len(data)) self.postgres_conn_manager.paginate = MagicMock(return_value=result) fetch_result = self.pool_manager.search( const="CONST", statuses=[self.active_status.get_id()]) self.assertEqual(len(data), fetch_result.get_full_count()) fetched_pools = fetch_result.get_data() self.assertEqual(len(data), len(fetched_pools)) pool: Pool for i in range(0, len(fetched_pools)): pool = fetched_pools[i] self.assertEqual(data[i]["id"], pool.get_id()) self.assertEqual(data[i]["uuid"], pool.get_uuid()) self.assertEqual(data[i]["status_id"], pool.get_status().get_id()) self.assertEqual(data[i]["const"], pool.get_const())
def migrate(self, root: str) -> Result: """ Run migrations Args: root (str): Root directory Returns: Result """ result = self.__migration_data.create_migration_table() if not result.get_status(): return Result(False, result.get_message()) all_scripts = [f for f in listdir(root) if isfile(join(root, f))] sorted(all_scripts) result = self.__migration_data.load_all() if not result.get_status(): return Result(False, result.get_message()) used_scripts = self.__build_used_scripts_array(result.get_data()) unused_scripts = list(set(all_scripts) - set(used_scripts)) completed = [] for script in unused_scripts: result = self.__migration_data.run(f"{root}/{script}") if not result.get_status(): return Result(False, f"Error in {script}: {result.get_message()}", completed) self.__migration_data.insert(script) completed.append(script) return Result(True, "", completed)
def test_update_updates_user(self): self.postgres_conn_manager.query = MagicMock(return_value=Result(True)) user_id = 1 first_name = "John" last_name = "Johnson" data = { "id": user_id, "uuid": "ERT-123", "username": "******", "first_name": first_name, "last_name": last_name, "status_id": self.status_active.get_id() } self.postgres_conn_manager.select = MagicMock( return_value=Result(True, "", [data])) try: user = self.user_manager.update(user_id, NameTicket("John", "Johnson")) self.postgres_conn_manager.query.assert_called_once() self.postgres_conn_manager.select.assert_called_once() self.assertEqual(data["first_name"], user.get_first_name()) self.assertEqual(data["last_name"], user.get_last_name()) self.assertEqual(data["id"], user.get_id()) except Exception as e: self.fail(str(e))
def test_authorize_fails_on_auth_status_error(self): pool_id = 1 pool_secret = "123123dsfsdfsdfsdfd3423" pool_secret_encrypted = bcrypt.hashpw(str.encode(pool_secret), bcrypt.gensalt(14)).decode() user_id = 1 password = "******" encrypted_password = bcrypt.hashpw(str.encode(password), bcrypt.gensalt(14)).decode() self.user_pool_data.load_password_by_username = MagicMock( return_value=Result( True, "", [{ "id": user_id, "password": encrypted_password, "status_id": self.user_status_disabled.get_id() }])) self.pool_data.load_secret_by_access_id = MagicMock( return_value=Result( True, "", [{ "id": pool_id, "secret": pool_secret_encrypted, "status_id": self.pool_active_status.get_id() }])) with self.assertRaises(AuthStatusError): self.auth_pool_manager.authorize("Some_access_id", pool_secret, "Some_username", "Some_password") self.fail("Did not fail on user status error") self.user_pool_data.load_password_by_username.assert_called_once()
def search(self, pool_ids: list, **kwargs) -> Result: """ Search user in pools Args: pool_ids (list): List of pool IDs **kwargs: username (str) first_name (str) last_name (str) statuses (list) - List of status IDs sorts (dict) - <key> column: <value> 1(ASC), -1(DESC) offset (int) limit (int) Returns: Result """ if len(pool_ids) == 0: raise UserPoolSearchError("No pools specified for search") fetch_result = self.__user_pool_data.search(pool_ids, **kwargs) if not fetch_result.get_status(): raise UserPoolSearchError("Could not search users in pools") data = fetch_result.get_data() users = [] for datum in data: users.append( User(id=datum["id"], uuid=datum["uuid"], username=datum["username"], first_name=datum["first_name"], last_name=datum["last_name"], status=self.__statuses.get_by_id(datum["status_id"]))) result = Result(True, "", users) result.set_full_count(fetch_result.get_full_count()) return result
def search(self, **kwargs) -> Result: """ Search super user list Args: **kwargs: username (str) first_name (str) last_name (str) statuses (list) - List of status IDs sorts (dict) - <key> column: <value> 1(ASC), -1(DESC) offset (int) limit (int) Returns: Result """ fetch_result = self.__user_super_data.search(**kwargs) if not fetch_result.get_status(): raise UserSuperSearchError("Could not load super users") data = fetch_result.get_data() users = [] for datum in data: users.append( User(id=datum["id"], uuid=datum["uuid"], username=datum["username"], first_name=datum["first_name"], last_name=datum["last_name"], status=self.__statuses.get_by_id(datum["status_id"]))) result = Result(True, "", users) result.set_full_count(fetch_result.get_full_count()) return result
def test_update_status_fails_on_update_error(self): self.postgres_conn_manager.query = MagicMock( return_value=Result(False)) self.postgres_conn_manager.select = MagicMock( return_value=Result(True)) with self.assertRaises(PoolUpdateError): self.pool_manager.update_status(1, 1) self.fail("Did not fail on update") self.postgres_conn_manager.query.assert_called_once() self.postgres_conn_manager.select.assert_not_called()
def test_update_status_fails_on_update_error(self): self.postgres_conn_manager.query = MagicMock( return_value=Result(False)) self.postgres_conn_manager.select = MagicMock( return_value=Result(True)) with self.assertRaises(UserUpdateError): self.user_manager.update_status(1, self.status_disabled.get_id()) self.fail("Did not fail") self.postgres_conn_manager.query.assert_called_once() self.postgres_conn_manager.select.assert_not_called()
def test_update_fails_on_update(self): self.postgres_conn_manager.query = MagicMock( return_value=Result(False)) self.postgres_conn_manager.select = MagicMock( return_value=Result(True)) with self.assertRaises(UserUpdateError): self.user_manager.update(1, NameTicket("John", "Johnson")) self.fail("Did not fail") self.postgres_conn_manager.query.assert_called_once() self.postgres_conn_manager.select.assert_not_called()
def test_create_fails_on_create_error(self): self.postgres_conn_manager.insert = MagicMock( return_value=Result(False)) self.postgres_conn_manager.select = MagicMock( return_value=Result(True)) with self.assertRaises(UserCreateError): self.user_manager.create(UsernameTicket("username123"), PasswordTicket("Password#123"), NameTicket("John", "Johnson")) self.fail("Did not fail") self.postgres_conn_manager.insert.assert_called_once() self.postgres_conn_manager.select.assert_not_called()
def test_authorize_authorizes_user(self): pool_id = 1 pool_access_id = "123asdasd" pool_secret = "123123dsfsdfsdfsdfd3423" pool_secret_encrypted = bcrypt.hashpw(str.encode(pool_secret), bcrypt.gensalt(14)).decode() user_id = 1 password = "******" encrypted_password = bcrypt.hashpw(str.encode(password), bcrypt.gensalt(14)).decode() self.user_pool_data.load_password_by_username = MagicMock( return_value=Result( True, "", [{ "id": user_id, "password": encrypted_password, "status_id": self.user_status_active.get_id() }])) self.pool_data.load_secret_by_access_id = MagicMock( return_value=Result( True, "", [{ "id": pool_id, "secret": pool_secret_encrypted, "status_id": self.pool_active_status.get_id() }])) user: User = User(id=user_id, uuid="123abc", username="******", first_name="Stephen", last_name="Ayre", status=self.user_status_active.get_id()) self.user_manager.get = MagicMock(return_value=user) token = self.auth_pool_manager.authorize(pool_access_id, pool_secret, user.get_username(), password) self.pool_data.load_secret_by_access_id.assert_called_once_with( pool_access_id) self.user_pool_data.load_password_by_username.assert_called_once_with( pool_id, user.get_username()) self.user_manager.get.assert_called_once_with(user.get_id()) token_decoded = jwt.decode(token.get_token(), pool_secret, algorithms=["HS256"]) self.assertEqual(4, len(token_decoded.items())) self.assertEqual(user.get_uuid(), token_decoded["uuid"]) self.assertEqual(user.get_username(), token_decoded["username"]) self.assertEqual(user.get_first_name(), token_decoded["first_name"]) self.assertEqual(user.get_last_name(), token_decoded["last_name"])
def test_search_fails_on_search_error(self): self.postgres_conn_manager.paginate = MagicMock( return_value=Result(False)) with self.assertRaises(UserSearchError): self.user_manager.search() self.fail("Did not fail on search") self.postgres_conn_manager.paginate.assert_called_once()
def test_get_fails_on_search_error(self): self.postgres_conn_manager.select = MagicMock( return_value=Result(False)) with self.assertRaises(PoolSearchError): self.pool_manager.get(1) self.fail("Did not fail on search") self.postgres_conn_manager.select.assert_called_once()
def test_get_all_fails_on_status_error(self): self.postgres_conn_manager.select = MagicMock( return_value=Result(False)) with self.assertRaises(PoolStatusError): self.status_manager.get_all() self.fail("Did not fail") self.postgres_conn_manager.select.assert_called_once()
def test_authorize_fails_on_auth_user_not_found_error(self): self.user_data.load_password_by_username = MagicMock( return_value=Result(True, "", [])) with self.assertRaises(AuthNotFoundError): self.auth_manager.authorize("Some_username", "Some_password") self.fail("Did not fail on no user found") self.user_data.load_password_by_username.assert_called_once()
def test_get_all_returns_all_statuses(self): status_1 = { "id": 1, "const": "STATUS1", "description": "Description 1" } status_2 = { "id": 2, "const": "STATUS2", "description": "Description 2" } self.postgres_conn_manager.select = MagicMock( return_value=Result(True, "", [status_1, status_2])) statuses = self.status_manager.get_all() self.assertEqual(status_1["id"], statuses.STATUS1.get_id()) self.assertEqual(status_1["const"], statuses.STATUS1.get_const()) self.assertEqual(status_1["description"], statuses.STATUS1.get_description()) self.assertEqual(status_2["id"], statuses.STATUS2.get_id()) self.assertEqual(status_2["const"], statuses.STATUS2.get_const()) self.assertEqual(status_2["description"], statuses.STATUS2.get_description())
def search(self, pool_ids: list, **kwargs) -> Result: """ Search users in pool Args: pool_ids (list) - List of pool IDs **kwargs: username (str) first_name (str) last_name (str) statuses (list) - List of status IDs sorts (dict) - <key> column: <value> 1(ASC), -1(DESC) offset (int) limit (int) Returns: Result """ if len(pool_ids) == 0: return Result(True) username = kwargs.get("username") or "" first_name = kwargs.get("first_name") or "" last_name = kwargs.get("last_name") or "" statuses = kwargs.get("statuses") or [] sorts = kwargs.get("sorts") or {"last_name": 1} updated_sorts = {} for key, value in sorts.items(): updated_sorts[f"u.{key}"] = value offset = kwargs.get("offset") or 0 limit = kwargs.get("limit") or 100 return self.__postgres_conn_manager.paginate(f""" SELECT u.id, u.uuid, u.username, u.first_name, u.last_name, u.status_id, count(*) OVER() AS full_count FROM users.users AS u INNER JOIN users.users_pool AS up ON u.id = up.user_id AND ({" OR ".join([f"pool_id = {pool_id}" for pool_id in pool_ids])}) """, search={ "u.username": username, "u.first_name": first_name, "u.last_name": last_name }, partitions={ "u.status_id": statuses, }, groups=["u.id"], sorts=updated_sorts, limit=limit, offset=offset)
def test_delete_fails_on_delete_error(self): pool_id = 1 user_id = 2 self.postgres_conn_manager.query = MagicMock(return_value=Result(False)) with self.assertRaises(UserPoolDeleteError): self.user_pool_manager.delete(pool_id, user_id) self.fail("Did not fail on delete error") self.postgres_conn_manager.query.assert_called_once()
def test_add_fails_on_add_error(self): pool_id = 1 user_id = 2 self.postgres_conn_manager.insert = MagicMock(return_value=Result(False)) with self.assertRaises(UserPoolAddError): self.user_pool_manager.add(pool_id, user_id) self.fail("Did not fail on add error") self.postgres_conn_manager.insert.assert_called_once()
def test_update_password_updates_password(self): self.postgres_conn_manager.query = MagicMock(return_value=Result(True)) try: self.user_manager.update_password(1, PasswordTicket("Password#123")) self.postgres_conn_manager.query.assert_called_once() except Exception as e: self.fail(str(e))
def test_update_password_fails_on_update(self): self.postgres_conn_manager.query = MagicMock( return_value=Result(False)) with self.assertRaises(UserUpdateError): self.user_manager.update_password(1, PasswordTicket("Password#123")) self.fail("Did not fail") self.postgres_conn_manager.query.assert_called_once()
def test_authorize_fails_on_auth_pool_not_found_error(self): self.pool_data.load_secret_by_access_id = MagicMock( return_value=Result(True, "", [])) with self.assertRaises(AuthPoolNotFoundError): self.auth_pool_manager.authorize("Some_access_id", "Some_Secret", "Some_username", "Some_password") self.fail("Did not fail on no pool found") self.pool_data.load_secret_by_access_id.assert_called_once()
def test_create_fails_on_create_error(self): pool_ticket = PoolTicket("SOME_NAME") self.postgres_conn_manager.insert = MagicMock( return_value=Result(False)) with self.assertRaises(PoolCreateError): self.pool_manager.create(pool_ticket) self.fail("Did not fail on create") self.postgres_conn_manager.insert.assert_called_once()
def test_update_status_updates(self): pool_id = 1 status_id = self.disabled_status.get_id() pool_data = { "id": pool_id, "uuid": "ERT-123", "status_id": status_id, "const": "CONST_HERE" } self.postgres_conn_manager.query = MagicMock(return_value=Result(True)) self.postgres_conn_manager.select = MagicMock( return_value=Result(True, "", [pool_data])) try: updated_pool = self.pool_manager.update_status(pool_id, status_id) self.assertEqual(pool_id, updated_pool.get_id()) self.assertEqual(status_id, updated_pool.get_status().get_id()) except Exception as e: self.fail(str(e))
def test_search_searches_users_in_pools(self): users = [ { "id": 1, "uuid": "ERT-123", "username": "******", "first_name": "John", "last_name": "Johnson", "status_id": self.status_active.get_id() }, { "id": 2, "uuid": "ERT-456", "username": "******", "first_name": "Jim", "last_name": "Jameson", "status_id": self.status_active.get_id() } ] result = Result(True, "", users) result.set_full_count(2) self.postgres_conn_manager.paginate = MagicMock(return_value=result) result_fetch = self.user_pool_manager.search( [1, 2], username="******", first_name="J", last_name="J", statuses=[self.status_active.get_id()], sorts={"username": 1}, offset=0, limit=2 ) user_objs = result_fetch.get_data() self.assertEqual(len(users), len(user_objs)) self.assertEqual(2, result_fetch.get_full_count()) for i in range(0, len(user_objs)): user: User = user_objs[i] self.assertEqual(users[i]["id"], user.get_id()) self.assertEqual(users[i]["uuid"], user.get_uuid()) self.assertEqual(users[i]["username"], user.get_username()) self.assertEqual(users[i]["first_name"], user.get_first_name()) self.assertEqual(users[i]["last_name"], user.get_last_name()) self.assertEqual(users[i]["status_id"], user.get_status().get_id())
def test_create_creates_pool(self): pool_ticket = PoolTicket("POOL_NAME") pool_data = { "id": 1, "uuid": "ERT-123", "const": pool_ticket.get_const(), "status_id": self.active_status.get_id() } self.postgres_conn_manager.insert = MagicMock( return_value=Result(True)) self.postgres_conn_manager.select = MagicMock( return_value=Result(True, "", [pool_data])) pool = self.pool_manager.create(pool_ticket) self.postgres_conn_manager.insert.assert_called_once() self.postgres_conn_manager.select.assert_called_once() self.assertEqual(pool_data["id"], pool.get_id()) self.assertEqual(pool_data["uuid"], pool.get_uuid()) self.assertEqual(pool_data["const"], pool.get_const()) self.assertEqual(pool_data["status_id"], pool.get_status().get_id())
def run(self, file: str) -> Result: """ Run sql file script Args: file (str): File with root directory Returns: Result """ file = open(file, "r") connection = self.__postgres_conn_manager.get_connection() cursor = self.__postgres_conn_manager.get_cursor() try: cursor.execute(file.read()) return Result(True) except Exception as e: connection.rollback() return Result(False, str(e)) finally: cursor.close() file.close()
def search(self, **kwargs) -> Result: """ Search pools by params Args: **kwargs: const (str) statuses (list) List of status IDs offset (int) limit (int) Returns: Result """ fetch_result = self.__pool_data.search(**kwargs) if not fetch_result.get_status(): raise PoolSearchError("Could not load pools") data = fetch_result.get_data() pools = [] for datum in data: pools.append(self.__build_pool_obj(datum)) result = Result(True, "", pools) result.set_full_count(fetch_result.get_full_count()) return result