use crate::database::models::{CreatePermissionsEntry, Permission}; use crate::database::{DatabaseResult, PostgresPool, Table, ADMIN_ROLE_NAME}; use crate::utils::error::DBError; #[derive(Clone)] pub struct Permissions { pool: PostgresPool, } impl Table for Permissions { fn new(pool: PostgresPool) -> Self { Self { pool } } fn init(&self) -> DatabaseResult<()> { self.pool .get()? .batch_execute( "CREATE TABLE IF NOT EXISTS permissions ( id SERIAL PRIMARY KEY, name VARCHAR(128) UNIQUE NOT NULL, description VARCHAR(512) );", ) .map_err(DBError::from) } } impl Permissions { pub fn create_permissions( &self, permissions: Vec, ) -> DatabaseResult> { let mut connection = self.pool.get()?; let mut transaction = connection.transaction()?; let mut created_permissions = Vec::new(); let _: Vec> = permissions .iter() .map(|CreatePermissionsEntry { name, description }| { let exists = transaction.query_opt("SELECT * FROM permissions WHERE name = $1", &[&name])?; if exists.is_none() { let row = transaction.query_one( "INSERT INTO permissions (name, description) VALUES ($1, $2) RETURNING *;", &[&name, &description], )?; let permission: Permission = serde_postgres::from_row(&row)?; if let Err(e) = transaction.execute( "INSERT INTO role_permissions (role_id, permission_id) VALUES ((SELECT id FROM roles WHERE name = $1), $2)", &[&ADMIN_ROLE_NAME, &permission.id], ) { log::debug!( "Failed to assign permission {} to ADMIN role: {}", name, e.to_string() ) } created_permissions.push(permission); } else { created_permissions.push(serde_postgres::from_row(&exists.unwrap())?); } Ok(()) }) .collect(); transaction.commit()?; Ok(created_permissions) } }