Save activity ID when processing remote follow request
This commit is contained in:
parent
b0f9b3537e
commit
f2037c9516
2 changed files with 87 additions and 5 deletions
|
@ -12,8 +12,13 @@ use crate::activitypub::{
|
||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
use crate::database::DatabaseError;
|
use crate::database::DatabaseError;
|
||||||
use crate::errors::ValidationError;
|
use crate::errors::ValidationError;
|
||||||
use crate::models::relationships::queries::follow;
|
use crate::models::{
|
||||||
use crate::models::users::queries::get_user_by_name;
|
relationships::queries::{
|
||||||
|
create_remote_follow_request_opt,
|
||||||
|
follow_request_accepted,
|
||||||
|
},
|
||||||
|
users::queries::get_user_by_name,
|
||||||
|
};
|
||||||
use super::{HandlerError, HandlerResult};
|
use super::{HandlerError, HandlerResult};
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
|
@ -45,7 +50,13 @@ pub async fn handle_follow(
|
||||||
&activity.object,
|
&activity.object,
|
||||||
)?;
|
)?;
|
||||||
let target_user = get_user_by_name(db_client, &target_username).await?;
|
let target_user = get_user_by_name(db_client, &target_username).await?;
|
||||||
match follow(db_client, &source_profile.id, &target_user.profile.id).await {
|
let follow_request = create_remote_follow_request_opt(
|
||||||
|
db_client,
|
||||||
|
&source_profile.id,
|
||||||
|
&target_user.id,
|
||||||
|
&activity.id,
|
||||||
|
).await?;
|
||||||
|
match follow_request_accepted(db_client, &follow_request.id).await {
|
||||||
Ok(_) => (),
|
Ok(_) => (),
|
||||||
// Proceed even if relationship already exists
|
// Proceed even if relationship already exists
|
||||||
Err(DatabaseError::AlreadyExists(_)) => (),
|
Err(DatabaseError::AlreadyExists(_)) => (),
|
||||||
|
|
|
@ -115,7 +115,7 @@ pub async fn unfollow(
|
||||||
).await?;
|
).await?;
|
||||||
let relationship_deleted = deleted_count > 0;
|
let relationship_deleted = deleted_count > 0;
|
||||||
// Delete follow request (for remote follows)
|
// Delete follow request (for remote follows)
|
||||||
let follow_request_deleted = delete_follow_request(
|
let follow_request_deleted = delete_follow_request_opt(
|
||||||
&transaction,
|
&transaction,
|
||||||
source_id,
|
source_id,
|
||||||
target_id,
|
target_id,
|
||||||
|
@ -135,6 +135,7 @@ pub async fn unfollow(
|
||||||
Ok(follow_request_deleted)
|
Ok(follow_request_deleted)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Follow remote actor
|
||||||
pub async fn create_follow_request(
|
pub async fn create_follow_request(
|
||||||
db_client: &impl GenericClient,
|
db_client: &impl GenericClient,
|
||||||
source_id: &Uuid,
|
source_id: &Uuid,
|
||||||
|
@ -160,6 +161,40 @@ pub async fn create_follow_request(
|
||||||
Ok(request)
|
Ok(request)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Save follow request from remote actor
|
||||||
|
pub async fn create_remote_follow_request_opt(
|
||||||
|
db_client: &impl GenericClient,
|
||||||
|
source_id: &Uuid,
|
||||||
|
target_id: &Uuid,
|
||||||
|
activity_id: &str,
|
||||||
|
) -> Result<DbFollowRequest, DatabaseError> {
|
||||||
|
let request_id = new_uuid();
|
||||||
|
let row = db_client.query_one(
|
||||||
|
"
|
||||||
|
INSERT INTO follow_request (
|
||||||
|
id,
|
||||||
|
source_id,
|
||||||
|
target_id,
|
||||||
|
activity_id,
|
||||||
|
request_status
|
||||||
|
)
|
||||||
|
VALUES ($1, $2, $3, $4, $5)
|
||||||
|
ON CONFLICT (source_id, target_id)
|
||||||
|
DO UPDATE SET activity_id = $4
|
||||||
|
RETURNING follow_request
|
||||||
|
",
|
||||||
|
&[
|
||||||
|
&request_id,
|
||||||
|
&source_id,
|
||||||
|
&target_id,
|
||||||
|
&activity_id,
|
||||||
|
&FollowRequestStatus::Pending,
|
||||||
|
],
|
||||||
|
).await?;
|
||||||
|
let request = row.try_get("follow_request")?;
|
||||||
|
Ok(request)
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn follow_request_accepted(
|
pub async fn follow_request_accepted(
|
||||||
db_client: &mut impl GenericClient,
|
db_client: &mut impl GenericClient,
|
||||||
request_id: &Uuid,
|
request_id: &Uuid,
|
||||||
|
@ -200,7 +235,7 @@ pub async fn follow_request_rejected(
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn delete_follow_request(
|
async fn delete_follow_request_opt(
|
||||||
db_client: &impl GenericClient,
|
db_client: &impl GenericClient,
|
||||||
source_id: &Uuid,
|
source_id: &Uuid,
|
||||||
target_id: &Uuid,
|
target_id: &Uuid,
|
||||||
|
@ -557,4 +592,40 @@ mod tests {
|
||||||
let following = get_following(db_client, &source.id).await.unwrap();
|
let following = get_following(db_client, &source.id).await.unwrap();
|
||||||
assert!(following.is_empty());
|
assert!(following.is_empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
#[serial]
|
||||||
|
async fn test_followed_by_remote_profile() {
|
||||||
|
let db_client = &mut create_test_database().await;
|
||||||
|
let source_data = ProfileCreateData {
|
||||||
|
username: "follower".to_string(),
|
||||||
|
hostname: Some("example.org".to_string()),
|
||||||
|
actor_json: Some(Actor::default()),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
let source = create_profile(db_client, source_data).await.unwrap();
|
||||||
|
let target_data = UserCreateData {
|
||||||
|
username: "test".to_string(),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
let target = create_user(db_client, target_data).await.unwrap();
|
||||||
|
// Create follow request
|
||||||
|
let activity_id = "https://example.org/objects/123";
|
||||||
|
let _follow_request = create_remote_follow_request_opt(
|
||||||
|
db_client, &source.id, &target.id, activity_id,
|
||||||
|
).await.unwrap();
|
||||||
|
// Repeat
|
||||||
|
let follow_request = create_remote_follow_request_opt(
|
||||||
|
db_client, &source.id, &target.id, activity_id,
|
||||||
|
).await.unwrap();
|
||||||
|
assert_eq!(follow_request.source_id, source.id);
|
||||||
|
assert_eq!(follow_request.target_id, target.id);
|
||||||
|
assert_eq!(follow_request.activity_id, Some(activity_id.to_string()));
|
||||||
|
assert_eq!(follow_request.request_status, FollowRequestStatus::Pending);
|
||||||
|
// Accept follow request
|
||||||
|
follow_request_accepted(db_client, &follow_request.id).await.unwrap();
|
||||||
|
let follow_request = get_follow_request_by_id(db_client, &follow_request.id)
|
||||||
|
.await.unwrap();
|
||||||
|
assert_eq!(follow_request.request_status, FollowRequestStatus::Accepted);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue