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