enigmatick 0.4.1

Enigmatick is a social media platform that integrates with servers that implement the ActivityPub protocol (e.g., Mastodon)
Documentation
use super::Inbox;
use crate::{
    db::runner::DbRunner,
    models::{
        activities::{create_activity, NewActivity},
        actors::{create_or_update_actor, NewActor},
        objects::create_object,
    },
    GetWebfinger,
};
use deadpool_diesel::postgres::Pool;
use jdt_activity_pub::MaybeReference;
use jdt_activity_pub::{ApActivity, ApAddress, ApObject, ApUpdate};
use reqwest::StatusCode;
use serde_json::Value;

impl Inbox for ApUpdate {
    async fn inbox<C: DbRunner>(
        &self,
        conn: &C,
        _pool: Pool,
        raw: Value,
    ) -> Result<StatusCode, StatusCode> {
        log::debug!("{:?}", self.clone());

        let activity: ApActivity = self.clone().into();

        match self.clone().object {
            MaybeReference::Actual(actual) => match actual {
                ApObject::Actor(actor) => {
                    log::debug!("{actor}");
                    let webfinger = actor.get_webfinger().await;

                    if let Ok(mut new_remote_actor) = NewActor::try_from(actor.clone()) {
                        new_remote_actor.ek_webfinger = webfinger;

                        if actor.clone().id.unwrap_or_default() == self.actor.clone() {
                            let actor = create_or_update_actor(conn, new_remote_actor)
                                .await
                                .map_err(|e| {
                                    log::error!("Failed to create or update Actor: {e}");
                                    StatusCode::INTERNAL_SERVER_ERROR
                                })?;

                            let mut activity =
                                NewActivity::try_from((activity, Some(actor.into()))).map_err(
                                    |e| {
                                        log::error!("Failed to build NewActivity: {e}");
                                        StatusCode::INTERNAL_SERVER_ERROR
                                    },
                                )?;
                            activity.raw = Some(raw);

                            create_activity(conn, activity).await.map_err(|e| {
                                log::error!("Failed to create Activity: {e}");
                                StatusCode::INTERNAL_SERVER_ERROR
                            })?;

                            Ok(StatusCode::ACCEPTED)
                        } else {
                            log::error!("Failed to handle Activity");
                            Err(StatusCode::UNAUTHORIZED)
                        }
                    } else {
                        log::error!("Failed to handle Activity");
                        Err(StatusCode::INTERNAL_SERVER_ERROR)
                    }
                }
                ApObject::Note(note) => {
                    log::debug!("{note}");
                    if note.clone().attributed_to == self.actor.clone() {
                        let object = create_object(conn, note.into()).await.map_err(|e| {
                            log::error!("Failed to create or update Note: {e}");
                            StatusCode::INTERNAL_SERVER_ERROR
                        })?;

                        let mut activity = NewActivity::try_from((activity, Some(object.into())))
                            .map_err(|e| {
                            log::error!("Failed to build NewActivity: {e}");
                            StatusCode::INTERNAL_SERVER_ERROR
                        })?;
                        activity.raw = Some(raw);

                        create_activity(conn, activity).await.map_err(|e| {
                            log::error!("Failed to create Activity: {e}");
                            StatusCode::INTERNAL_SERVER_ERROR
                        })?;

                        Ok(StatusCode::ACCEPTED)
                    } else {
                        log::error!("attributed_to does not match Actor");
                        Err(StatusCode::UNAUTHORIZED)
                    }
                }
                ApObject::Article(article) => {
                    log::debug!("{article}");
                    if article.clone().attributed_to == self.actor.clone() {
                        let object = create_object(conn, article.into()).await.map_err(|e| {
                            log::error!("Failed to create or update Article: {e}");
                            StatusCode::INTERNAL_SERVER_ERROR
                        })?;

                        let mut activity = NewActivity::try_from((activity, Some(object.into())))
                            .map_err(|e| {
                            log::error!("Failed to build NewActivity: {e}");
                            StatusCode::INTERNAL_SERVER_ERROR
                        })?;
                        activity.raw = Some(raw);

                        create_activity(conn, activity).await.map_err(|e| {
                            log::error!("Failed to create Activity: {e}");
                            StatusCode::INTERNAL_SERVER_ERROR
                        })?;

                        Ok(StatusCode::ACCEPTED)
                    } else {
                        log::error!("attributed_to does not match Actor");
                        Err(StatusCode::UNAUTHORIZED)
                    }
                }
                ApObject::Question(question) => {
                    log::debug!("{question}");
                    if question.clone().attributed_to == self.actor.clone() {
                        let object = create_object(conn, question.into()).await.map_err(|e| {
                            log::error!("Failed to create or update Question: {e}");
                            StatusCode::INTERNAL_SERVER_ERROR
                        })?;

                        let mut activity = NewActivity::try_from((activity, Some(object.into())))
                            .map_err(|e| {
                            log::error!("Failed to build NewActivity: {e}");
                            StatusCode::INTERNAL_SERVER_ERROR
                        })?;
                        activity.raw = Some(raw);

                        create_activity(conn, activity).await.map_err(|e| {
                            log::error!("Failed to create Activity: {e}");
                            StatusCode::INTERNAL_SERVER_ERROR
                        })?;

                        Ok(StatusCode::ACCEPTED)
                    } else {
                        log::error!("attributed_to does not match Actor");
                        Err(StatusCode::UNAUTHORIZED)
                    }
                }
                _ => {
                    log::debug!("Unimplemented Update type");
                    Err(StatusCode::NOT_IMPLEMENTED)
                }
            },
            _ => Err(StatusCode::UNPROCESSABLE_ENTITY),
        }
    }

    fn actor(&self) -> ApAddress {
        self.actor.clone()
    }
}