Compare commits
No commits in common. "3c8e33f681d5a9d9d3e1ee2003636de14cae7c0c" and "a3b89f77010a85d858ee1d26a7e46d184bb07b64" have entirely different histories.
3c8e33f681
...
a3b89f7701
|
@ -1,2 +0,0 @@
|
|||
[registries.crates-io]
|
||||
protocol = "sparse"
|
File diff suppressed because it is too large
Load Diff
|
@ -1,7 +1,7 @@
|
|||
[package]
|
||||
name = "magnetar"
|
||||
description = "An exploratory ActivityPub project"
|
||||
version = "0.1.1"
|
||||
version = "0.1.0"
|
||||
license = "AGPL-3.0-only"
|
||||
edition = "2021"
|
||||
|
||||
|
@ -33,6 +33,10 @@ tower-http = { version = "0.4", features = ["cors", "trace"] }
|
|||
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
||||
tracing = "0.1"
|
||||
|
||||
ring = "0.16"
|
||||
rand = { version = "0.8", features = ["getrandom"] }
|
||||
rsa = "0.8"
|
||||
|
||||
percent-encoding = "2.2"
|
||||
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
|
|
|
@ -0,0 +1,151 @@
|
|||
use crate::web_model::ListContaining;
|
||||
use serde::de::Error;
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
use std::str::FromStr;
|
||||
|
||||
#[derive(Copy, Clone, Eq, PartialEq, Debug, Default)]
|
||||
pub struct ContextActivityStreams;
|
||||
|
||||
impl AsRef<str> for ContextActivityStreams {
|
||||
fn as_ref(&self) -> &'static str {
|
||||
"https://www.w3.org/ns/activitystreams"
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for ContextActivityStreams {
|
||||
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
||||
serializer.serialize_str(self.as_ref())
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for ContextActivityStreams {
|
||||
type Err = String;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
if matches!(
|
||||
s,
|
||||
"https://www.w3.org/ns/activitystreams" | "http://www.w3.org/ns/activitystreams"
|
||||
) {
|
||||
Ok(Self)
|
||||
} else {
|
||||
Err(format!("Invalid context: {s}"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for ContextActivityStreams {
|
||||
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
|
||||
let context = String::deserialize(deserializer)?;
|
||||
|
||||
ContextActivityStreams::from_str(&context).map_err(Error::custom)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Eq, PartialEq, Debug, Deserialize, Serialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum Context {
|
||||
String(ContextActivityStreams),
|
||||
Object {
|
||||
#[serde(rename = "@vocab")]
|
||||
ld_vocab: ContextActivityStreams,
|
||||
},
|
||||
List(ListContaining<ContextActivityStreams>),
|
||||
}
|
||||
|
||||
impl Default for Context {
|
||||
fn default() -> Self {
|
||||
Context::String(ContextActivityStreams)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Eq, PartialEq, Debug, Deserialize, Serialize)]
|
||||
struct ActivityStreamsDocument<T> {
|
||||
#[serde(rename = "@context", default)]
|
||||
ld_context: Context,
|
||||
#[serde(flatten)]
|
||||
data: T,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use crate::web_model::activity_streams::{
|
||||
ActivityStreamsDocument, Context, ContextActivityStreams,
|
||||
};
|
||||
use crate::web_model::ListContaining;
|
||||
use serde_json::json;
|
||||
|
||||
#[test]
|
||||
fn should_parse_context() {
|
||||
let json = json!({
|
||||
"@context": "https://www.w3.org/ns/activitystreams",
|
||||
"some": "stuff"
|
||||
});
|
||||
|
||||
let doc: ActivityStreamsDocument<()> = serde_json::from_value(json).unwrap();
|
||||
|
||||
assert_eq!(doc.ld_context, Context::String(ContextActivityStreams));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_parse_missing_context() {
|
||||
let json = json!({
|
||||
"some": "stuff"
|
||||
});
|
||||
|
||||
let doc: ActivityStreamsDocument<()> = serde_json::from_value(json).unwrap();
|
||||
|
||||
assert_eq!(doc.ld_context, Context::String(ContextActivityStreams));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_parse_context_http() {
|
||||
let json = json!({
|
||||
"@context": "http://www.w3.org/ns/activitystreams",
|
||||
"some": "stuff"
|
||||
});
|
||||
|
||||
let doc: ActivityStreamsDocument<()> = serde_json::from_value(json).unwrap();
|
||||
|
||||
assert_eq!(doc.ld_context, Context::String(ContextActivityStreams));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_parse_context_vocab() {
|
||||
let json = json!({
|
||||
"@context": {
|
||||
"@vocab": "https://www.w3.org/ns/activitystreams",
|
||||
"foo": "bar"
|
||||
},
|
||||
"some": "stuff"
|
||||
});
|
||||
|
||||
let doc: ActivityStreamsDocument<()> = serde_json::from_value(json).unwrap();
|
||||
|
||||
assert_eq!(
|
||||
doc.ld_context,
|
||||
Context::Object {
|
||||
ld_vocab: ContextActivityStreams
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_parse_context_array() {
|
||||
let json = json!({
|
||||
"@context": [
|
||||
{
|
||||
"foo": "bar"
|
||||
},
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
],
|
||||
"some": "stuff"
|
||||
});
|
||||
|
||||
let doc: ActivityStreamsDocument<()> = serde_json::from_value(json).unwrap();
|
||||
|
||||
assert_eq!(
|
||||
doc.ld_context,
|
||||
Context::List(ListContaining(ContextActivityStreams))
|
||||
);
|
||||
}
|
||||
}
|
|
@ -5,6 +5,7 @@ use std::fmt::Debug;
|
|||
use std::str::FromStr;
|
||||
|
||||
pub mod acct;
|
||||
pub mod activity_streams;
|
||||
|
||||
pub trait ContentType: Serialize {
|
||||
fn mime_type(&self) -> &'static str;
|
||||
|
|
|
@ -20,8 +20,6 @@ pub struct Model {
|
|||
#[sea_orm(column_name = "publicUrl")]
|
||||
pub public_url: String,
|
||||
pub license: Option<String>,
|
||||
pub width: Option<i32>,
|
||||
pub height: Option<i32>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||
|
|
|
@ -179,14 +179,6 @@ pub struct Model {
|
|||
pub enable_guest_timeline: bool,
|
||||
#[sea_orm(column_name = "defaultReaction")]
|
||||
pub default_reaction: String,
|
||||
#[sea_orm(column_name = "libreTranslateApiUrl")]
|
||||
pub libre_translate_api_url: Option<String>,
|
||||
#[sea_orm(column_name = "libreTranslateApiKey")]
|
||||
pub libre_translate_api_key: Option<String>,
|
||||
#[sea_orm(column_name = "silencedHosts")]
|
||||
pub silenced_hosts: Vec<String>,
|
||||
#[sea_orm(column_name = "experimentalFeatures")]
|
||||
pub experimental_features: Json,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||
|
|
|
@ -34,7 +34,6 @@ pub mod moderation_log;
|
|||
pub mod muted_note;
|
||||
pub mod muting;
|
||||
pub mod note;
|
||||
pub mod note_edit;
|
||||
pub mod note_favorite;
|
||||
pub mod note_reaction;
|
||||
pub mod note_thread_muting;
|
||||
|
@ -52,6 +51,8 @@ pub mod registration_ticket;
|
|||
pub mod registry_item;
|
||||
pub mod relay;
|
||||
pub mod renote_muting;
|
||||
pub mod reversi_game;
|
||||
pub mod reversi_matching;
|
||||
pub mod sea_orm_active_enums;
|
||||
pub mod signin;
|
||||
pub mod sw_subscription;
|
||||
|
|
|
@ -58,8 +58,6 @@ pub struct Model {
|
|||
pub channel_id: Option<String>,
|
||||
#[sea_orm(column_name = "threadId")]
|
||||
pub thread_id: Option<String>,
|
||||
#[sea_orm(column_name = "updatedAt")]
|
||||
pub updated_at: Option<DateTimeWithTimeZone>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||
|
@ -96,8 +94,6 @@ pub enum Relation {
|
|||
on_delete = "Cascade"
|
||||
)]
|
||||
SelfRef1,
|
||||
#[sea_orm(has_many = "super::note_edit::Entity")]
|
||||
NoteEdit,
|
||||
#[sea_orm(has_many = "super::note_favorite::Entity")]
|
||||
NoteFavorite,
|
||||
#[sea_orm(has_many = "super::note_reaction::Entity")]
|
||||
|
@ -158,12 +154,6 @@ impl Related<super::muted_note::Entity> for Entity {
|
|||
}
|
||||
}
|
||||
|
||||
impl Related<super::note_edit::Entity> for Entity {
|
||||
fn to() -> RelationDef {
|
||||
Relation::NoteEdit.def()
|
||||
}
|
||||
}
|
||||
|
||||
impl Related<super::note_favorite::Entity> for Entity {
|
||||
fn to() -> RelationDef {
|
||||
Relation::NoteFavorite.def()
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.10.7
|
||||
|
||||
use sea_orm::entity::prelude::*;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)]
|
||||
#[sea_orm(table_name = "note_edit")]
|
||||
pub struct Model {
|
||||
#[sea_orm(primary_key, auto_increment = false)]
|
||||
pub id: String,
|
||||
#[sea_orm(column_name = "noteId")]
|
||||
pub note_id: String,
|
||||
#[sea_orm(column_type = "Text", nullable)]
|
||||
pub text: Option<String>,
|
||||
pub cw: Option<String>,
|
||||
#[sea_orm(column_name = "fileIds")]
|
||||
pub file_ids: Vec<String>,
|
||||
#[sea_orm(column_name = "updatedAt")]
|
||||
pub updated_at: DateTimeWithTimeZone,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||
pub enum Relation {
|
||||
#[sea_orm(
|
||||
belongs_to = "super::note::Entity",
|
||||
from = "Column::NoteId",
|
||||
to = "super::note::Column::Id",
|
||||
on_update = "NoAction",
|
||||
on_delete = "Cascade"
|
||||
)]
|
||||
Note,
|
||||
}
|
||||
|
||||
impl Related<super::note::Entity> for Entity {
|
||||
fn to() -> RelationDef {
|
||||
Relation::Note.def()
|
||||
}
|
||||
}
|
||||
|
||||
impl ActiveModelBehavior for ActiveModel {}
|
|
@ -32,7 +32,6 @@ pub use super::moderation_log::Entity as ModerationLog;
|
|||
pub use super::muted_note::Entity as MutedNote;
|
||||
pub use super::muting::Entity as Muting;
|
||||
pub use super::note::Entity as Note;
|
||||
pub use super::note_edit::Entity as NoteEdit;
|
||||
pub use super::note_favorite::Entity as NoteFavorite;
|
||||
pub use super::note_reaction::Entity as NoteReaction;
|
||||
pub use super::note_thread_muting::Entity as NoteThreadMuting;
|
||||
|
@ -50,6 +49,8 @@ pub use super::registration_ticket::Entity as RegistrationTicket;
|
|||
pub use super::registry_item::Entity as RegistryItem;
|
||||
pub use super::relay::Entity as Relay;
|
||||
pub use super::renote_muting::Entity as RenoteMuting;
|
||||
pub use super::reversi_game::Entity as ReversiGame;
|
||||
pub use super::reversi_matching::Entity as ReversiMatching;
|
||||
pub use super::signin::Entity as Signin;
|
||||
pub use super::sw_subscription::Entity as SwSubscription;
|
||||
pub use super::used_username::Entity as UsedUsername;
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.10.7
|
||||
|
||||
use sea_orm::entity::prelude::*;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)]
|
||||
#[sea_orm(table_name = "reversi_game")]
|
||||
pub struct Model {
|
||||
#[sea_orm(primary_key, auto_increment = false)]
|
||||
pub id: String,
|
||||
#[sea_orm(column_name = "createdAt")]
|
||||
pub created_at: DateTimeWithTimeZone,
|
||||
#[sea_orm(column_name = "startedAt")]
|
||||
pub started_at: Option<DateTimeWithTimeZone>,
|
||||
#[sea_orm(column_name = "user1Id")]
|
||||
pub user1_id: String,
|
||||
#[sea_orm(column_name = "user2Id")]
|
||||
pub user2_id: String,
|
||||
#[sea_orm(column_name = "user1Accepted")]
|
||||
pub user1_accepted: bool,
|
||||
#[sea_orm(column_name = "user2Accepted")]
|
||||
pub user2_accepted: bool,
|
||||
pub black: Option<i32>,
|
||||
#[sea_orm(column_name = "isStarted")]
|
||||
pub is_started: bool,
|
||||
#[sea_orm(column_name = "isEnded")]
|
||||
pub is_ended: bool,
|
||||
#[sea_orm(column_name = "winnerId")]
|
||||
pub winner_id: Option<String>,
|
||||
pub surrendered: Option<String>,
|
||||
pub logs: Json,
|
||||
pub map: Vec<String>,
|
||||
pub bw: String,
|
||||
#[sea_orm(column_name = "isLlotheo")]
|
||||
pub is_llotheo: bool,
|
||||
#[sea_orm(column_name = "canPutEverywhere")]
|
||||
pub can_put_everywhere: bool,
|
||||
#[sea_orm(column_name = "loopedBoard")]
|
||||
pub looped_board: bool,
|
||||
pub form1: Option<Json>,
|
||||
pub form2: Option<Json>,
|
||||
pub crc32: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||
pub enum Relation {
|
||||
#[sea_orm(
|
||||
belongs_to = "super::user::Entity",
|
||||
from = "Column::User2Id",
|
||||
to = "super::user::Column::Id",
|
||||
on_update = "NoAction",
|
||||
on_delete = "Cascade"
|
||||
)]
|
||||
User2,
|
||||
#[sea_orm(
|
||||
belongs_to = "super::user::Entity",
|
||||
from = "Column::User1Id",
|
||||
to = "super::user::Column::Id",
|
||||
on_update = "NoAction",
|
||||
on_delete = "Cascade"
|
||||
)]
|
||||
User1,
|
||||
}
|
||||
|
||||
impl ActiveModelBehavior for ActiveModel {}
|
|
@ -0,0 +1,38 @@
|
|||
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.10.7
|
||||
|
||||
use sea_orm::entity::prelude::*;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)]
|
||||
#[sea_orm(table_name = "reversi_matching")]
|
||||
pub struct Model {
|
||||
#[sea_orm(primary_key, auto_increment = false)]
|
||||
pub id: String,
|
||||
#[sea_orm(column_name = "createdAt")]
|
||||
pub created_at: DateTimeWithTimeZone,
|
||||
#[sea_orm(column_name = "parentId")]
|
||||
pub parent_id: String,
|
||||
#[sea_orm(column_name = "childId")]
|
||||
pub child_id: String,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||
pub enum Relation {
|
||||
#[sea_orm(
|
||||
belongs_to = "super::user::Entity",
|
||||
from = "Column::ParentId",
|
||||
to = "super::user::Column::Id",
|
||||
on_update = "NoAction",
|
||||
on_delete = "Cascade"
|
||||
)]
|
||||
User2,
|
||||
#[sea_orm(
|
||||
belongs_to = "super::user::Entity",
|
||||
from = "Column::ChildId",
|
||||
to = "super::user::Column::Id",
|
||||
on_update = "NoAction",
|
||||
on_delete = "Cascade"
|
||||
)]
|
||||
User1,
|
||||
}
|
||||
|
||||
impl ActiveModelBehavior for ActiveModel {}
|
|
@ -77,8 +77,6 @@ pub enum MutedNoteReasonEnum {
|
|||
pub enum NoteVisibilityEnum {
|
||||
#[sea_orm(string_value = "followers")]
|
||||
Followers,
|
||||
#[sea_orm(string_value = "hidden")]
|
||||
Hidden,
|
||||
#[sea_orm(string_value = "home")]
|
||||
Home,
|
||||
#[sea_orm(string_value = "public")]
|
||||
|
|
|
@ -61,6 +61,8 @@ pub struct Model {
|
|||
pub hide_online_status: bool,
|
||||
#[sea_orm(column_name = "isDeleted")]
|
||||
pub is_deleted: bool,
|
||||
#[sea_orm(column_name = "showTimelineReplies")]
|
||||
pub show_timeline_replies: bool,
|
||||
#[sea_orm(column_name = "driveCapacityOverrideMb")]
|
||||
pub drive_capacity_override_mb: Option<i32>,
|
||||
#[sea_orm(column_name = "movedToUri")]
|
||||
|
|
|
@ -68,8 +68,6 @@ pub struct Model {
|
|||
pub auto_sensitive: bool,
|
||||
#[sea_orm(column_name = "moderationNote")]
|
||||
pub moderation_note: String,
|
||||
#[sea_orm(column_name = "preventAiLearning")]
|
||||
pub prevent_ai_learning: bool,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||
|
|
|
@ -94,21 +94,3 @@ pub async fn handle_nodeinfo_20(State(config): State<&'static MagnetarConfig>) -
|
|||
metadata: HashMap::new(),
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::config::MagnetarConfig;
|
||||
use axum::extract::State;
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_nodeinfo() {
|
||||
std::env::set_var("MAG_C_HOST", "nattyarch.local");
|
||||
std::env::set_var("MAG_C_DATABASE_URL", "dummy");
|
||||
|
||||
let config = MagnetarConfig::default();
|
||||
let config_ref = Box::leak(Box::new(config));
|
||||
let nodeinfo = crate::nodeinfo::handle_nodeinfo(State(config_ref)).await;
|
||||
|
||||
println!("{:#?}", nodeinfo);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,7 +52,7 @@ pub async fn handle_webfinger(
|
|||
StatusCode::INTERNAL_SERVER_ERROR
|
||||
})?
|
||||
}
|
||||
// TODO: Make this work for local users
|
||||
// Kinda a
|
||||
WebFingerSubject::Url(url) => ck.get_user_by_uri(&url).await.map_err(|e| {
|
||||
error!("Data error: {e}");
|
||||
StatusCode::INTERNAL_SERVER_ERROR
|
||||
|
|
Loading…
Reference in New Issue