diff --git a/src/errors.rs b/src/errors.rs index da309d26..ff1a4736 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -36,6 +36,10 @@ impl UpubError { Self::Status(axum::http::StatusCode::FORBIDDEN) } + pub fn unauthorized() -> Self { + Self::Status(axum::http::StatusCode::UNAUTHORIZED) + } + pub fn not_modified() -> Self { Self::Status(axum::http::StatusCode::NOT_MODIFIED) } diff --git a/src/routes/activitypub/inbox.rs b/src/routes/activitypub/inbox.rs index e5b9ae25..d2fe203e 100644 --- a/src/routes/activitypub/inbox.rs +++ b/src/routes/activitypub/inbox.rs @@ -1,8 +1,8 @@ -use apb::{server::Inbox, ActivityType, Base, BaseType, ObjectType}; +use apb::{server::Inbox, target::Addressed, Activity, ActivityType, Base, BaseType, ObjectType}; use axum::{extract::{Query, State}, http::StatusCode, Json}; use sea_orm::{Order, QueryFilter, QueryOrder, QuerySelect}; -use crate::{errors::UpubError, model::{self, addressing::EmbeddedActivity}, server::{auth::AuthIdentity, Context}, url}; +use crate::{errors::UpubError, model::{self, addressing::EmbeddedActivity}, server::{auth::{AuthIdentity, Identity}, Context}, url}; use super::{jsonld::LD, JsonLD, Pagination}; @@ -40,10 +40,18 @@ pub async fn page( )) } + + pub async fn post( State(ctx): State, + AuthIdentity(auth): AuthIdentity, Json(activity): Json -) -> Result<(), UpubError> { +) -> crate::Result<()> { + match auth { + Identity::Remote(_server) => {}, + Identity::Local(_user) => return Err(UpubError::forbidden()), + Identity::Anonymous => return Err(UpubError::unauthorized()), + } match activity.base_type() { None => { Err(StatusCode::BAD_REQUEST.into()) }, diff --git a/src/routes/activitypub/user/inbox.rs b/src/routes/activitypub/user/inbox.rs index ed36bd6c..0ad4b04f 100644 --- a/src/routes/activitypub/user/inbox.rs +++ b/src/routes/activitypub/user/inbox.rs @@ -57,8 +57,9 @@ pub async fn page( pub async fn post( State(ctx): State, Path(_id): Path, - Json(activity): Json + AuthIdentity(_auth): AuthIdentity, + Json(activity): Json, ) -> Result<(), UpubError> { // POSTing to user inboxes is effectively the same as POSTing to the main inbox - super::super::inbox::post(State(ctx), Json(activity)).await + super::super::inbox::post(State(ctx), AuthIdentity(_auth), Json(activity)).await } diff --git a/src/server/fetcher.rs b/src/server/fetcher.rs index 67deb4ce..fb57ed63 100644 --- a/src/server/fetcher.rs +++ b/src/server/fetcher.rs @@ -11,18 +11,6 @@ use crate::{VERSION, model}; use super::Context; -#[derive(Debug, thiserror::Error)] -pub enum FetchError { - #[error("could not dereference resource: {0}")] - Network(#[from] reqwest::Error), - - #[error("error operating on database: {0}")] - Database(#[from] sea_orm::DbErr), - - #[error("missing field when constructing object: {0}")] - Field(#[from] model::FieldError), -} - pub struct Fetcher { db: DatabaseConnection, key: PKey, // TODO store pre-parsed @@ -94,7 +82,7 @@ impl Fetcher { .await } - pub async fn user(&self, id: &str) -> Result { + pub async fn user(&self, id: &str) -> crate::Result { if let Some(x) = model::user::Entity::find_by_id(id).one(&self.db).await? { return Ok(x); // already in db, easy } @@ -110,7 +98,7 @@ impl Fetcher { Ok(user_model) } - pub async fn activity(&self, id: &str) -> Result { + pub async fn activity(&self, id: &str) -> crate::Result { if let Some(x) = model::activity::Entity::find_by_id(id).one(&self.db).await? { return Ok(x); // already in db, easy } @@ -126,7 +114,7 @@ impl Fetcher { Ok(activity_model) } - pub async fn object(&self, id: &str) -> Result { + pub async fn object(&self, id: &str) -> crate::Result { if let Some(x) = model::object::Entity::find_by_id(id).one(&self.db).await? { return Ok(x); // already in db, easy }