From 59da2976abfc26268ee129424e1f8049cc5538ae Mon Sep 17 00:00:00 2001 From: Dessalines Date: Wed, 22 Jul 2020 14:20:08 -0400 Subject: [PATCH] Some more API cleanup. - Extracted methods for is_mod_or_admin, and is_admin. - Removed admins from GetPostResponse and GetCommunityResponse. - Some cleanup. --- docs/src/contributing_websocket_http_api.md | 2 -- server/src/api/comment.rs | 11 ++---- server/src/api/community.rs | 36 +++---------------- server/src/api/mod.rs | 34 ++++++++++++++++-- server/src/api/post.rs | 39 +++------------------ server/src/api/site.rs | 19 +++------- server/src/api/user.rs | 12 ++----- ui/src/components/community.tsx | 2 +- ui/src/components/post.tsx | 2 -- ui/src/interfaces.ts | 2 -- 10 files changed, 50 insertions(+), 109 deletions(-) diff --git a/docs/src/contributing_websocket_http_api.md b/docs/src/contributing_websocket_http_api.md index 8577a5e56..62cb1fc44 100644 --- a/docs/src/contributing_websocket_http_api.md +++ b/docs/src/contributing_websocket_http_api.md @@ -1054,7 +1054,6 @@ Search types are `All, Comments, Posts, Communities, Users, Url` data: { community: CommunityView, moderators: Vec, - admins: Vec, } } ``` @@ -1379,7 +1378,6 @@ Only admins can remove a community. comments: Vec, community: CommunityView, moderators: Vec, - admins: Vec, } } ``` diff --git a/server/src/api/comment.rs b/server/src/api/comment.rs index 2a5214554..df772f535 100644 --- a/server/src/api/comment.rs +++ b/server/src/api/comment.rs @@ -1,5 +1,5 @@ use crate::{ - api::{claims::Claims, APIError, Oper, Perform}, + api::{claims::Claims, is_mod_or_admin, APIError, Oper, Perform}, apub::{ApubLikeableType, ApubObjectType}, blocking, websocket::{ @@ -13,7 +13,6 @@ use crate::{ use lemmy_db::{ comment::*, comment_view::*, - community::Community, community_view::*, moderator::*, post::*, @@ -480,13 +479,7 @@ impl Perform for Oper { } // Verify that only a mod or admin can remove - let is_mod_or_admin = blocking(pool, move |conn| { - Community::is_mod_or_admin(conn, user_id, community_id) - }) - .await?; - if !is_mod_or_admin { - return Err(APIError::err("not_an_admin").into()); - } + is_mod_or_admin(pool, user_id, community_id).await?; // Do the remove let removed = data.removed; diff --git a/server/src/api/community.rs b/server/src/api/community.rs index 1ae7036f2..c5ae152aa 100644 --- a/server/src/api/community.rs +++ b/server/src/api/community.rs @@ -1,6 +1,6 @@ use super::*; use crate::{ - api::{claims::Claims, APIError, Oper, Perform}, + api::{claims::Claims, is_admin, is_mod_or_admin, APIError, Oper, Perform}, apub::ActorType, blocking, websocket::{ @@ -34,7 +34,6 @@ pub struct GetCommunity { pub struct GetCommunityResponse { pub community: CommunityView, pub moderators: Vec, - pub admins: Vec, // TODO this should be from GetSite, shouldn't need this pub online: usize, } @@ -196,13 +195,6 @@ impl Perform for Oper { Err(_e) => return Err(APIError::err("couldnt_find_community").into()), }; - let site = blocking(pool, move |conn| Site::read(conn, 1)).await??; - let site_creator_id = site.creator_id; - let mut admins = blocking(pool, move |conn| UserView::admins(conn)).await??; - let creator_index = admins.iter().position(|r| r.id == site_creator_id).unwrap(); - let creator_user = admins.remove(creator_index); - admins.insert(0, creator_user); - let online = if let Some(ws) = websocket_info { if let Some(id) = ws.id { ws.chatserver.do_send(JoinCommunityRoom { @@ -224,7 +216,6 @@ impl Perform for Oper { let res = GetCommunityResponse { community: community_view, moderators, - admins, online, }; @@ -534,13 +525,7 @@ impl Perform for Oper { } // Verify its an admin (only an admin can remove a community) - let admins: Vec = blocking(pool, move |conn| { - UserView::admins(conn).map(|v| v.into_iter().map(|a| a.id).collect()) - }) - .await??; - if !admins.contains(&user_id) { - return Err(APIError::err("not_an_admin").into()); - } + is_admin(pool, user_id).await?; // Do the remove let edit_id = data.edit_id; @@ -769,13 +754,7 @@ impl Perform for Oper { let community_id = data.community_id; // Verify that only mods or admins can ban - let is_mod_or_admin = blocking(pool, move |conn| { - Community::is_mod_or_admin(conn, user_id, community_id) - }) - .await?; - if !is_mod_or_admin { - return Err(APIError::err("not_an_admin").into()); - } + is_mod_or_admin(pool, user_id, community_id).await?; let community_user_ban_form = CommunityUserBanForm { community_id: data.community_id, @@ -858,13 +837,7 @@ impl Perform for Oper { let community_id = data.community_id; // Verify that only mods or admins can add mod - let is_mod_or_admin = blocking(pool, move |conn| { - Community::is_mod_or_admin(conn, user_id, community_id) - }) - .await?; - if !is_mod_or_admin { - return Err(APIError::err("not_an_admin").into()); - } + is_mod_or_admin(pool, user_id, community_id).await?; if data.added { let join = move |conn: &'_ _| CommunityModerator::join(conn, &community_moderator_form); @@ -1015,7 +988,6 @@ impl Perform for Oper { Ok(GetCommunityResponse { community: community_view, moderators, - admins, online: 0, }) } diff --git a/server/src/api/mod.rs b/server/src/api/mod.rs index bb65815ad..901172601 100644 --- a/server/src/api/mod.rs +++ b/server/src/api/mod.rs @@ -1,6 +1,14 @@ -use crate::{websocket::WebsocketInfo, DbPool, LemmyError}; +use crate::{blocking, websocket::WebsocketInfo, DbPool, LemmyError}; use actix_web::client::Client; -use lemmy_db::{community::*, community_view::*, moderator::*, site::*, user::*, user_view::*}; +use lemmy_db::{ + community::*, + community_view::*, + moderator::*, + site::*, + user::*, + user_view::*, + Crud, +}; pub mod claims; pub mod comment; @@ -44,3 +52,25 @@ pub trait Perform { websocket_info: Option, ) -> Result; } + +pub async fn is_mod_or_admin( + pool: &DbPool, + user_id: i32, + community_id: i32, +) -> Result<(), LemmyError> { + let is_mod_or_admin = blocking(pool, move |conn| { + Community::is_mod_or_admin(conn, user_id, community_id) + }) + .await?; + if !is_mod_or_admin { + return Err(APIError::err("not_an_admin").into()); + } + Ok(()) +} +pub async fn is_admin(pool: &DbPool, user_id: i32) -> Result<(), LemmyError> { + let user = blocking(pool, move |conn| User_::read(conn, user_id)).await??; + if !user.admin { + return Err(APIError::err("not_an_admin").into()); + } + Ok(()) +} diff --git a/server/src/api/post.rs b/server/src/api/post.rs index 70f46b2a2..79881c4b5 100644 --- a/server/src/api/post.rs +++ b/server/src/api/post.rs @@ -1,5 +1,5 @@ use crate::{ - api::{claims::Claims, APIError, Oper, Perform}, + api::{claims::Claims, is_mod_or_admin, APIError, Oper, Perform}, apub::{ApubLikeableType, ApubObjectType}, blocking, fetch_iframely_and_pictrs_data, @@ -13,16 +13,13 @@ use crate::{ }; use lemmy_db::{ comment_view::*, - community::*, community_view::*, moderator::*, naive_now, post::*, post_view::*, - site::*, site_view::*, user::*, - user_view::*, Crud, Likeable, ListingType, @@ -67,7 +64,6 @@ pub struct GetPostResponse { comments: Vec, community: CommunityView, moderators: Vec, - admins: Vec, pub online: usize, } @@ -334,14 +330,6 @@ impl Perform for Oper { }) .await??; - let site_creator_id = - blocking(pool, move |conn| Site::read(conn, 1).map(|s| s.creator_id)).await??; - - let mut admins = blocking(pool, move |conn| UserView::admins(conn)).await??; - let creator_index = admins.iter().position(|r| r.id == site_creator_id).unwrap(); - let creator_user = admins.remove(creator_index); - admins.insert(0, creator_user); - let online = if let Some(ws) = websocket_info { if let Some(id) = ws.id { ws.chatserver.do_send(JoinPostRoom { @@ -366,7 +354,6 @@ impl Perform for Oper { comments, community, moderators, - admins, online, }) } @@ -770,13 +757,7 @@ impl Perform for Oper { } // Verify that only the mods can remove - let is_mod_or_admin = blocking(pool, move |conn| { - Community::is_mod_or_admin(conn, user_id, community_id) - }) - .await?; - if !is_mod_or_admin { - return Err(APIError::err("not_an_admin").into()); - } + is_mod_or_admin(pool, user_id, community_id).await?; // Update the post let edit_id = data.edit_id; @@ -861,13 +842,7 @@ impl Perform for Oper { } // Verify that only the mods can lock - let is_mod_or_admin = blocking(pool, move |conn| { - Community::is_mod_or_admin(conn, user_id, community_id) - }) - .await?; - if !is_mod_or_admin { - return Err(APIError::err("not_an_admin").into()); - } + is_mod_or_admin(pool, user_id, community_id).await?; // Update the post let edit_id = data.edit_id; @@ -943,13 +918,7 @@ impl Perform for Oper { } // Verify that only the mods can sticky - let is_mod_or_admin = blocking(pool, move |conn| { - Community::is_mod_or_admin(conn, user_id, community_id) - }) - .await?; - if !is_mod_or_admin { - return Err(APIError::err("not_an_admin").into()); - } + is_mod_or_admin(pool, user_id, community_id).await?; // Update the post let edit_id = data.edit_id; diff --git a/server/src/api/site.rs b/server/src/api/site.rs index a945d9ec0..85511e6c9 100644 --- a/server/src/api/site.rs +++ b/server/src/api/site.rs @@ -1,6 +1,6 @@ use super::user::Register; use crate::{ - api::{claims::Claims, APIError, Oper, Perform}, + api::{claims::Claims, is_admin, APIError, Oper, Perform}, apub::fetcher::search_by_apub_id, blocking, version, @@ -257,10 +257,7 @@ impl Perform for Oper { let user_id = claims.id; // Make sure user is an admin - let user = blocking(pool, move |conn| UserView::read(conn, user_id)).await??; - if !user.admin { - return Err(APIError::err("not_an_admin").into()); - } + is_admin(pool, user_id).await?; let site_form = SiteForm { name: data.name.to_owned(), @@ -311,10 +308,7 @@ impl Perform for Oper { let user_id = claims.id; // Make sure user is an admin - let user = blocking(pool, move |conn| UserView::read(conn, user_id)).await??; - if !user.admin { - return Err(APIError::err("not_an_admin").into()); - } + is_admin(pool, user_id).await?; let found_site = blocking(pool, move |conn| Site::read(conn, 1)).await??; @@ -693,12 +687,7 @@ impl Perform for Oper { let user_id = claims.id; // Only let admins read this - let admins = blocking(pool, move |conn| UserView::admins(conn)).await??; - let admin_ids: Vec = admins.into_iter().map(|m| m.id).collect(); - - if !admin_ids.contains(&user_id) { - return Err(APIError::err("not_an_admin").into()); - } + is_admin(pool, user_id).await?; let config_hjson = Settings::read_config_file()?; diff --git a/server/src/api/user.rs b/server/src/api/user.rs index ec61c658e..32a16b00e 100644 --- a/server/src/api/user.rs +++ b/server/src/api/user.rs @@ -1,5 +1,5 @@ use crate::{ - api::{claims::Claims, APIError, Oper, Perform}, + api::{claims::Claims, is_admin, APIError, Oper, Perform}, apub::ApubObjectType, blocking, websocket::{ @@ -679,10 +679,7 @@ impl Perform for Oper { let user_id = claims.id; // Make sure user is an admin - let is_admin = move |conn: &'_ _| UserView::read(conn, user_id).map(|u| u.admin); - if !blocking(pool, is_admin).await?? { - return Err(APIError::err("not_an_admin").into()); - } + is_admin(pool, user_id).await?; let added = data.added; let added_user_id = data.user_id; @@ -741,10 +738,7 @@ impl Perform for Oper { let user_id = claims.id; // Make sure user is an admin - let is_admin = move |conn: &'_ _| UserView::read(conn, user_id).map(|u| u.admin); - if !blocking(pool, is_admin).await?? { - return Err(APIError::err("not_an_admin").into()); - } + is_admin(pool, user_id).await?; let ban = data.ban; let banned_user_id = data.user_id; diff --git a/ui/src/components/community.tsx b/ui/src/components/community.tsx index f70fa4f7a..f4610a08b 100644 --- a/ui/src/components/community.tsx +++ b/ui/src/components/community.tsx @@ -355,7 +355,6 @@ export class Community extends Component { let data = res.data as GetCommunityResponse; this.state.community = data.community; this.state.moderators = data.moderators; - this.state.admins = data.admins; this.state.online = data.online; document.title = `/c/${this.state.community.name} - ${this.state.site.name}`; this.setState(this.state); @@ -442,6 +441,7 @@ export class Community extends Component { } else if (res.op == UserOperation.GetSite) { let data = res.data as GetSiteResponse; this.state.site = data.site; + this.state.admins = data.admins; this.setState(this.state); } } diff --git a/ui/src/components/post.tsx b/ui/src/components/post.tsx index 9721eb05a..87b44bc34 100644 --- a/ui/src/components/post.tsx +++ b/ui/src/components/post.tsx @@ -405,7 +405,6 @@ export class Post extends Component { this.state.comments = data.comments; this.state.community = data.community; this.state.moderators = data.moderators; - this.state.siteRes.admins = data.admins; this.state.online = data.online; this.state.loading = false; document.title = `${this.state.post.name} - ${this.state.siteRes.site.name}`; @@ -531,7 +530,6 @@ export class Post extends Component { let data = res.data as GetCommunityResponse; this.state.community = data.community; this.state.moderators = data.moderators; - this.state.siteRes.admins = data.admins; this.setState(this.state); } } diff --git a/ui/src/interfaces.ts b/ui/src/interfaces.ts index e04eec63a..559fbca53 100644 --- a/ui/src/interfaces.ts +++ b/ui/src/interfaces.ts @@ -613,7 +613,6 @@ export interface GetCommunityForm { export interface GetCommunityResponse { community: Community; moderators: Array; - admins: Array; online: number; } @@ -688,7 +687,6 @@ export interface GetPostResponse { comments: Array; community: Community; moderators: Array; - admins: Array; online: number; }