forked from jmug/stoatchat
feat(core): provide user profile where appropriate
This commit is contained in:
@@ -60,7 +60,7 @@ impl AbstractMessages for ReferenceDb {
|
||||
.cloned()
|
||||
.collect();
|
||||
|
||||
// TODO: sorting, etc
|
||||
// TODO: sorting, etc (will be required for tests)
|
||||
|
||||
Ok(matched_messages)
|
||||
|
||||
|
||||
@@ -391,14 +391,14 @@ impl User {
|
||||
|
||||
EventV1::UserRelationship {
|
||||
id: target.id.clone(),
|
||||
user: self.clone().into(Some(&*target)).await,
|
||||
user: self.clone().into(db, Some(&*target)).await,
|
||||
}
|
||||
.private(target.id.clone())
|
||||
.await;
|
||||
|
||||
EventV1::UserRelationship {
|
||||
id: self.id.clone(),
|
||||
user: target.clone().into(Some(&*self)).await,
|
||||
user: target.clone().into(db, Some(&*self)).await,
|
||||
}
|
||||
.private(self.id.clone())
|
||||
.await;
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
use revolt_models::v0::*;
|
||||
use revolt_permissions::{calculate_user_permissions, UserPermission};
|
||||
|
||||
use crate::{util::permissions::DatabasePermissionQuery, Database};
|
||||
|
||||
impl crate::Bot {
|
||||
pub fn into_public_bot(self, user: crate::User) -> PublicBot {
|
||||
@@ -635,43 +638,69 @@ impl From<crate::FieldsRole> for FieldsRole {
|
||||
}
|
||||
|
||||
impl crate::User {
|
||||
pub async fn into<'a, P>(self, perspective: P) -> User
|
||||
pub async fn into<'a, P>(self, db: &Database, perspective: P) -> User
|
||||
where
|
||||
P: Into<Option<&'a crate::User>>,
|
||||
{
|
||||
let relationship = if let Some(perspective) = perspective.into() {
|
||||
let perspective = perspective.into();
|
||||
let (relationship, can_see_profile) = if self.bot.is_some() {
|
||||
(RelationshipStatus::None, true)
|
||||
} else if let Some(perspective) = perspective {
|
||||
let mut query = DatabasePermissionQuery::new(db, perspective).user(&self);
|
||||
|
||||
if perspective.id == self.id {
|
||||
RelationshipStatus::User
|
||||
(RelationshipStatus::User, true)
|
||||
} else {
|
||||
perspective
|
||||
.relations
|
||||
.as_ref()
|
||||
.map(|relations| {
|
||||
relations
|
||||
.iter()
|
||||
.find(|relationship| relationship.id == self.id)
|
||||
.map(|relationship| relationship.status.clone().into())
|
||||
.unwrap_or_default()
|
||||
})
|
||||
.unwrap_or_default()
|
||||
(
|
||||
perspective
|
||||
.relations
|
||||
.as_ref()
|
||||
.map(|relations| {
|
||||
relations
|
||||
.iter()
|
||||
.find(|relationship| relationship.id == self.id)
|
||||
.map(|relationship| relationship.status.clone().into())
|
||||
.unwrap_or_default()
|
||||
})
|
||||
.unwrap_or_default(),
|
||||
calculate_user_permissions(&mut query)
|
||||
.await
|
||||
.has_user_permission(UserPermission::ViewProfile),
|
||||
)
|
||||
}
|
||||
} else {
|
||||
RelationshipStatus::None
|
||||
(RelationshipStatus::None, false)
|
||||
};
|
||||
|
||||
// do permission stuff here
|
||||
// TODO: implement permissions =)
|
||||
let can_see_profile = false;
|
||||
|
||||
User {
|
||||
username: self.username,
|
||||
discriminator: self.discriminator,
|
||||
display_name: self.display_name,
|
||||
avatar: self.avatar.map(|file| file.into()),
|
||||
relations: vec![],
|
||||
relations: if let Some(crate::User { id, .. }) = perspective {
|
||||
if id == &self.id {
|
||||
self.relations
|
||||
.unwrap_or_default()
|
||||
.into_iter()
|
||||
.map(|relation| relation.into())
|
||||
.collect()
|
||||
} else {
|
||||
vec![]
|
||||
}
|
||||
} else {
|
||||
vec![]
|
||||
},
|
||||
badges: self.badges.unwrap_or_default() as u32,
|
||||
status: None,
|
||||
profile: None,
|
||||
status: if can_see_profile {
|
||||
self.status.map(|status| status.into())
|
||||
} else {
|
||||
None
|
||||
},
|
||||
profile: if can_see_profile {
|
||||
self.profile.map(|profile| profile.into())
|
||||
} else {
|
||||
None
|
||||
},
|
||||
flags: self.flags.unwrap_or_default() as u32,
|
||||
privileged: self.privileged,
|
||||
bot: self.bot.map(|bot| bot.into()),
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
use std::borrow::Cow;
|
||||
|
||||
use revolt_permissions::{
|
||||
calculate_user_permissions, ChannelType, Override, PermissionQuery, RelationshipStatus,
|
||||
calculate_user_permissions, ChannelType, Override, PermissionQuery, PermissionValue,
|
||||
RelationshipStatus,
|
||||
};
|
||||
|
||||
use crate::{Channel, Database, Member, Server, User};
|
||||
@@ -19,7 +20,8 @@ pub struct DatabasePermissionQuery<'a> {
|
||||
member: Option<Cow<'a, Member>>,
|
||||
|
||||
// flag_known_relationship: Option<&'a RelationshipStatus>,
|
||||
cached_user_permission: Option<u32>,
|
||||
cached_user_permission: Option<PermissionValue>,
|
||||
cached_mutual_connection: Option<bool>,
|
||||
cached_permission: Option<u64>,
|
||||
}
|
||||
|
||||
@@ -49,6 +51,10 @@ impl PermissionQuery for DatabasePermissionQuery<'_> {
|
||||
/// Get the relationship with have with the currently selected user
|
||||
async fn user_relationship(&mut self) -> RelationshipStatus {
|
||||
if let Some(other_user) = &self.user {
|
||||
if self.perspective.id == other_user.id {
|
||||
return RelationshipStatus::User;
|
||||
}
|
||||
|
||||
if let Some(relations) = &self.perspective.relations {
|
||||
for entry in relations {
|
||||
if entry.id == other_user.id {
|
||||
@@ -82,14 +88,17 @@ impl PermissionQuery for DatabasePermissionQuery<'_> {
|
||||
|
||||
/// Do we have a mutual connection with the currently selected user?
|
||||
async fn have_mutual_connection(&mut self) -> bool {
|
||||
if let Some(user) = &self.user {
|
||||
// TODO: cache result?
|
||||
matches!(
|
||||
self.perspective
|
||||
.has_mutual_connection(self.database, &user.id)
|
||||
.await,
|
||||
Ok(true)
|
||||
)
|
||||
if let Some(value) = self.cached_mutual_connection {
|
||||
value
|
||||
} else if let Some(user) = &self.user {
|
||||
let value = self
|
||||
.perspective
|
||||
.has_mutual_connection(self.database, &user.id)
|
||||
.await
|
||||
.unwrap_or_default();
|
||||
|
||||
self.cached_mutual_connection = Some(value);
|
||||
matches!(value, true)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
@@ -352,6 +361,7 @@ impl<'a> DatabasePermissionQuery<'a> {
|
||||
server: None,
|
||||
member: None,
|
||||
|
||||
cached_mutual_connection: None,
|
||||
cached_user_permission: None,
|
||||
cached_permission: None,
|
||||
}
|
||||
|
||||
@@ -5,37 +5,37 @@ use crate::{
|
||||
};
|
||||
|
||||
/// Calculate permissions against a user
|
||||
pub async fn calculate_user_permissions<P: PermissionQuery>(query: &mut P) -> u32 {
|
||||
pub async fn calculate_user_permissions<P: PermissionQuery>(query: &mut P) -> PermissionValue {
|
||||
if query.are_we_privileged().await {
|
||||
return u32::MAX;
|
||||
return u64::MAX.into();
|
||||
}
|
||||
|
||||
if query.are_the_users_same().await {
|
||||
return u32::MAX;
|
||||
return u64::MAX.into();
|
||||
}
|
||||
|
||||
let mut permissions = 0_u32;
|
||||
let mut permissions = 0_u64;
|
||||
match query.user_relationship().await {
|
||||
RelationshipStatus::Friend => return u32::MAX,
|
||||
RelationshipStatus::Friend => return u64::MAX.into(),
|
||||
RelationshipStatus::Blocked | RelationshipStatus::BlockedOther => {
|
||||
return UserPermission::Access as u32
|
||||
return (UserPermission::Access as u64).into()
|
||||
}
|
||||
RelationshipStatus::Incoming | RelationshipStatus::Outgoing => {
|
||||
permissions = UserPermission::Access as u32;
|
||||
permissions = UserPermission::Access as u64;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
if query.have_mutual_connection().await {
|
||||
permissions = UserPermission::Access + UserPermission::ViewProfile;
|
||||
permissions = UserPermission::Access as u64 + UserPermission::ViewProfile as u64;
|
||||
|
||||
if query.user_is_bot().await || query.are_we_a_bot().await {
|
||||
permissions += UserPermission::SendMessage as u32;
|
||||
permissions += UserPermission::SendMessage as u64;
|
||||
}
|
||||
|
||||
permissions
|
||||
permissions.into()
|
||||
} else {
|
||||
permissions
|
||||
permissions.into()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,9 +81,7 @@ pub async fn calculate_channel_permissions<P: PermissionQuery>(query: &mut P) ->
|
||||
query.set_recipient_as_user().await;
|
||||
|
||||
let permissions = calculate_user_permissions(query).await;
|
||||
if (permissions & UserPermission::SendMessage as u32)
|
||||
== UserPermission::SendMessage as u32
|
||||
{
|
||||
if permissions.has_user_permission(UserPermission::SendMessage) {
|
||||
(*DEFAULT_PERMISSION_DIRECT_MESSAGE).into()
|
||||
} else {
|
||||
(*DEFAULT_PERMISSION_VIEW_ONLY).into()
|
||||
@@ -121,7 +119,7 @@ pub async fn calculate_channel_permissions<P: PermissionQuery>(query: &mut P) ->
|
||||
if !permissions.has_channel_permission(ChannelPermission::ViewChannel) {
|
||||
permissions.revoke_all();
|
||||
}
|
||||
|
||||
|
||||
permissions
|
||||
} else {
|
||||
0_u64.into()
|
||||
|
||||
@@ -8,7 +8,7 @@ pub use server::*;
|
||||
pub use user::*;
|
||||
|
||||
/// Holds a permission value to manipulate.
|
||||
#[derive(Debug)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct PermissionValue(u64);
|
||||
|
||||
impl PermissionValue {
|
||||
@@ -43,6 +43,11 @@ impl PermissionValue {
|
||||
(self.0 & v) == v
|
||||
}
|
||||
|
||||
/// Check whether certain a user permission has been granted
|
||||
pub fn has_user_permission(&self, permission: UserPermission) -> bool {
|
||||
self.has(permission as u64)
|
||||
}
|
||||
|
||||
/// Check whether certain a channel permission has been granted
|
||||
pub fn has_channel_permission(&self, permission: ChannelPermission) -> bool {
|
||||
self.has(permission as u64)
|
||||
|
||||
@@ -12,7 +12,7 @@ async fn validate_user_permissions() {
|
||||
let mut query = Scenario {};
|
||||
|
||||
let perms = calculate_user_permissions(&mut query).await;
|
||||
assert_eq!(perms, u32::MAX);
|
||||
assert!(perms.has(u64::MAX));
|
||||
|
||||
let perms = calculate_channel_permissions(&mut query).await;
|
||||
let value: u64 = perms.into();
|
||||
|
||||
@@ -23,7 +23,7 @@ pub async fn fetch_bot(
|
||||
}
|
||||
|
||||
Ok(Json(FetchBotResponse {
|
||||
user: db.fetch_user(&bot.id).await?.into(None).await,
|
||||
user: db.fetch_user(&bot.id).await?.into(db, None).await,
|
||||
bot: bot.into(),
|
||||
}))
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ pub async fn message_send(
|
||||
}
|
||||
|
||||
// Create the message
|
||||
let author: v0::User = user.clone().into(Some(&user)).await;
|
||||
let author: v0::User = user.clone().into(db, Some(&user)).await;
|
||||
Ok(Json(
|
||||
Message::create_from_api(
|
||||
db,
|
||||
|
||||
Reference in New Issue
Block a user