add: ability to join/leave/be banned from communities

This commit is contained in:
trisua 2025-03-31 15:39:49 -04:00
parent f3c2157dfc
commit 619184d02e
28 changed files with 618 additions and 197 deletions

View file

@ -28,7 +28,7 @@ impl DataManager {
}
}
auto_method!(get_membership_by_id()@get_membership_from_row -> "SELECT * FROM memberships WHERE id = $1" --name="journal membership" --returns=CommunityMembership --cache-key-tmpl="atto.membership:{}");
auto_method!(get_membership_by_id()@get_membership_from_row -> "SELECT * FROM memberships WHERE id = $1" --name="community membership" --returns=CommunityMembership --cache-key-tmpl="atto.membership:{}");
/// Replace a list of community memberships with the proper community.
pub async fn fill_communities(&self, list: Vec<CommunityMembership>) -> Result<Vec<Community>> {
@ -73,7 +73,7 @@ impl DataManager {
let res = query_rows!(
&conn,
"SELECT * FROM memberships WHERE owner = $1",
"SELECT * FROM memberships WHERE owner = $1 AND role IS NOT 33",
&[&(owner as i64)],
|x| { Self::get_membership_from_row(x) }
);
@ -90,6 +90,16 @@ impl DataManager {
/// # Arguments
/// * `data` - a mock [`CommunityMembership`] object to insert
pub async fn create_membership(&self, data: CommunityMembership) -> Result<()> {
// make sure membership doesn't already exist
if self
.get_membership_by_owner_community(data.owner, data.community)
.await
.is_ok()
{
return Err(Error::MiscError("Already joined community".to_string()));
}
// ...
let conn = match self.connect().await {
Ok(c) => c,
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),

View file

@ -167,6 +167,35 @@ impl DataManager {
Ok(res.unwrap())
}
/// Check if the given `uid` can post in the given `community`.
pub async fn check_can_post(&self, community: &Community, uid: usize) -> bool {
match community.write_access {
CommunityWriteAccess::Owner => {
if uid != community.owner {
false
} else {
true
}
}
CommunityWriteAccess::Joined => {
match self
.get_membership_by_owner_community(uid, community.id)
.await
{
Ok(m) => {
if !m.role.check_member() {
false
} else {
true
}
}
Err(_) => false,
}
}
_ => true,
}
}
/// Create a new journal entry in the database.
///
/// # Arguments
@ -185,22 +214,9 @@ impl DataManager {
Err(e) => return Err(e),
};
match community.write_access {
CommunityWriteAccess::Owner => {
if data.owner != community.owner {
return Err(Error::NotAllowed);
}
}
CommunityWriteAccess::Joined => {
if let Err(_) = self
.get_membership_by_owner_community(data.owner, community.id)
.await
{
return Err(Error::NotAllowed);
}
}
_ => (),
};
if !self.check_can_post(&community, data.owner).await {
return Err(Error::NotAllowed);
}
// check if we're blocked
if let Some(replying_to) = data.replying_to {

View file

@ -57,7 +57,7 @@ impl DataManager {
Ok(res.unwrap())
}
/// Create a new journal membership in the database.
/// Create a new reaction in the database.
///
/// # Arguments
/// * `data` - a mock [`Reaction`] object to insert