fix: check server ownership for text channel
refactor: minor cleanup of code
This commit is contained in:
@@ -624,3 +624,148 @@ impl IntoDocumentPath for FieldsChannel {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use revolt_permissions::{calculate_channel_permissions, ChannelPermission, OverrideField};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
util::permissions::DatabasePermissionQuery, Channel, Member, MemberCompositeKey, Role,
|
||||||
|
Server, User,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[async_std::test]
|
||||||
|
async fn permissions_text_channel() {
|
||||||
|
database_test!(|db| async move {
|
||||||
|
let owner = User::create(&db, "Owner".to_string(), None, None)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let moderator = User::create(&db, "Moderator".to_string(), None, None)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let user = User::create(&db, "User".to_string(), None, None)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let server_id = ulid::Ulid::new().to_string();
|
||||||
|
|
||||||
|
let channel = Channel::TextChannel {
|
||||||
|
id: ulid::Ulid::new().to_string(),
|
||||||
|
server: server_id.clone(),
|
||||||
|
name: "Channel".to_string(),
|
||||||
|
description: None,
|
||||||
|
icon: None,
|
||||||
|
last_message_id: None,
|
||||||
|
default_permissions: Some(OverrideField {
|
||||||
|
d: 1048576, // TODO: bitfield
|
||||||
|
..Default::default()
|
||||||
|
}),
|
||||||
|
role_permissions: HashMap::from([(
|
||||||
|
"01F9HFTSBWTNA2F4TMSV7VM3FG".to_string(),
|
||||||
|
OverrideField {
|
||||||
|
a: 1048576, // TODO: bitfield
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
)]),
|
||||||
|
nsfw: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
let server = Server {
|
||||||
|
id: server_id,
|
||||||
|
owner: owner.id.clone(),
|
||||||
|
name: "My Server".to_string(),
|
||||||
|
description: None,
|
||||||
|
channels: vec![channel.id()],
|
||||||
|
categories: None,
|
||||||
|
system_messages: None,
|
||||||
|
roles: HashMap::from([
|
||||||
|
(
|
||||||
|
"01F9HFTSBWTNA2F4TMSV7VM3FG".to_string(),
|
||||||
|
Role {
|
||||||
|
name: "Moderator".to_string(),
|
||||||
|
permissions: OverrideField {
|
||||||
|
a: 545270208, // TODO: explicit
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
colour: None,
|
||||||
|
hoist: true,
|
||||||
|
rank: 3,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"01FBF9DNHSRPVTWFMNB3JNB8FK".to_string(),
|
||||||
|
Role {
|
||||||
|
name: "Owner".to_string(),
|
||||||
|
permissions: Default::default(),
|
||||||
|
colour: None,
|
||||||
|
hoist: true,
|
||||||
|
rank: 0,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
default_permissions: 4000322560, // TODO: use bitfield
|
||||||
|
icon: None,
|
||||||
|
banner: None,
|
||||||
|
flags: None,
|
||||||
|
nsfw: false,
|
||||||
|
analytics: false,
|
||||||
|
discoverable: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO: proper creation
|
||||||
|
db.insert_channel(&channel).await.unwrap();
|
||||||
|
server.create(&db).await.unwrap();
|
||||||
|
|
||||||
|
db.insert_member(&Member {
|
||||||
|
id: MemberCompositeKey {
|
||||||
|
user: owner.id.clone(),
|
||||||
|
server: server.id.clone(),
|
||||||
|
},
|
||||||
|
roles: vec!["01FBF9DNHSRPVTWFMNB3JNB8FK".to_string()],
|
||||||
|
..Default::default()
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
db.insert_member(&Member {
|
||||||
|
id: MemberCompositeKey {
|
||||||
|
user: moderator.id.clone(),
|
||||||
|
server: server.id.clone(),
|
||||||
|
},
|
||||||
|
roles: vec!["01F9HFTSBWTNA2F4TMSV7VM3FG".to_string()],
|
||||||
|
..Default::default()
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
db.insert_member(&Member {
|
||||||
|
id: MemberCompositeKey {
|
||||||
|
user: user.id.clone(),
|
||||||
|
server: server.id.clone(),
|
||||||
|
},
|
||||||
|
..Default::default()
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let mut query = DatabasePermissionQuery::new(&db, &owner).channel(&channel);
|
||||||
|
assert!(calculate_channel_permissions(&mut query)
|
||||||
|
.await
|
||||||
|
.has_channel_permission(ChannelPermission::SendMessage));
|
||||||
|
|
||||||
|
let mut query = DatabasePermissionQuery::new(&db, &moderator).channel(&channel);
|
||||||
|
assert!(calculate_channel_permissions(&mut query)
|
||||||
|
.await
|
||||||
|
.has_channel_permission(ChannelPermission::SendMessage));
|
||||||
|
|
||||||
|
let mut query = DatabasePermissionQuery::new(&db, &user).channel(&channel);
|
||||||
|
assert!(!calculate_channel_permissions(&mut query)
|
||||||
|
.await
|
||||||
|
.has_channel_permission(ChannelPermission::SendMessage));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -458,8 +458,7 @@ mod tests {
|
|||||||
use revolt_permissions::{calculate_server_permissions, ChannelPermission, OverrideField};
|
use revolt_permissions::{calculate_server_permissions, ChannelPermission, OverrideField};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
util::permissions::DatabasePermissionQuery, Channel, Member, MemberCompositeKey, Role,
|
util::permissions::DatabasePermissionQuery, Member, MemberCompositeKey, Role, Server, User,
|
||||||
Server, User,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#[async_std::test]
|
#[async_std::test]
|
||||||
@@ -479,24 +478,14 @@ mod tests {
|
|||||||
|
|
||||||
let server_id = ulid::Ulid::new().to_string();
|
let server_id = ulid::Ulid::new().to_string();
|
||||||
|
|
||||||
let channel = Channel::TextChannel {
|
// TODO: seeder functions
|
||||||
id: ulid::Ulid::new().to_string(),
|
// e.g. seed!("channel", "file.json")
|
||||||
server: server_id.clone(),
|
|
||||||
name: "Channel".to_string(),
|
|
||||||
description: None,
|
|
||||||
icon: None,
|
|
||||||
last_message_id: None,
|
|
||||||
default_permissions: None,
|
|
||||||
role_permissions: HashMap::new(),
|
|
||||||
nsfw: false,
|
|
||||||
};
|
|
||||||
|
|
||||||
let server = Server {
|
let server = Server {
|
||||||
id: server_id,
|
id: server_id,
|
||||||
owner: owner.id.clone(),
|
owner: owner.id.clone(),
|
||||||
name: "My Server".to_string(),
|
name: "My Server".to_string(),
|
||||||
description: None,
|
description: None,
|
||||||
channels: vec![channel.id()],
|
channels: vec![],
|
||||||
categories: None,
|
categories: None,
|
||||||
system_messages: None,
|
system_messages: None,
|
||||||
roles: HashMap::from([
|
roles: HashMap::from([
|
||||||
@@ -534,7 +523,6 @@ mod tests {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// TODO: proper creation
|
// TODO: proper creation
|
||||||
db.insert_channel(&channel).await.unwrap();
|
|
||||||
server.create(&db).await.unwrap();
|
server.create(&db).await.unwrap();
|
||||||
|
|
||||||
db.insert_member(&Member {
|
db.insert_member(&Member {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use std::num::NonZeroUsize;
|
use std::num::NonZeroUsize;
|
||||||
|
|
||||||
use revolt_result::{create_error, Result};
|
use revolt_result::{create_error, Result, Error};
|
||||||
|
|
||||||
use async_std::sync::Mutex;
|
use async_std::sync::Mutex;
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
|
|||||||
@@ -344,6 +344,7 @@ impl PermissionQuery for DatabasePermissionQuery<'_> {
|
|||||||
| Cow::Owned(Channel::TextChannel { server, .. })
|
| Cow::Owned(Channel::TextChannel { server, .. })
|
||||||
| Cow::Borrowed(Channel::VoiceChannel { server, .. })
|
| Cow::Borrowed(Channel::VoiceChannel { server, .. })
|
||||||
| Cow::Owned(Channel::VoiceChannel { server, .. }) => {
|
| Cow::Owned(Channel::VoiceChannel { server, .. }) => {
|
||||||
|
// FIXME: may double fetch
|
||||||
if let Ok(server) = self.database.fetch_server(server).await {
|
if let Ok(server) = self.database.fetch_server(server).await {
|
||||||
self.server.replace(Cow::Owned(server));
|
self.server.replace(Cow::Owned(server));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -104,7 +104,9 @@ pub async fn calculate_channel_permissions<P: PermissionQuery>(query: &mut P) ->
|
|||||||
ChannelType::ServerChannel => {
|
ChannelType::ServerChannel => {
|
||||||
query.set_server_from_channel().await;
|
query.set_server_from_channel().await;
|
||||||
|
|
||||||
if query.are_we_a_member().await {
|
if query.are_we_server_owner().await {
|
||||||
|
return ChannelPermission::GrantAllSafe.into();
|
||||||
|
} else if query.are_we_a_member().await {
|
||||||
let mut permissions = calculate_server_permissions(query).await;
|
let mut permissions = calculate_server_permissions(query).await;
|
||||||
permissions.apply(query.get_default_channel_permissions().await);
|
permissions.apply(query.get_default_channel_permissions().await);
|
||||||
|
|
||||||
|
|||||||
@@ -221,7 +221,6 @@ mod tests {
|
|||||||
// Create a few more sessions
|
// Create a few more sessions
|
||||||
let (first_session, second_session_id) = create_session(&user_id, 0).await;
|
let (first_session, second_session_id) = create_session(&user_id, 0).await;
|
||||||
assert!(!first_session);
|
assert!(!first_session);
|
||||||
dbg!(second_session_id);
|
|
||||||
assert_eq!(second_session_id as u8 & 1, 0);
|
assert_eq!(second_session_id as u8 & 1, 0);
|
||||||
|
|
||||||
let (first_session, other_session_id) = create_session(&other_id, 0).await;
|
let (first_session, other_session_id) = create_session(&other_id, 0).await;
|
||||||
|
|||||||
@@ -148,6 +148,7 @@ mod test {
|
|||||||
.await;
|
.await;
|
||||||
|
|
||||||
dbg!(response.into_string().await);
|
dbg!(response.into_string().await);
|
||||||
|
// TODO: finish impl
|
||||||
// assert_eq!(response.status(), Status::NotFound);
|
// assert_eq!(response.status(), Status::NotFound);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user