def test_grant_user_roles(self, pgidentifier, ensure_role, log): pgidentifier.side_effect = lambda d: "q_{}".format(d) existing_roles = set(["roleA", "roleB"]) wanted_roles = set(["roleB", "roleC"]) con = MagicMock() cur = con.cursor() cur.fetchall.return_value = [(r,) for r in existing_roles] postgresql.grant_user_roles(con, "fred", wanted_roles) # A new role was ensured. The others we know exist. ensure_role.assert_called_once_with(con, "roleC") role_query = dedent( """\ SELECT role.rolname FROM pg_roles AS role, pg_roles AS member, pg_auth_members WHERE member.oid = pg_auth_members.member AND role.oid = pg_auth_members.roleid AND member.rolname = %s """ ) cur.execute.assert_has_calls([call(role_query, ("fred",)), call("GRANT %s TO %s", ("q_roleC", "q_fred"))])
def test_grant_user_roles(self, pgidentifier, ensure_role, log): pgidentifier.side_effect = lambda d: 'q_{}'.format(d) existing_roles = set(['roleA', 'roleB']) wanted_roles = set(['roleB', 'roleC']) con = MagicMock() cur = con.cursor() cur.fetchall.return_value = [(r, ) for r in existing_roles] postgresql.grant_user_roles(con, 'fred', wanted_roles) # A new role was ensured. The others we know exist. ensure_role.assert_called_once_with(con, 'roleC') role_query = dedent("""\ SELECT role.rolname FROM pg_roles AS role, pg_roles AS member, pg_auth_members WHERE member.oid = pg_auth_members.member AND role.oid = pg_auth_members.roleid AND member.rolname = %s """) cur.execute.assert_has_calls([ call(role_query, ('fred', )), call('GRANT %s TO %s', ('q_roleC', 'q_fred')) ])
def ensure_db_relation_resources(rel): """Create the database resources needed for the relation.""" master = rel.local if "password" not in master: return hookenv.log("Ensuring database {!r} and user {!r} exist for {}" "".format(master["database"], master["user"], rel)) # First create the database, if it isn't already. postgresql.ensure_database(master["database"]) # Next, connect to the database to create the rest in a transaction. con = postgresql.connect(database=master["database"]) superuser, replication = _credential_types(rel) postgresql.ensure_user( con, master["user"], master["password"], superuser=superuser, replication=replication, ) if not superuser: postgresql.ensure_user(con, master["schema_user"], master["schema_password"]) # Grant specified privileges on the database to the user. This comes # from the PostgreSQL service configuration, as allowing the # relation to specify how much access it gets is insecure. config = hookenv.config() privs = set(filter(None, config["relation_database_privileges"].split(","))) postgresql.grant_database_privileges(con, master["user"], master["database"], privs) if not superuser: postgresql.grant_database_privileges(con, master["schema_user"], master["database"], privs) # Reset the roles granted to the user as requested. if "roles" in master: roles = filter(None, master.get("roles", "").split(",")) postgresql.grant_user_roles(con, master["user"], roles) # Create requested extensions. We never drop extensions, as there # may be dependent objects. if "extensions" in master: extensions = list(filter(None, master.get("extensions", "").split(","))) # Convert to the (extension, schema) tuple expected by # postgresql.ensure_extensions for i in range(0, len(extensions)): m = re.search(r"^\s*([^(\s]+)\s*(?:\((\w+)\))?", extensions[i]) if m is None: raise RuntimeError("Invalid extension {}".format(extensions[i])) extensions[i] = (m.group(1), m.group(2) or "public") postgresql.ensure_extensions(con, extensions) con.commit() # Don't throw away our changes.
def ensure_db_relation_resources(rel): """Create the database resources needed for the relation.""" master = rel.local hookenv.log("Ensuring database {!r} and user {!r} exist for {}" "".format(master["database"], master["user"], rel)) # First create the database, if it isn't already. postgresql.ensure_database(master["database"]) # Next, connect to the database to create the rest in a transaction. con = postgresql.connect(database=master["database"]) superuser, replication = _credential_types(rel) postgresql.ensure_user(con, master["user"], master["password"], superuser=superuser, replication=replication) if not superuser: postgresql.ensure_user(con, master["schema_user"], master["schema_password"]) # Grant specified privileges on the database to the user. This comes # from the PostgreSQL service configuration, as allowing the # relation to specify how much access it gets is insecure. config = hookenv.config() privs = set(filter(None, config["relation_database_privileges"].split(","))) postgresql.grant_database_privileges(con, master["user"], master["database"], privs) if not superuser: postgresql.grant_database_privileges(con, master["schema_user"], master["database"], privs) # Reset the roles granted to the user as requested. if "roles" in master: roles = filter(None, master.get("roles", "").split(",")) postgresql.grant_user_roles(con, master["user"], roles) # Create requested extensions. We never drop extensions, as there # may be dependent objects. if "extensions" in master: extensions = filter(None, master.get("extensions", "").split(",")) postgresql.ensure_extensions(con, extensions) con.commit() # Don't throw away our changes.