Skip to content

Commit f043457

Browse files
authored
[DPE-7302] Remove user from database (#31)
* Remove user from database * Revoke predefined roles
1 parent a18dd5f commit f043457

File tree

4 files changed

+108
-4
lines changed

4 files changed

+108
-4
lines changed

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
[project]
55
name = "postgresql-charms-single-kernel"
66
description = "Shared and reusable code for PostgreSQL-related charms"
7-
version = "16.1.1"
7+
version = "16.1.2"
88
readme = "README.md"
99
license = "Apache-2.0"
1010
authors = [

single_kernel_postgresql/utils/postgresql.py

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1885,7 +1885,7 @@ def list_databases(self, prefix: Optional[str] = None) -> List[str]:
18851885
def add_user_to_databases(
18861886
self, user: str, databases: List[str], extra_user_roles: Optional[List[str]] = None
18871887
) -> None:
1888-
"""Grant user access to database."""
1888+
"""Grant user access to a database."""
18891889
try:
18901890
roles, _ = self._process_extra_user_roles(user, extra_user_roles)
18911891
connect_stmt = []
@@ -1907,5 +1907,34 @@ def add_user_to_databases(
19071907
for statement in connect_stmt:
19081908
cursor.execute(statement)
19091909
except psycopg2.Error as e:
1910-
logger.error(f"Failed to create user: {e}")
1910+
logger.error(f"Failed to add user: {e}")
1911+
raise PostgreSQLUpdateUserError() from e
1912+
1913+
def remove_user_from_databases(self, user: str, databases: List[str]) -> None:
1914+
"""Revoke user access to a database."""
1915+
try:
1916+
for database in databases:
1917+
with self._connect_to_database() as connection, connection.cursor() as cursor:
1918+
cursor.execute(
1919+
SQL("REVOKE CONNECT ON DATABASE {} FROM {};").format(
1920+
Identifier(database), Identifier(user)
1921+
)
1922+
)
1923+
cursor.execute(
1924+
SQL("REVOKE {} FROM {};").format(
1925+
Identifier(f"charmed_{database}_owner"), Identifier(user)
1926+
)
1927+
)
1928+
cursor.execute(
1929+
SQL("REVOKE {} FROM {};").format(
1930+
Identifier(f"charmed_{database}_admin"), Identifier(user)
1931+
)
1932+
)
1933+
cursor.execute(
1934+
SQL("REVOKE {} FROM {};").format(
1935+
Identifier(f"charmed_{database}_dml"), Identifier(user)
1936+
)
1937+
)
1938+
except psycopg2.Error as e:
1939+
logger.error(f"Failed to remove user: {e}")
19111940
raise PostgreSQLUpdateUserError() from e

tests/unit/test_postgresql.py

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -922,3 +922,78 @@ def test_add_user_to_databases():
922922
with pytest.raises(PostgreSQLUpdateUserError):
923923
pg.add_user_to_databases("test-user", ["db1", "db2"])
924924
assert False
925+
926+
927+
def test_remove_user_from_databases():
928+
with (
929+
patch(
930+
"single_kernel_postgresql.utils.postgresql.PostgreSQL._connect_to_database"
931+
) as _connect_to_database,
932+
):
933+
pg = PostgreSQL(
934+
Substrates.VM, "primary", "current", "operator", "password", "postgres", None
935+
)
936+
execute = _connect_to_database.return_value.__enter__.return_value.cursor.return_value.__enter__.return_value.execute
937+
938+
pg.remove_user_from_databases("test-user", ["db1", "db2"])
939+
assert execute.call_count == 8
940+
execute.assert_any_call(
941+
Composed([
942+
SQL("REVOKE CONNECT ON DATABASE "),
943+
Identifier("db1"),
944+
SQL(" FROM "),
945+
Identifier("test-user"),
946+
SQL(";"),
947+
])
948+
)
949+
execute.assert_any_call(
950+
Composed([
951+
SQL("REVOKE CONNECT ON DATABASE "),
952+
Identifier("db2"),
953+
SQL(" FROM "),
954+
Identifier("test-user"),
955+
SQL(";"),
956+
])
957+
)
958+
execute.assert_any_call(
959+
Composed([
960+
SQL("REVOKE "),
961+
Identifier("charmed_db1_admin"),
962+
SQL(" FROM "),
963+
Identifier("test-user"),
964+
SQL(";"),
965+
])
966+
)
967+
execute.assert_any_call(
968+
Composed([
969+
SQL("REVOKE "),
970+
Identifier("charmed_db1_dml"),
971+
SQL(" FROM "),
972+
Identifier("test-user"),
973+
SQL(";"),
974+
])
975+
)
976+
execute.assert_any_call(
977+
Composed([
978+
SQL("REVOKE "),
979+
Identifier("charmed_db2_admin"),
980+
SQL(" FROM "),
981+
Identifier("test-user"),
982+
SQL(";"),
983+
])
984+
)
985+
execute.assert_any_call(
986+
Composed([
987+
SQL("REVOKE "),
988+
Identifier("charmed_db2_dml"),
989+
SQL(" FROM "),
990+
Identifier("test-user"),
991+
SQL(";"),
992+
])
993+
)
994+
995+
# Exception
996+
execute.side_effect = psycopg2.Error
997+
with pytest.raises(PostgreSQLUpdateUserError):
998+
pg.remove_user_from_databases("test-user", ["db1", "db2"])
999+
assert False

uv.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)