fix(bonfire): populate cache for calculating permissions (#259)

This commit is contained in:
TheBobBobs
2023-07-02 07:40:15 +00:00
committed by GitHub
parent 55bd6fb087
commit 6e4798f1d4
4 changed files with 36 additions and 37 deletions

View File

@@ -23,8 +23,7 @@ impl Cache {
pub async fn can_view_channel(&self, db: &Database, channel: &Channel) -> bool {
match &channel {
Channel::TextChannel { server, .. } | Channel::VoiceChannel { server, .. } => {
let member = self.members.values().find(|x| &x.id.server == server);
let member = self.members.get(server);
let server = self.servers.get(server);
let mut perms = perms(self.users.get(&self.user_id).unwrap()).channel(channel);
@@ -107,9 +106,15 @@ impl State {
// Fetch all memberships with their corresponding servers.
let members: Vec<Member> = db.fetch_all_memberships(&user.id).await?;
self.cache.members = members
.iter()
.cloned()
.map(|x| (x.id.server.clone(), x))
.collect();
let server_ids: Vec<String> = members.iter().map(|x| x.id.server.clone()).collect();
let servers = db.fetch_servers(&server_ids).await?;
self.cache.servers = servers.iter().cloned().map(|x| (x.id.clone(), x)).collect();
// Collect channel ids from servers.
let mut channel_ids = vec![];
@@ -164,17 +169,11 @@ impl State {
self.cache
.users
.insert(self.cache.user_id.clone(), user.clone());
self.cache.servers = servers.iter().cloned().map(|x| (x.id.clone(), x)).collect();
self.cache.channels = channels
.iter()
.cloned()
.map(|x| (x.id().to_string(), x))
.collect();
self.cache.members = members
.iter()
.cloned()
.map(|x| (x.id.server.clone(), x))
.collect();
// Make all users appear from our perspective.
let mut users: Vec<User> = users
@@ -353,7 +352,7 @@ impl State {
let could_view: bool = if let Some(channel) = self.cache.channels.get(id) {
self.cache.can_view_channel(db, channel).await
} else {
true
false
};
if let Some(channel) = self.cache.channels.get_mut(id) {
@@ -364,6 +363,12 @@ impl State {
channel.apply_options(data.clone());
}
if !self.cache.channels.contains_key(id) {
if let Ok(channel) = db.fetch_channel(id).await {
self.cache.channels.insert(id.clone(), channel);
}
}
if let Some(channel) = self.cache.channels.get(id) {
let can_view = self.cache.can_view_channel(db, channel).await;
if could_view != can_view {
@@ -398,7 +403,9 @@ impl State {
channels,
} => {
self.insert_subscription(id.clone());
self.cache.servers.insert(id.to_string(), server.clone());
self.cache.servers.insert(id.clone(), server.clone());
let member = Member::new(id.clone(), self.cache.user_id.clone());
self.cache.members.insert(id.clone(), member);
for channel in channels {
self.cache
@@ -436,6 +443,7 @@ impl State {
self.cache.channels.remove(channel);
}
}
self.cache.members.remove(id);
}
}
EventV1::ServerDelete { id } => {
@@ -447,6 +455,7 @@ impl State {
self.cache.channels.remove(channel);
}
}
self.cache.members.remove(id);
}
EventV1::ServerMemberUpdate { id, data, clear } => {
if id.user == self.cache.user_id {

View File

@@ -3,22 +3,10 @@ use crate::{AbstractServerMember, Result};
use super::super::DummyDb;
use iso8601_timestamp::Timestamp;
#[async_trait]
impl AbstractServerMember for DummyDb {
async fn fetch_member(&self, server: &str, user: &str) -> Result<Member> {
Ok(Member {
id: MemberCompositeKey {
server: server.into(),
user: user.into(),
},
joined_at: Timestamp::now_utc(),
nickname: None,
avatar: None,
roles: vec![],
timeout: None,
})
Ok(Member::new(server.into(), user.into()))
}
async fn insert_member(&self, member: &Member) -> Result<()> {

View File

@@ -1,6 +1,5 @@
use std::collections::HashSet;
use iso8601_timestamp::Timestamp;
use ulid::Ulid;
use crate::{
@@ -186,18 +185,7 @@ impl Server {
return Err(Error::Banned);
}
let member = Member {
id: MemberCompositeKey {
server: self.id.clone(),
user: user.id.clone(),
},
joined_at: Timestamp::now_utc(),
nickname: None,
avatar: None,
roles: vec![],
timeout: None,
};
let member = Member::new(self.id.clone(), user.id.clone());
db.insert_member(&member).await?;
let should_fetch = channels.is_none();

View File

@@ -3,13 +3,27 @@ use iso8601_timestamp::Timestamp;
use crate::{
events::client::EventV1,
models::{
server_member::{FieldsMember, PartialMember},
server_member::{FieldsMember, MemberCompositeKey, PartialMember},
Member, Server,
},
Database, Result,
};
impl Member {
pub fn new(server_id: String, user_id: String) -> Self {
Self {
id: MemberCompositeKey {
server: server_id,
user: user_id,
},
joined_at: Timestamp::now_utc(),
nickname: None,
avatar: None,
roles: vec![],
timeout: None,
}
}
/// Update member data
pub async fn update<'a>(
&mut self,