--- /dev/null
+alter table post
+drop column ap_id,
+drop column local;
+
+alter table comment
+drop column ap_id,
+drop column local;
--- /dev/null
+-- Add federation columns to post, comment
+
+alter table post
+-- TODO uniqueness constraints should be added on these 3 columns later
+add column ap_id character varying(255) not null default 'changeme', -- This needs to be checked and updated in code, building from the site url if local
+add column local boolean not null default true
+;
+
+alter table comment
+-- TODO uniqueness constraints should be added on these 3 columns later
+add column ap_id character varying(255) not null default 'changeme', -- This needs to be checked and updated in code, building from the site url if local
+add column local boolean not null default true
+;
+
deleted: None,
read: None,
updated: None,
+ ap_id: "changeme".into(),
+ local: true,
};
let inserted_comment = match Comment::create(&conn, &comment_form) {
Err(_e) => return Err(APIError::err("couldnt_create_comment").into()),
};
+ match Comment::update_ap_id(&conn, inserted_comment.id) {
+ Ok(comment) => comment,
+ Err(_e) => return Err(APIError::err("couldnt_create_comment").into()),
+ };
+
let mut recipient_ids = Vec::new();
// Scan the comment for user mentions, add those rows
let content_slurs_removed = remove_slurs(&data.content.to_owned());
+ let read_comment = Comment::read(&conn, data.edit_id)?;
+
let comment_form = CommentForm {
content: content_slurs_removed,
parent_id: data.parent_id,
} else {
Some(naive_now())
},
+ ap_id: read_comment.ap_id,
+ local: read_comment.local,
};
let _updated_comment = match Comment::update(&conn, data.edit_id, &comment_form) {
embed_description: iframely_description,
embed_html: iframely_html,
thumbnail_url: pictshare_thumbnail,
+ ap_id: "changeme".into(),
+ local: true,
};
let inserted_post = match Post::create(&conn, &post_form) {
}
};
+ match Post::update_ap_id(&conn, inserted_post.id) {
+ Ok(post) => post,
+ Err(_e) => return Err(APIError::err("couldnt_create_post").into()),
+ };
+
// They like their own post by default
let like_form = PostLikeForm {
post_id: inserted_post.id,
let (iframely_title, iframely_description, iframely_html, pictshare_thumbnail) =
fetch_iframely_and_pictshare_data(data.url.to_owned());
+ let read_post = Post::read(&conn, data.edit_id)?;
+
let post_form = PostForm {
name: data.name.to_owned(),
url: data.url.to_owned(),
embed_description: iframely_description,
embed_html: iframely_html,
thumbnail_url: pictshare_thumbnail,
+ ap_id: read_post.ap_id,
+ local: read_post.local,
};
let _updated_post = match Post::update(&conn, data.edit_id, &post_form) {
return Err(APIError::err("not_an_admin").into());
}
- let read_user = User_::read(&conn, data.user_id)?;
-
- // TODO make addadmin easier
- let user_form = UserForm {
- name: read_user.name,
- fedi_name: read_user.fedi_name,
- email: read_user.email,
- matrix_user_id: read_user.matrix_user_id,
- avatar: read_user.avatar,
- password_encrypted: read_user.password_encrypted,
- preferred_username: read_user.preferred_username,
- updated: Some(naive_now()),
- admin: data.added,
- banned: read_user.banned,
- show_nsfw: read_user.show_nsfw,
- theme: read_user.theme,
- default_sort_type: read_user.default_sort_type,
- default_listing_type: read_user.default_listing_type,
- lang: read_user.lang,
- show_avatars: read_user.show_avatars,
- send_notifications_to_email: read_user.send_notifications_to_email,
- actor_id: read_user.actor_id,
- bio: read_user.bio,
- local: read_user.local,
- private_key: read_user.private_key,
- public_key: read_user.public_key,
- last_refreshed_at: None,
- };
-
- match User_::update(&conn, data.user_id, &user_form) {
+ match User_::add_admin(&conn, user_id, data.added) {
Ok(user) => user,
Err(_e) => return Err(APIError::err("couldnt_update_user").into()),
};
return Err(APIError::err("not_an_admin").into());
}
- let read_user = User_::read(&conn, data.user_id)?;
-
- // TODO make bans and addadmins easier
- let user_form = UserForm {
- name: read_user.name,
- fedi_name: read_user.fedi_name,
- email: read_user.email,
- matrix_user_id: read_user.matrix_user_id,
- avatar: read_user.avatar,
- password_encrypted: read_user.password_encrypted,
- preferred_username: read_user.preferred_username,
- updated: Some(naive_now()),
- admin: read_user.admin,
- banned: data.ban,
- show_nsfw: read_user.show_nsfw,
- theme: read_user.theme,
- default_sort_type: read_user.default_sort_type,
- default_listing_type: read_user.default_listing_type,
- lang: read_user.lang,
- show_avatars: read_user.show_avatars,
- send_notifications_to_email: read_user.send_notifications_to_email,
- actor_id: read_user.actor_id,
- bio: read_user.bio,
- local: read_user.local,
- private_key: read_user.private_key,
- public_key: read_user.public_key,
- last_refreshed_at: None,
- };
-
- match User_::update(&conn, data.user_id, &user_form) {
+ match User_::ban_user(&conn, user_id, data.ban) {
Ok(user) => user,
Err(_e) => return Err(APIError::err("couldnt_update_user").into()),
};
.list()?;
for reply in &replies {
- let comment_form = CommentForm {
- content: reply.to_owned().content,
- parent_id: reply.to_owned().parent_id,
- post_id: reply.to_owned().post_id,
- creator_id: reply.to_owned().creator_id,
- removed: None,
- deleted: None,
- read: Some(true),
- updated: reply.to_owned().updated,
- };
-
- let _updated_comment = match Comment::update(&conn, reply.id, &comment_form) {
+ match Comment::mark_as_read(&conn, reply.id) {
Ok(comment) => comment,
Err(_e) => return Err(APIError::err("couldnt_update_comment").into()),
};
.list()?;
for comment in &comments {
- let comment_form = CommentForm {
- content: "*Permananently Deleted*".to_string(),
- parent_id: comment.to_owned().parent_id,
- post_id: comment.to_owned().post_id,
- creator_id: comment.to_owned().creator_id,
- removed: None,
- deleted: Some(true),
- read: None,
- updated: Some(naive_now()),
- };
-
- let _updated_comment = match Comment::update(&conn, comment.id, &comment_form) {
+ let _updated_comment = match Comment::permadelete(&conn, comment.id) {
Ok(comment) => comment,
Err(_e) => return Err(APIError::err("couldnt_update_comment").into()),
};
.list()?;
for post in &posts {
- let post_form = PostForm {
- name: "*Permananently Deleted*".to_string(),
- url: Some("https://deleted.com".to_string()),
- body: Some("*Permananently Deleted*".to_string()),
- creator_id: post.to_owned().creator_id,
- community_id: post.to_owned().community_id,
- removed: None,
- deleted: Some(true),
- nsfw: post.to_owned().nsfw,
- locked: None,
- stickied: None,
- updated: Some(naive_now()),
- embed_title: None,
- embed_description: None,
- embed_html: None,
- thumbnail_url: None,
- };
-
- let _updated_post = match Post::update(&conn, post.id, &post_form) {
+ let _updated_post = match Post::permadelete(&conn, post.id) {
Ok(post) => post,
Err(_e) => return Err(APIError::err("couldnt_update_post").into()),
};
Community,
User,
Post,
+ Comment,
}
pub fn make_apub_endpoint(endpoint_type: EndpointType, name: &str) -> Url {
let point = match endpoint_type {
- EndpointType::Community => "c",
- EndpointType::User => "u",
- EndpointType::Post => "p",
+ EndpointType::Community => "community",
+ EndpointType::User => "user",
+ EndpointType::Post => "post",
+ EndpointType::Comment => "comment",
};
Url::parse(&format!(
// This is for db migrations that require code
+use super::comment::Comment;
use super::community::{Community, CommunityForm};
+use super::post::Post;
use super::user::{UserForm, User_};
use super::*;
use crate::apub::{gen_keypair_str, make_apub_endpoint, EndpointType};
pub fn run_advanced_migrations(conn: &PgConnection) -> Result<(), Error> {
user_updates_2020_04_02(conn)?;
community_updates_2020_04_02(conn)?;
+ post_updates_2020_04_03(conn)?;
+ comment_updates_2020_04_03(conn)?;
Ok(())
}
Ok(())
}
+
+fn post_updates_2020_04_03(conn: &PgConnection) -> Result<(), Error> {
+ use crate::schema::post::dsl::*;
+
+ info!("Running post_updates_2020_04_03");
+
+ // Update the ap_id
+ let incorrect_posts = post
+ .filter(ap_id.eq("changeme"))
+ .filter(local.eq(true))
+ .load::<Post>(conn)?;
+
+ for cpost in &incorrect_posts {
+ Post::update_ap_id(&conn, cpost.id)?;
+ }
+
+ info!("{} post rows updated.", incorrect_posts.len());
+
+ Ok(())
+}
+
+fn comment_updates_2020_04_03(conn: &PgConnection) -> Result<(), Error> {
+ use crate::schema::comment::dsl::*;
+
+ info!("Running comment_updates_2020_04_03");
+
+ // Update the ap_id
+ let incorrect_comments = comment
+ .filter(ap_id.eq("changeme"))
+ .filter(local.eq(true))
+ .load::<Comment>(conn)?;
+
+ for ccomment in &incorrect_comments {
+ Comment::update_ap_id(&conn, ccomment.id)?;
+ }
+
+ info!("{} comment rows updated.", incorrect_comments.len());
+
+ Ok(())
+}
use super::post::Post;
use super::*;
+use crate::apub::{make_apub_endpoint, EndpointType};
+use crate::naive_now;
use crate::schema::{comment, comment_like, comment_saved};
// WITH RECURSIVE MyTree AS (
pub published: chrono::NaiveDateTime,
pub updated: Option<chrono::NaiveDateTime>,
pub deleted: bool,
+ pub ap_id: String,
+ pub local: bool,
}
#[derive(Insertable, AsChangeset, Clone)]
pub read: Option<bool>,
pub updated: Option<chrono::NaiveDateTime>,
pub deleted: Option<bool>,
+ pub ap_id: String,
+ pub local: bool,
}
impl Crud<CommentForm> for Comment {
}
}
+impl Comment {
+ pub fn update_ap_id(conn: &PgConnection, comment_id: i32) -> Result<Self, Error> {
+ use crate::schema::comment::dsl::*;
+
+ let apid = make_apub_endpoint(EndpointType::Comment, &comment_id.to_string()).to_string();
+ diesel::update(comment.find(comment_id))
+ .set(ap_id.eq(apid))
+ .get_result::<Self>(conn)
+ }
+
+ pub fn mark_as_read(conn: &PgConnection, comment_id: i32) -> Result<Self, Error> {
+ use crate::schema::comment::dsl::*;
+
+ diesel::update(comment.find(comment_id))
+ .set(read.eq(true))
+ .get_result::<Self>(conn)
+ }
+
+ pub fn permadelete(conn: &PgConnection, comment_id: i32) -> Result<Self, Error> {
+ use crate::schema::comment::dsl::*;
+
+ diesel::update(comment.find(comment_id))
+ .set((
+ content.eq("*Permananently Deleted*"),
+ deleted.eq(true),
+ updated.eq(naive_now()),
+ ))
+ .get_result::<Self>(conn)
+ }
+}
+
#[derive(Identifiable, Queryable, Associations, PartialEq, Debug, Clone)]
#[belongs_to(Comment)]
#[table_name = "comment_like"]
embed_description: None,
embed_html: None,
thumbnail_url: None,
+ ap_id: "changeme".into(),
+ local: true,
};
let inserted_post = Post::create(&conn, &new_post).unwrap();
read: None,
parent_id: None,
updated: None,
+ ap_id: "changeme".into(),
+ local: true,
};
let inserted_comment = Comment::create(&conn, &comment_form).unwrap();
parent_id: None,
published: inserted_comment.published,
updated: None,
+ ap_id: "changeme".into(),
+ local: true,
};
let child_comment_form = CommentForm {
deleted: None,
read: None,
updated: None,
+ ap_id: "changeme".into(),
+ local: true,
};
let inserted_child_comment = Comment::create(&conn, &child_comment_form).unwrap();
embed_description: None,
embed_html: None,
thumbnail_url: None,
+ ap_id: "changeme".into(),
+ local: true,
};
let inserted_post = Post::create(&conn, &new_post).unwrap();
deleted: None,
read: None,
updated: None,
+ ap_id: "changeme".into(),
+ local: true,
};
let inserted_comment = Comment::create(&conn, &comment_form).unwrap();
embed_description: None,
embed_html: None,
thumbnail_url: None,
+ ap_id: "changeme".into(),
+ local: true,
};
let inserted_post = Post::create(&conn, &new_post).unwrap();
read: None,
parent_id: None,
updated: None,
+ ap_id: "changeme".into(),
+ local: true,
};
let inserted_comment = Comment::create(&conn, &comment_form).unwrap();
use super::*;
+use crate::apub::{make_apub_endpoint, EndpointType};
+use crate::naive_now;
use crate::schema::{post, post_like, post_read, post_saved};
#[derive(Queryable, Identifiable, PartialEq, Debug, Serialize, Deserialize)]
pub embed_description: Option<String>,
pub embed_html: Option<String>,
pub thumbnail_url: Option<String>,
+ pub ap_id: String,
+ pub local: bool,
}
#[derive(Insertable, AsChangeset, Clone)]
pub embed_description: Option<String>,
pub embed_html: Option<String>,
pub thumbnail_url: Option<String>,
+ pub ap_id: String,
+ pub local: bool,
}
impl Post {
.filter(community_id.eq(the_community_id))
.load::<Self>(conn)
}
+
+ pub fn update_ap_id(conn: &PgConnection, post_id: i32) -> Result<Self, Error> {
+ use crate::schema::post::dsl::*;
+
+ let apid = make_apub_endpoint(EndpointType::Post, &post_id.to_string()).to_string();
+ diesel::update(post.find(post_id))
+ .set(ap_id.eq(apid))
+ .get_result::<Self>(conn)
+ }
+
+ pub fn permadelete(conn: &PgConnection, post_id: i32) -> Result<Self, Error> {
+ use crate::schema::post::dsl::*;
+
+ let perma_deleted = "*Permananently Deleted*";
+ let perma_deleted_url = "https://deleted.com";
+
+ diesel::update(post.find(post_id))
+ .set((
+ name.eq(perma_deleted),
+ url.eq(perma_deleted_url),
+ body.eq(perma_deleted),
+ deleted.eq(true),
+ updated.eq(naive_now()),
+ ))
+ .get_result::<Self>(conn)
+ }
}
impl Crud<PostForm> for Post {
embed_description: None,
embed_html: None,
thumbnail_url: None,
+ ap_id: "changeme".into(),
+ local: true,
};
let inserted_post = Post::create(&conn, &new_post).unwrap();
embed_description: None,
embed_html: None,
thumbnail_url: None,
+ ap_id: "changeme".into(),
+ local: true,
};
// Post Like
embed_description: None,
embed_html: None,
thumbnail_url: None,
+ ap_id: "changeme".into(),
+ local: true,
};
let inserted_post = Post::create(&conn, &new_post).unwrap();
use super::*;
use crate::schema::user_;
use crate::schema::user_::dsl::*;
-use crate::{is_email_regex, Settings};
+use crate::{is_email_regex, naive_now, Settings};
use bcrypt::{hash, DEFAULT_COST};
use jsonwebtoken::{decode, encode, DecodingKey, EncodingKey, Header, TokenData, Validation};
let password_hash = hash(new_password, DEFAULT_COST).expect("Couldn't hash password");
diesel::update(user_.find(user_id))
- .set(password_encrypted.eq(password_hash))
+ .set((
+ password_encrypted.eq(password_hash),
+ updated.eq(naive_now()),
+ ))
.get_result::<Self>(conn)
}
pub fn read_from_name(conn: &PgConnection, from_user_name: String) -> Result<Self, Error> {
user_.filter(name.eq(from_user_name)).first::<Self>(conn)
}
+
+ pub fn add_admin(conn: &PgConnection, user_id: i32, added: bool) -> Result<Self, Error> {
+ diesel::update(user_.find(user_id))
+ .set(admin.eq(added))
+ .get_result::<Self>(conn)
+ }
+
+ pub fn ban_user(conn: &PgConnection, user_id: i32, ban: bool) -> Result<Self, Error> {
+ diesel::update(user_.find(user_id))
+ .set(banned.eq(ban))
+ .get_result::<Self>(conn)
+ }
}
#[derive(Debug, Serialize, Deserialize)]
embed_description: None,
embed_html: None,
thumbnail_url: None,
+ ap_id: "changeme".into(),
+ local: true,
};
let inserted_post = Post::create(&conn, &new_post).unwrap();
read: None,
parent_id: None,
updated: None,
+ ap_id: "changeme".into(),
+ local: true,
};
let inserted_comment = Comment::create(&conn, &comment_form).unwrap();
published -> Timestamp,
updated -> Nullable<Timestamp>,
deleted -> Bool,
+ ap_id -> Varchar,
+ local -> Bool,
}
}
embed_description -> Nullable<Text>,
embed_html -> Nullable<Text>,
thumbnail_url -> Nullable<Text>,
+ ap_id -> Varchar,
+ local -> Bool,
}
}