summaryrefslogtreecommitdiffstats
path: root/server/src/apub/user_inbox.rs
blob: 4dd40161d9cb09db68ce8c9a8c3d2bf7dc59c75f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
use super::*;

#[serde(untagged)]
#[derive(Deserialize, Debug)]
pub enum UserAcceptedObjects {
  Accept(Accept),
}

/// Handler for all incoming activities to user inboxes.
pub async fn user_inbox(
  request: HttpRequest,
  input: web::Json<UserAcceptedObjects>,
  path: web::Path<String>,
  db: DbPoolParam,
  _chat_server: ChatServerParam,
) -> Result<HttpResponse, Error> {
  // TODO: would be nice if we could do the signature check here, but we cant access the actor property
  let input = input.into_inner();
  let conn = &db.get().unwrap();
  let username = path.into_inner();
  debug!("User {} received activity: {:?}", &username, &input);

  match input {
    UserAcceptedObjects::Accept(a) => handle_accept(&a, &request, &username, &conn),
  }
}

/// Handle accepted follows.
fn handle_accept(
  accept: &Accept,
  request: &HttpRequest,
  username: &str,
  conn: &PgConnection,
) -> Result<HttpResponse, Error> {
  let community_uri = accept
    .accept_props
    .get_actor_xsd_any_uri()
    .unwrap()
    .to_string();

  let community = get_or_fetch_and_upsert_remote_community(&community_uri, conn)?;
  verify(request, &community.public_key.unwrap())?;

  let user = User_::read_from_name(&conn, username)?;

  // Insert the received activity into the activity table
  let activity_form = activity::ActivityForm {
    user_id: community.creator_id,
    data: serde_json::to_value(&accept)?,
    local: false,
    updated: None,
  };
  activity::Activity::create(&conn, &activity_form)?;

  // Now you need to add this to the community follower
  let community_follower_form = CommunityFollowerForm {
    community_id: community.id,
    user_id: user.id,
  };

  // This will fail if they're already a follower
  CommunityFollower::follow(&conn, &community_follower_form)?;

  // TODO: make sure that we actually requested a follow
  // TODO: at this point, indicate to the user that they are following the community
  Ok(HttpResponse::Ok().finish())
}