5 #[derive(Serialize, Deserialize, Debug)]
7 username_or_email: String,
11 #[derive(Serialize, Deserialize)]
14 email: Option<String>,
16 password_verify: String,
21 #[derive(Serialize, Deserialize)]
22 pub struct SaveUserSettings {
28 #[derive(Serialize, Deserialize)]
29 pub struct LoginResponse {
34 #[derive(Serialize, Deserialize)]
35 pub struct GetUserDetails {
37 username: Option<String>,
41 community_id: Option<i32>,
46 #[derive(Serialize, Deserialize)]
47 pub struct GetUserDetailsResponse {
50 follows: Vec<CommunityFollowerView>,
51 moderates: Vec<CommunityModeratorView>,
52 comments: Vec<CommentView>,
54 admins: Vec<UserView>,
57 #[derive(Serialize, Deserialize)]
58 pub struct GetRepliesResponse {
60 replies: Vec<ReplyView>,
63 #[derive(Serialize, Deserialize)]
64 pub struct MarkAllAsRead {
68 #[derive(Serialize, Deserialize)]
75 #[derive(Serialize, Deserialize)]
76 pub struct AddAdminResponse {
78 admins: Vec<UserView>,
81 #[derive(Serialize, Deserialize)]
85 reason: Option<String>,
90 #[derive(Serialize, Deserialize)]
91 pub struct BanUserResponse {
97 #[derive(Serialize, Deserialize)]
98 pub struct GetReplies {
106 #[derive(Serialize, Deserialize)]
107 pub struct DeleteAccount {
111 impl Perform<LoginResponse> for Oper<Login> {
112 fn perform(&self) -> Result<LoginResponse, Error> {
113 let data: &Login = &self.data;
114 let conn = establish_connection();
116 // Fetch that username / email
117 let user: User_ = match User_::find_by_email_or_username(&conn, &data.username_or_email) {
120 return Err(APIError::err(
122 "couldnt_find_that_username_or_email",
127 // Verify the password
128 let valid: bool = verify(&data.password, &user.password_encrypted).unwrap_or(false);
130 return Err(APIError::err(&self.op, "password_incorrect"))?;
135 op: self.op.to_string(),
141 impl Perform<LoginResponse> for Oper<Register> {
142 fn perform(&self) -> Result<LoginResponse, Error> {
143 let data: &Register = &self.data;
144 let conn = establish_connection();
146 // Make sure passwords match
147 if &data.password != &data.password_verify {
148 return Err(APIError::err(&self.op, "passwords_dont_match"))?;
151 if has_slurs(&data.username) {
152 return Err(APIError::err(&self.op, "no_slurs"))?;
155 // Make sure there are no admins
156 if data.admin && UserView::admins(&conn)?.len() > 0 {
157 return Err(APIError::err(&self.op, "admin_already_created"))?;
160 // Register the new user
161 let user_form = UserForm {
162 name: data.username.to_owned(),
163 fedi_name: Settings::get().hostname.into(),
164 email: data.email.to_owned(),
165 password_encrypted: data.password.to_owned(),
166 preferred_username: None,
170 show_nsfw: data.show_nsfw,
171 theme: "darkly".into(),
175 let inserted_user = match User_::register(&conn, &user_form) {
177 Err(_e) => return Err(APIError::err(&self.op, "user_already_exists"))?,
180 // Create the main community if it doesn't exist
181 let main_community: Community = match Community::read(&conn, 2) {
184 let community_form = CommunityForm {
185 name: "main".to_string(),
186 title: "The Default Community".to_string(),
187 description: Some("The Default Community".to_string()),
190 creator_id: inserted_user.id,
195 Community::create(&conn, &community_form).unwrap()
199 // Sign them up for main community no matter what
200 let community_follower_form = CommunityFollowerForm {
201 community_id: main_community.id,
202 user_id: inserted_user.id,
205 let _inserted_community_follower =
206 match CommunityFollower::follow(&conn, &community_follower_form) {
208 Err(_e) => return Err(APIError::err(&self.op, "community_follower_already_exists"))?,
211 // If its an admin, add them as a mod and follower to main
213 let community_moderator_form = CommunityModeratorForm {
214 community_id: main_community.id,
215 user_id: inserted_user.id,
218 let _inserted_community_moderator =
219 match CommunityModerator::join(&conn, &community_moderator_form) {
222 return Err(APIError::err(
224 "community_moderator_already_exists",
232 op: self.op.to_string(),
233 jwt: inserted_user.jwt(),
238 impl Perform<LoginResponse> for Oper<SaveUserSettings> {
239 fn perform(&self) -> Result<LoginResponse, Error> {
240 let data: &SaveUserSettings = &self.data;
241 let conn = establish_connection();
243 let claims = match Claims::decode(&data.auth) {
244 Ok(claims) => claims.claims,
245 Err(_e) => return Err(APIError::err(&self.op, "not_logged_in"))?,
248 let user_id = claims.id;
250 let read_user = User_::read(&conn, user_id)?;
252 let user_form = UserForm {
253 name: read_user.name,
254 fedi_name: read_user.fedi_name,
255 email: read_user.email,
256 password_encrypted: read_user.password_encrypted,
257 preferred_username: read_user.preferred_username,
258 updated: Some(naive_now()),
259 admin: read_user.admin,
260 banned: read_user.banned,
261 show_nsfw: data.show_nsfw,
262 theme: data.theme.to_owned(),
265 let updated_user = match User_::update(&conn, user_id, &user_form) {
267 Err(_e) => return Err(APIError::err(&self.op, "couldnt_update_user"))?,
272 op: self.op.to_string(),
273 jwt: updated_user.jwt(),
278 impl Perform<GetUserDetailsResponse> for Oper<GetUserDetails> {
279 fn perform(&self) -> Result<GetUserDetailsResponse, Error> {
280 let data: &GetUserDetails = &self.data;
281 let conn = establish_connection();
283 let user_claims: Option<Claims> = match &data.auth {
284 Some(auth) => match Claims::decode(&auth) {
285 Ok(claims) => Some(claims.claims),
291 let user_id = match &user_claims {
292 Some(claims) => Some(claims.id),
296 let show_nsfw = match &user_claims {
297 Some(claims) => claims.show_nsfw,
302 let sort = SortType::from_str(&data.sort)?;
304 let user_details_id = match data.user_id {
307 User_::read_from_name(
309 data.username.to_owned().unwrap_or("admin".to_string()),
315 let user_view = UserView::read(&conn, user_details_id)?;
317 // If its saved only, you don't care what creator it was
318 let posts = if data.saved_only {
321 PostListingType::All,
327 Some(user_details_id),
337 PostListingType::All,
340 Some(user_details_id),
351 let comments = if data.saved_only {
358 Some(user_details_id),
368 Some(user_details_id),
377 let follows = CommunityFollowerView::for_user(&conn, user_details_id)?;
378 let moderates = CommunityModeratorView::for_user(&conn, user_details_id)?;
379 let site_creator_id = Site::read(&conn, 1)?.creator_id;
380 let mut admins = UserView::admins(&conn)?;
381 let creator_index = admins.iter().position(|r| r.id == site_creator_id).unwrap();
382 let creator_user = admins.remove(creator_index);
383 admins.insert(0, creator_user);
386 Ok(GetUserDetailsResponse {
387 op: self.op.to_string(),
390 moderates: moderates,
398 impl Perform<AddAdminResponse> for Oper<AddAdmin> {
399 fn perform(&self) -> Result<AddAdminResponse, Error> {
400 let data: &AddAdmin = &self.data;
401 let conn = establish_connection();
403 let claims = match Claims::decode(&data.auth) {
404 Ok(claims) => claims.claims,
405 Err(_e) => return Err(APIError::err(&self.op, "not_logged_in"))?,
408 let user_id = claims.id;
410 // Make sure user is an admin
411 if UserView::read(&conn, user_id)?.admin == false {
412 return Err(APIError::err(&self.op, "not_an_admin"))?;
415 let read_user = User_::read(&conn, data.user_id)?;
417 let user_form = UserForm {
418 name: read_user.name,
419 fedi_name: read_user.fedi_name,
420 email: read_user.email,
421 password_encrypted: read_user.password_encrypted,
422 preferred_username: read_user.preferred_username,
423 updated: Some(naive_now()),
425 banned: read_user.banned,
426 show_nsfw: read_user.show_nsfw,
427 theme: read_user.theme,
430 match User_::update(&conn, data.user_id, &user_form) {
432 Err(_e) => return Err(APIError::err(&self.op, "couldnt_update_user"))?,
436 let form = ModAddForm {
437 mod_user_id: user_id,
438 other_user_id: data.user_id,
439 removed: Some(!data.added),
442 ModAdd::create(&conn, &form)?;
444 let site_creator_id = Site::read(&conn, 1)?.creator_id;
445 let mut admins = UserView::admins(&conn)?;
446 let creator_index = admins.iter().position(|r| r.id == site_creator_id).unwrap();
447 let creator_user = admins.remove(creator_index);
448 admins.insert(0, creator_user);
450 Ok(AddAdminResponse {
451 op: self.op.to_string(),
457 impl Perform<BanUserResponse> for Oper<BanUser> {
458 fn perform(&self) -> Result<BanUserResponse, Error> {
459 let data: &BanUser = &self.data;
460 let conn = establish_connection();
462 let claims = match Claims::decode(&data.auth) {
463 Ok(claims) => claims.claims,
464 Err(_e) => return Err(APIError::err(&self.op, "not_logged_in"))?,
467 let user_id = claims.id;
469 // Make sure user is an admin
470 if UserView::read(&conn, user_id)?.admin == false {
471 return Err(APIError::err(&self.op, "not_an_admin"))?;
474 let read_user = User_::read(&conn, data.user_id)?;
476 let user_form = UserForm {
477 name: read_user.name,
478 fedi_name: read_user.fedi_name,
479 email: read_user.email,
480 password_encrypted: read_user.password_encrypted,
481 preferred_username: read_user.preferred_username,
482 updated: Some(naive_now()),
483 admin: read_user.admin,
485 show_nsfw: read_user.show_nsfw,
486 theme: read_user.theme,
489 match User_::update(&conn, data.user_id, &user_form) {
491 Err(_e) => return Err(APIError::err(&self.op, "couldnt_update_user"))?,
495 let expires = match data.expires {
496 Some(time) => Some(naive_from_unix(time)),
500 let form = ModBanForm {
501 mod_user_id: user_id,
502 other_user_id: data.user_id,
503 reason: data.reason.to_owned(),
504 banned: Some(data.ban),
508 ModBan::create(&conn, &form)?;
510 let user_view = UserView::read(&conn, data.user_id)?;
513 op: self.op.to_string(),
520 impl Perform<GetRepliesResponse> for Oper<GetReplies> {
521 fn perform(&self) -> Result<GetRepliesResponse, Error> {
522 let data: &GetReplies = &self.data;
523 let conn = establish_connection();
525 let claims = match Claims::decode(&data.auth) {
526 Ok(claims) => claims.claims,
527 Err(_e) => return Err(APIError::err(&self.op, "not_logged_in"))?,
530 let user_id = claims.id;
532 let sort = SortType::from_str(&data.sort)?;
534 let replies = ReplyView::get_replies(
544 Ok(GetRepliesResponse {
545 op: self.op.to_string(),
551 impl Perform<GetRepliesResponse> for Oper<MarkAllAsRead> {
552 fn perform(&self) -> Result<GetRepliesResponse, Error> {
553 let data: &MarkAllAsRead = &self.data;
554 let conn = establish_connection();
556 let claims = match Claims::decode(&data.auth) {
557 Ok(claims) => claims.claims,
558 Err(_e) => return Err(APIError::err(&self.op, "not_logged_in"))?,
561 let user_id = claims.id;
563 let replies = ReplyView::get_replies(&conn, user_id, &SortType::New, true, Some(1), Some(999))?;
565 for reply in &replies {
566 let comment_form = CommentForm {
567 content: reply.to_owned().content,
568 parent_id: reply.to_owned().parent_id,
569 post_id: reply.to_owned().post_id,
570 creator_id: reply.to_owned().creator_id,
574 updated: reply.to_owned().updated,
577 let _updated_comment = match Comment::update(&conn, reply.id, &comment_form) {
578 Ok(comment) => comment,
579 Err(_e) => return Err(APIError::err(&self.op, "couldnt_update_comment"))?,
583 let replies = ReplyView::get_replies(&conn, user_id, &SortType::New, true, Some(1), Some(999))?;
585 Ok(GetRepliesResponse {
586 op: self.op.to_string(),
592 impl Perform<LoginResponse> for Oper<DeleteAccount> {
593 fn perform(&self) -> Result<LoginResponse, Error> {
594 let data: &DeleteAccount = &self.data;
595 let conn = establish_connection();
597 let claims = match Claims::decode(&data.auth) {
598 Ok(claims) => claims.claims,
599 Err(_e) => return Err(APIError::err(&self.op, "not_logged_in"))?,
602 let user_id = claims.id;
605 let comments = CommentView::list(
617 for comment in &comments {
618 let comment_form = CommentForm {
619 content: "*Permananently Deleted*".to_string(),
620 parent_id: comment.to_owned().parent_id,
621 post_id: comment.to_owned().post_id,
622 creator_id: comment.to_owned().creator_id,
626 updated: Some(naive_now()),
629 let _updated_comment = match Comment::update(&conn, comment.id, &comment_form) {
630 Ok(comment) => comment,
631 Err(_e) => return Err(APIError::err(&self.op, "couldnt_update_comment"))?,
636 let posts = PostView::list(
638 PostListingType::All,
653 let post_form = PostForm {
654 name: "*Permananently Deleted*".to_string(),
655 url: Some("https://deleted.com".to_string()),
656 body: Some("*Permananently Deleted*".to_string()),
657 creator_id: post.to_owned().creator_id,
658 community_id: post.to_owned().community_id,
661 nsfw: post.to_owned().nsfw,
664 updated: Some(naive_now()),
667 let _updated_post = match Post::update(&conn, post.id, &post_form) {
669 Err(_e) => return Err(APIError::err(&self.op, "couldnt_update_post"))?,
674 op: self.op.to_string(),
675 jwt: data.auth.to_owned(),