1
0
Fork 0
forked from 2sys/phonograph
phonograph/interim-server/src/base_user_perms.rs

81 lines
2.2 KiB
Rust
Raw Normal View History

2025-05-26 22:08:21 -07:00
use std::collections::HashSet;
2025-08-04 13:59:42 -07:00
use anyhow::Result;
use interim_models::{base::Base, client::AppDbClient};
2025-07-08 16:54:51 -07:00
use interim_pgtypes::{
2025-08-04 13:59:42 -07:00
client::BaseClient,
2025-07-08 16:54:51 -07:00
pg_acl::PgPrivilegeType,
pg_database::PgDatabase,
pg_role::{PgRole, RoleTree, user_id_from_rolname},
};
2025-08-04 13:59:42 -07:00
use sqlx::query;
2025-05-26 22:08:21 -07:00
use uuid::Uuid;
pub struct BaseUserPerm {
pub id: Uuid,
pub base_id: Uuid,
pub user_id: Uuid,
pub perm: String,
}
pub async fn sync_perms_for_base(
base_id: Uuid,
2025-08-04 13:59:42 -07:00
app_db: &mut AppDbClient,
base_client: &mut BaseClient,
2025-05-26 22:08:21 -07:00
) -> Result<()> {
2025-08-04 13:59:42 -07:00
let db = PgDatabase::current().fetch_one(base_client).await?;
let explicit_roles = PgRole::with_name_in(
2025-05-26 22:08:21 -07:00
db.datacl
2025-08-04 13:59:42 -07:00
.unwrap_or_default()
2025-05-26 22:08:21 -07:00
.into_iter()
.filter(|item| {
item.privileges
.iter()
.any(|privilege| privilege.privilege == PgPrivilegeType::Connect)
})
.map(|item| item.grantee)
.collect(),
)
2025-08-04 13:59:42 -07:00
.fetch_all(base_client)
2025-05-26 22:08:21 -07:00
.await?;
let mut all_roles: HashSet<PgRole> = HashSet::new();
for explicit_role in explicit_roles {
2025-08-04 13:59:42 -07:00
if let Some(role_tree) = RoleTree::members_of(explicit_role.oid)
.fetch_tree(base_client)
.await?
{
2025-05-26 22:08:21 -07:00
for implicit_role in role_tree.flatten_inherited() {
all_roles.insert(implicit_role.clone());
}
}
}
2025-08-04 13:59:42 -07:00
let base = Base::with_id(base_id).fetch_one(app_db).await?;
2025-05-26 22:08:21 -07:00
let user_ids: Vec<Uuid> = all_roles
.iter()
.filter_map(|role| user_id_from_rolname(&role.rolname, &base.user_role_prefix).ok())
.collect();
query!(
"delete from base_user_perms where base_id = $1 and not (user_id = any($2))",
base_id,
user_ids.as_slice(),
)
2025-08-04 13:59:42 -07:00
.execute(app_db.get_conn())
2025-05-26 22:08:21 -07:00
.await?;
for user_id in user_ids {
query!(
"
insert into base_user_perms
(id, base_id, user_id, perm)
values ($1, $2, $3, 'connect')
on conflict (base_id, user_id, perm) do nothing
",
Uuid::now_v7(),
base.id,
user_id
)
2025-08-04 13:59:42 -07:00
.execute(app_db.get_conn())
2025-05-26 22:08:21 -07:00
.await?;
}
Ok(())
}