Breaking: Provide new user object instead of id.

Fix rustup complaining about join macros.
This commit is contained in:
Paul
2021-05-01 15:54:29 +01:00
parent c8981ac695
commit 5da26cb833
12 changed files with 90 additions and 31 deletions

5
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,5 @@
{
"rust-analyzer.diagnostics.disabled": [
"unresolved-macro-call"
]
}

2
Cargo.lock generated
View File

@@ -2475,7 +2475,7 @@ dependencies = [
[[package]] [[package]]
name = "revolt" name = "revolt"
version = "0.4.1-alpha.1" version = "0.4.1-alpha.2"
dependencies = [ dependencies = [
"async-std", "async-std",
"async-tungstenite", "async-tungstenite",

View File

@@ -1,6 +1,6 @@
[package] [package]
name = "revolt" name = "revolt"
version = "0.4.1-alpha.1" version = "0.4.1-alpha.2"
authors = ["Paul Makles <paulmakles@gmail.com>"] authors = ["Paul Makles <paulmakles@gmail.com>"]
edition = "2018" edition = "2018"

View File

@@ -82,6 +82,8 @@ pub struct User {
impl User { impl User {
/// Mutate the user object to include relationship as seen by user. /// Mutate the user object to include relationship as seen by user.
pub fn from(mut self, user: &User) -> User { pub fn from(mut self, user: &User) -> User {
self.relationship = Some(RelationshipStatus::None);
if self.id == user.id { if self.id == user.id {
self.relationship = Some(RelationshipStatus::User); self.relationship = Some(RelationshipStatus::User);
return self; return self;
@@ -102,12 +104,26 @@ impl User {
pub fn with(mut self, permissions: UserPermissions<[u32; 1]>) -> User { pub fn with(mut self, permissions: UserPermissions<[u32; 1]>) -> User {
if permissions.get_view_profile() { if permissions.get_view_profile() {
self.online = Some(is_online(&self.id)); self.online = Some(is_online(&self.id));
} else {
self.status = None;
} }
self.profile = None; self.profile = None;
self self
} }
/// Mutate the user object to appear as seen by user.
/// Also overrides the relationship status.
pub async fn from_override(mut self, user: &User, relationship: RelationshipStatus) -> Result<User> {
let permissions = PermissionCalculator::new(&user)
.with_relationship(&relationship)
.for_user(&self.id).await?;
self.relations = None;
self.relationship = Some(relationship);
Ok(self.with(permissions))
}
/// Utility function for checking claimed usernames. /// Utility function for checking claimed usernames.
pub async fn is_username_taken(username: &str) -> Result<bool> { pub async fn is_username_taken(username: &str) -> Result<bool> {
if username.to_lowercase() == "revolt" && username.to_lowercase() == "admin" { if username.to_lowercase() == "revolt" && username.to_lowercase() == "admin" {

View File

@@ -9,6 +9,7 @@ pub struct PermissionCalculator<'a> {
perspective: &'a User, perspective: &'a User,
user: Option<&'a User>, user: Option<&'a User>,
relationship: Option<&'a RelationshipStatus>,
channel: Option<&'a Channel>, channel: Option<&'a Channel>,
has_mutual_connection: bool, has_mutual_connection: bool,
@@ -20,6 +21,7 @@ impl<'a> PermissionCalculator<'a> {
perspective, perspective,
user: None, user: None,
relationship: None,
channel: None, channel: None,
has_mutual_connection: false, has_mutual_connection: false,
@@ -33,6 +35,13 @@ impl<'a> PermissionCalculator<'a> {
} }
} }
pub fn with_relationship(self, relationship: &'a RelationshipStatus) -> PermissionCalculator {
PermissionCalculator {
relationship: Some(&relationship),
..self
}
}
pub fn with_channel(self, channel: &'a Channel) -> PermissionCalculator { pub fn with_channel(self, channel: &'a Channel) -> PermissionCalculator {
PermissionCalculator { PermissionCalculator {
channel: Some(&channel), channel: Some(&channel),

View File

@@ -49,7 +49,7 @@ impl<'a> PermissionCalculator<'a> {
} }
let mut permissions: u32 = 0; let mut permissions: u32 = 0;
match get_relationship(&self.perspective, &target) { match self.relationship.clone().map(|v| v.to_owned()).unwrap_or_else(|| get_relationship(&self.perspective, &target)) {
RelationshipStatus::Friend => return Ok(u32::MAX), RelationshipStatus::Friend => return Ok(u32::MAX),
RelationshipStatus::Blocked | RelationshipStatus::BlockedOther => { RelationshipStatus::Blocked | RelationshipStatus::BlockedOther => {
return Ok(UserPermission::Access as u32) return Ok(UserPermission::Access as u32)

View File

@@ -80,8 +80,8 @@ pub enum ClientboundNotification {
}, },
UserRelationship { UserRelationship {
id: String, id: String,
user: String, user: User,
status: RelationshipStatus, status: RelationshipStatus
}, },
UserPresence { UserPresence {
id: String, id: String,
@@ -116,7 +116,7 @@ pub fn prehandle_hook(notification: &ClientboundNotification) {
} }
ClientboundNotification::UserRelationship { id, user, status } => { ClientboundNotification::UserRelationship { id, user, status } => {
if status != &RelationshipStatus::None { if status != &RelationshipStatus::None {
subscribe_if_exists(id.clone(), user.clone()).ok(); subscribe_if_exists(id.clone(), user.id.clone()).ok();
} }
} }
_ => {} _ => {}
@@ -132,7 +132,7 @@ pub fn posthandle_hook(notification: &ClientboundNotification) {
if status == &RelationshipStatus::None { if status == &RelationshipStatus::None {
get_hive() get_hive()
.hive .hive
.unsubscribe(&id.to_string(), &user.to_string()) .unsubscribe(&id.to_string(), &user.id.to_string())
.ok(); .ok();
} }
} }

View File

@@ -9,7 +9,7 @@ use rocket_contrib::json::JsonValue;
#[get("/")] #[get("/")]
pub async fn root() -> JsonValue { pub async fn root() -> JsonValue {
json!({ json!({
"revolt": "0.4.1-alpha.1", "revolt": "0.4.1-alpha.2",
"features": { "features": {
"registration": !*DISABLE_REGISTRATION, "registration": !*DISABLE_REGISTRATION,
"captcha": { "captcha": {

View File

@@ -31,6 +31,8 @@ pub async fn req(user: User, username: String) -> Result<JsonValue> {
with: "user", with: "user",
})?; })?;
let target_user = Ref::from(target_id.to_string())?.fetch_user().await?;
match get_relationship(&user, &target_id) { match get_relationship(&user, &target_id) {
RelationshipStatus::User => return Err(Error::NoEffect), RelationshipStatus::User => return Err(Error::NoEffect),
RelationshipStatus::Friend => return Err(Error::AlreadyFriends), RelationshipStatus::Friend => return Err(Error::AlreadyFriends),
@@ -65,16 +67,19 @@ pub async fn req(user: User, username: String) -> Result<JsonValue> {
) )
) { ) {
Ok(_) => { Ok(_) => {
let target_user = target_user.from_override(&user, RelationshipStatus::Friend).await?;
let user = user.from_override(&target_user, RelationshipStatus::Friend).await?;
try_join!( try_join!(
ClientboundNotification::UserRelationship { ClientboundNotification::UserRelationship {
id: user.id.clone(), id: user.id.clone(),
user: target_id.to_string(), user: target_user,
status: RelationshipStatus::Friend status: RelationshipStatus::Friend
} }
.publish(user.id.clone()), .publish(user.id.clone()),
ClientboundNotification::UserRelationship { ClientboundNotification::UserRelationship {
id: target_id.to_string(), id: target_id.to_string(),
user: user.id.clone(), user,
status: RelationshipStatus::Friend status: RelationshipStatus::Friend
} }
.publish(target_id.to_string()) .publish(target_id.to_string())
@@ -121,16 +126,18 @@ pub async fn req(user: User, username: String) -> Result<JsonValue> {
) )
) { ) {
Ok(_) => { Ok(_) => {
let target_user = target_user.from_override(&user, RelationshipStatus::Outgoing).await?;
let user = user.from_override(&target_user, RelationshipStatus::Incoming).await?;
try_join!( try_join!(
ClientboundNotification::UserRelationship { ClientboundNotification::UserRelationship {
id: user.id.clone(), id: user.id.clone(),
user: target_id.to_string(), user: target_user,
status: RelationshipStatus::Outgoing status: RelationshipStatus::Outgoing
} }
.publish(user.id.clone()), .publish(user.id.clone()),
ClientboundNotification::UserRelationship { ClientboundNotification::UserRelationship {
id: target_id.to_string(), id: target_id.to_string(),
user: user.id.clone(), user,
status: RelationshipStatus::Incoming status: RelationshipStatus::Incoming
} }
.publish(target_id.to_string()) .publish(target_id.to_string())

View File

@@ -10,6 +10,8 @@ use rocket_contrib::json::JsonValue;
pub async fn req(user: User, target: Ref) -> Result<JsonValue> { pub async fn req(user: User, target: Ref) -> Result<JsonValue> {
let col = get_collection("users"); let col = get_collection("users");
let target = target.fetch_user().await?;
match get_relationship(&user, &target.id) { match get_relationship(&user, &target.id) {
RelationshipStatus::User | RelationshipStatus::Blocked => Err(Error::NoEffect), RelationshipStatus::User | RelationshipStatus::Blocked => Err(Error::NoEffect),
RelationshipStatus::BlockedOther => { RelationshipStatus::BlockedOther => {
@@ -33,7 +35,7 @@ pub async fn req(user: User, target: Ref) -> Result<JsonValue> {
ClientboundNotification::UserRelationship { ClientboundNotification::UserRelationship {
id: user.id.clone(), id: user.id.clone(),
user: target.id.clone(), user: target,
status: RelationshipStatus::Blocked, status: RelationshipStatus::Blocked,
} }
.publish(user.id.clone()) .publish(user.id.clone())
@@ -74,19 +76,23 @@ pub async fn req(user: User, target: Ref) -> Result<JsonValue> {
) )
) { ) {
Ok(_) => { Ok(_) => {
let target = target.from_override(&user, RelationshipStatus::Friend).await?;
let user = user.from_override(&target, RelationshipStatus::Friend).await?;
let target_id = target.id.clone();
try_join!( try_join!(
ClientboundNotification::UserRelationship { ClientboundNotification::UserRelationship {
id: user.id.clone(), id: user.id.clone(),
user: target.id.clone(), user: target,
status: RelationshipStatus::Blocked status: RelationshipStatus::Blocked
} }
.publish(user.id.clone()), .publish(user.id.clone()),
ClientboundNotification::UserRelationship { ClientboundNotification::UserRelationship {
id: target.id.clone(), id: target_id.clone(),
user: user.id.clone(), user,
status: RelationshipStatus::BlockedOther status: RelationshipStatus::BlockedOther
} }
.publish(target.id.clone()) .publish(target_id)
) )
.ok(); .ok();
@@ -128,19 +134,23 @@ pub async fn req(user: User, target: Ref) -> Result<JsonValue> {
) )
) { ) {
Ok(_) => { Ok(_) => {
let target = target.from_override(&user, RelationshipStatus::Blocked).await?;
let user = user.from_override(&target, RelationshipStatus::BlockedOther).await?;
let target_id = target.id.clone();
try_join!( try_join!(
ClientboundNotification::UserRelationship { ClientboundNotification::UserRelationship {
id: user.id.clone(), id: user.id.clone(),
user: target.id.clone(), user: target,
status: RelationshipStatus::Blocked status: RelationshipStatus::Blocked
} }
.publish(user.id.clone()), .publish(user.id.clone()),
ClientboundNotification::UserRelationship { ClientboundNotification::UserRelationship {
id: target.id.clone(), id: target_id.clone(),
user: user.id.clone(), user,
status: RelationshipStatus::BlockedOther status: RelationshipStatus::BlockedOther
} }
.publish(target.id.clone()) .publish(target_id)
) )
.ok(); .ok();

View File

@@ -10,6 +10,8 @@ use rocket_contrib::json::JsonValue;
pub async fn req(user: User, target: Ref) -> Result<JsonValue> { pub async fn req(user: User, target: Ref) -> Result<JsonValue> {
let col = get_collection("users"); let col = get_collection("users");
let target = target.fetch_user().await?;
match get_relationship(&user, &target.id) { match get_relationship(&user, &target.id) {
RelationshipStatus::Friend RelationshipStatus::Friend
| RelationshipStatus::Outgoing | RelationshipStatus::Outgoing
@@ -43,19 +45,23 @@ pub async fn req(user: User, target: Ref) -> Result<JsonValue> {
) )
) { ) {
Ok(_) => { Ok(_) => {
let target = target.from_override(&user, RelationshipStatus::None).await?;
let user = user.from_override(&target, RelationshipStatus::None).await?;
let target_id = target.id.clone();
try_join!( try_join!(
ClientboundNotification::UserRelationship { ClientboundNotification::UserRelationship {
id: user.id.clone(), id: user.id.clone(),
user: target.id.clone(), user: target,
status: RelationshipStatus::None status: RelationshipStatus::None
} }
.publish(user.id.clone()), .publish(user.id.clone()),
ClientboundNotification::UserRelationship { ClientboundNotification::UserRelationship {
id: target.id.clone(), id: target_id.clone(),
user: user.id.clone(), user,
status: RelationshipStatus::None status: RelationshipStatus::None
} }
.publish(target.id.clone()) .publish(target_id)
) )
.ok(); .ok();

View File

@@ -9,10 +9,11 @@ use rocket_contrib::json::JsonValue;
#[delete("/<target>/block")] #[delete("/<target>/block")]
pub async fn req(user: User, target: Ref) -> Result<JsonValue> { pub async fn req(user: User, target: Ref) -> Result<JsonValue> {
let col = get_collection("users"); let col = get_collection("users");
let target = target.fetch_user().await?;
match get_relationship(&user, &target.id) { match get_relationship(&user, &target.id) {
RelationshipStatus::Blocked => { RelationshipStatus::Blocked => {
match get_relationship(&target.fetch_user().await?, &user.id) { match get_relationship(&target, &user.id) {
RelationshipStatus::Blocked => { RelationshipStatus::Blocked => {
col.update_one( col.update_one(
doc! { doc! {
@@ -32,9 +33,10 @@ pub async fn req(user: User, target: Ref) -> Result<JsonValue> {
with: "user", with: "user",
})?; })?;
let target = target.from_override(&user, RelationshipStatus::BlockedOther).await?;
ClientboundNotification::UserRelationship { ClientboundNotification::UserRelationship {
id: user.id.clone(), id: user.id.clone(),
user: target.id.clone(), user: target,
status: RelationshipStatus::BlockedOther, status: RelationshipStatus::BlockedOther,
} }
.publish(user.id.clone()) .publish(user.id.clone())
@@ -73,19 +75,23 @@ pub async fn req(user: User, target: Ref) -> Result<JsonValue> {
) )
) { ) {
Ok(_) => { Ok(_) => {
let target = target.from_override(&user, RelationshipStatus::None).await?;
let user = user.from_override(&target, RelationshipStatus::None).await?;
let target_id = target.id.clone();
try_join!( try_join!(
ClientboundNotification::UserRelationship { ClientboundNotification::UserRelationship {
id: user.id.clone(), id: user.id.clone(),
user: target.id.clone(), user: target,
status: RelationshipStatus::None status: RelationshipStatus::None
} }
.publish(user.id.clone()), .publish(user.id.clone()),
ClientboundNotification::UserRelationship { ClientboundNotification::UserRelationship {
id: target.id.clone(), id: target_id.clone(),
user: user.id.clone(), user: user,
status: RelationshipStatus::None status: RelationshipStatus::None
} }
.publish(target.id.clone()) .publish(target_id)
) )
.ok(); .ok();