Some more API cleanup.

- Extracted methods for is_mod_or_admin, and is_admin.
- Removed admins from GetPostResponse and GetCommunityResponse.
- Some cleanup.
This commit is contained in:
Dessalines 2020-07-22 14:20:08 -04:00
parent b6a6d52a92
commit 59da2976ab
10 changed files with 50 additions and 109 deletions

View File

@ -1054,7 +1054,6 @@ Search types are `All, Comments, Posts, Communities, Users, Url`
data: { data: {
community: CommunityView, community: CommunityView,
moderators: Vec<CommunityModeratorView>, moderators: Vec<CommunityModeratorView>,
admins: Vec<UserView>,
} }
} }
``` ```
@ -1379,7 +1378,6 @@ Only admins can remove a community.
comments: Vec<CommentView>, comments: Vec<CommentView>,
community: CommunityView, community: CommunityView,
moderators: Vec<CommunityModeratorView>, moderators: Vec<CommunityModeratorView>,
admins: Vec<UserView>,
} }
} }
``` ```

View File

@ -1,5 +1,5 @@
use crate::{ use crate::{
api::{claims::Claims, APIError, Oper, Perform}, api::{claims::Claims, is_mod_or_admin, APIError, Oper, Perform},
apub::{ApubLikeableType, ApubObjectType}, apub::{ApubLikeableType, ApubObjectType},
blocking, blocking,
websocket::{ websocket::{
@ -13,7 +13,6 @@ use crate::{
use lemmy_db::{ use lemmy_db::{
comment::*, comment::*,
comment_view::*, comment_view::*,
community::Community,
community_view::*, community_view::*,
moderator::*, moderator::*,
post::*, post::*,
@ -480,13 +479,7 @@ impl Perform for Oper<RemoveComment> {
} }
// Verify that only a mod or admin can remove // Verify that only a mod or admin can remove
let is_mod_or_admin = blocking(pool, move |conn| { is_mod_or_admin(pool, user_id, community_id).await?;
Community::is_mod_or_admin(conn, user_id, community_id)
})
.await?;
if !is_mod_or_admin {
return Err(APIError::err("not_an_admin").into());
}
// Do the remove // Do the remove
let removed = data.removed; let removed = data.removed;

View File

@ -1,6 +1,6 @@
use super::*; use super::*;
use crate::{ use crate::{
api::{claims::Claims, APIError, Oper, Perform}, api::{claims::Claims, is_admin, is_mod_or_admin, APIError, Oper, Perform},
apub::ActorType, apub::ActorType,
blocking, blocking,
websocket::{ websocket::{
@ -34,7 +34,6 @@ pub struct GetCommunity {
pub struct GetCommunityResponse { pub struct GetCommunityResponse {
pub community: CommunityView, pub community: CommunityView,
pub moderators: Vec<CommunityModeratorView>, pub moderators: Vec<CommunityModeratorView>,
pub admins: Vec<UserView>, // TODO this should be from GetSite, shouldn't need this
pub online: usize, pub online: usize,
} }
@ -196,13 +195,6 @@ impl Perform for Oper<GetCommunity> {
Err(_e) => return Err(APIError::err("couldnt_find_community").into()), 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 { let online = if let Some(ws) = websocket_info {
if let Some(id) = ws.id { if let Some(id) = ws.id {
ws.chatserver.do_send(JoinCommunityRoom { ws.chatserver.do_send(JoinCommunityRoom {
@ -224,7 +216,6 @@ impl Perform for Oper<GetCommunity> {
let res = GetCommunityResponse { let res = GetCommunityResponse {
community: community_view, community: community_view,
moderators, moderators,
admins,
online, online,
}; };
@ -534,13 +525,7 @@ impl Perform for Oper<RemoveCommunity> {
} }
// Verify its an admin (only an admin can remove a community) // Verify its an admin (only an admin can remove a community)
let admins: Vec<i32> = blocking(pool, move |conn| { is_admin(pool, user_id).await?;
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());
}
// Do the remove // Do the remove
let edit_id = data.edit_id; let edit_id = data.edit_id;
@ -769,13 +754,7 @@ impl Perform for Oper<BanFromCommunity> {
let community_id = data.community_id; let community_id = data.community_id;
// Verify that only mods or admins can ban // Verify that only mods or admins can ban
let is_mod_or_admin = blocking(pool, move |conn| { is_mod_or_admin(pool, user_id, community_id).await?;
Community::is_mod_or_admin(conn, user_id, community_id)
})
.await?;
if !is_mod_or_admin {
return Err(APIError::err("not_an_admin").into());
}
let community_user_ban_form = CommunityUserBanForm { let community_user_ban_form = CommunityUserBanForm {
community_id: data.community_id, community_id: data.community_id,
@ -858,13 +837,7 @@ impl Perform for Oper<AddModToCommunity> {
let community_id = data.community_id; let community_id = data.community_id;
// Verify that only mods or admins can add mod // Verify that only mods or admins can add mod
let is_mod_or_admin = blocking(pool, move |conn| { is_mod_or_admin(pool, user_id, community_id).await?;
Community::is_mod_or_admin(conn, user_id, community_id)
})
.await?;
if !is_mod_or_admin {
return Err(APIError::err("not_an_admin").into());
}
if data.added { if data.added {
let join = move |conn: &'_ _| CommunityModerator::join(conn, &community_moderator_form); let join = move |conn: &'_ _| CommunityModerator::join(conn, &community_moderator_form);
@ -1015,7 +988,6 @@ impl Perform for Oper<TransferCommunity> {
Ok(GetCommunityResponse { Ok(GetCommunityResponse {
community: community_view, community: community_view,
moderators, moderators,
admins,
online: 0, online: 0,
}) })
} }

View File

@ -1,6 +1,14 @@
use crate::{websocket::WebsocketInfo, DbPool, LemmyError}; use crate::{blocking, websocket::WebsocketInfo, DbPool, LemmyError};
use actix_web::client::Client; 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 claims;
pub mod comment; pub mod comment;
@ -44,3 +52,25 @@ pub trait Perform {
websocket_info: Option<WebsocketInfo>, websocket_info: Option<WebsocketInfo>,
) -> Result<Self::Response, LemmyError>; ) -> Result<Self::Response, LemmyError>;
} }
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(())
}

View File

@ -1,5 +1,5 @@
use crate::{ use crate::{
api::{claims::Claims, APIError, Oper, Perform}, api::{claims::Claims, is_mod_or_admin, APIError, Oper, Perform},
apub::{ApubLikeableType, ApubObjectType}, apub::{ApubLikeableType, ApubObjectType},
blocking, blocking,
fetch_iframely_and_pictrs_data, fetch_iframely_and_pictrs_data,
@ -13,16 +13,13 @@ use crate::{
}; };
use lemmy_db::{ use lemmy_db::{
comment_view::*, comment_view::*,
community::*,
community_view::*, community_view::*,
moderator::*, moderator::*,
naive_now, naive_now,
post::*, post::*,
post_view::*, post_view::*,
site::*,
site_view::*, site_view::*,
user::*, user::*,
user_view::*,
Crud, Crud,
Likeable, Likeable,
ListingType, ListingType,
@ -67,7 +64,6 @@ pub struct GetPostResponse {
comments: Vec<CommentView>, comments: Vec<CommentView>,
community: CommunityView, community: CommunityView,
moderators: Vec<CommunityModeratorView>, moderators: Vec<CommunityModeratorView>,
admins: Vec<UserView>,
pub online: usize, pub online: usize,
} }
@ -334,14 +330,6 @@ impl Perform for Oper<GetPost> {
}) })
.await??; .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 { let online = if let Some(ws) = websocket_info {
if let Some(id) = ws.id { if let Some(id) = ws.id {
ws.chatserver.do_send(JoinPostRoom { ws.chatserver.do_send(JoinPostRoom {
@ -366,7 +354,6 @@ impl Perform for Oper<GetPost> {
comments, comments,
community, community,
moderators, moderators,
admins,
online, online,
}) })
} }
@ -770,13 +757,7 @@ impl Perform for Oper<RemovePost> {
} }
// Verify that only the mods can remove // Verify that only the mods can remove
let is_mod_or_admin = blocking(pool, move |conn| { is_mod_or_admin(pool, user_id, community_id).await?;
Community::is_mod_or_admin(conn, user_id, community_id)
})
.await?;
if !is_mod_or_admin {
return Err(APIError::err("not_an_admin").into());
}
// Update the post // Update the post
let edit_id = data.edit_id; let edit_id = data.edit_id;
@ -861,13 +842,7 @@ impl Perform for Oper<LockPost> {
} }
// Verify that only the mods can lock // Verify that only the mods can lock
let is_mod_or_admin = blocking(pool, move |conn| { is_mod_or_admin(pool, user_id, community_id).await?;
Community::is_mod_or_admin(conn, user_id, community_id)
})
.await?;
if !is_mod_or_admin {
return Err(APIError::err("not_an_admin").into());
}
// Update the post // Update the post
let edit_id = data.edit_id; let edit_id = data.edit_id;
@ -943,13 +918,7 @@ impl Perform for Oper<StickyPost> {
} }
// Verify that only the mods can sticky // Verify that only the mods can sticky
let is_mod_or_admin = blocking(pool, move |conn| { is_mod_or_admin(pool, user_id, community_id).await?;
Community::is_mod_or_admin(conn, user_id, community_id)
})
.await?;
if !is_mod_or_admin {
return Err(APIError::err("not_an_admin").into());
}
// Update the post // Update the post
let edit_id = data.edit_id; let edit_id = data.edit_id;

View File

@ -1,6 +1,6 @@
use super::user::Register; use super::user::Register;
use crate::{ use crate::{
api::{claims::Claims, APIError, Oper, Perform}, api::{claims::Claims, is_admin, APIError, Oper, Perform},
apub::fetcher::search_by_apub_id, apub::fetcher::search_by_apub_id,
blocking, blocking,
version, version,
@ -257,10 +257,7 @@ impl Perform for Oper<CreateSite> {
let user_id = claims.id; let user_id = claims.id;
// Make sure user is an admin // Make sure user is an admin
let user = blocking(pool, move |conn| UserView::read(conn, user_id)).await??; is_admin(pool, user_id).await?;
if !user.admin {
return Err(APIError::err("not_an_admin").into());
}
let site_form = SiteForm { let site_form = SiteForm {
name: data.name.to_owned(), name: data.name.to_owned(),
@ -311,10 +308,7 @@ impl Perform for Oper<EditSite> {
let user_id = claims.id; let user_id = claims.id;
// Make sure user is an admin // Make sure user is an admin
let user = blocking(pool, move |conn| UserView::read(conn, user_id)).await??; is_admin(pool, user_id).await?;
if !user.admin {
return Err(APIError::err("not_an_admin").into());
}
let found_site = blocking(pool, move |conn| Site::read(conn, 1)).await??; let found_site = blocking(pool, move |conn| Site::read(conn, 1)).await??;
@ -693,12 +687,7 @@ impl Perform for Oper<GetSiteConfig> {
let user_id = claims.id; let user_id = claims.id;
// Only let admins read this // Only let admins read this
let admins = blocking(pool, move |conn| UserView::admins(conn)).await??; is_admin(pool, user_id).await?;
let admin_ids: Vec<i32> = admins.into_iter().map(|m| m.id).collect();
if !admin_ids.contains(&user_id) {
return Err(APIError::err("not_an_admin").into());
}
let config_hjson = Settings::read_config_file()?; let config_hjson = Settings::read_config_file()?;

View File

@ -1,5 +1,5 @@
use crate::{ use crate::{
api::{claims::Claims, APIError, Oper, Perform}, api::{claims::Claims, is_admin, APIError, Oper, Perform},
apub::ApubObjectType, apub::ApubObjectType,
blocking, blocking,
websocket::{ websocket::{
@ -679,10 +679,7 @@ impl Perform for Oper<AddAdmin> {
let user_id = claims.id; let user_id = claims.id;
// Make sure user is an admin // Make sure user is an admin
let is_admin = move |conn: &'_ _| UserView::read(conn, user_id).map(|u| u.admin); is_admin(pool, user_id).await?;
if !blocking(pool, is_admin).await?? {
return Err(APIError::err("not_an_admin").into());
}
let added = data.added; let added = data.added;
let added_user_id = data.user_id; let added_user_id = data.user_id;
@ -741,10 +738,7 @@ impl Perform for Oper<BanUser> {
let user_id = claims.id; let user_id = claims.id;
// Make sure user is an admin // Make sure user is an admin
let is_admin = move |conn: &'_ _| UserView::read(conn, user_id).map(|u| u.admin); is_admin(pool, user_id).await?;
if !blocking(pool, is_admin).await?? {
return Err(APIError::err("not_an_admin").into());
}
let ban = data.ban; let ban = data.ban;
let banned_user_id = data.user_id; let banned_user_id = data.user_id;

View File

@ -355,7 +355,6 @@ export class Community extends Component<any, State> {
let data = res.data as GetCommunityResponse; let data = res.data as GetCommunityResponse;
this.state.community = data.community; this.state.community = data.community;
this.state.moderators = data.moderators; this.state.moderators = data.moderators;
this.state.admins = data.admins;
this.state.online = data.online; this.state.online = data.online;
document.title = `/c/${this.state.community.name} - ${this.state.site.name}`; document.title = `/c/${this.state.community.name} - ${this.state.site.name}`;
this.setState(this.state); this.setState(this.state);
@ -442,6 +441,7 @@ export class Community extends Component<any, State> {
} else if (res.op == UserOperation.GetSite) { } else if (res.op == UserOperation.GetSite) {
let data = res.data as GetSiteResponse; let data = res.data as GetSiteResponse;
this.state.site = data.site; this.state.site = data.site;
this.state.admins = data.admins;
this.setState(this.state); this.setState(this.state);
} }
} }

View File

@ -405,7 +405,6 @@ export class Post extends Component<any, PostState> {
this.state.comments = data.comments; this.state.comments = data.comments;
this.state.community = data.community; this.state.community = data.community;
this.state.moderators = data.moderators; this.state.moderators = data.moderators;
this.state.siteRes.admins = data.admins;
this.state.online = data.online; this.state.online = data.online;
this.state.loading = false; this.state.loading = false;
document.title = `${this.state.post.name} - ${this.state.siteRes.site.name}`; document.title = `${this.state.post.name} - ${this.state.siteRes.site.name}`;
@ -531,7 +530,6 @@ export class Post extends Component<any, PostState> {
let data = res.data as GetCommunityResponse; let data = res.data as GetCommunityResponse;
this.state.community = data.community; this.state.community = data.community;
this.state.moderators = data.moderators; this.state.moderators = data.moderators;
this.state.siteRes.admins = data.admins;
this.setState(this.state); this.setState(this.state);
} }
} }

View File

@ -613,7 +613,6 @@ export interface GetCommunityForm {
export interface GetCommunityResponse { export interface GetCommunityResponse {
community: Community; community: Community;
moderators: Array<CommunityUser>; moderators: Array<CommunityUser>;
admins: Array<UserView>;
online: number; online: number;
} }
@ -688,7 +687,6 @@ export interface GetPostResponse {
comments: Array<Comment>; comments: Array<Comment>;
community: Community; community: Community;
moderators: Array<CommunityUser>; moderators: Array<CommunityUser>;
admins: Array<UserView>;
online: number; online: number;
} }