pub mod query { use diesel::prelude::*; use crate::models::documents::Document; use crate::models::projects::Project; use diesel::SqliteConnection; /// Users have permissions directly on projects which they are members of. pub fn accessible_project_ids( db: &mut SqliteConnection, user_id: &str, ) -> Result, diesel::result::Error> { use crate::schema::project_memberships::dsl as pm; let project_ids = pm::project_memberships .filter(pm::user_id.eq(user_id)) .select(pm::project_id) .load::(db)?; Ok(project_ids) } /// Users have permissions directly on projects which they are members of. pub fn accessible_projects( db: &mut SqliteConnection, user_id: &str, ) -> Result, diesel::result::Error> { use crate::schema::projects::dsl as p; let project_ids = accessible_project_ids(db, user_id)?; let projects = p::projects .filter(p::id.eq_any(project_ids)) .load::(db)?; Ok(projects) } /// Users can access documents which they are members of or which are in /// projects they're members of. pub fn accessible_document_ids( db: &mut SqliteConnection, user_id: &str, ) -> Result, diesel::result::Error> { use crate::schema::documents::dsl as d; use crate::schema::project_memberships::dsl as pm; let project_ids = accessible_project_ids(db, user_id)?; let direct_documents = pm::project_memberships .filter(pm::user_id.eq(user_id)) .select(pm::project_id) .load::(db)?; let project_documents = d::documents .filter(d::project_id.eq_any(project_ids)) .select(d::id) .load::(db)?; let document_ids = direct_documents .into_iter() .chain(project_documents.into_iter()) .collect(); Ok(document_ids) } /// Users can access documents which they are members of or which are in /// projects they're members of. pub fn accessible_documents( db: &mut SqliteConnection, user_id: &str, ) -> Result, diesel::result::Error> { use crate::schema::documents::dsl as d; let document_ids = accessible_document_ids(db, user_id)?; let documents = d::documents .filter(d::id.eq_any(document_ids)) .load::(db)?; Ok(documents) } }